Archives de catégorie : PHP

Le PHP (PHP: Hypertext Preprocessor) est un langage de scripts libre principalement utilisé pour produire des pages Web dynamiques via un serveur HTTP, mais pouvant également fonctionner comme n’importe quel langage interprété de façon locale, en exécutant les programmes en ligne de commande. PHP est un langage impératif disposant depuis la version 5 de fonctionnalités de modèle objet complètes. En raison de la richesse de sa bibliothèque, on désigne parfois PHP comme une plate-forme plus qu’un simple langage.
Le PHP est un langage que j’utilise assez souvent et il m’arrive donc de découvrir de nouvelles choses à son sujet. Du coup, rien de tel pour se fixer les idées que d’essayer de résumer ça dans un billet.

Vocabulaire à connaître de la POO

Publié dans PHP objet | 2 commentaires

Voici quelques mots de vocabulaire qu’il peut être utile de connaître pour s’y retrouver en programmation orientée objet. Je complèterai cette liste au fil du temps. (en fonction de mes souvenirs et de mes découvertes)

  • Classe : Permet de définir la structure d’un objet qui pourra ensuite être utilisé plusieurs fois avec des options différentes, et dupliqué à loisir par le biais de classes filles. Mot clef : class
  • Instance : Une classe définie et chargée. Une instance (un objet) est donc utilisable concrètement, alors qu’une classe. Mot clef : new
  • Objet : Instance d’une classe
  • Attribut ou Propriété : Variable d’une classe. Mot clefs : var ou const
  • Méthode : Fonction d’une classe. Mot clefs : function
  • Surcharge ou polymorphisme Ad hoc : Permet de définir des méthodes avec le même nom et ayant des fonctionnalités similaires (ex : afficher(), supprimer()) dans des classes héritant d’une même classe mais n’ayant pas d’autres liens entres elles. On parle ainsi de surcharge d’une méthode lorsque l’on redéfinie une méthode qui avait déjà été définie dans une classe parente. Ex : fonction trier() qui fonctionnera pour trier des livres ou des CD sans que le programmeur se souci du nom de la méthode.
  • Attribut ou méthode magique : Attribut ou méthode commençant généralement par deux underscores (__) , étant apparu dans PHP 5, et ayant des fonctionnalités impossible à coder « à la main » comme par exemple le déclenchement d’une méthode lors de l’instanciation d’une classe ou la suppression d’une instance. Ex : __construct, __clone, __toString
  • Méthode prédéfinie : Méthode déjà définie par PHP. Ex : get_parent_class, class_exists
  • Héritage : Notion permettant qu’une classe (dites fille) hérite des attributs et des méthodes d’une autre classe (dites parente). Mot clef : extends
  • Constructeur : Méthode permettant de créer un objet en instanciant une classe. Mot Clef : __construct($params)
  • Interface : Définie une liste de méthodes que doit contenir les classes qui implémentent cette interface. Mot clef : interface

Pour se fixer les idées sur self et this

Publié dans PHP objet | Un commentaire

Voici un petit exemple pour bien comprendre ce qui se passe lorsque l’on utilise self ou $this, avec des attributs static ou non :

<?php
class DitBonjour {
	public static $fr = 'Coucou le monde !';
	public static $de = 'Guten tag!';
	public $en = 'Hello world!';
	public $es = 'Buenos dias!';
	function saluer()
	{
		echo '<strong>1. Public, static, direct :</strong> '.$this->de.'<br />';
		echo '<strong>2. Public, static, self :</strong> '.self::$fr.'<br />';
		echo '<strong>3. Public, direct :</strong> '.$this->en.'<br />';
		echo '<strong>4. Public, self :</strong> '.self::$es.'<br />';
	}
}
$appel = new DitBonjour();
$appel->saluer();
?>

Ce qui renvoie :

Notice: Undefined property: DitBonjour::$de in F:\bn\Web\Test\PHPObjet\test2.php on line 13
1. Protected, static, direct :
2. Protected, static, self : Coucou le monde !
3. Public, direct : Hello world!
Fatal error: Access to undeclared static property: DitBonjour::$es in F:\bn\Web\Test\PHPObjet\test2.php on line 16

Moralité

  • On ne peut accéder à un attribut static qu’avec self (ou parent, ou NomClass)
  • On ne peut accéder à un attribut non static avec self, on y accède avec $this

Utiliser les méthodes et les attributs d’une autre class

Publié dans PHP objet | Laisser un commentaire

