验证PHP特性

这次我们来讨论一下Trait的问题。虽然和官方文档里的内容可能是一样的,但我个人会以备忘录的形式来解释,以便更容易理解。1到3的行为和官方文档一致,但是我会写下个人注意到的问题。

基本的用法

<?php

require_once(__DIR__ . '/HelloWorld.php');

$app = new say();

$app->sayHello();
$app->sayWorld();

?>
<?php

trait HelloWorld
{
    public function sayHello(){
        echo 'Hello ';
    }

}

class say
{
    use HelloWorld;
    public function sayWorld(){
        echo 'world';
    }

}

?>
$ php test_sample.php
Hello world

如果使用use来加载Trait,就可以使用它了。

2. 如果方法名相同

<?php

require_once(__DIR__ . '/HelloWorld.php');

$app = new say();

$app->sayHelloWorld();

?>
<?php

trait HelloWorld
{
    public function sayHelloWorld(){
        echo '1';
    }

}

class say
{
    use HelloWorld;
    public function sayHelloWorld(){
        echo '2';
    }

}

?>
$ php test_sample.php
2

在上述情况下,say类的方法受到优先考虑。

3. 当特征存在多个情况时。

<?php

require_once(__DIR__ . '/HelloWorld.php');

$app = new say();

$app->sayHello();
$app->sayWorld();
$app->sayHelloWorld();

?>
<?php

trait Hello
{
    public function sayHello(){
        echo 'Hello ';
    }

}

trait World
{
    public function sayWorld(){
        echo 'World';
    }

}

class say
{
    use Hello, World;
    public function sayHelloWorld(){
        echo '!';
    }

}

?>
$ php test_sample.php
Hello World!

在多种情况下,可以用逗号进行分隔。

4. 构造函数和析构函数可以使用吗?

因为这部分是我个人感兴趣的地方,所以我将进行验证。

<?php

require_once(__DIR__ . '/HelloWorld.php');

$app = new say();

$app->sayHelloWorld();

?>
<?php

trait Hello
{
    public function __construct(){
        echo 'Hello';
    }

    public function __destruct(){
        echo 'world';
    }

}

class say
{
    use Hello;
    public function sayHelloWorld(){
        echo '_';
    }

}

?>
$ php test_sample.php
Hello_world

结论:构造函数和析构函数都会被调用。

顺便提一下,好像无法将Trait设置为父类进行继承。
反过来也不行。

例1.
class say extends Hello

例2.
trait Hello extends say