search

Home  >  Q&A  >  body text

Alias ​​definition of Trait function in magic method __callStatic

<p>I have a Queryable trait that uses the __callStatic method to create a new instance of a Builder and run the called function on it if it exists. It returns a Builder for chaining queries (similar to Eloquent). <br /><br />Now I'm trying to implement an interface that requires a find() function, but the find() function is declared in the phpDoc of the Queryable trait (@method static static find(mixed $primaryKeyValue) ), which creates a conflict: </p><p><code></code></p> <blockquote> <p>The declaration of Queryable's find(primaryKeyValue: mixed) must be compatible with StorageInterface->find(primaryKeyValue: mixed), and the interface method cannot be created. </p> </blockquote> <p>In order to resolve this conflict, I tried to use a method similar to trait aliases (use Queryable { Queryable::find as queryFind; }), but then I encountered...</p> <blockquote> <p>Compilation error: An alias is defined for appFrameworkTraitsQueryable::find, but the method does not exist.</p> </blockquote> <p>I can't seem to find a solution. Can anyone help me? :) (I believe this has to do with some kind of existence check on the class since it's a magic method, but I don't know how to fix it either..) </p> <pre class="brush:php;toolbar:false;"><?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; }</pre> <p><br /></p>
P粉226642568P粉226642568488 days ago452

reply all(1)I'll reply

  • P粉439804514

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

    Trait methods can be "renamed": (actually an alias)

    use Queryable {
        find as MyFind;
    }
    

    Reference

    Simple example:

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

    reply
    0
  • Cancelreply