Výhody interpretovaného jazyka u PHP

Pavel Tipy & triky, PHP

Jaké výhody oproti programovacím jazykům nabízí PHP, jakou výhodu mají proměnné začínající dolarem a mnoho dalšího, co PHP umí, ale při běžném vývoji se moc nepoužívá.

Výhody interpretovaného jazyka u PHP

Že v PHP do jedné proměnné lze ukládat různé datové typy v průběhu programu ví každý PHP programátor. Je to výsada snad všech skriptovacích jazyků a určitě všech dynamicky typovaných. Proto bude lepší si ukázat trochu pokročilejší možnosti jazyka PHP.

Volání podle názvu uloženého jako string

Většina moderních programovacích jazyků nabízí možnosti reflexe. Pomocí reflexe lze zjistit vlastnosti tříd a metod za běhu programu a poté je vytvořit či zavolat, i když jméno je uloženo jako string. PHP to samozřejmě umí také, ale mnohem jednodušeji.

Volání funkce

PHP dokáže zjistit, jestli funkce existuje a poté ji i zavolat, pokud je její název uložen jako string. Zde je i první ukázka, jaké výhody má povinnost pojmenovávat proměnné dolarem. Poslední možnost volání by v jiném jazyce moc nešla.

$funcName = "printName";
if (function_exists($funcName)) {
    // Všechny parametry se specifikují zvlášť
    echo call_user_func($funcName, "Pavel", "Kutac");
    // Všechny parametry se předávají jako 1 pole
    echo call_user_func_array($funcName, ["Pavel", "Kutac"]);
    // Zavolání funkce přímo pomocí 
    echo $funcName("Pavel", "Kutac");
}

Vytvoření instance a zavolání metody

Když se dá zavolat funkce pomocí jejího jména v proměnné, asi nikoho nepřekvapí, že to samé lze s třídami a metodami

$className = "Database";
$methodName = "connect";
if (class_exists($className)){
    $inst = new $className;

    if (method_exists($inst, $methodName)) {
        // Stejně jako výše je možné použít i call_user_func_array
        call_user_func([$inst, $methodName], "localhost", "root", "root");
        // Nebo opět využít přímo proměnné, { } se mohou vynechat
        $inst->{$methodName}("localhost", "root", "root");

        // Pokud je metoda statická, můžeme udělat toto:
        // Lze až od PHP verze 5.2.3
        call_user_func($className."::".$methodName, "localhost", "root", "root");
    }
}

Využití

Obě metody jsou hojně využívány především v různých frameworcích. Volání funkce pomocí proměnné s názvem funkce je využíváno ve WordPressu. Vytváření instancí třídy a volání jejich metod asi v každém frameworku, kde se takto mapuje controller na "routy".

// Přidávání "háčků" ve WordPressu
add_action('init', 'register_my_menu');
function register_my_menu() {
   ...
}

// Definování controlleru na routy v Laravelu
Route::get('/', 'FrontendController@hello');

Zdvojený dolar, ztrojený dolar, ...

Nutnost proměnné pojmenovávat dolarem má i další výhody. Lze vytvořit proměnnou se jménem, který je uložený jako string. Takto to lze skládat i dále, přímo v dokumentaci k PHP je ale doporučeno používat maximálně zdvojený dolar.

$name = "firstLevel";
$$name = "secondLevel";
$$$name = "Hello...";

echo $name;        // Vypíše "firstLevel"
echo $firstLevel;  // Vypíše "secondLevel"
echo $secondLevel; // Vypíše "Hello..."

Využití

I tato technika má využití, a to nejčastěji v šablonovacích systémech... Pro ukázku může sloužit tato velmi jednoduchá třída Template a její použití.

// Soubor: Template.php
class Template{
    private $vars;

    public function addVar($name, $value)
    {
        $this->vars[$name] = $value;
    }

    public function render($file)
    {
        foreach ($this->vars as $key => $value) {            
            // { } jsou zde pro vyšší přehlednost, lze je vynechat
            ${$key} = $value; 
        }
        include $file;
    }
}

// Soubor: home.php
echo "Welcome to ".$siteName;

// Soubor: index.php
$tpl = new Template();
$tpl->addVar("siteName", "My Blog");
$tpl->render("home.php"); // Vypíše "Welcome to My Blog"

Magické metody v PHP

Magická metoda vždy začíná __. Nejznámější je __construct() a možná i __destruct(), případně z jiných jazyků __toString(). Je jich ale mnohem více. Nejlepší bude opět příklad

class MyMagicTest{
    public $normalProperty = "Hello...";
    public function normalMethod(){
        echo "Normal method";
    }

    public function __set($name, $value){
        echo "Trying to write {$value} to property {$name}";
    }
    public function __get($name){
        echo "Trying to read property {$name}";
    }
    public function __isset($name){
        echo "Checking if property {$name} is set";
    }
    public function __unset($name){
        echo "Removing property {$name}";
    }
    public function __call($funcName, $params){
        echo "Calling method {$funcName} with params: ".implode(", ", $params);
    }
}

Pomocí magických metod se dá přistupovat k vlastnostem objektu které neexistují, stejně tak volat metody které nejsou definovány. Pokud se přistupuje k existujícím vlastnostem nebo metodám, magické metody se samozřejmě nevolají.

Reflexe

Pokud je to opravdu nutné, lze použít reflexi jaká je v jiných programovacích jazycích. Lze získat signatury metod, konstanty a vlastně zjistit cokoli o třídě. Reflexe samotná by byla na jeden článek, takže to teď vynechám a jen dám odkaz http://php.net/manual/en/book.reflection.php.


Znáte v PHP jiné možnosti, o kterých jsem se nezmínil? Podělte se v komentářích

Přidat komentář

Právě odpovídáte na existující komentář. Zrušit

Komentáře

Novinky z blogu

Jak na Laravel frontu na sdíleném hostingu

Laravel pro spouštění fronty vyžaduje supervisora nebo daemona, který ale na sdíleném hostingu spustit nelze. Přesto se dá i tato úžasná funkce používat na běžném...

Další články