[英]polymorphic static and non-static functions in PHP
我想用PHP創建一個簡單的Path
類。 我決定使用一些類似多態的機制來實現它,但是我發現對靜態和非靜態函數都無法做到。 您是否有任何想法如何以一種優雅的方式實現absolute()
函數?
class Path {
private $path = '';
// Some code here [...]
public function absoulte() {
return "http://$_SERVER[HTTP_HOST]$this->path";
}
public static function absoulte($path) {
return "http://$_SERVER[HTTP_HOST]$path";
}
}
您可以嘗試使用“ __callStatic”。 如果您在此類上調用任何靜態函數,它將觸發。 “ $ name”將成為方法名稱,“ $ arguments”是傳遞的任何參數。 :d
class Path {
private $path = '';
// Some code here [...]
public function absoulte() {
return "http://$_SERVER[HTTP_HOST]$this->path";
}
public static function __callStatic($name,$arguments) {
if ($name == "absoulte") { return "http://$_SERVER[HTTP_HOST]$arguments"; }
}
}
好的,我會嘗試一下,您看它是否對您有幫助。 :)
我認為實際上有很多方法可以實現您所描述的公共接口,盡管它們似乎對代碼和維護來說都相當復雜。 因此,我的建議是,如果沒有必要,不要走這條路。 我會舉一些例子...
__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}";
}
}
因為我們可以以靜態方式也可以以非靜態方式訪問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
一個參數很容易處理,但是您的類變得越復雜,實現不同場景的工作就越多。
總而言之,我想談談我的評論:如果有解決方案,請嘗試不兩次實施。 稍后您會發現自己在多個地方尋找bug的情況。 因此,最好是只有兩個具有相同實現的不同接口。 它實際上甚至可以說是有意義的,因為在靜態和非靜態環境中,相同的方法名稱不一定都有意義。 因此,請考慮使用如下所示的內容:
/**
* @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}";
}
}
它已經解決了,但也許會幫助其他人。 這是使用func_num_args()
和func_get_arg()
函數的另一種方法,也可以正常使用。
class Path {
private $path = '';
// ...
public function absolute() {
switch (func_num_args()) {
case 0: return "http://" . $_SERVER[HTTP_HOST] . $this->path;
case 1: return "http://" . $_SERVER[HTTP_HOST] . func_get_arg(0);
default: trigger_error("Invalid number of arguments", E_USER_ERROR);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.