Accueil ¦ Approche objet ¦ POO avec PHP ¦ Exemples ¦ Exercices

Introduction à la programmation orientée objet avec le langage PHP

Définir une classe ¦ Créer un objet ¦ Héritage ¦ Opérateur :: et parent ¦ Durée de vie ¦ Les fonctions magiques ¦ Conclusion ¦ Bibliographie

Classe, attribut, méthode, constructeuren haut

spacer
* PHP n’est pas un langage orienté objet mais il permet, dans une certaine mesure, la géstion des objets.
* PHP supporte la notion d’héritage et permet donc la construction d'une hiérarchie de classes et l’introduction du polymorphisme.
* PHP, dans le concept d’encapsulation, permet de définir un seul niveau de visibilité des éléments de la classe : publique.
spacer

La déclaration d'une classe se fait par l'utilisation du mot clé class, suivit du nom de la classe. A partir de ce point, le moteur PHP sait que des objets de type user (voir le code) pourront être intentés et il sera capable de leur allouer un emplacement mémoire.

spacer
classe

<?php

class user {


// propriétés

// var Déclaration des variables
var $name;
var $password;
var $last_login;


// méthodes

// constructeur
function user ($inputName, $inputPassword) {
$this->name = $inputName;
$this->password = $inputPassword;
$this->last_login = time();

}

// méthode d'accès
// lire la date de la dérnière connexion
function getLastLogin() {
return (Date("M d Y", $this->last_login));

}
}
?>

