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 ou protected, en private 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

Méthode magique __get

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;
	}
}

Source

La POO en PHP, de Grafikart