Traits ist eine neue Methode, die in 5.4 hinzugefügt wurde, um die Wiederverwendung von Code zu erreichen.
PHP ist eine einzelne Vererbungssprache. Wir können nicht mehrere Basisklassen in einer Klasse erweitern, um die Wiederverwendung von Code zu erreichen. Jetzt können Traits dieses Problem der Codewiederverwendung lösen, wodurch Entwickler die Wiederverwendung von Code in mehreren verschiedenen Klassen implementieren können.
Die semantische Definition von Merkmalen und Klassen soll die Komplexität des Codes reduzieren und das Problem der Mehrfachvererbung vermeiden.
Traits ähneln Klassen, werden jedoch nur verwendet, um eine Reihe von Funktionen auf einheitliche und feinkörnige Weise bereitzustellen. Sie können nicht innerhalb von Traits instanziiert werden, das heißt, es gibt keinen klassenähnlichen Konstruktor __construct(. ). Traits fungiert als Erweiterung der traditionellen PHP-Vererbung und implementiert horizontale Integration; daher ist Vererbung in Anwendungsklassen nicht mehr erforderlich.
1) Wie man
verwendet, um Merkmale mithilfe des Schlüsselworts „use“ in der Klasse zu referenzieren. Mehrere Merkmale werden durch „,“ getrennt.
Der Beispielcode lautet wie folgt:
<?php trait ezcReflectionReturnInfo { function getReturnType() { } function getReturnDescription() { } }class ezcReflectionMethod extends ReflectionMethod { use ezcReflectionReturnInfo; /* ... */ } class ezcReflectionFunction extends ReflectionFunction { use ezcReflectionReturnInfo; /* ... */ } ?>
2) Priorität
Member-Funktion in der Basisklasse Wird von Funktionen in Traits überschrieben, und Mitgliedsfunktionen in der aktuellen Klasse überschreiben Funktionen in Traits.
<?php class Base { public function sayHello() { echo 'Hello '; } } trait SayWorld { public function sayHello() { parent::sayHello(); echo "World!\n"; } } class MyHelloWorld extends Base { use SayWorld; } class MyHelloWorldExt extends Base { use SayWorld; public function sayHello() { /** * 这里是5.4中的新的改动,5.4之前的版本会提示: * PHP Fatal error: Cannot use string offset as an array * 5.4中改进为返回字符串中的该索引号的字符 */ $str = "Arvin"; echo $str[0][0];// echo 'A'; } public function shortArray() { $array = ['first', 2, 3, 4];//5.4中的数组简单语法 echo $array[0];//5.4中的数组解引用取数组元素方法 } } $o = new MyHelloWorld(); $o->sayHello(); $oe = new MyHelloWorldExt(); $oe->sayHello(); echo "\n"; $oe->shortArray();
Ausgabe:
Hello World! A first
3) Mehrere Merkmale
Mehrere Merkmale können hinzugefügt werden In der Deklaration einer Klasse werden mehrere Traits durch "," getrennt.
<?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World'; } } class MyHelloWorld { use Hello, World; } $o = new MyHelloWorld(); $o->sayHello(); $o->sayWorld(); ?>
Ausgabeergebnis:
Hello World
4) Multi-Traits-Konflikt
Falls hinzugefügt Wenn zwei Merkmale derselben Klasse denselben Funktionsnamen haben und nicht explizit verarbeitet werden, tritt ein Fehler auf.
Um den Konflikt zwischen zwei Funktionen mit demselben Namen in Tratis in derselben Klasse zu lösen, müssen Sie den Statt-Operator verwenden, um die richtige Funktion auszuwählen.
Aufgrund der Einzigartigkeit und Exklusivität von Methoden darf der Operator „as“ nach widersprüchlichen Funktionen verwendet werden, um interne Konflikte zu lösen.
<?php trait A { public function smallTalk() { echo 'a'; } public function bigTalk() { echo 'A'; } } trait B { public function smallTalk() { echo 'b'; } public function bigTalk() { echo 'B'; } } class Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; } } class Aliased_Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; B::bigTalk as talk; } } ?>
Im obigen Beispiel verwendet Talker die Merkmale A und B, sodass in beiden ein Konflikt zwischen denselben Funktionsnamen besteht.
alker definiert, dass smallTalk aus Traits B und bigTalk aus Traits A übernommen wird.
Aliased_Talker verwendet den as-Operator, um sicherzustellen, dass bigTalk in Traits B durch den Alias-Talk implementiert wird.
5) Funktionszugriffsberechtigungen ändern
Wir können die Syntax verwenden, um die Zugriffsberechtigungsattribute von Funktionen in Traits zu ändern.
<?php trait HelloWorld { public function sayHello() { echo 'Hello World!'; } } // Change visibility of sayHello,改变sayHello的访问权限。 class MyClass1 { use HelloWorld { sayHello as protected; } } // Alias method with changed visibility // sayHello visibility not changed,设置别名myPrivateHello。 class MyClass2 { use HelloWorld { sayHello as private myPrivateHello; } } ?>
6) Merkmale bilden neue Merkmale
Wie viele Klassen können Merkmale in Klassen und Merkmale in Merkmalen verwendet werden. Ein oder mehrere Merkmale können in einem Merkmal definiert werden, und diese Merkmale können in anderen Merkmalen als Teil oder als alle Mitglieder definiert werden.
<?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World!'; } } trait HelloWorld { use Hello, World; } class MyHelloWorld { use HelloWorld; } $o = new MyHelloWorld(); $o->sayHello(); $o->sayWorld(); ?>
Die obige Routine gibt Folgendes aus:
Hello World!
7) Abstract Trait-Mitglied
Um bestimmte Methoden in einer Klasse durchzusetzen, können Sie abstrakte Methoden in Traits verwenden.
Zum Beispiel:
<?php trait Hello { public function sayHelloWorld() { echo 'Hello '.$this->getWorld(); } abstract public function getWorld(); } class MyHelloWorld { private $world; use Hello; public function __construct($world) { $this->world = $world; } public function getWorld() { return $this->world; } } /** * 这里用到了5.4新功能 类实例化解引用操作 * (new class())->method(); */ (new MyHelloWorld('Arvin'))->sayHelloWorld(); ?>
Diese Instanz gibt Folgendes aus:
Hello Arvin
8) Static Trait-Mitglied
Statische Variablen können nicht in Traits definiert werden, sie können jedoch in Tratis-Funktionen definiert werden. Statische Funktionen können auch in Tratis definiert werden.
<?php trait Counter { public function inc() { static $c = 0;//静态变量 $c += 1; echo "$c\n"; } /** * 静态方法 */ public static function doSomething() { echo 'Doing something'; } } class C1 { use Counter; } (new C1())->inc(); // echo 1 C1::doSomething(); ?> 输出为: 1 Doing something
9) Merkmale definieren Attribute
Wenn ein Attribut in einem Merkmal definiert ist, kann derselbe Name nicht in der Klasse definiert werden, die darauf verweist Merkmal Wenn das in der Klasse definierte Attribut denselben Namen und dieselbe Zugriffssichtbarkeit wie das im Merkmal definierte Attribut hat, handelt es sich um eine E_STRICT-Eingabeaufforderung. Andernfalls wird ein Syntaxfehler ausgegeben.
<?php trait PropertiesTrait { public $x = 1; public $y = 2; } class PropertiesExample { use PropertiesTrait; public $x = 1; //public $y = 3; } $example = new PropertiesExample; echo $example->x, $example->y; ?>
Ausgabe:
12
Veröffentlichen Sie am Ende einige neue Funktionen des PHP5.4.0-Änderungsprotokolls:
Added short array syntax support ([1,2,3]), see UPGRADING guide for full details. Added binary numbers format (0b001010). Added support for Class::{expr}() syntax. Added support for Traits.//本文的主要内容 Added closure $this support back. Added array dereferencing support.//数组解引用支持,上文中有实例 Added callable typehint. Added indirect method call through array. #47160. Added DTrace support.//传说DTrace是一个性能分析工具,可以跟踪出函数调用点,返回点等数据 Added class member access on instantiation (e.g. (new foo)->bar()) support.//类新实例解引用操作,上文中有实例
Dieser Artikel Ich hoffe, dass alle weiterhin gemeinsam die neuen Funktionen von PHP5.4 erkunden. ^_^