当前位置: 首页 > 知识库问答 >
问题:

扩展特性与自身冲突

华泳
2023-03-14

我正试图扩展一种特质。我的意思是创建一个特性,为不同的特性重新定义几个方法

这是我的代码(PHP5.6和Laravel 5.4):

namespace App\Traits;

use Illuminate\Database\Eloquent\Concerns\HasTimestamps;

trait ExtendHasTimestamps
{
    use HasTimestamps {
        HasTimestamps::setCreatedAt as parentSetCreatedAt;
        HasTimestamps::setUpdatedAt as parentSetUpdatedAt;
    }

    public function setCreatedAt($value) {
        if ($value !== '') return $this;
        return $this->parentSetCreatedAt($value);
    }

    public function setUpdatedAt($value) {
        if ($value !== '') return $this;
        return $this->parentSetUpdatedAt($value);
    }
}

当我在一个模型中使用ExtendHasTimestamps时,问题就出现了,它与hastinmestamps冲突,因为elokent\Model具有使用hastinmestamps。在PHP7之前,如果您尝试两次定义同一属性,traits会抛出一个致命错误。因此,由于我在hastinestamps中定义了$timestamps,并通过extendhastinestamps借助使用hastinestamps再次定义了$timestamps,因此它就中断了。

简言之:

trait HasTimestamps {
    protected $timestamps = true; //problematic property
}

trait ExtendHasTimestamps {
    use HasTimestamps;
    // add validation then call HasTimestamps method
}

class Model {
    use HasTimestamps;
}

class MyModel extends Model {
    use ExtendHasTimestamps; //everything breaks
}

有没有办法说服PHP,它真的是同样的事情,它可以停止与自己冲突,或者通知我正在使用的类(雄辩\Model的扩展)停止使用HasTimestamps我的特质?

这个问题并没有回答我的问题,因为我试图使用一个trait来覆盖另一个trait,而不仅仅是在需要使用此代码的每个类中添加方法

共有1个答案

翁翰
2023-03-14

在我看来,你根本不需要在一开始就扩展这种特质。我只需重写您的子类中使用的trait中的方法,然后调用trait中的parent方法。

演示:https://3v4l.org/2DqZQ

<?php

trait HasTimestamps
{
    protected $timestamps = true;

    public function setCreatedAt($value)
    {
        echo 'HasTimestamps::setCreatedAt'.PHP_EOL;
        return $this;
    }

    public function setUpdatedAt($value)
    {
        echo 'HasTimestamps::setUpdatedAt'.PHP_EOL;
        return $this;
    }
}

trait ExtendHasTimestamps
{
    public function setCreatedAt($value)
    {
        echo 'ExtendHasTimestamps::setCreatedAt'.PHP_EOL;

        if ($value !== '') return $this;

        return parent::setCreatedAt($value);
    }

    public function setUpdatedAt($value)
    {
        echo 'ExtendHasTimestamps::setUpdatedAt'.PHP_EOL;

        if ($value !== '') return $this;

        return parent::setUpdatedAt($value);
    }
}

class Model
{
    use HasTimestamps;
}

class MyModel extends Model
{
    use ExtendHasTimestamps;
}

(new MyModel)->setCreatedAt('');

echo PHP_EOL;

(new MyModel)->setCreatedAt('time');

extendhastistestamps::setCreatedAt
hastinmestamps::setCreatedAt

extendhastistestamps::setCreatedAt

 类似资料:
  • 由于某些跟踪调试的PHP扩展大量使用了全局变量 可能会导致Swoole协程发生崩溃。请关闭以下相关扩展: xdebug phptrace aop molten xhprof phalcon(Swoole协程无法运行在 phalcon 框架中) 其中xdebug和phptrace可以用sdebug代替,xhprof、blackfire和molten可以用SwooleTracker 代替。

  • 我正试图安装一个PostgreSQL docker化服务,与plpython。我能够成功地构建映像,但是当我来运行容器时,我得到以下错误: 错误:无法打开扩展控制文件"/usr/share/postgresql/9.5/扩展/plpython3u.control":没有这样的文件或目录声明:创建扩展"plpython3u"; psql:/docker-entrypoint-initdb. d/cr

  • 和类: 和特性: 但是当我运行我的代码时,我得到了这个错误:

  • PHP代码无法实现的特性,必须扩展底层支持,优先级P0 PHP代码可以实现,但性能较差。如协议解析、密集计算的功能,优先级P1 PHP代码可以实现,无性能瓶颈,但功能使用频率较高,属于通用特性,优先级P2 非上述情况,原则上不应该在扩展中进行支持

  • 下面的章节展示了 Sublime Text 各种各样被扩展的附加功能。 指令 Sublime Text 中指令是无处不在的:按键绑定、菜单项、宏等都可以通过指令来工作。有些指令是在 Sublime Text 编辑器的核心实现的,但是他们当中的很多都是作为 Python 插件,每一个指令都可以由一个通过 Python 插 件来调用。 指令调度 通常情况,指令是被绑定到应用程序对象、一个窗口对象或是一

  • 问题内容: 这两个扩展功能有什么区别? 尽管jquery.extend有充分的文档记录,但是angular.extend缺少详细信息,并且注释没有提供答案。(https://docs.angularjs.org/api/ng/function/angular.extend)。 angular.extend是否也提供深层复制? 问题答案: 并且是 非常 相似的。它们都从一个或多个源对象到目标对象进行