Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Zaostřeno na PHP (po roce) 3

Dokončení prohlídky vlastností připravovaného jazyka PHP 5.

Tweetni to Twitter Jaggni to! Jagg Del.icio.us Delicious

Statické metody

S metodami v PHP 4 byl tak trochu problém. Nerozlišovalo se volání metody objektu od statického volání. PHP 5 zavádí po vzoru ostatních objektově orientovaných jazyků klíčové slovo static. Jeho užitečnost je ale v mých očích prozatím docela sporná (možná se do finální verze ještě leccos změní).

Použití nebo vynechání slova static v záhlaví metody vás nijak neomezuje ve volání metody oběma způsoby. Asi jediná výhoda spočívá v tom, že vás interpret PHP při pokusu o použití pseudo-proměnné $this uvnitř statické metody upozorní chybovou hláškou.

Nechci spekulovat, ale jistě by se dalo zařídit, aby PHP varovalo programátora i při statickém volání nestatické metody nebo nestatickém volání statické metody…

Příklad:

<?php
class NejakaTrida {
  public static function statickaFunkce() {
    ...
  }
  ...
}

NejakaTrida::statickaFunkce(); // statické volání
?>

Metody __get(), __set() a __call()

Další výbornou vlastnost jazyka PHP přináší trojice vyhrazených metod tříd z nadpisu tohoto odstavce. Pomocí nich můžete definovat akce spouštěné automaticky při přístupu k atributům nebo metodám objektu.

Vy, kteří už nějaké zkušenosti s objektově orientovaným programováním máte, jistě znáte ono dilema, zda k nějaké hodnotě objektu přistupovat přímo, nebo ji zapouzdřit do dvojice metod typu setHodnota($hod­nota) a getHodnota().

Od verze 5 alespoň v PHP tento „problém“ řešit nemusíte. V každé třídě můžete definovat metody __get() a __set() určené k tomu, aby obsluhovaly přístup k neznámým atributům. Funguje to asi takhle. Napíšete-li v programu příkaz:

$objekt->x = 3.8;

a proměnná x v definici třídy objektu $objekt neexistuje, pokusí se místo toho PHP vykonat příkaz

$objekt->__set('x', 3.8);

Vtip je v tom, že záleží jen a jen na vás, jak metodu __set() implementujete.

K doplňkovému účelu slouží i metoda __get() – PHP ji volá pro vrácení hodnoty nedefinovaného atributu.

Příklad:

<?php
class UpovidanaTrida {
    public $n;
    private $x = array("a" => 1, "b" => 2, "c" => 3);

    function __get($nazev) {
        echo "Pokus o získání '$nazev'\n";

        if (isset($this->x[$nazev])) {
            $hodnota = $this->x[$nazev];
            echo "Vracím: $hodnota\n";
            return $hodnota;
        } else {
            echo "Nelze!\n";
        }
    }

    function __set($nazev, $hodnota) {
        echo "Pokus o nastavení '$nazev' na $hodnota\n";

        if (isset($this->x[$nazev])) {
            $this->x[$nazev] = $hodnota;
            echo "OK!\n";
        } else {
            echo "Nelze!\n";
        }
    }
}

$objekt = new UpovidanaTrida();

echo "n:\n";
$objekt->n = 1;

echo "\na:\n";
$objekt->a += $objekt->b;

echo "\nz:\n";
$objekt->z++;

echo "\n";
var_dump($objekt);
?>

Na výstupu by se mělo objevit:

n:

a:
Pokus o získání 'b'
Vracím: 2
Pokus o získání 'a'
Vracím: 1
Pokus o nastavení 'a' na 3
OK!

z:
Pokus o získání 'z'
Nelze!
Pokus o nastavení 'z' na 1
Nelze!

object(upovidanatrida)#1 (2) {
  ["n"]=>
  int(1)
  [""]=>
  array(3) {
    ["a"]=>

    int(3)
    ["b"]=>
    int(2)
    ["c"]=>
    int(3)
  }
}

Vidíme, že v případě atributu $n se metody __set() a__get() nevolají, protože jde o atribut, který byl ve třídě náležitě definován. Rovněž si můžeme všimnout, že atributy lze používat nadále tak, jak jsme zvyklí, a že i složité výrazy PHP dekóduje do správné posloupnosti volání __set() a __get().

Dlužím vám ještě ukázat, k čemu je metoda __call(). Půjdeme rovnou k příkladu:

<?php
class DalsiUpovidanaTrida {
    function __call($nazev, $parametry) {
        echo "Volám $nazev:\n";
        var_dump($parametry);
        return 1;
    }