Ah, je viens enfin de mieux comprendre à quoi servait l’opérateur cons ::. Dans le précédent billet où j’en parlais je disais qu’il permet de résoudre un attribut ou une méthode, éh bien c’est tout à fait vrai !

  • Pour appeler un attribut ou une méthode d’une class dans cette même class, on utilise $this->methodeOuAttribut.
  • Pour appeler un attribut ou une méthode d’une class lorsqu’on a instancié cette class, on utilise $nomInstance->methodeOuAttribut.
  • Pour appeler un attribut ou une méthode d’une class dans une autre class, on utilise NomDeLaClass::methodeOuAttribut. Les deux class doivent bien sûr se trouver dans le même fichier, ou on peut inclure l’une dans le fichier de l’autre avec include() ou require().

Dans le cas d’un attribut, si l’on tente d’y accéder avec le nom d’une class, cela signifie que notre attribut doit être static, il reste identique pour toutes les instances de cette class.
Prêt pour un petit exemple (débile) ?

<?php
class DitBonjour {
	protected static $fr = 'Coucou le monde !';
	public static $en = 'Hello world!';
	public static $de = 'Guten tag!';
	function saluer()
	{
		return 'Guten tag!'.'<br />';
	}
	function saluer_en_langue($langue)
	{
		return $langue;
	}
	function fr()
	{
		return self::$fr;
	}
	function de()
	{
		return $this->de;
	}
}

class Appeler {
	function dire_bonjour()
	{
		echo DitBonjour::saluer();
	}
	function dire_bonjour_en_langue()
	{
		echo DitBonjour::saluer_en_langue(DitBonjour::fr()).'<br />';
		echo DitBonjour::saluer_en_langue(DitBonjour::$en).'<br />';
		echo DitBonjour::saluer_en_langue(DitBonjour::de()).'<br />';
	}
}

$appel = new Appeler();
$appel->dire_bonjour();
$appel->dire_bonjour_en_langue();

Ceci renverra :

Guten tag!
Coucou le monde !
Hello world!
Notice: Undefined property: Appeler::$de in F:\bn\Web\Test\PHPObjet\test2.php on line 26

Continuer la lecture

Traduction instantannée avec BabelFish

Publié dans PHP objet | Un commentaire

Parce qu’il faut bien mettre un petit peu en pratique de temps en temps, je me suis amusé à créer une class qui implémente un module de traduction à l’aide de BabelFish (le système de traduction de Yahoo). En résumé, j’ai plusieurs attributs qui déterminent les différents paramètres de la classe (url de la page de retour, url de BabelFish, langue du message à traduire, langue de la traduction), le constructeur permet de définir ces deux derniers, puisque ce sont les seules succeptible de changer assez souvent ! (pour pouvoir faire du Espagnol -> Anglais ou Grec -> Chinois) L’url pour traduire une phrase avec BabelFish se décompose de la manière suivante :

  • http://fr.babelfish.yahoo.com/translate_txt : base de l’url
  • lp : langues à utiliser (ex : fr_en)
  • trtext : chaine de caractères à traduire. Les caractères accentués sont bien traités, mais les guillements et les espaces posent un problème. Il faut remplacer les espaces par des + ou des %20, quant aux guillemets, bah je n’arrive pas à savoir par quoi il fut les transformer, donc pour l’instant je bloque.

Et voilà, il n’y a plus qu’à faire un petit file_get_contents pour récupérer la page chargée par cet url, et une petite regex pour ne récupérer que la traduction : et le tour est joué !
Continuer la lecture

Un objet en sortie d’une requête Mysql

Publié dans PHP objet | Laisser un commentaire

Parfois, on peut être un peu mordu de PHP objet, et au lieu de vouloir un array associatif (le nom du champ comme clé : mysql_fetch_assoc), ou un array indexé numériquement (un numéro comme clé : mysql_fetch_row -> le plus rapide), on veut un objet « associatif » (le nom des champs comme attribut) grâce à mysql_fetch_object. C’est tout aussi rapide que mysql_fetch_assoc ou mysql_fetch_array, un peu moins que mysql_fetch_row (quand même) mais ça peut être utile.
Le manuel PHP nous dit : mysql_fetch_object() retourne un tableau qui contient la ligne demandée dans le résultat result et déplace le pointeur de données interne d’un cran.
Voici un exemple d’utilisation (tiré du manuel PHP) avec matable(user_id, user_name, user_age) que voici :

user_id | user_name | user_age
   1       Fylhan	NULL
   2        BN	         18
