Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/webvol34/an/96qmbdpibm1sspm/danielliljeberg.se/public_html/blog/wp-content/mu-plugins/gkphp.php on line 1
Länka anrop i PHP « Php « Daniel Liljeberg
Warning: count(): Parameter must be an array or an object that implements Countable in /www/webvol34/an/96qmbdpibm1sspm/danielliljeberg.se/public_html/blog/wp-includes/post-template.php on line 284

Warning: count(): Parameter must be an array or an object that implements Countable in /www/webvol34/an/96qmbdpibm1sspm/danielliljeberg.se/public_html/blog/wp-includes/post-template.php on line 284

Länka anrop i PHP

27 augusti, 2009 av Daniel Liljeberg Lämna en kommentar »

När man kodar objektorienterat i PHP så använder man sig som i så många andra språk ofta av befintliga och beprövade design patterns. Dessa är generella återanvändbara lösningar på vanligt förekommande problem i systemutveckling. Till dessa hör bland annat Factory, Singelton, Adapter, Bridge, Iterator osv. Ett design pattern som jag själv aldrig kommit i kontakt med under mina år med C++ och PHP fångade min uppmärksamhet då det används flitigt i ZendFramework som jag använder flitigt. Jag är inte säker på att namnet jag använder är rätt, men jag kallar det Command Chaining. Om någon vet det riktiga namnet så lämna det gärna i komentarerna.

Det hela är egentligen väldigt enkelt. Genom att varje medlemsfunktion i klassen returnerar en $this referens (dvs en referens till instansen av klassen) så kan man på den kalla ytterliggare funktioner. Ett exeplel kunde vara

"]<?php// Create a new instance$ftp = new Ftp();// Connect to the ftp, change to correct directory, // download a file and close the connection in one go$ftp->connect('username', 'password', 'ftp.foobar.com')    ->chdir('/folder_with_the_stuff')    ->download('thefile.txt')    ->closeConnection();?>

Fördelen med detta design pattern är att man väldigt snabb och sammanhängande kan skriva en serie androp som hör ihop. Används t ex effektivt i ZendFrameworks Zend_Db_Table klass som fungerar som ett objektorienterat interface till databastabeller.

"]<?php// Fetching a rowset$rows = $table->fetchAll(  $table->select()        ->where('bug_status = ?', 'NEW')        ->order('bug_id ASC')        ->limit(10, 0)    );?>

En nackdel som jag dock tycker detta pattern har är att felhanteringen blir
mycket jobbigare. Eller nja, man måste tänka på att man gör det annorlunda
iaf. Säg att personen i exemplet med ftp klassen ovan kunde logga in men
 fanns inte just den filen han ville ladda ner, då kanske han vill ladda ner
en annan fil istället. Men hur gör man då? Om download() bara returnerar
en referens till $this ändå så kommer vi aldrig att få veta att filen inte fanns
och closeConnection() kommer sedan att köras. Att returnera en felkod
funkar inte heller eftersom closeConnection() då kommer försöka köras
 det returvärdet. Vad man bör och skall göra är naturligtvis att använda
Exceptions och kasta ett sådant i de funktioner där något går fel.

"]// Create a new instance$ftp = new Ftp();try {// Connect to the ftp, change to correct directory, // download a file and close the connection in one go$ftp-;>connect('username', 'password', 'ftp.foobar.com')    ->chdir('/folder_with_the_stuff')    ->download('thefile.txt')        ->closeConnection();}catch(Exception $e) {// Handle the exception...?>

Om man är van vid att använda felkoder som returvärden som felhantering
så får man tänka om lite. Det ändrar också flödet med if() checkar man
kanske då traditionellt haft när man hanterat fel. Men kommar man bara
över det så kan detta design pattern snygga upp koden en hel del i ens
projekt. Om vill kan man börja lite enklare och tex implementera detta
på något så simpellt som en config klass. Om man låter alla
set−funktioner returnera en $this referens så kan man lätt känna lite
på detta design pattern utan att man behöver tänka så mycket på
felhanteringen som följer om funktionerna gör lite mera avancerade saker.

"]// Load config from inifile$config = new Config('foobar.ini');// Change some settings$config->setWidth('200')->setHeight('400');...$config->save('foobar.ini');

Flattr this!

Annonser

Kommentera

Du måste vara inloggad för att kunna posta kommentarer..