PHP之Trait特性

发布时间:2020-07-15 00:02:31 作者:hgditren
来源:网络 阅读:666
自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。
<?php

//日志类
class Logger
{
    //读取日志信息
    public function log(string $message, int $level)
    {
        echo "[message]:{$message}" . PHP_EOL;
        echo "[level]:{$level}" . PHP_EOL;
    }
}

//扩展日志功能
trait Loggable
{
    protected $logger;

    /**
     * 记录日志
     * @param DemoLogger $logger
     */
    public function setLogger(Logger $logger)
    {
        $this->logger = $logger;
    }

    /**
     * 读取日志
     * @param string $message
     * @param int $level
     */
    public function getLog(string $message, int $level)
    {
        $this->logger->log($message, $level);
    }

    public function test()
    {
        echo 'trait test' . PHP_EOL;
    }
}

//基类
class Base
{
    public static $className = 'Base';

    public function test()
    {
        echo static::getClassName() . ' test' . PHP_EOL;
    }

    //获取类名称
    public static function getClassName(): string
    {
        //return self::$className;
        return static::$className;//static延时静态绑定
    }
}

class Foo extends Base
{
    public static $className = 'Foo';
    use Loggable;
}

$foo = new Foo;
$foo->setLogger(new Logger);
$foo->getLog('trait works', 1);//打印日志信息

$foo->test(); //trait test

Trait优先级
当前类的函数会覆盖 trait 的同名函数,trait 会覆盖父类的同名函数( use trait 相当于当前类直接覆写了父类的同名函数)

因此,$foo->test()调用的是Trait类中的方法



使用多个Trait及冲突的解决
Trait Alibaba
{
    public function getCEO(): string
    {
        return '阿里巴巴CEO:马云' . PHP_EOL;
    }

    public function getAddress(): string
    {
        return '阿里巴巴总部位于杭州' . PHP_EOL;
    }
}

Trait Tencent
{
    public function getCEO(): string
    {
        return '腾讯CEO:马化腾' . PHP_EOL;
    }

    public function getAddress(): string
    {
        return '腾讯总部位于深圳' . PHP_EOL;
    }
}

class TopBoss
{
    use Alibaba, Tencent;
}

$MaBoss = new TopBoss();

echo $MaBoss->getCEO();
echo $MaBoss->getAddress();

解决方案

最终代码:

class TopBoss
{
    use Alibaba, Tencent {
        Tencent::getCEO insteadof Alibaba;//指定冲突时,使用谁
        Tencent::getAddress insteadof Alibaba;
        Alibaba::getAddress as getA;//取别名,可以通过别名调用
        Alibaba::getCEO as getC;
    }
}

$MaBoss = new TopBoss();

echo $MaBoss->getCEO();//腾讯CEO:马化腾
echo $MaBoss->getAddress();//腾讯总部位于深圳

echo $superBoss->getC();//阿里巴巴CEO:马云
echo $superBoss->getA();//阿里巴巴总部位于杭州

Laravel中的代码示例

<?php

namespace Illuminate\Support;

use ArrayAccess;

class Optional implements ArrayAccess
{
    use Traits\Macroable {
        __call as macroCall;
    }

        ...

   /**
     * Dynamically pass a method to the underlying object.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->macroCall($method, $parameters);
        }
                ...
    }
推荐阅读:
  1. php中trait的用法
  2. PHP中的Trait怎么用?

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

php trait 后期

上一篇:Oracle Study之案例--安装Oracle内核参数配置

下一篇:大数据技术扫盲,你必须会的这些点

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》