Undefined variable $results
- mimacala
- Člen | 113
Ahojte, prosím jakou věc dělám špatně ?
Odešlu form z home do search a hláška o neznámé proměnné $results, ale
proměnnou definuji a i nastavuji v Searchrenderu :/
<?php
declare(strict_types=1);
namespace App\Presenters;
use Nette;
use Nette\Utils\Finder;
use Nette\Application\UI\Form;
use Nette\Application\Responses\FileResponse;
use Nette\Database\Explorer;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Explorer $db,
)
{
}
public function renderHome()
{
}
protected function createComponentUpload(): Form // form na upload souborů
{
$form = new Form;
$form->addMultiUpload('files', 'Soubory:');
$form->addSubmit('send', 'Upload');
$form->onSuccess[] = [$this, 'formSucceeded'];
return $form;
}
public function formSucceeded(Form $form, $data): void // zpracování uploadu souboru
{
$buffer = [];
$c = "http://localhost/ecufiles/files/";
foreach ($data->files as $file) //přesune všechyn soubory do files a uloží do db
{
$name = $file->getSanitizedName();
$cesta = $c.$name;
$file->move('../files/'.$name);
array_push($buffer, $name);
$this->db->table("files")->insert([
"location" => $cesta,
"name" => $name
]);
}
$this->flashMessage($name); // kontrola vypis
$this->flashMessage($cesta);// kontrola vypis
$this->redirect('Home:');
}
protected function createComponentFind(): Form // formulář k vyhledávání
{
$form = new Form;
$form->addText('text', 'Ecu number');
$form->addSubmit('send', 'Find');
$form->onSuccess[] = [$this, 'formOk'];
return $form;
}
public function formOk(Form $form, $data): void // zpracování vyhledávání
{
$files = $this->db->table("files")->where("name LIKE ? ", "%".$data->text."%")->fetchAll(); // vytáhne fulltext z db
$this->redirect("Search:",$files); // přesměruje na stránku výpisu a odešle vyhledané věci do SearchPresenteru
}
}
<?php
declare(strict_types=1);
namespace App\Presenters;
use Nette;
use Nette\Utils\Finder;
use Nette\Application\UI\Form;
use Nette\Application\Responses\FileResponse;
use Nette\Database\Explorer;
final class SearchPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Explorer $db,
)
{
}
public function renderSearch($search) //tady někde se děje chyba mělo by převezmout data přeposlané z Home"
{
$this->template->results = $search; // proměnnou results hlásí v .latte jako nedefinovanou
}
protected function createComponentFind(): Form
{
$form = new Form;
$form->addText('text', 'Ecu number');
$form->addSubmit('send', 'Find');
$form->onSuccess[] = [$this, 'formOk'];
return $form;
}
public function formOk(Form $form, $data): void
{
$files = $this->db->table("files")->where("name LIKE ? ", "%".$data->text."%")->fetchAll();
$this->redirect("Search:",$files);
}
}
{block content}
{control find}
{foreach $results as $result}
{$result->name}
<a href="{$result->id}">Show</a><br>
{/foreach}
- nightfish
- Člen | 474
@mimacala Přesměrováváš pomocí
$this->redirect("Search:",$files);
, takže na
renderDefault()
. Šablona zřejmě taky bude k
SearchPresenter::renderDefault()
(default.latte
?),
zatímco proměnnou $results
do šablony nastavuješ v
SearchPresenter::renderSearch()
, což je metoda, která se ve tvém
případě nevolá.
Editoval nightfish (12. 2. 21:25)
- mimacala
- Člen | 113
Ale jistě to je ono.
Pak tedy bych chtěl ještě poprosit, zjednodušil jsem to na jeden
presenter.
Pokud není dole redirect ale pouze se nastaví proměnná, tak vše funguje,
ale jak nastavím redirect a proměnnou až v renderu, tak nic nezobrazí, jako
by se data při redirectu někde ztratila :/
<?php
declare(strict_types=1);
namespace App\Presenters;
use Nette;
use Nette\Utils\Finder;
use Nette\Application\UI\Form;
use Nette\Application\Responses\FileResponse;
use Nette\Database\Explorer;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Explorer $db,
)
{
}
public function renderDefault($files = array())
{
$this->template->results = $files;
}
protected function createComponentUpload(): Form // form na upload souborů
{
$form = new Form;
$form->addMultiUpload('files', 'Soubory:');
$form->addSubmit('send', 'Upload');
$form->onSuccess[] = [$this, 'formSucceeded'];
return $form;
}
public function formSucceeded(Form $form, $data): void // zpracování uploadu souboru
{
$buffer = [];
$c = "http://localhost/ecufiles/files/";
foreach ($data->files as $file) //přesune všechyn soubory do files a uloží do db
{
$name = $file->getSanitizedName();
$cesta = $c.$name;
$file->move('../files/'.$name);
array_push($buffer, $name);
$this->db->table("files")->insert([
"location" => $cesta,
"name" => $name
]);
}
$this->flashMessage($name); // kontrola vypis
$this->flashMessage($cesta);// kontrola vypis
$this->redirect('Home:');
}
protected function createComponentFind(): Form // formulář k vyhledávání
{
$form = new Form;
$form->addText('text', 'Ecu number');
$form->addSubmit('send', 'Find');
$form->onSuccess[] = [$this, 'formOk'];
return $form;
}
public function formOk(Form $form, $data): void // zpracování vyhledávání
{
$files = $this->db->table("files")->where("name LIKE ? ", "%".$data->text."%")->fetchAll(); // vytáhne fulltext z db
$this->template->results = $files; // toto zobrazí vyhledaný obsah v pořádku
// $this->redirect("Home:",$files); // refreshne a přepošle data, ale nic se neukáže
}
}
- m.brecher
- Generous Backer | 765
@mimacala
refreshne a přepošle data, ale nic se neukáže
Pátrej po datech $files, kde končí jejich stopa. Použij bdump($files), třeba takto:
public function renderDefault($files = array())
{
bdump($files); // zobrazí se dump nebo ne a jsou ve $files date nebo ne??
$this->template->results = $files;
}
Ověříš, jestli se akce default spustí nebo ne a jestli do akce data doputovaly nebo ne. Aby Ti někdo poradil, je potřeba dodat další informace – šablona, kde se formulář vykresluje a jméno šablony atd…
- Pepino
- Člen | 249
@mimacala
public function formOk(Form $form, $data): void
{
$this->redirect('default', $data->text);
}
public function renderDefault(?string $text = null): void
{
if ($text !== null) {
$files = $this->db->table("files")->where("name LIKE ? ", "%".$text."%")->fetchAll(); // vytáhne fulltext z db
$this->template->results = $files; // toto zobrazí vyhledaný obsah v pořádku
} else {
$this->template->results = [];
}
}
- mimacala
- Člen | 113
Moc se mi líbí řešení zpracovávat to až v renderu, tato verze
funguje, moc bych chtěl za to poděkovat.
Ať se také něco přiučím, prosím můžeme nějak rozebrat toto ?
?string $text = null // vytvořím proměnnou s hodnotou null, definuji tedy,
že bude string což moc nechápu proč, když php je dynamicky typovaný ? a co
znamená ten „?“.
Další věc je proč se za funkcí píše :void, když to funguje i bez :)
public function renderDefault(?string $text = null): void
{
if ($text !== null) {
$files = $this->db->table("files")->where("name LIKE ? ", "%".$text."%")->fetchAll(); // vytáhne fulltext z db
$this->template->results = $files; // toto zobrazí vyhledaný obsah v pořádku
} else {
$this->template->results = [];
}
}
Tady u result->id mi vyhazuje chybu, že must be of type Stringable|string, int given, zkusil jsem tedy smazat definování proměnné jako string, ale chyba nezmizela. Nechápu tedy, proč rozlišuje jestli vypisuji string nebo int :/
Opět moc děkuji za velmi poučné rady.
{block content}
{control upload}
{control find}
{foreach $results as $result}
{$result->name}
<a href="{$result->id}">Show</a><br>
{/foreach}
- Infanticide0
- Člen | 64
@mimacala
Dynamický typování je nemoc PHP (kapavka nakažená HIV). Tvoje dotazy
ukazují, že jsi zůstal v PHP 4. Projdi si nějaký PHP 8 tutoriály, jeden
dobrej je přímo na nette.org
https://doc.nette.org/…-programming
Editoval Infanticide0 (13. 2. 11:54)
- m.brecher
- Generous Backer | 765
@mimacala
?string $text = null // vytvořím proměnnou s hodnotou null, definuji tedy, že bude string což moc nechápu proč, když php je dynamicky typovaný ? a co znamená ten “?”.
Dynamické typování PHP má řadu nevýhod a proto bylo v PHP cca 2015 zavedeno alternativní silné typování, které je nepovinné, ale důrazně doporučované. Zapne se takto:
<?php
declare(strict_types=1);
Po jeho zapnutí PHP kontroluje typy na vstupu a výstupu funkcí/metod a v propertách objektů.
public function renderDefault(?string $text = null): void
{
// ...
}
tento zápis znamená:
a) proměnná $text je string nebo null (otazník) a má defaultní hodnotu
null
b) : void znamená, že metoda nevrací žádný výstup
V PHP není typování povinné, takže funguje i zápis bez typů (i když zapneš declare(strict_types=1)), ale každý, kdo v PHP pracuje alespoň trochu profesionálně typování používá.
Na obecné dotazy okolo PHP když něčemu nerozumíš je naprosto skvělá nějaká umělá inteligence, stačí položit vhodně formulovaný dotaz třeba „význam znaku ? v php kódu public function renderDefault(?string $text = null): void“ a umělá inteligence Ti obvykle odpoví lépe než komunita zde na fóru.
Editoval m.brecher (13. 2. 18:10)
- mimacala
- Člen | 113
Kažodpádně, odstranil jsem
declare(strict_types=1);
a ted to vypadá takto
public function renderDefault($text = null): void
{
if ($text !== null) {
$files = $this->db->table("files")->where("name LIKE ? ", "%".$text."%")->fetchAll(); // vytáhne fulltext z db
$this->template->results = $files; // toto zobrazí vyhledaný obsah v pořádku
} else {
$this->template->results = [];
}
}
{block content}
{control upload}
{control find}
{foreach $results as $result}
{$result->name}
<a href="{$result->id}">Show</a><br> //tady chyba
{/foreach}
a řeším problém stále i po odstranění definování typů proměnných
chybu.
TypeError
Latte\Runtime\Filters::safeUrl(): Argument #1 ($s) must be of type
Stringable|string, int given, called in
označuje řádek <a href=„{$result->id}“>Show</a><br>
Nechápu tedy, když jsem mu řekl, ať neřeší typ proměnné co mu vadí :D, moc děkuji za osvětu.
Pokud vypisuji něco jiného než int ID, tak text normálně funguje.
- Infanticide0
- Člen | 64
Problém ti to píše, jenom si neuvědomuješ jednu magii, která je na
pozadí a kterou snadno zjistíš přečtením error hlášky.
Když Latte vypisuje <a> tag, tak proměnnou v atributu href vypíše
přes funkci:
// Sanitizes string for use inside href attribute.
public static function safeUrl(string|\Stringable $s): string;
A ta striktně (protože tak je to správně, ááno) vyžaduje string nebo
Stringable objekt.
Takže pokud potřebuješ vypsat do hrefu číslo a nechceš použít n:href pro
vygenerování URL podle Routeru aplikace, přetypuj to číslo na string.
tohle vygeneruje PHP chybu
<a href="{1}">test int</a>
echo LR\Filters::escapeHtmlAttr(LR\Filters::safeUrl(1))
…
a tohle vygeneruje validní PHP
<a href="{(string)1}">test string</a>
echo LR\Filters::escapeHtmlAttr(LR\Filters::safeUrl((string) 1))
Editoval Infanticide0 (21. 2. 0:56)
- m.brecher
- Generous Backer | 765
@mimacala
a) nikdy nepoužívej:
<a href="{$result->id}">Show</a>
V Nette frameworku je potřeba odkazovat na presentery a akce, k tomu slouží latte atribut n:href, takže správně to má být takto:
<a n:href="Presenter:action $result->id">Show</a>
b) nikdy nevypínej declare(strict_types=1)
c) používej typehinty všude, kde to jde
Tím, že nebudeš typovat nic nevyřešíš a naopak se dostaneš do problémů. Typování Ti bude pomáhat a pokud narazíš na problém, bude v něčem jiném než v typování.