好的,我会试一试,你看看它是否对你有帮助。 :)
我认为实际上有很多方法可以实现您所描述的公共接口,尽管它们的编码和维护看起来都相当复杂。因此,如果不是真的必要,我的建议是不要走这条路。我会举一些例子......
可能的解决方案1:使用__call和__callStatic
我们可以简单地使用__call 和__callStatic 作为我们方法的代理,并使用稍微不同的参数调用实际方法。顶部的 PhpDoc 应该支持 IDE 了解这里发生的事情。
/**
* @method string absolute()
* @method static string absolute(string $path)
*/
class Path
{
protected $path;
public function __construct(string $path)
{
$this->path = $path;
}
public function __call(string $name, array $args)
{
if ($name === 'absolute') {
return self::getAbsolutePath($this->path);
}
// ... other functions ...
}
public function __callStatic(string $name, array $args)
{
if ($name === 'absolute' && count($args) >= 1) {
return self::getAbsolutePath($args[0]);
}
// ... other functions ...
}
private static function getAbsolutePath(string $path): string
{
return "http://{$_SERVER[HTTP_HOST]}{$path}";
}
}
可能的解决方案 2:对执行环境做出反应
因为我们可以以静态方式和非静态方式访问 PHP 中的方法,所以我们只需使用我们手中的信息来返回正确的结果。
/**
* @method string absolute()
* @method static string absolute(string $path)
*/
class Path
{
protected $path;
public function __construct(string $path)
{
$this->path = $path;
}
public function absolute(?string $path): string
{
if (isset($this) && $this instanceof self) {
$path = $this->path;
}
return "http://{$_SERVER[HTTP_HOST]}{$path}";
}
}
其他解决方案
我认为还有其他方法可以实现这一点,可能是使用代理类左右。但正确的做法也取决于我们迄今为止所看到的其他要求。因为一个参数$path 很容易处理,但是你的类越复杂,实现不同场景的工作就越多。
最后,我想继续我上面的评论:如果有解决办法,尽量不要执行两次。稍后您会发现自己在多个地方寻找错误。因此,最好只有两个不同的接口和一个通用的实现。它实际上甚至是有意义的,因为相同的方法名称不一定在静态和非静态环境中都有意义。所以考虑使用这样的东西:
/**
* @method string absolute()
* @method static string absolute(string $path)
*/
class Path
{
protected $path;
public function __construct(string $path)
{
$this->path = $path;
}
public function getAbsolutePath(): string
{
return self::absolute($this->path);
}
public static function absolute(string $path): string
{
return "http://{$_SERVER[HTTP_HOST]}{$path}";
}
}