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>