Best way to do multiple constructors in PHP Best way to do multiple constructors in PHP php php

Best way to do multiple constructors in PHP


I'd probably do something like this:

<?phpclass 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    }}?>

Then if i want a Student where i know the ID:

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

Or if i have an array of the db row:

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

Technically you're not building multiple constructors, just static helper methods, but you get to avoid a lot of spaghetti code in the constructor this way.


The solution of Kris is really nice, but I prefer a mix of factory and fluent style:

<?phpclass 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 resultvar_dump($student);?>


PHP is a dynamic language, so you can't overload methods. You have to check the types of your argument like this:

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.      }}