web-dev-qa-db-ja.com

PHP:子クラスの__construct()引数をparent :: __ construct()に渡す方法は?

私はPHPにクラスを持っています:

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

そのため、次のような子クラスがあります。

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

何らかの理由で、ParentClassを変更して複数のオプションの引数を取得する必要がある場合はどうすればよいですか? ChildClassを再コード化しない限り、コンストラクターに渡す引数は1つだけで、渡される引数は1つだけです。

これは非常にまれなことであるので、通常のケースでは、ChildClassは、異なる引数を取るParentClassから継承する必要がないということです。

本質的に、私はPythonで見たことがあります。ここで、潜在的に未知の数の引数をsomefunction(*args)を介して関数に渡すことができます。ここで、 'args'はある種の配列/反復可能です。このようなものはPHPに存在しますか?続行する前にこれらのクラスをリファクタリングする必要がありますか?

38
none

Phpには次のようなものがありますが、少し冗長です:

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

これは、PHP> = 5.6でcall_user_func_array()なしで ...(splat)演算子 を使用して実行できます。

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

phpの入れ子の制限エラーが発生した場合は、次を試してください。

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

私のやり方(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
    }
}
4
zstate

Php.netで以下の関数を確認してください。

func_get_args
func_num_args

また、オプションの引数を作成する場合は、次のようにできます。

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

ええ、親とは異なるコンストラクター引数を使用する子クラスを作成するのはかなり悪い習慣です。特にPHPのような言語では、サポートが不十分です。

もちろん、PHP=で「必要な引数は何でも」のセットを渡す一般的な方法は、設定値の配列で構成される単一の引数を渡すことです。

0
chaos

PHPStormインスペクションは、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()); 
    }
}
0
Chris