PHP Objet - noelno/dovelei GitHub Wiki
Appel
$instance = new Classe();
//nouvelle instance de classe
$instance->propriete;
//accès à une propriété (sans le $
)
$instance->methode();
//appel à une méthode
mot-clé $this
pour faire référence à la valeur de la propriété de l'instance ($this->propriete
)
class Personnage{
private $nom;
private $vie = 80;
private $atk = 20;
public function __construct($nom){
$this->nom = $nom;
}
public function regenerer($pt = null){
if (is_null($pt)){
$this->vie = 100;
}
else{
$this->vie += $pt;
}
}
public function mort(){
return $this->vie <= 0;
}
public function attaque($perso){
$perso->vie -= $this->atk;
}
public function getAtk(){
return $this->atk;
}
public function setNom($nom){
$this->nom = $nom;
}
}
En PHP on peut générer des propriétés à la volée, sans qu'elles ne figurent dans la déclaration de la classe (mais déconseillé)
Passage des objets par référence
Possibilité de paramètre par défaut ( function nomFonction($variable = null)
)
Visibilité des propriétés et méthodes
Public : accessible de dedans et de dehors
Private : accessible uniquement de l'intérieur (ou de l'extérieur avec une nouvelle fonction get*()
qui retourne $this->*
Protected : accessible de l'intérieur et par les classes héritières
Pour qu'une variable soit interprétée dans une chaîne de caractère, les mettre entre {}
Documentation PHPDOC
Entête PHP
/**
* Class nom
* Description
*/
@var type Description
//pour les propriétés
@param type Description
//pour les paramètres de méthodes
@return type Description
//pour la valeur retournée
PHP Storm génère tous les commentaires PHPDoc automatiquement, et affiche les commentaires en infobulle. Documenter progressivement.
Méthodes statiques
Si pas besoin d'instance. Mot-clé static
sur la propriété ou la méthode
Classe::methode()
self::$propriete;
//fait appel à une propriété statique dans la définition de la classe (dollar obligatoire pour ne pas les confondre avec les constantes) ; self fait référence au nom de la classe
self::methode();
//fait appel à une méthode statique dans la définition de la classe
private static const NOM_CONSTANTE;
//déclaration de propriété constante statique
self::propriete;
//fait appel à une propriété constante statique dans l'instance de classe
Héritage
Mot-clé extends
class Archer extends Personnage{}
L'héritage offre les possibilités suivantes :
- Propriétés supplémentaires par-rapport à la classe parente
- Redéfinition des propriétés parentes (si
public
ouprotected
, enprivate
les deux propriétés cohabitent) - Redéfinition des méthodes (en conservant la même signature)
parent::nomMethode()
//Appeler la méthode parente dans la classe héritière
Autoloading
Permet de charger automatiquement une classe quand on fait un new
, sans avoir besoin de faire explicitement un require
.
Class Autoloader{
static function register(){
spl_autoload_register(array(__CLASS__, 'autoload'));
}
static function autoload($class_name){
require 'class/' . $class_name . '.php';
}
}
Pour charger l'autoload :
require 'class/Autoloader.php';
Autoloader::register();
$merlin = new Personnage(); //la classe personnage sera chargée automatiquement
Namespace
Deux classes ne peuvent avoir le même nom (conflits)
La solution : les namespaces (équivalent du package en Java)
namespace Tutoriel;
// la classe déclarée après est dans le namespace Tutoriel
... extends \nomNamespace\nomClasse
//chemin d'une classe dans un autre namespace
Le nom de la classe récupérée automatiquement dans l'autoloader contient aussi le chemin du namespace, ce qui posera problème pour le require
si les fichiers de classe ne sont pas dans un répertoire /nomNamespace
(il va confondre le chemin du namespace avec l'emplacement physique du fichier.)
Penser à utiliser str_replace
dans la fonction d'autoload pour virer le chemin du namespace avant l'inclusion :
static function autoload($class){
$class = str_replace(__NAMESPACE__ . '\\' , '',$class); //retire le chemin du namespace ainsi que son antislash final
$class = str_replace( '\\' , '/',$class); //remplace les antislashes (deux antislashes à la suite = un antislash échappé) par des slashes
require 'class/' . $class_name . '.php';
}
Ce code ne fonctionne que si vous précédez la déclaration de la classe d'une déclaration du namespace à utiliser (__NAMESPACE__
vaut le namespace utilisé)
On peut rendre cette fonction encore plus spécifique, en ajoutant comme condition que la classe doit appartenir à un namespace particulier pour charger :
static function autoload($class){
if(strpos($class, __NAMESPACE__ . '\\') === 0){//si la classe appartient au namespace utilisé par mon Autoload
$class = str_replace(__NAMESPACE__ . '\\' , '',$class); //retire le chemin du namespace ainsi que son antislash final
$class = str_replace('\\' , '/',$class); //remplace les antislashes par des slashes
require 'class/' . $class_name . '.php';
}
}
Dans un fichier .php on peut écrire $merlin = new \chemin\du\namespace\Personnage();
ou \chemin\du\namespace\Personnage::methodeStatique();
pour qu'il trouve la classe dans un autre namespace. Mais il est plus simple de spécifier en début de fichier quelle classe de quel namespace utiliser par défaut, grâce à l'instruction use \chemin\du\namespace\nomClasse;
Pour continuer à utiliser les classes générales de PHP (par exemple Date
), on fera précéder le nom de la classe par un antislash : $date = new \Date();
TP blog
Nouvelle instance
$pdo = new PDO('mysql:dbname=nomdemabase;host=localhost','root','');
Activation des erreurs
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Requêtes courantes
SELECT :
$stmt = $pdo->query('SELECT * FROM maTable');
$data = $stmt->fetchAll(); //ou fetch() pour n'en récupérer qu'un
INSERT :
$pdo->exec('INSERT INTO maTable SET maColonne = "valeur1", col2 = "valeur2"');//retourne le nombre de lignes affectées
INSERT requête préparée :
$pdo = '';
Formats de retour
$data = $stmt->fetchAll(PDO::FETCH_OBJ); //permet de récupérer le tout sous forme d'objet
$data = $stmt->fetchAll(PDO::FETCH_CLASS, $class_name); //permet de récupérer le tout sous forme d'instance d'une classe particulière
Syntaxe alternative des structures
<?php foreach ($db->query("SELECT * FROM articles","App\Table\Article") as $post) : ?>
…
<?php endforeach; ?>
Fonctionne aussi avec if
elseif
else
, while
…
__get
Méthode magique Se déclenche lors de l'appel d'une propriété inaccessible, par exemple une propriété inexistante.
public function __get($key){
$method = 'get' . ucfirst($key);
$this->$key = $this->$method();
return $this->$key;
}
Avec cette méthode, si je souhaite par exemple afficher la propriété url
alors qu'elle n'a pas été déclarée dans la classe, c'est getUrl()
qui est appelée.
Late static binding
On a vu que le mot-clé self::
permettait d'appeler une méthode ou une variable statique au sein de sa classe. Cependant en cas d'héritage, self::
fait toujours référence à la méthode ou la variable héritée du parent, même après avoir été redéfinie dans la classe héritière. Il existe en fait un autre mot-clé permettant de faire référence à la méthode ou variable de la classe en cours : ::static
.
class Table{
protected static $table;
private static function getTable(){
if (static::$table === null){
$class_name = explode('\\', get_called_class());
static::$table = strtolower(end($class_name)) . 's';
}
return static::$table;
}
}
Toutes les classes qui hériteront de Table
auront leur propre valeur de $table
, ce qui n'aurait pas été le cas si on avait utilisé self::
.
Comme ::self
, __CLASS__
prend pour référence la classe où elle est déclarée. C'est pourquoi on a ici utilisé la fonction get_called_class()
, qui retourne bien la classe courante, au lieu de __CLASS__
qui aurait toujours retourné 'Table' même dans les classes héritières.
Design patterns
Singleton
Pour les classes dont on ne veut utiliser qu'une instance durant toute l'exécution de l'application, par exemple une classe de configuration.
class App{
private static $instance;
//autres propriétés
private function __construct(){
//
}
public static function getInstance(){
if(is_null(self::$instance)){
self::$instance = new App();
}
return self::$instance;
}
}