405 Stimmen

Der beste Weg, mehrere Konstruktoren in PHP zu verwenden

Sie können nicht zwei __construct-Funktionen mit eindeutigen Argument-Signaturen in eine PHP-Klasse einfügen. Ich würde das gerne tun:

class Student 
{
   protected $id;
   protected $name;
   // etc.

   public function __construct($id){
       $this->id = $id;
      // other members are still uninitialized
   }

   public function __construct($row_from_database){
       $this->id = $row_from_database->id;
       $this->name = $row_from_database->name;
       // etc.
   }
}

Wie lässt sich dies in PHP am besten bewerkstelligen?

556voto

Kris Punkte 38235

Ich würde wahrscheinlich etwas in der Art machen:

<?php

class Student
{
    public function __construct() {
        // allocate your stuff
    }

    public static function withID( $id ) {
        $instance = new self();
        $instance->loadByID( $id );
        return $instance;
    }

    public static function withRow( array $row ) {
        $instance = new self();
        $instance->fill( $row );
        return $instance;
    }

    protected function loadByID( $id ) {
        // do query
        $row = my_awesome_db_access_stuff( $id );
        $this->fill( $row );
    }

    protected function fill( array $row ) {
        // fill all properties from array
    }
}

?>

Wenn ich dann einen Schüler suche, dessen ID ich kenne:

$student = Student::withID( $id );

Oder wenn ich ein Array der Datenbankzeile habe:

$student = Student::withRow( $row );

Technisch gesehen bauen Sie nicht mehrere Konstruktoren, sondern nur statische Hilfsmethoden, aber auf diese Weise können Sie eine Menge Spaghetti-Code im Konstruktor vermeiden.

97voto

timaschew Punkte 15574

Die Lösung von Kris ist wirklich schön, aber ich bevorzuge eine Mischung aus Fabrik und fließendem Stil:

<?php

class Student
{

    protected $firstName;
    protected $lastName;
    // etc.

    /**
     * Constructor
     */
    public function __construct() {
        // allocate your stuff
    }

    /**
     * Static constructor / factory
     */
    public static function create() {
        return new self();
    }

    /**
     * FirstName setter - fluent style
     */
    public function setFirstName($firstName) {
        $this->firstName = $firstName;
        return $this;
    }

    /**
     * LastName setter - fluent style
     */
    public function setLastName($lastName) {
        $this->lastName = $lastName;
        return $this;
    }

}

// create instance
$student= Student::create()->setFirstName("John")->setLastName("Doe");

// see result
var_dump($student);
?>

46voto

Daff Punkte 42755

PHP ist eine dynamische Sprache, daher können Sie Methoden nicht überladen. Sie müssen die Typen Ihrer Argumente wie folgt überprüfen:

class Student 
{
   protected $id;
   protected $name;
   // etc.

   public function __construct($idOrRow){
    if(is_int($idOrRow))
    {
        $this->id = $idOrRow;
        // other members are still uninitialized
    }
    else if(is_array($idOrRow))
    {
       $this->id = $idOrRow->id;
       $this->name = $idOrRow->name;
       // etc.  
    }
}

27voto

Nasif Md. Tanjim Punkte 3534

Wie hier bereits gezeigt wurde, gibt es viele Möglichkeiten, zu erklären multiple Konstruktoren in PHP, aber keiner von ihnen ist der correct Möglichkeit, dies zu tun (da PHP dies technisch nicht zulässt). Aber das hält uns nicht davon ab, diese Funktion zu hacken... Hier ist ein weiteres Beispiel:

<?php

class myClass {
    public function __construct() {
        $get_arguments       = func_get_args();
        $number_of_arguments = func_num_args();

        if (method_exists($this, $method_name = '__construct'.$number_of_arguments)) {
            call_user_func_array(array($this, $method_name), $get_arguments);
        }
    }

    public function __construct1($argument1) {
        echo 'constructor with 1 parameter ' . $argument1 . "\n";
    }

    public function __construct2($argument1, $argument2) {
        echo 'constructor with 2 parameter ' . $argument1 . ' ' . $argument2 . "\n";
    }

    public function __construct3($argument1, $argument2, $argument3) {
        echo 'constructor with 3 parameter ' . $argument1 . ' ' . $argument2 . ' ' . $argument3 . "\n";
    }
}

$object1 = new myClass('BUET');
$object2 = new myClass('BUET', 'is');
$object3 = new myClass('BUET', 'is', 'Best.');

Quelle: Der einfachste Weg, mehrere Konstruktoren zu verwenden und zu verstehen:

Ich hoffe, das hilft. :)

27voto

Björn Punkte 28353
public function __construct() {
    $parameters = func_get_args();
    ...
}

$o = new MyClass('One', 'Two', 3);

Jetzt wird $paramters ein Array mit den Werten 'One', 'Two', 3 sein.

Bearbeiten,

Ich kann hinzufügen, dass

func_num_args()

gibt Ihnen die Anzahl der Parameter für die Funktion an.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X