Statické proměnné

Školení, která pořádám

Statické proměnné se vyznačují tím, že jejich hodnota zůstává při opakovaném volání funkce zachována.

<?php
function test_static() {
    static $a = 0; // použije se pouze při prvním zavolání funkce
    $a++;
    return $a; // bude postupně vracet 1, 2, 3, ...
}
?>

Možnosti použití statických proměnných jsou pouze příležitostné, v některých případech ale mohou ušetřit psaní spousty neelegantního kódu. Řekněme, že chceme v HTML kódu nadpisy <h2> doplnit číslovanými záložkami pomocí <a name="">.

<?php
function zalozky($matches) {
    static $poradi = 0;
    $poradi++;
    return "$matches[0]<a name='h2-$poradi'></a>";
}
preg_replace_callback('~<h2>~', 'zalozky', $html);
?>

Na statické proměnné si vzpomeňte také vždy, když chcete ve funkci používat globální proměnné – často jsou vhodnějším obratem a nemohou způsobit žádnou katastrofu.

V JavaScriptu statické proměnné nejsou, ale lze si pomoci touto kontrukcí:

var zalozky = function () {
	var poradi = 0;
	return function () {
		poradi++;
	}
}();
Jakub Vrána, Výuka, 6.6.2005, diskuse: 10 (nové: 0)

Diskuse

Hondrej:

"Name" se používá jako kotvy, že? Pro dosáhnutí stejného výsledku je možno používat element ID. Jak by řekl pan J. Grossman: "Je to kratší a znamená to totéž."

ikona Jakub Vrána OpenID:

Mám dojem, že odkazování na <a name=""> je starší než odkazování na id="" a funguje ve všech prohlížečích, jak o tom pojednával Filosof: http://blog.filosof.biz/index.php?p=216

joe:

Za upozorneni imho stoji, ze pri pouziti staticke promenne v metode tridy, je staticky  definovana promenna 'stejna' pro vsechny objekty od teto tridy odvozene. Proto doporucuji na to dat dost pozor :)

ikona dgx:

Čehož se dá i využít, například pro simulaci statických proměnných v PHP4. Viz http://www.dgx.cz/trine/item/bezva-finta-…-promenne-v-php-4

ikona spaze:

staticky promenny jsou dobry na "lokalni" cache, napr. mam nejakou fci/metodu, ktera napr. zjisti obsah adresare a tu fci/m volam v jednom behu skriptu nekolikrat a pokazdy mi staci stejnej vysledek:

<?php
function getDir()
{
  static $dir;
  if (!isset($dir)) {
    $dir = dir('.');
    // ...
  }
  return $dir;
}
?>

Zdeněk Merta:

A není lepší (systematičtější) v takových případech použít třeba návrhový vzor Registry a při prvním volání si výsledek uložit do něj.
Přijde mi celkem drsné, když budu pročítat zdroják, uvidím několikrát použít funkci getDir(), podle názvu mi bude jasné, co dělá a nepodívám se do jejího kódu a nakonec se budu divit, že to funguje jinak než bych očekával.

ikona dgx:

Jelikož jde o nativní (a velmi snadný) způsob, proč ho nevyužít? Spazeho kešování je elegantní trik, který při vhodném použití dokáže významně zrychlit aplikaci.

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL: Reakce na: dgx

Zdeněk Merta:

To je pravda, jen si myslím, že to snižuje čitelnost zdrojového kódu - není okamžitě jasné, co ta funkce dělá.
Respektive vypadá to jasně, ale funguje to jinak.
Asi by stačilo tu funkci jen nějak vhodně přejmenovat ;-)

ikona spaze:

getDir() byl jenom priklad, kterej me honem napadl. Ale myslim, ze to neni takovej problem, spousta navratovejch hodnot FS funkci je cacheovana ("Affected functions include stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype(), and fileperms().")

ikona Jakub Vrána OpenID:

Je to šikovný obrat, byl vidět i ve článku z minulého týdne: http://php.vrana.cz/kontrola-pravopisu-v-html-dokumentu.php
avatar © 2005-2020 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.