PHP orienté objet
L'orienté objet (OO en abrégé) est une idée et une méthodologie de programmation qui encapsule les données d'un programme avec les méthodes qui opèrent sur ces données, formant des « objets », et réalise les fonctions du programme par l'interaction et le passage de messages entre objets. La programmation orientée objet met l'accent sur des caractéristiques telles que l'encapsulation, l'héritage, le polymorphisme et la liaison dynamique, ce qui rend le programme plus extensible, plus maintenable et plus réutilisable.
Dans la programmation orientée objet (en anglais : Object-oriented programming, abrégé en OOP), un objet est un tout composé d'informations et de la description du traitement de ces informations, et c'est une abstraction du monde réel.
Dans le monde réel, tout ce à quoi nous sommes confrontés est un objet, comme les ordinateurs, les télévisions, les bicyclettes, etc.
Les trois principales caractéristiques d'un objet :
- Comportement d'un objet : les opérations qu'un objet peut effectuer. Par exemple, allumer une lumière ou éteindre une lumière sont des comportements.
- Forme d'un objet : la manière dont l'objet répond à différents comportements, comme la couleur, la taille et l'apparence.
- Représentation d'un objet : la représentation d'un objet équivaut à une carte d'identité, distinguant spécifiquement les différences entre des objets ayant le même comportement et le même état.
Par exemple, Animal est une classe abstraite. Nous pouvons la spécifier comme un chien et un mouton. Le chien et le mouton sont des objets concrets. Ils ont des attributs de couleur et des états de comportement tels qu'aboyer et courir.