    function jarmilo($x) {
      return $x + 1;
    }
}

$objekt = new DalsiUpovidanaTrida();

$a = $objekt->hynku(1, '2', 3.4, true);
var_dump($a);
echo "\n";

$a = $objekt->vileme(3, 2, 1, 'start');
var_dump($a);
echo "\n";

$a = $objekt->jarmilo(3.1);
var_dump($a);
?>

Výstup:

Volám hynku:
array(4) {
  [0]=>

  int(1)
  [1]=>
  string(1) "2"
  [2]=>
  float(3.4)
  [3]=>
  bool(true)
}
int(1)

Volám vileme:
array(4) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>

  int(1)
  [3]=>
  string(5) "start"
}
int(1)

float(4.1)

Jak jste si asi všimli, metoda __call() má něco do činění s nedefinovanými metodami. Volání $objekt->hynku() a$objekt->vileme() vedlo k vykonání metody __call(), protože PHP nemohlo v definici třídy DalsiUpovidanaTrida nalézt jejich implementaci. V případě volání metody jarmilo() už PHP do metody __call() nezabruslilo.

__autoload()

Mechanismus __autoload() je spíše už jen kosmetickou úpravou nové syntaxe jazyka; onou často vzpomínanou třešinkou na dortu nebo gramem ptačího trusu na hnojišti velkokapacitního kravína. Umožňuje vykonat určitý kód v okamžiku instanciace nedeklarované třídy. Jako jediný argument se funkci předává název třídy.

Typické využití ukazuje následující příklad:

<
function __autoload($jmenoTridy) {
  include_once('moje_knihovna_trid/' . $jmenoTridy . '.php');
}

V souvislosti s tímto „vylepšením“ si ale dovedu představit určitý problém: dá se předpokládat, že __autoload() budou používat zejména knihovny tříd. Co když ale programátor bude chtít použít knihovny dvě, přičemž každá z nich si ponese svůj __autoload()? Inu, uvidíme, jak se s tím poperou…

davame_internetu_obsah
       

Tímto náš obnovený seriál o PHP verze 5 končí. PHP přináší mnoho změn. Pro někoho to asi přinese řadu problémů s kompatibilitou se stávajícím kódem, ale to je bohužel nutné zlo na cestě vývojem, které pro dlouholeté uživatele tohoto skriptovacího jazyka jistě není novinkou. Nicméně objekty ve čtyřkové verzi byly opravdu hrozné (narážím zejména na přiřazování hodnotou) a zasloužily předělat.

PS: Pokud se v budoucnosti v syntaxi jazyka objeví nějaká další vylepšení, určitě se o nich na Rootu dočtete.

Michal Burda

Michal Burda

Michal Burda vystudoval informatiku a aplikovanou matematiku a nyní pracuje na Ostravské univerzitě jako odborný asistent. Zajímá se o data mining, Javu a Linux.

Školení: Linux – Firewall, Samba, VPN

Na třídenním školení se naučíte nainstalovat a spravovat Firewall a Router, SAMBA Doménový a Souborový server. Dále si zprovozníte vlastní, zabezpečený VPN server.

Podrobnější informace a přihláška

Ohodnoťte jako ve škole:
Průměrná známka 3,50

Přehled názorů

PHP
Ralf 9. 9. 2003 21:42
Nový
└ 
Re: PHP
Jirka bianco Vagner 10. 9. 2003 08:43
Nový
 
├ 
Re: PHP
hkmaly 10. 9. 2003 17:33
Nový
 
└ 
Re: PHP
Michal Burda 11. 9. 2003 20:05
Nový
Chybí nějaká koncepce PHP
Miloslav Ponkrác 10. 9. 2003 13:52
Nový
└ 
Re: Chybí nějaká koncepce PHP
hkmaly 10. 9. 2003 17:34
Nový
 
└ 
Re: Překladač
Jirka Pech 13. 9. 2003 00:25
Nový
 
 
└ 
Re: Překladač
Miloslav Ponkrác 15. 9. 2003 17:56
Nový
_set _get
optik 11. 9. 2003 23:33
Nový
├ 
Re: _set _get
Michal Kubeček 12. 9. 2003 16:34
Nový
└ 
Re: _set _get
Michal Burda 14. 9. 2003 09:37
Nový
Interface
Jakub Podhorský 18. 9. 2003 18:01
Nový
└ 
Re: Interface
Jirka Hradil 22. 10. 2003 20:52
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem