statické atributy třídy a statické proměnné (ne)statických metod

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
doomed
Člen | 17
+
0
-

Zdravím, rád bych se zeptal, proč mi „nefungují“ statické atributy a proměnné. Nemám pro to momentálně žádné smysluplné využití, spíše s nette experimentuju.

Fragment kódu presenteru:

<?php

  private static $i = 0;

  public function actionShow()
  {
    $this->template->numberOfViews = ++self::$i;
  }

  public function handleRefresh()
  {
    $this->redirect('this');
  }

?>

Fragment kódu view:

<p>Počet zobrazení: {$numberOfViews}</p>
<a href="{link refresh!}">refresh</a>

Pokud kliknu na refresh zobrazuje se mi stále 1. Čím to je? Výsledek je stejný i v případě:

<?php

  public function actionShow()
  {
    static $i = 0;
    $this->template->numberOfViews = ++$i;
  }

?>

Editoval doomed (22. 7. 2010 16:06)

blacksun
Člen | 177
+
0
-

Protože se nejedná o persistentní parametr?
Takže se ti při každém novém requestu nastaví na jedničku, pak se zobrazí, pak inkrementuje, ale už si nikde nepředáváš tu změněnou hodnotu nijak (v parametru metody nebo jako persistentní parametr).

Editoval blacksun (22. 7. 2010 15:52)

doomed
Člen | 17
+
0
-

Eh, tak teď vůbec nevím, neznám pojem persistentní parametr. Jsem totiž z běžného čistého php zvyklej, že když inkrementuju nějakou statickou proměnnou či atribut třídy a průběžně ji zobrazuji, tak to funguje. Mohl bys mě odkázat do patřičných míst dokumentace?

Editoval doomed (22. 7. 2010 16:09)

Majkl578
Moderator | 1364
+
0
-

doomed napsal(a):

Jsem totiž z běžného čistého php zvyklej, že když inkrementuju nějakou statickou proměnnou či atribut třídy a průběžně ji zobrazuji, tak to funguje.

To dost pochybuji, při přechodu na jinou stránku se hodnota ztratí. Četl jsi dokumentaci? Tam se o persistentních parametrech píše.

doomed
Člen | 17
+
0
-

Majkl578 napsal(a):

doomed napsal(a):

Jsem totiž z běžného čistého php zvyklej, že když inkrementuju nějakou statickou proměnnou či atribut třídy a průběžně ji zobrazuji, tak to funguje.

To dost pochybuji, při přechodu na jinou stránku se hodnota ztratí. Četl jsi dokumentaci? Tam se o persistentních parametrech píše.

Jasně, máš pravdu, to je hloupost, musel bych ji předávat buď v url nebo uchovávat v sessions. Hmm, snažím se to v dokumetaci najít, ale zatím nic, co by mi to trochu objasnilo. Vím už, že persistentní parametr se vytváří tak, že před něj uvedu /** @persistent */. Pak se ale dostanu do smyčky :-/

Editoval doomed (22. 7. 2010 16:41)

Vyki
Člen | 388
+
0
-

Neco o persistentních parametrech jsem psal zde. EDIT: Dalo by se říct, že je to parametr, který se ti předává automaticky mezi requesty. Předává se v url, aniž by jsi ho tam ručně v makru {link} přidával. V tom příspěvku, na který vede výše uvedený odkaz jsem se to snažil vysvětlit na příkladu pro vypnutí JS celém presenteru.

Editoval Vyki (22. 7. 2010 17:38)

doomed
Člen | 17
+
0
-

Zdravím, tak vám moc děkuju, hlavně Vykimu, už mi to funguje. Následující fragemnt kódu funguje tak, jak by měl:

<?php

  /** @persistent int */
  public $numberOfViews = 0;

  public function actionShow()
  {
    if ($this->numberOfViews == 0)
      $this->numberOfViews = 1;

    $this->template->numberOfViews = $this->numberOfViews;
  }

  public function handleRefresh()
  {
    $this->numberOfViews += 1;
    $this->redirect('this');
  }

?>

Pokud ale přesunu inkrementaci persistentního parametru do action, pak se mi to podle prohlížeče zacyklý. Proč?

<?php

  /** @persistent int */
  public $numberOfViews = 0;

  public function actionShow()
  {
    $this->numberOfViews += 1;

    $this->template->numberOfViews = $this->numberOfViews;
  }

  public function handleRefresh()
  {
    $this->redirect('this');
  }

?>

Ještě bych se chtěl zeptat, zda se dá nějak docílit toho, aby se mi, ten persistentní parametr neobjevoval v url? Nebo se to řeší jen pomocí routy v bootsrapu?

Moc děkuju za vaši trpělivost ;-)

Editoval doomed (23. 7. 2010 15:15)

Vyki
Člen | 388
+
0
-

doomed napsal(a):
Pokud ale přesunu inkrementaci persistentního parametru do action, pak se mi to podle prohlížeče zacyklý. Proč?

<?php

  /** @persistent int */
  public $numberOfViews = 0;

  public function actionShow()
  {
    $this->numberOfViews += 1;

    $this->template->numberOfViews = $numberOfViews; //zde používáš nedeklarovanou proměnnou $numberOfViews. Nemá tu být $this->numberOfViews??
  }
  [...]

?>

Persistentní parametr se v URL bezobrazí jenom když má výchozí hodnotu, jinak se předává v URL vždy. Pokud by ty parametry měly být z nějakého důvodu skryté, ukládej je do session. Záleží na situaci, kde to chceš aplikovat.

doomed
Člen | 17
+
0
-

Vyki napsal(a):

doomed napsal(a):
Pokud ale přesunu inkrementaci persistentního parametru do action, pak se mi to podle prohlížeče zacyklý. Proč?

<?php

  /** @persistent int */
  public $numberOfViews = 0;

  public function actionShow()
  {
    $this->numberOfViews += 1;

    $this->template->numberOfViews = $numberOfViews; //zde používáš nedeklarovanou proměnnou $numberOfViews. Nemá tu být $this->numberOfViews??
  }
  [...]

?>

Persistentní parametr se v URL bezobrazí jenom když má výchozí hodnotu, jinak se předává v URL vždy. Pokud by ty parametry měly být z nějakého důvodu skryté, ukládej je do session. Záleží na situaci, kde to chceš aplikovat.

Máš pravdu, při přepisování (nekopíroval jsem to) jsem tam zanesl chybu. Už jsem to opravil. Přesto se mi to zacyklý. Prohlížeč mi ohlásí: „Smyčka při přesměrování – Server přesměrovává požadavky na tuto adresu sám na sebe a to takovým způsobem, které zabraňují jejich dokončení.“

Editoval doomed (23. 7. 2010 15:19)

doomed
Člen | 17
+
0
-

Hmm, tak teď jsem zjistil, že se to nezacyklý, poku metodu změním na render:

<?php
public function renderShow()
  {
    $this->numberOfViews += 1;

    $this->template->numberOfViews = $this->numberOfViews;
  }
?>

Chová se to pak tak, že se mi objeví v šabloně při prvním načtení 1 a v url nic, ale při dalším načtení, resp. použití toho mého signálu refresh se v šabloně hodnota zvýší o jedničku a v url je parametr o jedna menší než zobrazená hodnota v šabloně (na stránce).

Ondřej Mirtes
Člen | 1536
+
0
-

Zkus to dát do actionShow metody :)