spacer
spacer
Propriété (attribut ou variable)
spacer
spacer
- Les attributs sont des sortes de variables internes à l'objet qui ne sont accessibles qu'à travers celui-ci.
spacer
- La déclaration d'un attribut au sein d'une classe se fait par l'utilisation du mot clé var suivi du nom de l'attribut. (PHP ne nécessite pas de déclaration préalable des variables, mais, dans la cadre d'une classe, il est préférable de la faire.)
spacer
- Quand vous déclarez une propriété, vous ne spécifiez aucun type de donnée. Elle pourra contenir, par exemple, un entier, chaîne de caractères, un autre objet.
spacer
Méthode (fonction)
spacer
- Les méthodes quant à elles, sont des fonctions internes à l'objet qui vont permette d'agir sur les attributs de l'objet.
spacer
- La déclaration d'une méthode (ou fonction) à l'intérieur d'une classe se fait de la même façon que dans un script classique. On utilise pour cela le mot réservé function suivi du nom de la méthode.
spacer
- Si la méthode requiert des paramètres, on les indiquera entre parenthèses. En PHP il n'est pas nécessaire de spécifier le type de retour de la fonction.
spacer
Une méthode particulière, le constructeur de la classe, est automatiquement appelée lors de la création d'un objet (instanciation de la classe).Cette méthode permet d'initialiser l'objet à sa création en donnant par exemple des valeurs à chacun de ses attributs. Le constructeur d'une classe est donc une méthode qui porte le même nom que la classe dont elle est le constructeur.
spacer
spacer
spacer
Les méthodes disposent d'une variable spéciale, this (suivi de l'opérateur -> qui référence une classe, une mèthode ou une propriété d'une classe), qui contient l'objet ou l'instance courante. Il faut utiliser cette variable chaque fois qu'on veut nous référer à une propriété ou à une méthode de l'objet. PHP supposera qu'il s'agit d'une variable locale (voir l'usage de this au sein du constructeur de la classe user et la fonction d'affichage getLastLogin).

Instanciation, accéder aux propriétés et aux méthodesen haut

spacer
La création d'un objet à partir d'une classe, s'appelle l'instanciation (un objet étant alors appelé instance d'une classe).
La création d'un objet permet plusieurs choses:
- La création d'un espace mémoire est réservé pour recevoir toutes les propriétés durant son utilisation
- L'atribution d'un nom à l'objet.
- En appelant le constructeur, cet objet sera initialisé (avec des valeurs par défaut ou des valeurs passées en paramètres).
- Chaque instance possède son propre jeu de propriétés, mais ses méthodes sont communes à toutes les instances de cette classe.
spacer
Pour la création d'un objet à partir d'une classe il y a quatre manière de générer l'objet:
spacer
1. Comme dans notre exemple, la variable $currentuser contient l'objet créé avec le mot réservé new suivi du nom de la classe user. Si le constructeur de la classe ne comporte pas des arguments, il n'est pas nécéssaire d'utiliser des parenthèses. En cas contraire placez-les entre parenthèses après le nom de la classe (comme pour un appel de fonction).
spacer
2. Copier un objet par un simple jeu des variables (dans l'exemple ci-dessous $obj2 contient une copie, une nouvelle instance, susceptible de vivre sa propre vie en n'utilisant pas le constructeur de la classe user).
spacer
3. La troisième manière de générer l'objet est par inférence, c'est à dire par déduction à partir du contexte. Vue le fait que PHP permet de créer des variables $obj3 sans une déclaration préalable on peut créer l'objet par le simple fait d'utiliser une variable dans un context d'objet (en appliquant l'opérateur -> à une variable suffit que cette variable contienne un objet même si jamais la classe correspondante n'a été définie (pas valable pour ajouter des méthodes !).
spacer
4. La dernière manière de générer l'objet est par la transformation (casting) d'un tableau associatif. Lorsqu'un tableau devient un objet, $obj4 , tous les éléments du tableau indexés par une chaîne de caractères deviennent des propriétés (en cas d'indexés par chaîne vide ils sont cachés pour l'objets).
spacer
Pour les objets générés par inférence (3) et casting (4) aucune classe n'a été définie. Ils apartiennent à la classe stdClass du PHP.
spacer
spacer
spacer
exemple1

<?php

// création d'une instance par le mot new

$currentuser = new user ("Dorel", "staf2x");

// création d'une nouvelle instance par copy

$obj2 = $currentuser;
$obj2 -> commentaire = "ajoutons une propriété";

// création d'une nouvelle instance par inférence

$obj3 -> age = 25;
$obj3 -> poids= 75;

// création d'une nouvelle instance par casting

$arr['nom'] = "Jean";
$arr['pays'] = "Suisse";
$obj4 = (object) $arr;
print ($obj4->nom); // affiche la propriété nom

// imprimer la date

print ($currentuser->getLastLogin());

// imprimer le nom

print ($currentuser->name);
print ("<br />\n");

?>

spacer
spacer
Le propriétés d'une instance correspondent à des variables identiques à toutes celles que nous avons vues jusqu'à présent.
spacer
- Pour accéder aux propriétés il faut utiliser l'opérateur ->
spacer
- Si un propriété d'objet est elle-même un objet on peut utiliser deux fois l'opérateur -> dans la même instruction (seulement avec la version PHP4)
spacer
- Á la différence des langages orientés objet (Java, C++) les membres (propriétés et méthodes) des classes PHP ne peuvent être déclarées protected, private ou public (c'est à dire que n'importe quelle partie du script on peut y accéder pour lire ou modifier les valeurs qu'elles contient).
spacer
L'accès aux méthodes est semblable à l'accès aux propriétés
spacer
- L'opérateur -> est utilisé pour indiquer sur quelle instance doit porter la méthode (par exemple l'expression $currentuser->getLastLogin()).
spacer
- Pour ce qui reste, les méthodes se comportent exactement comme des fonctions ordinaires.
spacer
spacer
exemple 2
<?php
//Objet composé d'autres objets

class chambre {
var $nom;
function chambre ($nom){

//pas de conflit entre les deux "nom"
$this->nom=$nom;
}
}

class maison
{

//une liste des chambres
var $chambres;
}


// créer une maison vide
$home = new maison();

// ajouter des chambres
$home->chambres[] = new chambre (chambre de JJ);
$home->chambres[] = new chambre (chambre de Stek);
$home->chambres[] = new chambre (salle de bains);


// montrer le nom de la première chambre
print($home->chambres[0]); // on affiche: "chambre de JJ"

?>
spacer
spacer

Héritageen haut

spacer
Le principal apport de la programmation objet est certainement de faciliter la réutilisation (reusability) de modules, en occurrence des objets. Les deux techniques utilisées sont, l'héritage et la composition (un exemple simplifié de composition dans l'exemple 2, en haut).
spacer
Ecrire une classe spécialisée à partir d'une classe générale est le meilleur moyen de réutiliser ce code déjà produit.
spacer
Cette procédure s'appelle héritage et elle est introduite par le mot clé extends.
spacer
spacer
exemple3
//
<?php

class myclass {
var $myvar;
function myclass($myparameter) {
$this->myvar = $myparameter;
}

function afficher() {
echo "myvar vaut : $this->myvar";
}
}


?>

p


<?php

class myclass2 extends myclass {

var $myvar2 ;

function myclass2($myparameter, $myparameter2) {
$this->myvar = $myparameter;
$this->myvar2 = $myparameter2;
}

function afficher2($color) {
echo "<font color=\"$color\">myvar vaut : $this->myvar</font><br>";
echo "<font color=\"$color\">myvar2 vaut : $this->myvar2</font><br>";
}

}


?>

Dans cet exemple nous venons de déclarer une classe fille myclass2 qui étend la classe mère myclass précédemment créée. Dans cette classe, nous avons ajouté un attribut myvar2 et une méthode afficher2($color ) qui ne seront définis que dans cette classe. Nous avons également redéfini un constructeur myclass2($parameter, $parameter2) qui permet d'initialiser les 2 attributs de l'objet lors de sa création.

//

<?php

$myobject2 = new myclass2(10, 20);
$myobject2->afficher2("red");
$myobject2->afficher();


?>

Ces trois lignes montrent comment utiliser un objet créé à partir d'une classe fille. Dans un premier temps, on crée une instance de la classe myclass2 que l'on stocke dans un objet nommé $myobject2, en attribuant les valeurs 10 et 20 aux attributs $myvar et $myvar2 . Puis on fait simplement appel à la méthode afficher2($color) définie dans mycalss2. La troisième quant à elle est plus intéressante. En effet, à aucun moment, la méthode afficher() n'apparaît dans la classe myclass2. Et pourtant, il est tout à fait possible d'utiliser cette méthode à cet endroit car celle-ci a été héritée de la classe mère.

De la même manière, les attributs des classes mères sont également accessible dans les classes filles. Nous avons déjà pu le remarquer dans le constructeur de la classe fille myclass2 ou l'on a affecté une valeur à l'attribut $myvar qui n'est défini que dans la classe mère.

$this->myvar = $myparameter;
spacer
spacer
spacer
À partir de la version 4, PHP inclut un jeu de douze fonctions de gestion des classes et des instances utiles à la POO:
spacer
call_user_method_array -- Appelle une méthode utilisateur avec un tableau de paramètres
call_user_method -- Appelle une méthode utilisateur d'un objet
class_exists -- Vérifie qu'une classe a été définie
get_class_methods -- Retourne les noms des méthodes d'une classe
get_class_vars -- Retourne les valeurs par défaut des attributs d'une classe.
get_class -- Retourne la classe d'un objet
get_declared_classes -- Liste toutes les classes définies
get_object_vars -- Retourne un tableau associatif des propriétés d'un objet
get_parent_class -- Retourne le nom de la classe d'un objet
is_a -- Retourne TRUE si un objet a pour parent une classe donnée
is_subclass_of -- Détermine si un objet est une sous-classe
method_exists -- Vérifie que la méthode existe pour une classe.
spacer
Ces fonctions sont disponibles dans le module PHP standard, qui est toujours accessible. Il n'y pas d'installation nécessaire pour utiliser ces fonctions, elles font parties du coeur de PHP. [ch2.php.net.php]

spacer
exemple4
// Dans cet exemple, on définit une classe de base, et une extension.
// La classe de base définit un légume, s'il est mangeable ou pas et sa couleur.
//La sous-classe epinard ajoute une méthode pour le cuisiner, et une autre pour savoir s'il est cuisiné.

// Exemple 1. Fonctions d'objets : classes.inc

<?php

// classe de base, avec ses membres et ses méthodes

class Legume {

var $edible;
var $color;

function Legume( $edible, $color="green" ) {
$this->edible = $edible;
$this->color = $color;
}

function is_edible() {
return $this->edible;
}

function what_color() {
return $this->color;
}

}

// fin de la classe Legume // Extension la classe de base

class Epinard extends Legume {

var $cuit = FALSE;

function Epinard() {
$this->Legume( TRUE, "green" );
}

function cuisine() {
$this->cuit = TRUE;
}

function is_cooked() {
return $this->cooked;
}

}

// fin de la classe Epinard

?>

// Exemple 2. Fonctions d'objets : test_script.php

<?php

include "classes.inc";

// Fonctions utilitaires

function print_vars($obj) {
$arr = get_object_vars($obj);
while (list($prop, $val) = each($arr))
echo "\t$prop = $val\n";
}


function print_methods($obj) {
$arr = get_class_methods(get_class($obj));
foreach ($arr as $method)
echo "\tfonction $method()\n";
}


function class_parentage($obj, $class) {

if (is_subclass_of($GLOBALS[$obj], $class)) {
echo "L'objet $obj appartient à la classe ".get_class($$obj);
echo " est une sous-classe de $class\n";
} else {

echo "L'objet $obj n'est pas une sous-classe de $class\n";
}
}


// instantie 2 objets

$veggie = new Legume(true,"blue");
$leafy = new Epinard();


// affiche les informations sur ces objets

echo "légume : CLASS ".get_class($veggie)."\n";
echo "feuillues : CLASS ".get_class($leafy);
echo ", PARENT ".get_parent_class($leafy)."\n";


// affiche les propriétés du légume

echo "\nlégumes : Propriétés\n";
print_vars($veggie);


// et les méthodes des feuillus

echo "\nfeuillus : Méthodes\n";
print_methods($leafy);

echo "\nParentée:\n";
class_parentage("leafy", "Epinard");
class_parentage("leafy", "Legume");


?>

Il est important de noter que dans les exemples ci-dessus, les objets $feuilles sont une instance de Epinard qui est une sous-classe de Legume, donc la dernière partie du script va afficher :


[...]
Parentée:
L'objet feuilles n'est pas une sous classe epinard
L'objet feuilles est une sous-classe de Legume
spacer
spacer

Opérateur :: et parenten haut

spacer
Nous venons de voir qu'il était possible de définir des classes à partir d'autres classes. Dans l'utilisation des objets, il pourra aussi être utile de faire appel à certaines méthodes de certaines classes sans avoir la contrainte que l'objet de cette classe soit créé auparavant..
spacer
Dans sa version 4, PHP permet d'effectuer ce genre de traitement sur des classes. On utilisera alors l'opérateur :: qui à la manière du -> pour un objet permettra l'accès aux méthodes à travers un nom de classe.
spacer
spacer
exemple5
<?php

// exemple d'utilisation du l'opérateur ::
// création d'une classe simple pour afficher la date

class myDate {

var $day;
var $mounth;
var $year;

function mydate($day, $mounth, $year) {
$this->day = $day;
$this->mounth = $mounth;
$this->year = $year;
}

function printTodayDate() {
echo date("j/m/Y");
}

}


?>

// Nous appelons la méthode printTodayDate() de la classe myDate sans qu'aucun objet de type myDate ne soit préalablement instancié.

<?php

myDate::printTodayDate();

?>

Une méthode de classe telle que celle-ci ne dois pas faire référence aux attributs qui ne seront valorisés que lors de la création effective de l'objet.


// exemple comment on utilise le mot résérvé parent

//De façon similaire, on peut également faire appel à la méthode de la classe mère d'un objet sans pour autant être obligé de créer un objet à partir de cette classe mère. Au lieu d'utiliser le nom littéral de la classe de base dans votre code, vous pouvez utiliser le mot réservé parent , qui représente votre classe de base (celle indiqué par extends , dans la déclaration de votre classe).

<?php

class A {


function example() {
echo "Je suis A::example() et je fournis une fonctionnalité de base.<br>\n";
}

}


//

class B extends A {

function example() {
echo "Je suis B::example() et je fournis une fonctionnalité supplémentaire.<br>\n";
parent::example();
}

}


//

$b = new B;

// Cette syntaxe va appeler B::example(), qui, à sont tour, va appeler A::example().

$b->example();

?>

// Si l'héritage change, vous n'aurez plus qu'à modifier le nom de la classe dans la déclaration extends de votre classe.

spacer
spacer

Durée de vie des objets, fonctions serialize() et unserialize().en haut

spacer
Comme toutes variables en PHP, le durée de vie d'un objet n'excède pas la durée d'exécution du script qui le crée. Il faut transformer notre objet, en une chaîne de caractères avec la fonction serialize().
spacer
La fonction serialize retourne une chaîne représentant une valeur qui peut être stockée dans les sessions de PHP , ou une base de données et la fonction unserialize() peut relire cette chaîne pour recréer la valeur originale. La fonction serialize va sauver toutes les variables d'un objet. Le nom de la classe sera sauvé mais par les méthodes de cet objet.
spacer
Pour permettre à unserialize de lire un objet, la classe de cet objet doit être définie. C'est-à-dire, si vous avez un objet $a de la classe A dans une page php1.php, et que vous le linéarisez avec serialize , vous obtiendrez une chaîne qui fait référence à la classe A, et contient toutes les valeurs de $a. Pour pouvoir le relire avec la fonction unserialize dans une page page2.php, il faut que la définition de la classe A soit présente dans cette deuxième page. Cela peut se faire de manière pratique en sauvant la définition de la classe A dans un fichier séparé, et en l'incluant dans les deux pages page1.php et page2.php.
spacer
spacer
spacer
exemple6

// Définir la classe A dans un fichier externe classa.inc

<?php

// classa.inc:

class A {

var $one = 1;

function show_one() {
echo $this->one;
}
}

?>

// Créer la page1.php

//page1.php:

<?php

include("classa.inc");

$a = new A;
$s = serialize($a);

// enregistrez $s où la page2.php pourra le trouver.

$fp = fopen("store", "w");
fputs($fp, $s);
fclose($fp);

?>

// Créer la page2.php

//page2.php:

<?php

// Ceci est nécessaire pour que unserialize() fonctionne correctement

include("classa.inc");

$s = implode("", @file("store"));
unserialize($s);

// maintenant, utilisez la méthode show_one de l'objet $a.

$a->show_one();

?>
spacer
spacer
Si vous utilisez les sessions et la fonction session_register pour sauver des objets, ces objets seront linéarisés automatiquement avec la fonction serialize à la fin de chaque script, et relus avec unserialize au début du prochain script. Cela signifie que ces objets peuvent apparaître dans n'importe quelle page qui utilise vos sessions.
spacer
Il est vivement recommandé d'inclure la définition de classe dans toutes vos pages, même si vous n'utilisez pas ces classes dans toutes vos pages. Si vous l'oubliez et qu'un tel objet est présent, il perdra sa classe, et deviendra un objet de classe stdClass sans aucune fonction, et donc, plutôt inutile.
spacer
Si, dans l'exemple ci-dessus, $a devient un objet de session avec l'utilisation de session_register("a") , vous devez pensez à inclure le fichier classa.inc dans toutes vos pages, et pas seulement page1.php et page2.php.
spacer

Les fonctions magiquesen haut

spacer
La fonction serialize() qui transforme les objets en une chaîne de caractères, le fait de façon trop "brutale"dans certains cas. En effet, il est possible que vos objets aient ouvert une connexion à une base de données et ne l’aient pas encore fermée. Dans ce cas, il est préférable (et même capital) de s’assurer que certaines opérations soit effectuées avant que l’objet ne soit effectivement linéarisé.
spacer
La fonction magique __sleep() ferme proprement toute connexion à une base de données, de valider les requêtes, de finaliser toutes les actions commencées. La fonction __sleep() retourne obligatoirement un tableau contenant la liste des attributs à linéariser. Cette fonction est aussi pratique si vous avez de très grands objets qui n'ont pas besoin d'être sauvé entièrement. Cette fonction, doit exister dans l’objet qui sera automatiquement appelée par la fonction serialize().
spacer
La fonction __wakeup va rétablir toutes les connexions aux bases de données, et de recréer les variables qui n'ont pas été sauvées, et, si elle existe, sera automatiquement appelée par la fonction unserialize().
spacer
a
spacer
spacer
exemple7
 

// Voici un exemple qui montre comment préparer les objets de la classe myclass à être linéarisés grâce à la fonction __sleep() et la fonction _wakeup().



<?php

class myclass {
...
function __sleep() {
$this->myvar = 50;
return array('myvar');
}

function __wakeup() {
$this->myvar = 100;
}

}


?>
spacer

Conclusionen haut

spacer
Les objets sont actuellement l'un des aspects du langage PHP qui concentre le plus l'attention des développeurs du langage. On peut donc s'attendre dans les prochaines versions de PHP à une meilleur intégration et des possibilités encore plus étendues.
spacer
La partie théorique de ce cours est à présent terminé. J'espère qu'il aura répondu à vos attentes. Si vous observez des erreurs, des imprécisions ou d'autres fautes, merci de m'en faire part.
spacer

Bibliographieen haut

spacer
[PHP2002] Atkinson L., Programmation en PHP, CampusPress, 2002
[PHP2003] Atkinson L., PHP 5, CampusPress, 2003
[Anthology I 2003] Fueks Harry, The PHP Anthology, Volume I: Foundations, SitePoint Pty Ltd., 2003
[Anthology II 2003] Fueks Harry, The PHP Anthology, Volume II:Applicatons, SitePoint Pty Ltd., 2003
[Intclass] Welcome to the PHP Classes Repository[lien]
[Doc-PHP-fr] Documentation PHP 4.3.3 en Français[lien]
[Man-PHP-en] Manuals at the official PHP site[lien]
[Library-PHP] A set of PHP classes and library functions[lien]
[Tutoriel-1-fr] Cours et tutoriels, outils de développement[lien]
[SitePoint] Articles, books, forums to Site Point[lien]
[Tutoriel-2-fr] Tutoriels francophones PHP4 et MySQL[lien]
[Intro-class-en] An Introduction to Classes[lien]
[Ex-class-fr] Quelques exemples des classes[lien]

© 2010 Dorel Gorga