Identity – Důvod přetypovávání ID na integer

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
maarlin
Člen | 207
+
0
-

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?

https://github.com/…ac0245c152dd

Filip Procházka
Moderator | 4668
+
0
-

Číslo je číslo. Povedlo se ti snad vytvořit v databázi 2147483647 uživatelů?

hrach
Člen | 1819
+
0
-

Ty sis to neprecetl?

Filip Procházka
Moderator | 4668
+
0
-

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?

hrach
Člen | 1819
+
0
-

K tomu, ze je PHP svina: je, podle me ti nebude fungovat ani vlozeni jako klic pole. Ono uvidi, ze je to numeric a hned to bude taky prevadet naint… :)

22
Člen | 1478
+
0
-

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.

Editoval 22 (3. 9. 2012 19:13)

Filip Procházka
Moderator | 4668
+
0
-

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)

paranoiq
Člen | 390
+
0
-

a co to ošetřit takhle? https://github.com/…tatement.php#L112

maarlin
Člen | 207
+
0
-

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
+
0
-

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?

22
Člen | 1478
+
0
-

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.

Patrik Votoček
Člen | 2221
+
0
-

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
+
0
-

Jsem připraven poslat pull request, nicméně nabízí se několik variant:

  1. prostě kontrolu + přetypování odebrat
public function setId($id)
{
	$this->updating();
	$this->id = $id;
	return $this;
}
  1. nahradit kontrolou + přetypováním na string
public function setId($id)
{
	$this->updating();
	$this->id = is_string($id) ? $id : (string) $id;
	return $this;
}
  1. 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!

22
Člen | 1478
+
0
-

co spíš do konstruktoru dát přepínáč, jak se setId() má chovat? Default zůstane současný stav a přepínač vypne přetypování..?

Edit: nebo na přepínač nějaký setter, ať se nesahá na construct

Editoval 22 (5. 9. 2012 23:10)

David Grudl
Nette Core | 7420
+
0
-

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).

LeonardoCA
Člen | 296
+
0
-

+1 zrušit

Honza Kuchař
Backer | 1660
+
0
-

Jsem pro variantu č. 3

Filip Procházka
Moderator | 4668
+
0
-

Zrušit. Nevidím v tom žádný přínos.

Aurielle
Člen | 1281
+
0
-

+1 pro zrušit

uestla
Backer | 765
+
0
-

I já jsem pro zrušení. Nechce se mi více psáti $this->user->identity->data['id'].