jak ošetřit vyjímku v url
- tomas_straka
- Člen | 32
Ahoj, posilam parametry do metody public function actionEdit(int $postId, int
$page): void
Hodnoty jsou z formuláře. Jak osetrit, aby mi uzivatel v url nezmenil
$postId na string? Zkousel jsem do tela metody dat try catch, to je blbost. Jde
nejak vynutit POST? Diky
- Šaman
- Člen | 2659
Do actionEdit($postId, $page)
ti vždycky může někdo něco
podstrčit. Osobně v těchto metodách nemám typovou kontrolu paramterů a
v action, nebo render metodě si kontroluji že paramtery mají správný typ a
že dávají smysl (třeba že to není neexistující stránka) a že na danou
akci má přihlášený uživatel oprávnění.
Edit: Tak koukám, že v novém PHP 7.2 projektu už typovou kontrolu mám.
Tam to spadne jako 404 do ErrorPresenteru, tam si můžeš odchytit
BadRequestException
a nějak to zpracovat po svém. Nebo to prostě
nechat jako Page Not Found
.
Editoval Šaman (20. 1. 2021 20:13)
- tomas_straka
- Člen | 32
Ahoj, kod tady
/**
* @param int $postId
* @param int $page
* @throws Nette\Application\AbortException
*/
public function actionEdit(int $postId, int $page): void
{
try {
$existEntity = $this->companyRepository->getExistCompany($postId);
if (!$existEntity ) {
$this->template->flashes = $this->flashMessage("Společnost nebyla upravena.", 'alert-warning ');
$this->redirect('Company:show');
}
$comp= $this->companyRepository->getOneCompany($postId);
$this['createCompany']->setDefaults($comp->toArray());
}catch (Exeption $e){
$this->redirect('Company:show');
echo('chyba '.$e);
}
}
<form n:name=createFirma>
<div class="form-group row">
<label for="company" class="col-sm-2 col-form-label">Společnost:</label>
<div class="col-md-10">
<input n:name=company type="text" class="form-control" id="nazev">
</div>
</div>
<div class="form-group row">
<label for="owner" class="col-sm-2 col-form-label">Majitel:</label>
<div class="col-md-10">
<input n:name=owner type="text" class="form-control" id="owner">
</div>
</div>
<div class="form-group row">
<label for="note" class="col-sm-2 col-form-label">Pozn:</label>
<div class="col-md-10">
<textarea n:name=notetype="text" class="form-control" id="note" rows="5"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
<button n:name=send type="submit" class="btn btn-primary mb-2">Uložit</button>
</div>
</div>
</form>
Jak muzu kontrolovat typ promenne, kdyz v URL ho zmenim z int na string? To jedine ze bych na to udelal nejaky router.
- tomas_straka
- Člen | 32
Takze oprava......POST defaultni hodnota formulare i kdyz v neni tag method=„POST“. Nicmene jsem ji tam radeji pridal. Ale to porad neresi tu metodu. v URL http://nette-test-back/company/edit?… Jak se zbavit postId resp. to nejak odchytit?
- Kamil Valenta
- Člen | 815
Proč Tě vadí, že někdo v URL přepíše id na string?
$existEntity = $this->companyRepository->getExistCompany($postId);
vrátí false a v podmínce dojde k redirectu, ne? Nebo jak se chová getExistCompany? Vyhodí výjimku?
- tomas_straka
- Člen | 32
No prave.........nedostane se to do vyjimky. Dostanu hlasku: Nette\Application\BadRequestException #404
Argument $postId passed to App\Presenters\FirmyPresenter::actionEdit() must be int, string given.
- Šaman
- Člen | 2659
Opakuji, stejný problém budeš řešit když si někdo ručně přepíše
třeba URL /company/show/blbost123
pro routu
Company:show, $id
. S tím nic nenaděláš.
@KamilValenta Řeší to, že pokud $postId
bude
blbost123
, tak aplikace spadne už při typové kontrole
předaného parametru. Tedy že actionEdit
očekává jako první
parametr int
a dostane string
.
Jak jsem psal – buď to necháš spadnout do Error Presenteru, nebo zrušíš tu typovou kontrolu v záhlaví funkce.
P.S. David to tady na fóru evidentně nechává spadnout do ErrorPresenteru a nechává tam běžné zpracování chyby. Zkus si v url odstranit to číslo za lomítkem. Versus když ho jen přepíšeš za neexistující, třeba tam přidáš pár devítek na začátek.
Zajímavé je, že do textu zasahovat můžeš – imho je to ukázka
chytrého routování. Důležité je evidentně jen to číslo
($id
). To další přidá do adresy asi až router jen pro lepší
uživatelskou orientaci. Třeba když si to uložíš do záložek, vidíš
rovnou název tématu. A při zpracování routy se pak zase zahodí, protože
appce stačí vyparsovat jen to id.
Editoval Šaman (20. 1. 2021 22:01)
- tomas_straka
- Člen | 32
Diky a jak to necham spadnout do error presenteru? Musim pridat routu, ktera se vykona vzdy, kdyz ne ty predchozi?
- tomas_straka
- Člen | 32
Šaman napsal(a):
Tam to spadne samo (pokud máš jako základ Sandbox, nebo Nette\web-project). Jen si zkus vypnout laděnku (nasimulovat produkční server).
Diky to pomohlo. Pises, ze kontrolujes „správný typ“. Jak to myslis? Ten typ se kontroluje v paramterech metody, ne? Mohl bys mi ukazat nejaky priklad? Diky
- Šaman
- Člen | 2659
O čem teď mluvíš? Kontrolu typu dělám v případě, že odstraním typy z parametrů handle*, action* nebo render* metody. To může být užitečné, pokud chci nějak víc analyzovat co mi vlastně přišlo a nenechat spadnout presenter do chybové stránky.
Nicméně když jsem teď koukal do kódu nové aplikace, tak už i tady používám striktní typovou kontrolu a tahle ruční tedy je už zbytečná. Nicméně si vzpomínám, že ve výjimečnych případech jsem ji schválně zrušil, abych si mohl i špatně předaný parametr zpracovat sám. Nejspíš to byl nějaký požadavek abych polopaticky uživateli napsal v čem je problém a nevrátil mu jen 404.
/**
* @param int $id
*/
public function actionEdit($id): void
{
if ( is_int($id) && $id > 0 ) {
// mohu se pokusit získat záznam
// většinou pak ještě kontrola oprávnění
}
else {
// uživatel se snaží podstrčit nějakou blbost
// ale teď mu mohu třeba zobrazit flashmessage a zůstat na stránce
}
}
P.S. Mimochodem, pokud používáš php7 typovou kontrolu
actionEdit(int $id)
, tak už není potřeba to mít jako phpDoc
anotaci. A dokonce může dojít k nekonzistenci.
Editoval Šaman (22. 1. 2021 17:12)
- tomas_straka
- Člen | 32
Šaman napsal(a):
O čem teď mluvíš? Kontrolu typu dělám v případě, že odstraním typy z parametrů handle*, action* nebo render* metody. To může být užitečné, pokud chci nějak víc analyzovat co mi vlastně přišlo a nenechat spadnout presenter do chybové stránky.
Nicméně když jsem teď koukal do kódu nové aplikace, tak už i tady používám striktní typovou kontrolu a tahle ruční tedy je už zbytečná. Nicméně si vzpomínám, že ve výjimečnych případech jsem ji schválně zrušil, abych si mohl i špatně předaný parametr zpracovat sám. Nejspíš to byl nějaký požadavek abych polopaticky uživateli napsal v čem je problém a nevrátil mu jen 404.
/** * @param int $id */ public function actionEdit($id): void { if ( is_int($id) && $id > 0 ) { // mohu se pokusit získat záznam // většinou pak ještě kontrola oprávnění } else { // uživatel se snaží podstrčit nějakou blbost // ale teď mu mohu třeba zobrazit flashmessage a zůstat na stránce } }
P.S. Mimochodem, pokud používáš php7 typovou kontrolu
actionEdit(int $id)
, tak už není potřeba to mít jako phpDoc anotaci. A dokonce může dojít k nekonzistenci.
Díky za vyčerpávající odpověď. Práve mi bylo vyčteno, že jsem ty parametry neošetřil, bohužel jsem z dotyčného nevyrazil jak. Tu anotaci používám, protože mi doplňuje nápovědu při volání metody.