quickStart tutor. – Objekt nelze pretypovat na array
- Dtx
- Člen | 17
Zdravím, dělám si první aplikačku pomocí quickstartutoše a tutoše na ACL. Mám presenter NotesPresenter (v tutoriálu je pojmenován jako TodoPresenter) a v něm metodu pro zpracování formuláře
Presenter NotesPresenter má metodu:
public function processAddnoteForm(AppForm $form)
{
....
$values = $form->getValues();
$notes = new Notes(); // v tutoši $todo = new Todo;
$notes->name = $values['name'];
$notes->text = $values['text'];
$notes->publish = $values['publish'];
$this->model->createNote($notes); // v tutoši $this->model->createTodo($todo)
}
}
Zde je model NotesManager a jeho metoda createNote:
public function createNote(Notes $notes)
{
print_r($notes);
Debug::dump($notes);
exit;
return dibi::query('INSERT INTO [notes]', (array) $notes );
}
V druhé metodě vidíte, že se snažím dumpnout obsah objektu $notes dvěma způsoby.
- První dump pomocí print_r vypíše správně „obsah“ objektu, jsou v něm vidět hodnoty, jaké byly poslány z formuláře.
- Ten druhý (Debug::dump) ale říká, že objekt je prázdný (object(Notes) (0) {})
Což mi nějak neleze do hlavy. Něco s tím objektem je asi opravdu v nepořádku, protože následující řádek pro uložení do databáze mě vyřve, že se snažím vložit NULL (nedokáže $notes přetypovat na array, resp jen na prázdný array). Co je s tím objektem v nepořádku? Zdá se mi, že mám vše podle tutoriálu. Pro jistotu přikládám i definici classy Notes, z které se tento objekt vytváří. Třeba někoho něco praští do oka.
Definice třídy Notes:
Class Notes extends DibiRow
{
public $name;
public $text;
public $publish;
public function __construct($arr = array())
{
parent::__construct($arr);
}
public function delete()
{
return dibi::query("
DELETE
FROM [notes]
WHERE [id] = %i
", $this->id);
}
public function save()
{
return dibi::query(
"UPDATE [notes] SET",
(array) $this,
"WHERE [id] = %i",
$this->id
);
}
}
- Dtx
- Člen | 17
No tak to je sranda, přišel jsem na řešení hnedka po odeslání tohoto postu :) V classe Notes nesmí být definovány její vlastnosti. Tedy musel jsem smazat následující
public $name;
public $text;
public $publish;
Poté už vše pracuje správně. Může mi někdo vysvětlit, proč to tak je? Jsem zvyklý vlastnosti objektu takto definovat a mám obavy, že nejsem sám.
- Šaman
- Člen | 2666
Třída DibiRow slouží jako přepravka pro data, ale nedoporučuji od ní dědit. Já jí používám jako náhradu za ArrayObjekt (dá se s ní pracovat jako s objektem i jako s polem).
Aby ti DibiRow fungovala jako pole, tak nesmí obsahovat žádné protected nebo private proměnné.
⇒ model (třídu Notes) neděď od DibiRow (je notes specializací nějaké
DibiRow?!?) ale jen od Object a DibiRow použij jako přepravku na data, která
ti ulehčí práci s databází (když to máš dobře navržené, tak
proměnnou $data
která je typu DibiRow můžeš předávat dibi
dotazu a zároveň ji můžeš plnit rovnou výsledkem
dibi::query("SELECT...")->fetch()
)
// edit. Ulehčí ti to i práci s formuláři, když je dobře navrhneš
(úplně na začátku tvého příspěvku plníš data hodnotama z
$values
. To bys udělal jednoduše
$this->data = $values
).
Editoval Šaman (10. 12. 2010 10:52)
- Dtx
- Člen | 17
Popravdě ti moc nerozumím. Konrétně té druhé části (⇒ model (třídu Notes) neděď od DibiRow …)
Jak mam DibiRow v tomto případě použít jako „přepravku“ na data?
Pak je tu ještě jeden problém, který je trochu mimo:
$this->redirect(‚Notes‘); v metodě pro zpracování formuláře vyhodí
výjimku, že http headers allready sent. Přesto jsem v několika příkladech
našel, že lidé opravdu používají $this->redirect bez problémů. Asi
jsem nějakej prašivej :|
Editoval Dtx (10. 12. 2010 10:53)
- Šaman
- Člen | 2666
<?php
Class Notes extends Object
{
public $data = NULL; // bude typu DibiRow.
//ale doporučil bych ti udělat $data protected a napsat si settery a gettery
public function __construct($data = NULL)
// konstruktor akceptuje pole, objekt DibiRow nebo nic
{
if ( isset($data) && $data instanceof DibiRow )
{
$this->data = $data;
}
elseif ( isset($data) && is_array($data) )
{
$this->data = new DibiRow($data);
}
else
{
$this->data = new DibiRow(array());
}
}
public function delete()
{
return dibi::query("
DELETE
FROM [notes]
WHERE [id] = %i
", $this->data->id);
}
public function save()
{
return dibi::query(
"UPDATE [notes] SET",
$this->data,
"WHERE [id] = %i",
$this->data->id
);
}
// pokud budeš mít getter $this->getId() tak ho používej místo $this->data->id.
// a bude ti to našeptávat i editor (např. NetBeans)
// bez setterů a getterů teď budeš zvenku přistupovat do dat přes proměnnou:
// $notes->data->cosi
// nebo $notes->data['cosi']
// ale s použitím setterů a getterů budeš mít plně zdokumentované a našeptávatelné
// $notes->setCosi(..)
// resp. (protože dědíš od Nette Object) tak můžeš psát i $notes->cosi = ...
?>
Editoval Šaman (10. 12. 2010 11:13)