PHP: Wie übergibt man __construct()-Argumente der untergeordneten Klasse an parent::__construct()?

Lesezeit: 4 Minuten

Benutzer-Avatar
keiner

Ich habe eine Klasse in PHP wie folgt:

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

Es hat eine untergeordnete Klasse, als solche:

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

Was ist, wenn die ParentClass aus irgendeinem Grund geändert werden muss, um mehr als ein optionales Argument zu akzeptieren, das meine untergeordnete Klasse “nur für den Fall” bereitstellen soll? Wenn ich die ChildClass nicht neu codiere, nimmt sie immer nur das eine Argument an den Konstruktor und gibt immer nur dieses eine Argument weiter.

Ist dies so selten oder eine so schlechte Praxis, dass der übliche Fall ist, dass eine ChildClass nicht von einer ParentClass erben muss, die andere Argumente akzeptiert?

Im Wesentlichen habe ich in Python gesehen, wo Sie eine potenziell unbekannte Anzahl von Argumenten an eine Funktion über übergeben können somefunction(*args) wobei ‘args’ eine Art Array/Iterable ist. Gibt es so etwas in PHP? Oder sollte ich diese Klassen umgestalten, bevor ich fortfahre?

Dies ist in PHP >= 5.6 ohne möglich call_user_func_array() durch die Verwendung der ... (Splat)-Operator:

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

  • Aber warum würdest du nicht machen __construct() variadisch um nicht anrufen zu müssen func_get_args()? Z.B public function __construct(...$args) { parent::__construct(...$args); }

    – Mike32

    7. Mai 2019 um 22:53 Uhr


  • @ miken32 Sie könnten das tun, aber Sie verlieren die Möglichkeit, Ihre Parameter zu tippen.

    – Andy

    9. Mai 2019 um 10:34 Uhr

Benutzer-Avatar
Seelenverschmelzung

Es gibt so etwas in PHP, wenn auch etwas ausführlich:

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

  • Dies verursacht eine Endlosschleife auf PHP 5.4.14

    – Hubro

    12. Mai 2013 um 23:26 Uhr

  • In 5.5 (vielleicht früher) können Sie einfach Folgendes tun: call_user_func_array('parent::__construct', func_get_args());;

    – km6zla

    19. Juni 2014 um 20:30 Uhr

  • @ogc-nick Ich habe es gerade mit den Versionen 5.2 bis 5.6 mit Erfolg ausprobiert.

    – Uhrwerkfreak

    2. November 2014 um 12:52 Uhr

  • Siehe meine Antwort, wie man das ohne macht call_user_func_array() in PHP 5.6 und höher.

    – Andy

    12. April 2017 um 18:50 Uhr

Wenn Sie einen PHP-Nested-Limit-Fehler erhalten, versuchen Sie Folgendes:

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

Meine Vorgehensweise (getestet in 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

Probier es aus https://3v4l.org/csJ68

In diesem Fall haben das übergeordnete und das untergeordnete Element dieselbe Konstruktorsignatur. Es funktioniert auch, wenn Sie Ihre Argumente im übergeordneten Konstruktor entpacken möchten:

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

Probier es aus https://3v4l.org/JGE1A

Es ist auch erwähnenswert, dass Sie in PHP >= 5.6 Typen für variadische Funktionen erzwingen können (skalare Typen in PHP >= 7):

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

Sehen Sie sich diese Funktionen auf php.net an:

func_get_args
func_num_args

Wenn Sie ein optionales Argument angeben möchten, können Sie dies auch tun:

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

  • Es beantwortet nicht die Frage: Wie rufen Sie den übergeordneten Konstruktor mit einem dynamischen Array von Parametern auf. Sie können NICHT einfach tun parent::__construct(func_get_args())

    – Pierre-Olivier Vares

    14. Mai 2020 um 8:17 Uhr

Benutzer-Avatar
Chaos

Ja, es ist ziemlich schlecht, eine untergeordnete Klasse zu erstellen, die andere Konstruktorargumente als die übergeordnete Klasse verwendet. Besonders in einer Sprache wie PHP, wo es schlecht unterstützt wird.

Natürlich besteht die generische Art, in PHP einen Satz von „beliebigen Argumenten“ zu übergeben, darin, ein einzelnes Argument zu übergeben, das aus einem Array von Konfigurationswerten besteht.

  • Es beantwortet nicht die Frage: Wie rufen Sie den übergeordneten Konstruktor mit einem dynamischen Array von Parametern auf. Sie können NICHT einfach tun parent::__construct(func_get_args())

    – Pierre-Olivier Vares

    14. Mai 2020 um 8:17 Uhr

Benutzer-Avatar
Animation

parent::__construct( func_get_args() );

  • Hm, geht nicht Argumente in der richtigen Reihenfolge halten (wirft sie einfach in ein Array im ersten Argument).

    – Wrikken

    14. Januar 2012 um 14:24 Uhr

1300320cookie-checkPHP: Wie übergibt man __construct()-Argumente der untergeordneten Klasse an parent::__construct()?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy