Proč používat Nette\Utils\ArrayHash namísto php ArrayObject?

Šaman
Člen | 2654
+
+1
-

Pracuji s kolekcemi, které dědím od ArrayObject. A teď koukám, že v Nette\Utils je stále třída ArrayHash – tak jsem chvíli hledal, ale nenašel odpověď na otázku jaký je její účel? V čem je lepší?

(Zato jsem našel, že třída Collection byla v Nette někdy ve verzi 0.8 nativně. :)

m.brecher
Generous Backer | 840
+
-4
-

@Šaman

odpověď na otázku jaký je její účel?

ArrayHash používají Nette formuláře jako doporučený formát odeslaných dat. Výhodou formátu ArrayHash je, že umožňuje objektovou syntaxi property i syntaxi pole (oproti stdClass). Na rozdíl od ArrayObject lze property dynamicky přidávat/odebírat, což je při zpracování formulářů výhodné. Dost často formulář obsahuje data, která neodpovídají přesně struktuře dat v databázi a některá pole se přidávají/odebírají. Použití ArrayHash tak zjednodušuje kód. Stejně lze použít formát stdClass, kde ale chybí možnost array access. Příklad:

protected function handleCreate(BaseForm $form, ArrayHash $values)
{
    $values->filename = $this->fileModel->saveUploadedFile($values->file);  // přidání pole
    $values = Helpers::remove($values, 'file');            //   odstranění nežádoucího pole
	$this->fileModel->save($values);
}

Editoval m.brecher (8. 3. 0:49)

Kamil Valenta
Člen | 799
+
0
-

m.brecher napsal(a):

Na rozdíl od ArrayObject lze property dynamicky přidávat/odebírat

Proč by to u ArrayObject nemělo jít?

m.brecher
Generous Backer | 840
+
0
-

@KamilValenta

Proč by to u ArrayObject nemělo jít?

// PHP 8.3
$object = new ArrayObject();
$object->property = 'abc';
Deprecated
Creation of dynamic property ArrayObject::$property is deprecated
Kamil Valenta
Člen | 799
+
0
-

m.brecher napsal(a):

// PHP 8.3
$object = new ArrayObject();
$object->property = 'abc';
Deprecated
Creation of dynamic property ArrayObject::$property is deprecated
// PHP 8.3
$object = new ArrayObject();
$object->setFlags(ArrayObject::ARRAY_AS_PROPS);
$object->property = 'abc';
m.brecher
Generous Backer | 840
+
0
-

@KamilValenta, @Šaman

Opravuji, po upozornění Kamila to vypadá, že Nette ArrayHash

$values = new ArrayHash();

oproti PHP ArrayObject:

$values = new ArrayObject(flags: ArrayObject::ARRAY_AS_PROPS);

nepřináší nové funkce, nicméně syntaxe je o něco pohodlnější.

Editoval m.brecher (8. 3. 15:18)

Šaman
Člen | 2654
+
0
-

Popravdě šlo mi spíš o to, že David nedědil od ArrayObject, ale implementoval si potřebná rozhranní sám. Tak spíš jestli je to doporučovaný jakoby Nette ArrayObject (stejně jako má Nette svůj DateTime), nebo jestli je to jen třída vytvořená třeba pro ty pohodlnější pole formuláře.

David Grudl
Nette Core | 8206
+
+4
-

ArrayHash existuje kvůli tomu, že data formulářu (a taky Row u databaze) se historicky nějak vyvíjela od pole k objektům a tohle byl mezičlánek, který zachovával kompatibilitu. Zaroveň nedělal (na rozdíl od ArrayObject) nic navíc.