在魔术方法__callStatic中对Trait函数进行别名定义
P粉226642568
P粉226642568 2023-07-31 11:46:23
[PHP讨论组]

我有一个Queryable trait,它使用__callStatic方法创建一个Builder的新实例,并在其上运行调用的函数(如果存在)。它返回Builder以便链式查询(类似于Eloquent)。

现在我正在尝试实现一个需要find()函数的接口,但是在Queryable trait的phpDoc中声明了find()函数(@method static static find(mixed $primaryKeyValue)),这就创建了冲突:

Queryable的find(primaryKeyValue: mixed)的声明必须与StorageInterface->find(primaryKeyValue: mixed)兼容,无法创建接口方法。

为了解决这个冲突,我尝试使用类似于trait别名的方式(use Queryable { Queryable::find as queryFind; })来解决,但是接着我遇到了...

编译错误:为appFrameworkTraitsQueryable::find定义了一个别名,但是该方法不存在。

我似乎找不到解决办法,能有位高手帮帮我吗? :)(我相信这与类上的某种存在检查有关,因为它是一个魔术方法,但我也不知道如何修复它..)

<?php

namespace appFrameworkTraits;

use appFrameworkDatabaseBuilder;
use appFrameworkDatabasePaginator;

/**
 * @method static int count()
 * @method static static|array<static> first(int $amount = 1)
 * @method static static|array<static> last(int $amount = 1)
 * @method static string getQuery()
 * @method static string getRawQuery()
 * @method static string getPrimaryKey()
 * @method static static find(mixed $primaryKeyValue)
 * @method static array<static> all()
 * @method static array<static> get()
 * @method static Paginator paginate()
 * @method static Builder table(string $tableName)
 * @method static Builder primaryKey(string $primaryKey)
 * @method static Builder perPage(int $perPageAmount)
 * @method static Builder where(string $column, mixed $operatorOrValue = null, mixed $value = null)
 * @method static Builder whereIn(string $column, array $search)
 * @method static Builder whereNotNull(string $column)
 * @method static Builder select(...$columns)
 * @method static Builder with(string $relation, Closure $closure)
 * @method static Builder orderBy(string $column, string $direction = 'desc')
 * @method static Builder limit(int $amount)
 * @method static Builder offset(int $amount)
 */
trait Queryable
{
    public static function __callStatic(string $name, array $arguments)
    {
        $functions = get_class_methods(Builder::class);
        if (in_array($name, $functions)) {
            $builder = new Builder(static::class);
            return $builder->$name(...$arguments);
        }

        $selfFunctions = get_class_methods($calledClass = static::class);
        if (!in_array($name, $selfFunctions)) {
            throw new BadMethodCallException("Static method '{$name}' does not exist on {$calledClass}.");
        }

        return static::$name(...$arguments);
    }

}


class BaseModel extends stdClass implements QueryableInterface, StorableInterface
{
    use Queryable {
        Queryable::find as queryFind;
    }

    public function find(mixed $primaryKeyValue): static
    {
        return self::queryFind($primaryKeyValue);
    }
}

<?php

namespace appStorageMethods;

interface StorableInterface
{
    function getObject(mixed $primaryKeyValue): static;

    function find(mixed $primaryKeyValue): static;

    function save(): static;
}


P粉226642568
P粉226642568

全部回复(1)
P粉439804514

Trait方法可以被“重命名”:(实际上是一个别名)

use Queryable {
    find as MyFind;
}

Reference

简单示例:

<?php

Trait myTrait
{
    public static function __callStatic ($method, $arguments)
    {
        $className = self::class;
        
        return (new $className ())->$method(...$arguments);
    }
    
    
    private function find()
    {
        echo "\naaaaaaaaaaaaa\n";
        return $this;
    }
}


interface MyInterface
{
    public function find();
}   


class Test Implements MyInterface
{
    Use myTrait {
        find as myFind;
    }
    
    public function find()
    {
        echo "\nxxxxxx\n";
    }
    
}


Test::myFind()->find(); 
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号