在魔術方法__callStatic中對Trait函數進行別名定義
P粉226642568
2023-07-31 11:46:23
<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靜態數組;得到()
* @方法靜態分頁器 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(字串$column, 陣列$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 偏移量(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>
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();