Trois principales caractéristiques de la programmation orientée objet :
Encapsulation : désigne le fait d'encapsuler ensemble les propriétés et les méthodes d'un objet, afin que l'extérieur ne puisse pas accéder directement à l'état interne de l'objet ni le modifier. En utilisant des modificateurs de contrôle d'accès (public, private, protected) pour restreindre l'accès aux propriétés et aux méthodes, l'encapsulation est réalisée.
Héritage : désigne la capacité de créer une nouvelle classe qui hérite des propriétés et des méthodes d’une classe parente, et qui peut ajouter ses propres propriétés et méthodes. Grâce à l’héritage, vous pouvez éviter d’écrire du code similaire de manière répétée et parvenir à la réutilisation du code.
Polymorphisme : désigne la capacité d’utiliser une variable de type classe parente pour référencer des objets de différents types de sous-classes, permettant ainsi des opérations unifiées sur différents objets. Le polymorphisme rend le code plus flexible, avec une meilleure extensibilité et maintenabilité. En PHP, le polymorphisme peut être obtenu en implémentant des interfaces et en utilisant des classes abstraites.
Contenu orienté objet
Classe− Définit les caractéristiques abstraites d’une chose. La définition d’une classe inclut la forme des données et les opérations sur ces données.
Objet− Est une instance d’une classe.
Variables membres− Variables définies à l’intérieur d’une classe. La valeur de la variable n’est pas visible de l’extérieur, mais elle peut être accessible via les fonctions membres. Après l’instanciation de la classe en objet, la variable devient une propriété de l’objet.
Fonctions membres− Définies à l’intérieur de la classe, elles peuvent être utilisées pour accéder aux données de l’objet.
Héritage− L’héritage est un mécanisme par lequel une sous-classe partage automatiquement les structures de données et les méthodes de la classe parente ; c’est une relation entre classes. Lorsque vous définissez et implémentez une classe, vous pouvez le faire sur la base d’une classe existante, en reprenant à votre compte le contenu défini par la classe existante et en ajoutant du nouveau contenu.
Classe parente− Si une classe est héritée par d’autres classes, cette classe peut être appelée classe parente, classe de base ou superclasse.
Classe enfant− Une classe qui hérite d’une autre classe est appelée classe enfant, également appelée classe dérivée.
Polymorphisme− Le polymorphisme signifie que la même fonction ou méthode peut agir sur plusieurs types d'objets et obtenir des résultats différents. Différents objets recevant le même message peuvent produire des résultats différents ; ce phénomène est appelé polymorphisme.
Surcharge− En termes simples, il s'agit de la situation où des fonctions ou méthodes ont le même nom mais des listes de paramètres différentes. De telles fonctions ou méthodes avec le même nom mais des paramètres différents sont appelées fonctions ou méthodes surchargées.
Abstraction− L'abstraction consiste à abstraire des objets ayant des structures de données (attributs) et des comportements (opérations) cohérents en classes. Une classe est une telle abstraction ; elle reflète des propriétés importantes liées à l'application tout en ignorant d'autres contenus non pertinents. Toute classification de classes est subjective, mais elle doit être liée à l'application spécifique.
Encapsulation− L'encapsulation consiste à lier ensemble les attributs et les comportements d'un objet existant dans le monde réel et à les placer dans une unité logique.
Constructeur− Principalement utilisé pour initialiser un objet lors de sa création, c'est-à-dire pour attribuer des valeurs initiales aux variables membres de l'objet. Il est toujours utilisé avec l'opérateur new dans les instructions qui créent des objets.
Destructeur− Le destructeur est l'opposé du constructeur. Lorsqu'un objet termine son cycle de vie (par exemple, lorsque la fonction contenant l'objet a fini de s'exécuter), le système exécute automatiquement le destructeur. Le destructeur est souvent utilisé pour effectuer un travail de « nettoyage » (par exemple, si un espace mémoire a été alloué avec new lors de la création de l'objet, il doit être libéré avec delete dans le destructeur avant la sortie).
Dans la figure ci-dessous, nous avons créé trois objets à l'aide de la classe Car : Mercedes, Bmw et Audi.
$mercedes = new Car (); $bmw = new Car (); $audi = new Car ();

Définition de classe en PHP
La syntaxe habituelle pour définir une classe en PHP est la suivante :
<?php
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
?>
L'analyse est la suivante :
Les classes sont définies à l'aide duclassmot-clé class suivi du nom de la classe.
Les variables et les méthodes peuvent être définies entre la paire d'accolades ({}) après le nom de la classe.
Les variables de classe sont déclarées à l'aide devaret les variables peuvent également être initialisées avec des valeurs.
Les définitions de fonctions sont similaires aux définitions de fonctions PHP, mais les fonctions ne sont accessibles que via la classe et ses objets instanciés.
Exemple
<?php
class Site {
/* 成员变量 */
var $url;
var $title;
/* 成员函数 */
function setUrl($par){
$this->url = $par;
}
function getUrl(){
echo $this->url . PHP_EOL;
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title . PHP_EOL;
}
}
?>
Variable$this$this représente l'objet lui-même.
PHP_EOLest le caractère de nouvelle ligne.
Création d'objets en PHP
Après qu'une classe est créée, nous pouvons utiliser l'opérateurnewpour instancier un objet de la classe :
$example = new Site; $taobao = new Site; $google = new Site;
Dans le code ci-dessus, nous avons créé trois objets. Chacun des trois objets est indépendant. Voyons maintenant comment accéder aux méthodes membres et aux variables membres.
Appel des méthodes membres
Après avoir instancié un objet, nous pouvons utiliser l'objet pour appeler des méthodes membres. Les méthodes membres de l'objet ne peuvent opérer que sur les variables membres de l'objet :
// 调用成员函数,设置标题和URL $example->setTitle( "Example" ); $taobao->setTitle( "淘宝" ); $google->setTitle( "Google 搜索" ); $example->setUrl( 'www.example.com' ); $taobao->setUrl( 'www.taobao.com' ); $google->setUrl( 'www.google.com' ); // 调用成员函数,获取标题和URL $example->getTitle(); $taobao->getTitle(); $google->getTitle(); $example->getUrl(); $taobao->getUrl(); $google->getUrl();
Le code complet est le suivant :
Exemple
class Site {
/* Variables membres */
var $url;
var $title;
/* Fonctions membres */
function setUrl($par){
$this->url = $par;
}
function getUrl(){
echo $this->url . PHP_EOL;
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title . PHP_EOL;
}
}
$example = new Site;
$taobao = new Site;
$google = new Site;
// Appeler les fonctions membres pour définir le titre et l'URL
$example->setTitle( Exemple);
$taobao->setTitle( Taobao);
$google->setTitle( Recherche Google);
$example->setUrl( 'www.example.com' );
$taobao->setUrl( 'www.taobao.com' );
$google->setUrl( 'www.google.com' );
// Appeler les fonctions membres pour obtenir le titre et l'URL
$example->getTitle();
$taobao->getTitle();
$google->getTitle();
$example->getUrl();
$taobao->getUrl();
$google->getUrl();
?>
Exécuter l'exemple »
L'exécution du code ci-dessus produit la sortie suivante :
Example 淘宝 Google 搜索 www.example.com www.taobao.com www.google.com
Constructeur PHP
Un constructeur est une méthode spéciale. Il est principalement utilisé pour initialiser un objet lors de sa création, c'est-à-dire pour attribuer des valeurs initiales aux variables membres de l'objet. Dans l'instruction qui crée l'objet, avecnewl'opérateur.
PHP 5 permet aux développeurs de définir une méthode dans une classe comme constructeur. La syntaxe est la suivante :
void __construct ([ mixed $args [, $... ]] )
Dans l'exemple ci-dessus, nous pouvons initialiser les variables $url et $title via le constructeur :
function __construct( $par1, $par2 ) {
$this->url = $par1;
$this->title = $par2;
}
Maintenant, nous n'avons plus besoin d'appeler les méthodes setTitle et setUrl :
Exemple
$taobao = new Site('www.taobao.com', 'Taobao');
$google = new Site('www.google.com', 'Google Search');
// Appeler les fonctions membres pour obtenir le titre et l'URL
$example->getTitle();
$taobao->getTitle();
$google->getTitle();
$example->getUrl();
$taobao->getUrl();
$google->getUrl();
Exécuter l'exemple »
Destructeur
Le destructeur est l'opposé du constructeur. Lorsqu'un objet termine son cycle de vie (par exemple, lorsque la fonction dans laquelle l'objet se trouve a fini de s'exécuter), le système exécute automatiquement le destructeur.
PHP 5 a introduit le concept de destructeur, comme dans d'autres langages orientés objet. Sa syntaxe est la suivante :
void __destruct ( void )
Exemple
<?php
class MyDestructableClass {
function __construct() {
print "构造函数\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "销毁 " . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
?>
L'exécution du code ci-dessus produit la sortie suivante :
构造函数 销毁 MyDestructableClass
Héritage
PHP utilise le mot-cléextendspour hériter d'une classe. PHP ne prend pas en charge l'héritage multiple, le format est le suivant :
class Child extends Parent {
// 代码部分
}
Exemple
Dans l'exemple, la classe Child_Site hérite de la classe Site et étend ses fonctionnalités :
<?php
// 子类扩展站点类别
class Child_Site extends Site {
var $category;
function setCate($par){
$this->category = $par;
}
function getCate(){
echo $this->category . PHP_EOL;
}
}
Redéfinition de méthode
Si les méthodes héritées de la classe parente ne peuvent pas répondre aux besoins de la classe enfant, elles peuvent être réécrites. Ce processus est appelé redéfinition de méthode (override).
Dans l'exemple, les méthodes getUrl et getTitle sont redéfinies :
function getUrl() {
echo $this->url . PHP_EOL;
return $this->url;
}
function getTitle(){
echo $this->title . PHP_EOL;
return $this->title;
}
Contrôle d'accès
PHP met en œuvre le contrôle d'accès aux propriétés ou aux méthodes en ajoutant les mots-clés public, protected ou private devant celles-ci.
- public :Les membres publics d'une classe sont accessibles depuis n'importe où.
- protected :Les membres protégés d'une classe sont accessibles par la classe elle-même, ainsi que par ses classes enfants et sa classe parente.
- private :Les membres privés d'une classe ne sont accessibles que par la classe dans laquelle ils sont définis.
Contrôle d'accès des propriétés
Les propriétés de classe doivent être définies avec l'un des mots-clés public, protected ou private. Si elles sont définies avec var, elles sont considérées comme publiques.
<?php
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // 这行能被正常执行
echo $obj->protected; // 这行会产生一个致命错误
echo $obj->private; // 这行也会产生一个致命错误
$obj->printHello(); // 输出 Public、Protected 和 Private
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// 可以对 public 和 protected 进行重定义,但 private 而不能
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // 这行能被正常执行
echo $obj2->private; // 未定义 private
echo $obj2->protected; // 这行会产生一个致命错误
$obj2->printHello(); // 输出 Public、Protected2 和 Undefined
?>
Contrôle d'accès des méthodes
Les méthodes d'une classe peuvent être définies comme public, private ou protected. Si aucun de ces mots-clés n'est défini, la méthode est publique par défaut.
<?php
/**
* Define MyClass
*/
class MyClass
{
// 声明一个公有的构造函数
public function __construct() { }
// 声明一个公有的方法
public function MyPublic() { }
// 声明一个受保护的方法
protected function MyProtected() { }
// 声明一个私有的方法
private function MyPrivate() { }
// 此方法为公有
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); // 这行能被正常执行
$myclass->MyProtected(); // 这行会产生一个致命错误
$myclass->MyPrivate(); // 这行会产生一个致命错误
$myclass->Foo(); // 公有,受保护,私有都可以执行
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// 此方法为公有
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // 这行会产生一个致命错误
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 这行能被正常执行
$myclass2->Foo2(); // 公有的和受保护的都可执行,但私有的不行
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>
Interfaces
À l'aide d'interfaces, vous pouvez spécifier quelles méthodes une classe doit implémenter, sans définir le contenu spécifique de ces méthodes.
Une interface est définie à l'aide du mot-cléinterface, comme pour définir une classe standard, mais toutes les méthodes qui y sont définies sont vides.
Toutes les méthodes définies dans une interface doivent avoir la visibilité public ; c'est une caractéristique des interfaces.
Pour implémenter une interface, utilisez l'opérateurimplements. La classe doit implémenter toutes les méthodes définies dans l'interface, sinon une erreur fatale sera signalée. Une classe peut implémenter plusieurs interfaces, en séparant les noms des différentes interfaces par des virgules.
<?php
// 声明一个'iTemplate'接口
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// 实现接口
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
Constantes
Vous pouvez définir comme constantes les valeurs qui restent constantes dans une classe. Lors de la définition et de l'utilisation de constantes, le symbole $ n'est pas nécessaire.
La valeur d'une constante doit être une valeur fixe ; elle ne peut pas être une variable, une propriété de classe, le résultat d'une opération mathématique ou un appel de fonction.
À partir de PHP 5.3.0, une variable peut être utilisée pour appeler dynamiquement une classe. Cependant, la valeur de cette variable ne peut pas être un mot-clé (tel que self, parent ou static).
Exemple
<?php
class MyClass
{
const constant = '常量值';
function showConstant() {
echo self::constant . PHP_EOL;
}
}
echo MyClass::constant . PHP_EOL;
$classname = "MyClass";
echo $classname::constant . PHP_EOL; // 自 5.3.0 起
$class = new MyClass();
$class->showConstant();
echo $class::constant . PHP_EOL; // 自 PHP 5.3.0 起
?>
Classes abstraites
Toute classe qui possède au moins une méthode déclarée abstract doit elle-même être déclarée abstract.
Une classe définie comme abstract ne peut pas être instanciée.
Les méthodes définies comme abstract ne déclarent que leur méthode d'appel (paramètres) et ne peuvent pas définir leur implémentation fonctionnelle spécifique.
Lors de l'héritage d'une classe abstract, la classe fille doit définir toutes les méthodes abstract de la classe parente. De plus, le contrôle d'accès de ces méthodes doit être identique à (ou plus permissif que) celui de la classe parente. Par exemple, si une méthode abstract est déclarée protected, alors la méthode implémentée dans la classe fille doit être déclarée protected ou public, et ne peut pas être définie comme private.
<?php
abstract class AbstractClass
{
// 强制要求子类定义这些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . PHP_EOL;
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>
L'exécution du code ci-dessus produit la sortie suivante :
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2
De plus, les méthodes de la classe fille peuvent contenir des paramètres optionnels qui n'existent pas dans les méthodes abstract de la classe parente.
Par exemple, si une classe fille définit un paramètre optionnel qui n'est pas présent dans la déclaration de la méthode abstract de la classe parente, elle peut toujours fonctionner normalement.
<?php
abstract class AbstractClass
{
// 我们的抽象方法仅需要定义需要的参数
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// 我们的子类可以定义父类签名中不存在的可选参数
public function prefixName($name, $separator = ".") {
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return "{$prefix}{$separator} {$name}";
}
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>
Résultat de sortie :
Mr. Pacman Mrs. Pacwoman
Mot-clé static
Déclarer une propriété ou une méthode de classe comme static permet un accès direct sans instancier la classe.
Les propriétés statiques ne sont pas accessibles via un objet instancié d'une classe (mais les méthodes statiques le peuvent).
Comme les méthodes statiques n'ont pas besoin d'être appelées via un objet, la pseudo-variable $this n'est pas disponible dans les méthodes statiques.
Les propriétés statiques ne peuvent pas être accédées par un objet à l'aide de l'opérateur ->.
À partir de PHP 5.3.0, une variable peut être utilisée pour appeler dynamiquement une classe. Cependant, la valeur de cette variable ne peut pas être les mots-clés self, parent ou static.
<?php
class Foo {
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
}
print Foo::$my_static . PHP_EOL;
$foo = new Foo();
print $foo->staticValue() . PHP_EOL;
?>
L'exécution du programme ci-dessus produit la sortie suivante :
foo foo
Mot-clé final
PHP 5 a ajouté un mot-clé final. Si une méthode de la classe parente est déclarée final, la classe enfant ne peut pas la redéfinir. Si une classe est déclarée final, elle ne peut pas être héritée.
Le code suivant générera une erreur lors de son exécution :
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called" . PHP_EOL;
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called" . PHP_EOL;
}
}
class ChildClass extends BaseClass {
public function moreTesting() {
echo "ChildClass::moreTesting() called" . PHP_EOL;
}
}
// 报错信息 Fatal error: Cannot override final method BaseClass::moreTesting()
?>
Appel du constructeur parent
PHP n'appelle pas automatiquement le constructeur de la classe parente dans le constructeur de la classe enfant. Pour exécuter le constructeur de la classe parente, vous devez l'appeler dans le constructeur de la classe enfant :parent::__construct() 。
<?php
class BaseClass {
function __construct() {
print "BaseClass 类中构造方法" . PHP_EOL;
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct(); // 子类构造方法不能自动调用父类的构造方法
print "SubClass 类中构造方法" . PHP_EOL;
}
}
class OtherSubClass extends BaseClass {
// 继承 BaseClass 的构造方法
}
// 调用 BaseClass 构造方法
$obj = new BaseClass();
// 调用 BaseClass、SubClass 构造方法
$obj = new SubClass();
// 调用 BaseClass 构造方法
$obj = new OtherSubClass();
?>
L'exécution du programme ci-dessus produit la sortie suivante :
BaseClass 类中构造方法 BaseClass 类中构造方法 SubClass 类中构造方法 BaseClass 类中构造方法Autres extensions