<?php
// Connexion à la BDD
mysql_connect('serveur', 'utilisateur', 'mdp');
mysql_select_db('nombdd');
// Exécution de la requête
$result = mysql_query('select * from matable');
if (mysql_num_rows($result) == 0)
  echo 'Aucun résultat.';
else {
  // Boucle sur les champs (chaque champ étant renvoyé en tant qu'objet)
  while ($row = mysql_fetch_object($result))) {
    echo $row->user_id.' ';
    echo $row->user_name.'<br />';
  }
}
// Libération de la mémoire 
mysql_free_result($result);

Ceci renverra :

1 Fylhan
2 BN

Continuer la lecture

La visibilité tu vois…

Publié dans PHP objet | Laisser un commentaire

Je viens de découvrir un nouveau tutoriel sur la POO en PHP sur le site Apprendre PHP. Le site est bien joli, et le tutoriel est bien expliqué. L’auteur s’est donné la peine de donner de nombreux exemples, et c’est ce qui rend ce tutoriel encore plus intéressant à mon sens.
Dans un précédent billet, j’avais expliqué l’utilisation des mots clés private, protected et private, mais avec ce tutoriel, je viens d’apprendre que cette notion s’appelle la visibilité d’attributs ou de méthodes.

Petit rappel sur la visibilité

  • public (valeur par défaut) : l’attribut ou la méthode ainsi défini pourra être utilisé par n’importe qui.
  • protected : l’attribut ou la méthode ainsi défini ne pourra être utilisé que dans la class parente et ses dérivées (bref, celles qui en héritent quoi).
  • private : l’attribut ou la méthode ainsi défini ne pourra être utilisé que dans la class parente.

Un petit exemple d’utilisation :

class MaClass {
  public $var1;
  public function fonction()
  {
    echo 'Coucou';
  }
}

Et une petite erreur renvoyé si on utilise un attribut ou une méthode protégée ou privée à mauvaise escient : Fatal error: Cannot access private property NomClass::$attribut in /path/to/Apprendre-php/magic_methods.php on line X.
Continuer la lecture

Rendre __construct() comptatible PHP 4

Publié dans PHP objet | Laisser un commentaire

La méthode magique __construct() est apparue dans PHP5, par conséquent PHP4 (ou inférieur) ne la reconnait pas. Auparavant, au lieu d’utiliser __construct(), on utilisait une méthode qui portait le même nom que la classe elle-même. Donc pour avoir une compatibilité PHP4 et PHP5, on peut utiliser le code suivant :

<?php
class MaClass
{
  var $app;

  function MaClass($app)
  {
    $this->__construct($app);
  }

  function __construct($app)
  {
    $this->app = $app;
  }
}

Ainsi, si on est en PHP5, le __construct() est bien compris et utilisé. Si on est en PHP4 (ou inférieur), on utilise MaClass() qui utilise une nouvelle méthode que l’on définie : __construct().
Alors pourquoi ne pas laisser tomber __construct() et n’utiliser que MaClass()__construct() c’est l’avenir le présent. Un développeur de la boîte où j’ai effectué un stage m’a appris que si on est en PHP5, ce dernier va sauter sur le __construct() et lira ensuite plus tard le MaClass() (et donc le zappera), on gagne un peu de temps pour une exécution en PHP5. Par conséquent ce bout de code utilise les avantages du PHP5 et est compatible PHP4 (et inférieur) 😀

Le clonage n’est pas une référence

Publié dans PHP objet | Laisser un commentaire

Aujourd’hui j’ai fini le cours de PHP 5 sur Developpez.com consacré au PHP objet. Il y a encore quelques trucs que je détaillerai dans les billets des prochains jours, mais en somme, mis à part mon problème avec self et parent, je pense avoir compris l’essentiel. Il se trouve que je suis actuellement en stage et que je vais avoir l’occasion de me confronter au framework maison de la boîte où je travaille, et, ô miracle, c’est un framework objet ! Il a l’air bigrement complet et bien fichu, mais aussi peut-être un petit peu compliqué pour moi… ça va être l’occasion de voir ce que j’ai compris ! Mais bref… parlons un peu de l’instanciation d’une classe et clonage d’objets.

Instanciation d’une classe et destruction d’objets

Lorsqu’on instancie une classe avec le mot clé new, on créé une référence de cette instanciation. Et si on fait une copie de cet objet avec le symbole =, on créé une nouvelle référence vers cette instanciation. Or pour supprimer une instanciation d’une classe, avec la fonction unset(), il faut que toutes les références de cette classe soient supprimées. Pour bien comprendre, reprenons l’exemple de Développez.com. Pour cela, il faut savoir que la méthode magique __destruct() est déclenchée lorsqu’on supprime une instance d’une classe.

