簡體   English   中英

PHP:如何將子類 __construct() 參數傳遞給 parent::__construct()?

[英]PHP: How to Pass child class __construct() arguments to parent::__construct()?

我在 PHP 中有一個類,如下所示:

class ParentClass {
    public function __construct($arg) {
        // Initialize a/some variable(s) based on $arg
    }
}

它有一個子類,如下所示:

class ChildClass extends ParentClass {
    public function __construct($arg) {
        // Let the parent handle construction. 
        parent::__construct($arg); 
    }
}

如果出於某種原因,ParentClass 需要更改以采用多個可選參數,我希望我的 Child 類“以防萬一”提供該參數怎么辦? 除非我重新編碼 ChildClass,否則它只會將一個參數傳遞給構造函數,並且只會傳遞那個參數。

這是罕見的還是糟糕的做法,以至於通常的情況是 ChildClass 不需要從采用不同參數的 ParentClass 繼承?

本質上,我在 Python 中看到過,您可以通過somefunction(*args)將潛在未知數量的參數傳遞給函數,其中 'args' 是某種數組/可迭代對象。 PHP中是否存在這樣的東西? 或者我應該在繼續之前重構這些類?

這可以通過使用... (splat)運算符在沒有call_user_func_array()的PHP> = 5.6中完成:

public function __construct()
{
    parent::__construct(...func_get_args());
}

在PHP中有這樣的東西,雖然有點冗長:

$args = func_get_args();
call_user_func_array(array($this, 'parent::__construct'), $args);

如果你得到php嵌套限制錯誤,試試這個:

$args = func_get_args();
call_user_func_array(array('parent', '__construct'), $args);

我的方式(在PHP 7.1中測試):

class ParentClass {
    public function __construct(...$args) {
        print 'Parent: ' . count($args) . PHP_EOL;
    }
}

class ChildClass extends ParentClass {
    public function __construct(...$args) {
        parent::__construct(...$args);
        print 'Child: ' . count($args). PHP_EOL;
    }
}

$child = new ChildClass(1, 2, 3, new stdClass);

//Output: 
//Parent: 4
//Child: 4

測試它https://3v4l.org/csJ68

在這種情況下,父級和子級具有相同的構造函數簽名。 如果要在父構造函數中解壓縮參數,它也可以工作:

class ParentClass {
    public function __construct($a, $b, $c, $d = null) {
        print 'Parent: ' . $a .  $b .  $c . PHP_EOL;
    }
}

class ChildClass extends ParentClass {
    public function __construct(...$args) {
        parent::__construct(...$args);
    }
}

$child = new ChildClass(1, 2, 3);

//Output: Parent: 123

測試它https://3v4l.org/JGE1A

值得注意的是,在PHP> = 5.6中,您可以強制執行可變函數的類型(PHP中的標量類型> = 7):

class ParentClass {
    public function __construct(DateTime ...$args) {
        //Do something
    }
}

在php.net上查看這些函數:

func_get_args
func_num_args

此外,如果要創建可選參數,可以執行以下操作:

class ParentClass {
    function __construct($arg, $arg2="Default Value") {
        // Initialize a/some variable(s) based on $arg
    }
}

是的,制作一個使用父節點不同構造函數參數的子類是非常糟糕的做法。 特別是在PHP這樣的語言中,它支持得很差。

當然,在PHP中傳遞一組“我們可能想要的任何參數”的通用方法是傳遞一個由一組配置值組成的參數。

PHPStorm Inspection建議使用參數解包功能而不是call_user_func_array()。 除了神奇之外,功能更快。 資料來源: https//wiki.php.net/rfc/argument_unpacking

class ChildClass extends ParentClass {
    function __construct($arg) {
        // Let the parent handle construction. 
        parent::__construct(...func_get_args()); 
    }
}
parent::__construct( func_get_args() );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM