Advanced PHP Trickery

napísal , 22 Jan 2012 [ PHP ]

Viete čo sú v PHPčku anonymné funkcie, closures, ako fungujú statické premenné vo funkciách a načo je register_shutdown_function()? Ak nie, ste na správnom mieste, za 2 minúty to budete vedieť a budú z vás neporaziteľní mágovia PHP. Ak to už viete, môžte sa spokojne potľapkať po chrbte, znamená to, že ste asi s PHP strávili viac času, ako by bolo zdravé :)

Poďme si tieto 4 veci vysvetliť na krátkom príklade "zo života". Predstavte si, že máme triedu na odosielanie SMSiek. Ale predtým než začneme posielať SMSky, sa treba prostredníctvom triedy pripojiť k serveru a po doposielaní všetkých SMS sa treba odhlásiť.

My sa však nechceme zaoberať takými blbinami ako pripájanie a odpájanie. Cheme mať len globálnu funkciu send_sms(). Na to použijeme celkom elegantné riešenie, v ktorom budú obsiahnuté všetky spomínané advanced koncepty.

Statické premenné vo funkciách

function send_sms($number, $text)
{
	static $connection = false;

	if (!$connection)
	{
		require_once('extensions/SMS/connect.php');
		$connection = new SMSConnect();
		if (!$connection->create("login","heslo")) return false;

Statická premenná vo funkcii si zachováva hodnotu v rámci všetkých volaní danej funkcie. Pri prvom spustení bude obsahovať hodnotu false. Podmienka nižšie sa teda vykoná, do premennej $connection strčíme SMSkovú triedu a pripojíme sa k serveru. Pri ďalšom spustení funkcie bude v premennej SMSková trieda a celý tento blok "if" sa preskočí.

V OOP sa zvyknú používať statické premenné vo vnútri tried, každopádne je dobré vedieť, že sa dajú použiť aj vo vnútri funkcií. V manuále nájdete ďalšie príklady využitia.

		$callback = function() use($connection)
		{
			$connection->Logout();
		};

		register_shutdown_function($callback);

Na tomto čudnom kúsku sa nachádzajú zvyšné 3 koncepty. V skratke docielime, že keď dobehne PHP skript, zavolá sa odhlasovacia metóda SMSkovej triedy.

Anonymné funkcie

Prvý koncept sú anonymné funkcie. Čiže funckie bez mena. Ako sa dajú volať funkcie ktoré nemajú meno? Takto:

$gule = function($hodnota) {
	echo "Počet gúľ: $hodnota";
}
$gule(42);
// Počet gúľ: 42

Closures

S anonymnými funkciami súvisia closures (netuším ako sa to povie po slovensky:). Closure je v podstate jav, kedy do anonymnej funkcie magicky prejdú premenné z nadradeného kontextu (scope). Príklad:

$atribut = "Kaliber";

$gule = function($hodnota) use ($atribut) {
	echo "$atribut gúľ: $hodnota";
}
$gule("masívne");
// Kaliber gúľ: masívne

Kľúčové slovo use udáva ktoré premenné majú magicky prejsť z nadradeného kontextu. V takom Javascripte sa closures dejú automaticky, netreba nič špecifikovať. Mimochodom pozor na PHP manuál. Anonymné funkcie sú tam označované ako closures, čo je blbosť! To sú 2 rozdielne veci. Funkcia je funkcia, closure je jav prejdenia premennej do iného kontextu.

register_shutdown_function

No a nakoniec si povieme niečo o register_shutdown_function($funkcia[, $parameter1[, $parameter2[, ...]]]). Čo robí táto funkcia je zrejmé z názvu. Keď dobehne PHP skript, zavolajú sa registrované funkcie (v poradí v akom boli registrované). Ak skript počas behu padne kvôli chybe, nezavolá sa nič.

Keďže prvý parameter je callback, máme viacero možností - môžme použiť názov globálnej funkcie register_shutdown_function('mojaFunkcia'), metódu objektu register_shutdown_function(array($objekt, 'mojaMetoda')), statickú metódu triedy register_shutdown_function(array('MojaTrieda', 'mojaMetoda')) alebo anonymnú funkciu, ako v príklade vyššie register_shutdown_function(function() { echo 'lol'; })

Aby sme dokončili reálny príklad zo života, už len odošleme SMS.

	}

	return $connection->sendSMS($number,$text);
}

Nerozsekaný príklad s SMSkami

Teraz by ste teoreticky mali chápať celý príklad s odosielaním SMSky. Ak nechápete, je možné, že som to na riť vysvetlil. :) V takom prípade napíšte do komentárov a skúsim to uviesť na pravú mieru.

function send_sms($number, $text)
{
	static $connection = false;

	if (!$connection)
	{
		require_once('extensions/SMS/connect.php');
		$connection = new SMSConnect();
		if (!$connection->create("login","heslo")) return false;

		$callback = function() use($connection)
		{
			$connection->Logout();
		};

		register_shutdown_function($callback);
	}

	return $connection->sendSMS($number,$text);
}

send_sms("+421903031337", "Ach ty bzdocha"); // tu sa pripojíme
send_sms("+421903031337", "Stvrtok je a cibulu doma nema");
send_sms("+421903031337", "To je zivot");
send_sms("+421903031337", "MRAVCE CHODA");

// a tu sa odpojíme
napísal , 22 Jan 2012

8 komentárov

komentuj ku každému komentáru sa v databáze ukladá iba meno, text a dátum, iba za účelom zobrazenia pod článkom
neukladá sa email, IP adresa ani informácie o prehliadači a údaje sa nepoužívajú na reklamu, newsletter, na žiadnu ekonomickú aktivitu, nikam sa neposielajú, sú v databáze len aby sa mohli zobraziť pod článkom

Archivovaný archív je bez komentárov. Radšej.