搜索

首页  >  问答  >  正文

在魔术方法__callStatic中对Trait函数进行别名定义

<p>我有一个Queryable trait,它使用__callStatic方法创建一个Builder的新实例,并在其上运行调用的函数(如果存在)。它返回Builder以便链式查询(类似于Eloquent)。<br /><br />现在我正在尝试实现一个需要find()函数的接口,但是在Queryable trait的phpDoc中声明了find()函数(@method static static find(mixed $primaryKeyValue)),这就创建了冲突:</p><p><code></code></p> <blockquote> <p>Queryable的find(primaryKeyValue: mixed)的声明必须与StorageInterface->find(primaryKeyValue: mixed)兼容,无法创建接口方法。</p> </blockquote> <p>为了解决这个冲突,我尝试使用类似于trait别名的方式(use Queryable { Queryable::find as queryFind; })来解决,但是接着我遇到了...</p> <blockquote> <p>编译错误:为appFrameworkTraitsQueryable::find定义了一个别名,但是该方法不存在。</p> </blockquote> <p>我似乎找不到解决办法,能有位高手帮帮我吗? :)(我相信这与类上的某种存在检查有关,因为它是一个魔术方法,但我也不知道如何修复它..)</p> <pre class="brush:php;toolbar:false;"><?php namespace appFrameworkTraits; use appFrameworkDatabaseBuilder; use appFrameworkDatabasePaginator; /*** @方法静态 int count() * @method static static|数组;首先(int $金额 = 1) * @method static static|数组;最后(int $金额 = 1) * @method 静态字符串 getQuery() * @method 静态字符串 getRawQuery() * @method 静态字符串 getPrimaryKey() * @method static static find(混合$primaryKeyValue) * @method静态数组;全部() * @method静态数组;得到() * @method static Paginator paginate() * @method static Builder table(string $tableName) * @method static Builder PrimaryKey(字符串 $primaryKey) * @method static Builder perPage(int $perPageAmount) * @method static Builder 其中(字符串$column,混合$operatorOrValue = null,混合$value = null) * @method static Builder whereIn(字符串$列,数组$搜索) * @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 偏移量(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; }</pre> <p><br /></p>
P粉226642568P粉226642568485 天前450

全部回复(1)我来回复

  • P粉439804514

    P粉4398045142023-08-01 10:51:41

    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(); 

    回复
    0
  • 取消回复