Identity – Důvod přetypovávání ID na integer
- maarlin
- Člen | 207
Existuje nějaký opodstatněný důvod, proč se číselná ID
přetypovávají v \Nette\Security\Identity
na integer?
https://github.com/…Identity.php#L63
Dle mého názoru je to kontraproduktivní – s ID asi nikdy nebudu dělat žádné výpočty (rozuměj nebudu dvě ID sčítat nebo násobit), abych to vůbec potřeboval v integeru.
Co je horší, je fakt, že to může způsobovat potíže na kombinaci 32bit OS a vysokými ID. Většina aktuálních Facebookových ID již spolehlivě přesahuje 32bit integer. Tudíž při přetypování na takovém stroji z toho vyleze úplně jiné ID, než bylo zamýšleno.
Existoval před 3 mi roky nějaký důvod k tomuto commitu?
- Filip Procházka
- Moderator | 4668
Číslo je číslo. Povedlo se ti snad vytvořit v databázi 2147483647 uživatelů?
- Filip Procházka
- Moderator | 4668
Eh, omlouvám se :) Ten nejdelší odstavec jsem nedočetl :)
Uživatele bych si být tebou vedl pod vlastním ID, facebookId je imho jen nějaké asociace „navíc“. PHPčko je sviňa, když može tak zkouší všechno převádět na inty. Když to budeš porovnávat, tak dřív nebo později budeš mít problém, protože to bude porovnávat blbě.
Ale hledal jsem a důvod jsem nenašel. Možná je to něco historického, co by se mohlo odstranit?
- Filip Procházka
- Moderator | 4668
Tu hodnotu si v pohodě předáš kam chceš ve stringu, ale jakmile to budeš porovnávat, tak to bude porovnávat špatně.
Editoval HosipLan (3. 9. 2012 19:45)
- maarlin
- Člen | 207
HosipLan napsal(a):
Tu hodnotu si v pohodě předáš kam chceš ve stringu, ale jakmile to budeš porovnávat, tak to bude porovnávat špatně.
Asi nechápu problém při porovnávání – jediné porovnání, které v případě ID dává smysl je rovnost. A pokud to ID, se kterým jiné ID porovnáváš odněkud taháš, řešíš stejný problém – tvoje ORM/databázová vrstva to musí v nějakém typu vytáhnout do PHPka.
Pokud to vytáhne v integeru, máš stejný problém a dokonce ještě horší = ID z ORM a Identity se budou rovnat, protože v obou případech přetečou.
- maarlin
- Člen | 207
22 napsal(a):
No já nevím, když je v DB ID jako int s autoincrementem, proč by v Nette Identitě mělo být string? Nebo někdo má v DB ID jako string?
Edit: navíc mám pocit, že PHP SDK počítá s FB ID taky jako se stringem.
Kdo říká že ID v Identity musí být vzato z auto-incremented hodnoty v databázi?
- Patrik Votoček
- Člen | 2221
22 napsal(a):
… Nebo někdo má v DB ID jako string?
Co jiného by mělo být ID uživatele, než unikátní číslo? je jedno, jestli vzniklo autoinkrementací, nebo jiným způsobem.
Ve většině dokumentových databází ID není INT ale nějaká složenina hashe a dalších údajů. Kdo říká že ID nemůže být třeba UUID string.
- maarlin
- Člen | 207
Jsem připraven poslat pull request, nicméně nabízí se několik variant:
- prostě kontrolu + přetypování odebrat
public function setId($id)
{
$this->updating();
$this->id = $id;
return $this;
}
- nahradit kontrolou + přetypováním na string
public function setId($id)
{
$this->updating();
$this->id = is_string($id) ? $id : (string) $id;
return $this;
}
- nahradit kontrolou + vyhazováním InvalidArgumentException, pokud to nebude string nebo integer + ponechání původního typu
public function setId($id)
{
$this->validateId($id);
$this->updating();
$this->id = $id;
return $this;
}
private function validateId($id)
{
if (!is_string($id) && !is_numeric($id)) {
throw new Nette\InvalidArgumentException(
'Expected int or string, ' . gettype($id) . ' given')
}
}
Co z toho vám dává největší smysl?
Faktem je, že programátor by měl vědět co předává jako ID a framework by mu měl klást v tomto minimum WTFs tím, že mu to bude pod rukama měnit.
= mě se nejvíc zamlouvá varianta 3.
Případně pokud máte ještě jiné nápady jak to vyřešit, sem s nimi!
- David Grudl
- Nette Core | 8218
Buď zrušit přetypovávání bez náhrady (tím, že to dělá Nette\Database, to není vlastně potřeba) nebo ho udělat hodně opatrně (kontrola na float + levostranných nul).