„Undefined offset“ při dotazu z databáze po vymazání cache
- Richard Jedlička
- Člen | 51
Ahoj,
podobný problém se tu už řešil, ale týkal se starších verzí Nette.
Když použiju metodu count
na výsledek získaný z databáze a
poté na ten samý výsledek aplikuju metodu page
, tak mi při
vymazání cache Nette hodí výjimku Notice Undefined offset: ...
.
Následné obnovení stránky už jede v pořádku.
Zkoušel jsem verze nette 2.0.5, 2.0.7, 2.0.8, 2.1dev, všechny se chovají stejně.
ProductModel.php:
public function getProducts()
{
$products = $this->connection->table('product');
return $products;
}
MainPresenter.php
public function renderProduct($page = 1, $category = null)
{
$products = $this->productModel->getProducts();
$paginatorComponent = $this->getComponent("paginator");
$paginatorComponent->link = "Main:product";
$paginator = $paginatorComponent->paginator;
$paginator->page = $page;
$paginator->itemsPerPage = 6;
$paginator->itemCount = $products->count(); // KDYŽ ZAVOLÁM TOTO ZDE
$this->template->products = $products->page($page, 6); // A PAK TOTO ZDE
}
Main.product.latte:
<div n:foreach="$products as $product">
<div n:class="block, product, $iterator->odd ? odd : even">
<h2>{$product->name}</h2> {* TAK TO ZDE VYHODÍ VÝJIMKU *}
...
</div>
</div>
Uiii
Editoval uiii (29. 1. 2013 14:04)
- Richard Jedlička
- Člen | 51
hAssassin napsal(a):
abych ale nebyl uplne OT, nemas $page nahodou zapornou?
Ne, to ne. Jak říkám hází to jen hned po vyčištění cache. Po aktualizaci stránky (úplně stejná url) to funguje v pohodě.
- Richard Jedlička
- Člen | 51
castamir napsal(a):
count("*")
funguje?
Ty jo, s tou hvězdičkou to funguje. Jsem očekával, že prostě
count
metoda vrátí počet prvků jako u pole (zkoušel jsem i
count($products)
ale chovalo se to stejně).
Editoval uiii (29. 1. 2013 14:38)
- ViPEr*CZ*
- Člen | 817
Todle $products->count(); nad celou Selection je blbost. To jestli se
nepletu zavolá
count(„pole ze selekšny“); a to vlastně vrátí všechny řádky. Zavolal
bych $products->count(„“); což vyvolá dotaz do SQL
COUNT().
Metoda page volá toto:
return $this->limit($itemsPerPage, ($page - 1) * $itemsPerPage);
Takže to je jen alias k metodě limit. Což by ale padat nemělo v kombinaci s count(„*“) a měli by se volat dva SQL dotazy.
- Richard Jedlička
- Člen | 51
castamir napsal(a):
Edit: Nastavujes si $paginator, ale pro orez dotazu ho, zda se, nepouzivas. Bez ohledu na to, ze z uvedeneho kodu nevime, zda $paginator nepouzivas i jinde, nebo co je obsahem te metody page nad $product
Ta metoda page
je metoda z Nette na třídě Selection https://api.nette.org/…ion.php.html#368.
EDIT: píše o tom ViPEr*CZ*
https://forum.nette.org/…mazani-cache#…
Editoval uiii (29. 1. 2013 14:46)
- Richard Jedlička
- Člen | 51
Je teda ale divný, že použití metody count
bez parametrů
nefunguje (teda funguje ale ne ve spojení s následným stránkováním).
Podle API
dokumentace to má bez parametrů dělat co bych očekával.
EDIT: problém teda asi bude volání page
(nebo nejspíš
jakéhokoli dotazu) na Selection
, která byla vyhodnocena
(execute
).
Editoval uiii (29. 1. 2013 14:53)
- hrach
- Člen | 1838
Je to naprosto zrejme:
- metoda count s parametrem spousti oddeleny dotaz do db, kde se provede
SELECT COUNT(*)
, takto by to melo byt naprogramovane - bez parametru to fetchne vsechna data a spocita pocet radku
- nicmene to, ze potom nefunguje
page()
je chyba, kterou se pokusim opravit.
- Richard Jedlička
- Člen | 51
hrach napsal(a):
Potrebuji videt landeku a obsah
getProducts()
.
Rád zašlu jen mi pověz, jak to nejlépe udělat. Když uložim laděnku jako stránku, tak to stejně potřebuje běžící web pro zobrazení obsahu souboru a tak. A co se týče getProducts(), tak ti stačí dump?
- Richard Jedlička
- Člen | 51
enumag napsal(a):
@hrach: Zřejmě jsi myslel zapnout produkční mód. Nevadí ti, že v produkčním módu se ignoruje notice a výsledná chyba tedy bude jiná?
JJ, zapnul jsem si produkční mód a výsledná chyba opravdu jiná je, ale třeba se z ní taky něco zjistí.
- Richard Jedlička
- Člen | 51
Obsah getProducts máš v prvním příspěvku. Ve skutečnosti tam toho dělám víc, ale zkoušel jsem to v téhle nejjednodušší formě a taky nefungovalo.
EDIT: Jestli to nejde stáhnout tak tady je odkaz do dropboxu: https://www.dropbox.com/…7/HeXvaVfcAH
Editoval uiii (29. 1. 2013 18:06)
- Jirda
- Člen | 103
Jen se pridam, ze jsem si pri vyvoji na jednom projektu vsiml podobneho problemu.
Nette Framework 2.1-dev (revision $WCREV$ released on $WCDATE$)
Hmm, koukam ze ladenka nevypsala $WCREV$ a $WCDATE$ – prepokladam, ze by tam
za to mely byt dosazeny hodnoty. ALe to je jiny pribeh.
- Richard Jedlička
- Člen | 51
No co se týče $strictModu
, tak ten mám v config.neon
nastaven na true, ale stejně to nezachytí. Proč ti to nenabídne dialog na
uložení to nevim, dal jsem tam ještě odkaz na dropbox.
- Richard Jedlička
- Člen | 51
hrach napsal(a):
No nic, asi potrebuju tu notice… :| a taky obsah te metody!
Tak tady je ta notice: https://www.dropbox.com/…da917cc.html . Dalo to celkem zabrat :-) Nejdřív jsem musel najít ve zdrojácích, kde se loguje na produkčnim serveru a pak si to ručně zapnul i development mode. Je možný, že střílim vrabčáky kanónem, ale jednodušší způsob mě nenapad.
No a obsah tý medoty:
public function getProducts(
$filterParams = array(
'category' => null,
'tags' => array(),
'minPrice' => null,
'maxPrice' => null
)
)
{
$products = $this->connection->table('product');
if($filterParams['category'])
{
$products = $products->where("product_category:category.url_name", $filterParams['category']);
}
if($filterParams['tags'])
{
$products = $products->where("product_tag:tag.name", $filterParams['tags']);
}
if($filterParams['minPrice'])
{
$products->where('price >= ?', $filterParams['minPrice']);
}
if($filterParams['maxPrice'])
{
$products->where('price <= ?', $filterParams['maxPrice']);
}
return $products;
}
Ale jak jsem řikal. V situaci, kdy nastává ta Notica, se nepoužije ani jedna filtrační podmínka.