ArrayHash a integer klice
- bene
- Člen | 82
Nevím, jestli tohle brát jako chybu. Kam to vůbec napsat…
ArrayHash
mi celkem zkomplikoval život, než jsem na to
přišel.
Měl jsem dynamické položky ve formuláři, tzn. název (klíč) form. prvku
bylo číslo.
Ale přetypování ArrayHash
na pole vytvoří něco, co normálně
v PHP neuděláte. Číselné klíče, jsou string
!!!
Nejlépe to předvést na ukázce:
<?php
$a = new Nette\ArrayHash;
$a['0'] = 'a';
$a[1] = 'b';
$a = (array) $a;
var_dump($a); // array(2) { ["0"]=> string(1) "a" ["1"]=> string(1) "b" }
unset($a['0']);
unset($a[1]);
var_dump($a); // array(2) { ["0"]=> string(1) "a" ["1"]=> string(1) "b" }
$a = array();
$a['0'] = 'a';
$a[1] = 'b';
var_dump($a); // array(2) { [0]=> string(1) "a" [1]=> string(1) "b" }
unset($a['0']);
unset($a[1]);
var_dump($a); // array(0) { }
// problem je jasny
$a = array();
$a[] = 'a';
var_dump($a); // array(1) { [0]=> string(1) "a" }
$a = Nette\ArrayHash::from($a);
$a = (array) $a;
var_dump($a); // array(1) { ["0"]=> string(1) "a" }
// a takto se v podstate tvori formularove 'getValues'
$a = new Nette\ArrayHash;
$key = 0;
$a->$key = 'a';
$a = (array) $a;
var_dump($a); // array(1) { ["0"]=> string(1) "a" }
- Filip Procházka
- Moderator | 4668
Souhlasím, po půl roce pořád nechápu přidanou hodnotu
ArrayHash
. Nebudu rejpat do Davida, to už jsem zkoušel a stejně
to furt nevím :)
Takže jak to řešit?
- nespoléhat se na indexy (ignorovat je)
- zbavit se potřeby unsetovat hodnoty (tohle je fakt úchylnost. Že se to snažíš pak vkládat do db?)
- přetypovávat na pole (asi nejlepší co můžeš udělat…)
- používat foreach (tomu je jedno, že je to objekt)
- David Grudl
- Nette Core | 8228
Přidal jsem do metodě getValues() parameter $asArray, když bude TRUE vrátí se normální pole.
- Ascaria
- Člen | 187
Já jsem narazil ještě na jednu záludnost. Pokud ArrayHash z formuláře uložím do session:
<?php
$this->sessionSection = $this->presenter->context->session->getSection('certification-request-form');
$this->sessionSection->values = $form->getValues();
?>
A poté po redirectu na další stránce se snažím z té session data tahat ven:
<?php
$this->sessionSection = $this->presenter->context->session->getSection('certification-request-form');
// V $this->sessionSection->values je nyní vše ArrayHash
$class = 1;
// selže
$requirements = $this->sessionSection->values['main']['stars'][$class];
// provede se a $requirements je stále ArrayHash
$stars = (Array)$this->sessionSection->values['main']['stars'];
$requirements = $stars[$class];
?>
Problémové inputy mají name napriklad:
main[stars][1][pozadavek1]
main[stars][1][pozadavek2]
main[stars][2][pozadavek3]
main[stars][2][pozadavek4]
a když chci iterovat „foreach(main[stars][1] as pozadavek)“ tak mám smůlu, musím nejdřiv „main[stars]“ přetypovat na pole a pak iterovat nad „foreach(pole[1] as pozadavek)“. Obejít by to šlo přidáním písmena před číslo v indexu, ale na to už je pozdě.
Editoval Ascaria (21. 3. 2012 15:27)
- David Grudl
- Nette Core | 8228
Tohle je opraveno v PHP 5.3.9 a 5.4 https://bugs.php.net/bug.php?…. Jak to opravit na straně PHP netuším.