Best Way to Do Multiple Constructors in PHP

Best way to do multiple constructors in PHP

I'd probably do something like this:

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

?>

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.

Is it possible to overload a constructor in PHP

The best way to do this is with an optional param, as others have said in the comments, PHP does not support overloading, so this would be my suggestion:

class Foo
{
public function __construct($p1, $p2 = null)
{
$this->p1 = $p1;
$this->p2 = $p2;
}
}

This means that you can choose to use $p2 when creating the class but you must use $p1.

AFAIK, this is the only form of overloading (if you can call it that) that exists as yet in PHP

Edit

An extension from kingkero's answer, I came up with this solution which keeps logic out of the constructor minus a function call:

<?php
class overload
{
public function __construct()
{
return $this->switchConstruct(func_get_args());
}

protected function switchConstruct(array $args)
{
switch (count($args))
{
case 0:
return print "0 params<br />";
case 1:
return call_user_func_array(array($this, 'constr1'), $args);
case 2:
return call_user_func_array(array($this, 'constr2'), $args);
}
die("Invalid number of args");
}

protected function constr1($a)
{
print "constr1 called<br />";
}

protected function constr2($a, $b)
{
print "constr2 called<br />";
}
}

oop PHP more than one constructors

  1. There are many ways of declaring 'multiple' constructors in PHP, but none of them are the 'correct' way of doing so (since PHP technically doesn't allow it). I don't see anything wrong with how you're doing it there, however. If you'd like more information, check out this Stack Overflow question.

  2. You could just use an if statement. Something like this, perhaps?

    public function __set($property_name,$value)
    {
    $hidden_properties = array(
    'comment_id',
    'any_other_properties'
    );

    if(!in_array($property_name, $hidden_properties) &&
    property_exists($this, $property_name))
    {
    $this->$property_name = $value;
    }
    }

Type hinting and multiple constructors

Correct, that's one of the limitations of the language.
(and the strlen() > 0 anyway can't be checked via a type. That auto-casts to string… so your method allows everything but "", null and false?)

Generally, there is RFCs in draft to expand the typehinting of PHP in 7.1:
https://wiki.php.net/rfc/union_types

That would allow you to write int | float | array | string $data = null.

Multiple constructors in an abstract class

Here is a little approach:

<?php

abstract class MyClass {

protected $id = "";
protected $title = "";

function __construct($title) {
$this->id = strtolower($title);
$this->title = $title;
}

static function createWithTitle($title) {
$instance = new static($title);
return $instance;
}

static function createWithIdAndTitle($id, $title) {
$instance = new static($title);
$instance->id = $id;
return $instance;
}

abstract function render();
}

class Concrete extends MyClass {
function render() {
var_dump('id=' . $this->id, 'title=' . $this->title);
}
}

Concrete::createWithTitle('Title')->render();

Concrete::createWithIdAndTitle(1, 'Title')->render();

Note the static keyword is very important here instead of self see Late Static Bindings

How to implement php constructor that can accept different number of parameters?

One solution is to use defaults:

public function __construct($name, $lastname = null, $age = 25) {
$this->name = $name;
if ($lastname !== null) {
$this->lastname = $lastname;
}
if ($age !== null) {
$this->age = $age;
}
}

The second one is to accept array, associative array or object (example about associative array):

public function __construct($params = array()) {
foreach ($params as $key => $value) {
$this->{$key} = $value;
}
}

But in the second case it should be passed like this:

$x = new Person(array('name' => 'John'));

The third option has been pointed by tandu:

Constructor arguments work just like any other function's arguments. Simply specify defaults php.net/manual/en/… or use func_get_args().

EDIT: Pasted here what I was able to retrieve from original answer by tandu (now: Explosion Pills).



Related Topics



Leave a reply



Submit