<?php
class Blog {
  function __destruct()
  {
    echo 'Je me meurs !';
  }
}
$monBlog = new Blog();
$monAutreBlog = $monBlog;
echo 'Allons soldats, tuons monBlog !';
unset($monBlog);
echo 'Puisqu\'il résiste, éliminons donc son frère !';
unset($monAutreBlog);

Cet exemple affichera :

Allons soldats, tuons monBlog !
Puisqu'il résiste, éliminons donc son frère !
Je me meurs !

Continuer la lecture

Interfaces : plus utiles qu’il n’y parait

Publié dans PHP objet | Laisser un commentaire

C’est en regardant le détails des interfaces prédéfinies sur le Manuel PHP que j’ai mieux compris l’intérêt des Interfaces. Prenons comme exemple l’interface Traversable : elle signifie que les classes l’implémentant doivent pouvoir parcourir des objets avec foreach. Pour cela, il faut que les classes en question implémentent, par exemple, l’interface prédéfinie Iterator qui définit les itérateurs. Ces itérateurs doivent pouvoir utiliser les fonctions rewind (retour arrière), next (au suivant), current (position actuelle), etc… Et le manuel nous montre des exemples d’implémentations de ces interfaces.
En somme, j’ai envie de dire que les interfaces sont aux classes ce que sont les types aux variables en programmation « classique ». Un peu quoi… En structurant sa manière de programmer (en utilisant des types et/ou des interfaces) on diminue le risque d’erreurs ou de bugs, on améliore la lisibilité, la relecture et la réutilisation du code et ça : c’est quand même tout l’enjeu d’un code durable !!!
Ah, il est à noter qu’une interface peut hériter d’une autre. L’interface Iterator hérite de Traversable par exemple. Si on devait créer cette interface, on écrirait :

<?php
interface Iterator extends Traversable
{ }

Même syntaxe qu’avec les classes en fait !
Et une classe peut aussi implémenter plusieurs interfaces, alors pour faciliter l’écriture, il est possible de séparer les interfaces par des virgules :

<?php
class RecursiveCachingIterator extends CachingIterator implements Countable , ArrayAccess , Iterator , Traversable , OuterIterator , RecursiveIterator
{ }

Comme toujours, le Manuel PHP m’aura été d’une grande aide ! Je l’utilise beaucoup pour le procédural (i.e. la programmation non-objet), j’aurai dû y penser plus tôt pour l’objet !

Je me demande s’il est possible de définir une classe qui hérite de plusieurs autres classes en les séparant par des virgules. En théorie oui. Une classe ne peut hériter de plusieurs classes. Bref l’héritage multiple est impossible en PHP, mais l’interfaçage multiple existe. Nuançons cette seconde partie de ma sentence : une classe ne peut pas implémenter deux interfaces partageant des noms de méthodes.

Interface, les Mousquetaires sont toujours de la partie

Publié dans PHP objet | Laisser un commentaire

Je n’ai pas encore bien saisi l’intérêt des Interfaces dans la POO. Si je comprend bien, une interface liste toutes les méthodes que doivent impérativement « connaître » les classes si elles veulent implémenter cette Interface. Pour moi, cela permet de structurer légèrement le code (si on a plusieurs classes qui implémentent une Interface, il suffit d’aller voir cette Interface pour connaitre toutes les méthodes importantes), et … bah franchement, non, je ne vois pas. A voir…
On créé une Interface avec le mot clé interface ! Facile jusqu’ici 🙂 Puis il reste à préciser qu’une classe l’implémente avec le mot clé implements.

<?php
interface Joli
{
  public function design();
  public function autoCompleter();
}

class BlogDeBN implements Joli
{
  public function design()
  {
    echo 'Je suis un joli design !';
  }
  public function autoCompleter()
  {
    // Appel à l'auto-completer de Scriptaculous :D
  }
}

Des Interfaces sont prédéfinies en PHP, et il est possible de les connaitre à l’aide du code suivant :

<?php
print_r(get_declared_interfaces());

Qui affichera :

<?php
Array (
    [0] => Traversable
    [1] => IteratorAggregate
    [2] => Iterator
    [3] => ArrayAccess
    [4] => reflector
    [5] => RecursiveIterator
    [6] => SeekableIterator )

Il existe aussi des class prédéfinies :

<?php
print_r(get_declared_classes());

Qui affichera :

<?php
Array (
    [0] => stdClass
    [1] => __PHP_Incomplete_Class
    [2] => Directory )