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.

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

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 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.