Alias-Definition der Trait-Funktion in der magischen Methode __callStatic
P粉226642568
2023-07-31 11:46:23
<p>Ich habe ein abfragbares Merkmal, das die __callStatic-Methode verwendet, um eine neue Instanz eines Builders zu erstellen und die aufgerufene Funktion darauf auszuführen, falls vorhanden. Es gibt einen Builder zum Verketten von Abfragen zurück (ähnlich wie Eloquent). <br /><br />Jetzt versuche ich, eine Schnittstelle zu implementieren, die eine find()-Funktion erfordert, aber die find()-Funktion ist im phpDoc des Queryable-Merkmals (@method static static find) deklariert (mixed $primaryKeyValue) ), wodurch ein Konflikt entsteht: </p><p><code></code></p>
<blockquote>
<p>Die Deklaration von find(primaryKeyValue: Mixed) von Queryable muss mit StorageInterface->find(primaryKeyValue: Mixed) kompatibel sein, und Schnittstellenmethoden können nicht erstellt werden. </p>
</blockquote>
<p>Um diesen Konflikt zu lösen, habe ich versucht, eine Methode zu verwenden, die Merkmalsaliasen ähnelt (verwenden Sie Queryable { Queryable::find as queryFind; }), aber dann stieß ich auf ...</p>
<blockquote>
<p>Kompilierungsfehler: Für appFrameworkTraitsQueryable::find ist ein Alias definiert, aber die Methode existiert nicht.</p>
</blockquote>
<p>Ich kann anscheinend keine Lösung finden. Kann mir jemand helfen? :) (Ich glaube, das hat mit einer Art Existenzprüfung der Klasse zu tun, da es sich um eine magische Methode handelt, aber ich weiß auch nicht, wie ich das beheben kann.) </p>
<pre class="brush:php;toolbar:false;"><?php
Namespace appFrameworkTraits;
verwenden Sie appFrameworkDatabaseBuilder;
verwenden Sie appFrameworkDatabasePaginator;
/*** @method static int count()
* @method static static|array<static> first(int $amount = 1)
* @method static static|array<static> last(int $amount = 1)
* @method statischer String getQuery()
* @method statischer String getRawQuery()
* @method statischer String getPrimaryKey()
* @method static static find(mixed $primaryKeyValue)
* @method statisches Array<static> alle()
* @method statisches Array<static> erhalten()
* @method static Paginator paginate()
* @method static Builder-Tabelle(string $tableName)
* @method static Builder PrimaryKey(string $primaryKey)
* @method static Builder perPage(int $perPageAmount)
* @method static Builder where(string $column, gemischt $operatorOrValue = null, gemischt $value = null)
* @method static Builder whereIn(string $column, array $search)
* @method static Builder whereNotNull(string $column)
* @method static Builder select(...$columns)
* @method static Builder mit(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)*/
Merkmal abfragbar
{
öffentliche statische Funktion __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($claimedClass = static::class);
if (!in_array($name, $selfFunctions)) {
throw new BadMethodCallException("Statische Methode '{$name}' existiert nicht auf {$claimedClass}.");
}
return static::$name(...$arguments);
}
}
Die Klasse BaseModel erweitert die stdClass und implementiert QueryableInterface und StorableInterface
{
Verwenden Sie abfragbar {
Queryable::find as queryFind;
}
öffentliche Funktion find(mixed $primaryKeyValue): statisch
{
return self::queryFind($primaryKeyValue);
}
}
<?php
Namespace appStorageMethods;
Schnittstelle StorableInterface
{
Funktion getObject(mixed $primaryKeyValue): static;
function find(mixed $primaryKeyValue): static;
Funktion save(): static;
}</pre>
<p><br /></p>
Trait方法可以被“重命名”:(实际上是一个别名)
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();