PHP: Quelques fonctions méconnues de la programmation objet

En parcourant la doc de PHP, et spécialement le chapitre réservé aux objets (http://www.php.net/manual/en/language.oop5.php), j’ai découvert pas mal de fonctions que je ne connaissais pas malgré que je repratique de façon courante depuis les deux dernières années.

Même si PHP5 a été introduit en 2004, ces méthodes relatives aux objets sont toujours en constantes évolutions.

__autoload

Si l’on fait appel à une classe (ou une interface) encore non déclarée, PHP effectuera un appel à la fonction __autoload si celle ci a été déclarée. Cela a pour but de décharger les longues listes d’appels à require_once/include visant à inclure les différents fichiers sources définissant ces classes.

Exemple simple:

<?php // fichier Objet.class.php
class Objet
{
};
<?php // fichier test.php
function __autoload($class_name)
{
    echo "Autoloading class $class_name\n";
    $class_file = $class_name . '.class.php';
    if(FALSE === file_exists($class_file))
    {
        throw new Exception('Class "' . $class_name . '" could not be autoloaded (file missing)');
    }
    require_once $class_name . '.class.php';
    if(FALSE === class_exists($class_name))
    {
        throw new Exception('Class "' . $class_name . '" could not be autoloaded (not in file)');
    }
    echo "Autoloading done!";
    return true;
}

// Utilisation de la classe "Objet" définie dans Objet.class.php
$obj = new Objet;

// Tentative d'utilisation de la classe "ObjetNonDefini" qui provoquera une erreur:
$obj2 = new ObjetNonDefini;
$ php test.php
Autoloading class Objet
Autoloading done!
Autoloading class ObjetNonDefini
PHP Fatal error:  Uncaught exception 'Exception' with message 'Class "ObjetNonDefini" could not be autoloaded (file missing)' in /home/mycroft/tmp/php/test.php:9
Stack trace:
#0 /home/mycroft/tmp/php/test.php(26): __autoload('ObjetNonDefini')
#1 {main}
  thrown in /home/mycroft/tmp/php/test.php on line 9

__construct et __destruct

Comme les autres langages programmation objet, PHP propose de définir des constructeurs/destructeurs génériques qui seront appelés lors de la construction (et de la destruction) des dits objets.

A noter que le destructeur sera appelé même si l’objet n’est pas explicitement détruit (à la fin d’un script par exemple).

<?php // Objet.class.php
class Objet
{
    public function __construct()
    {
        echo "Constructor\n";
    }

    public function __destruct()
    {
        echo "Destructor\n";
    }
};
<?php // test.php
require_once("Objet.class.php");
$obj = new Objet;
echo "Fin du script.\n";
$ php test.php
Constructor
Fin du script.
Destructor

Les objets et la visibilité des méthodes privées

PHP gère aussi les variables et méthodes privées, accessible que dans la classe où celles ci existent. Cependant, surement du fait à comment sont gérés les objets dans PHP, il est possible d’appeler une méthode privée d’une instance d’un objet hors de cette instance, à la seule condition que l’on appelle dans un autre objet du même type. Ceci est également expliqué dans le chapitre « Visibility from other objects » de la documentation.

Exemple:

<?php // Objet.class.php
class Objet
{
    private $obj_name = NULL;

    public function __construct($name = NULL)
    {
        $this->obj_name = $name;
    }

    // La méthode privée en question
    private function privateMethod()
    {
        echo "Methode privée dans " . $this->obj_name . "\n";
    }

    // Une méthode publique qui va servir de "tremplin" vers la fonction privée d'une instance tierce
    public function test(Objet $t)
    {
        $t->privateMethod();
    }
};
<?php // fichier test.php
require_once("Objet.class.php");
$obj = new Objet('objet n°1');
$obj2 = new Objet('objet n°2');
// C'est l'objet "obj" qui va appeler une méthode privée appartenant à obj2:
$obj->test($obj2);

Et cela marche:

$ php test.php
Methode privée dans objet n°2

Cependant, cela est à mon avis tout simplement une abération du langage qui ne devrait être utilisée.

__toString

La fonction __toString est une fonction toute simple permettant de définir la façon dont la classe va réagir quand on demandera à la convertir en String (en faisant un appel à « echo », par exemple).

// En reprenant l'Objet ci dessus en rajoutant la méthode:
    public function __toString()
    {
        return "class " . $this->obj_name;
    }
// Et dans test.php
echo $obj;
// Retournera 'class objet n°1'

__invoke

En restant sur la même page de documentation, une autre fonction existe pour définir comment agira la classe si on l’appelle comme étant une fonction. Il s’agit de la fonction __invoke.

// En reprenant Objet.class.php, en y ajoutant:
    public function __invoke()
    {
        echo "Appel de echo sur " . $this . "\n";
    }
<?php // fichier test.php
require_once("Objet.class.php");
$obj = new Objet('objet n°1');
$obj();

Et cela donnera:

$ php test.php
Appel de echo sur class objet n°1

Il reste encore beaucoup de fonctions à découvrir (setters et getters/callers génériques…), et celles ci feront l’objet d’une suite à cet article.

Laisser un commentaire


NOTE - Vous pouvez utiliser les éléments et attributs HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>