10

I have __construct($parameter)

public function __construct($nick) {
    $query = "SELECT * FROM Users WHERE nick='".$nick."'";
    $result = App::runQuery($query);
    $user = $result->fetch_object();

    $this->id = $user->id;
    $this->nick = $user->nick;
    $this->email = $user->email;
    $this->password = $user->password;
    $this->birthDay = $user->birthDay;
    $this->sex = $user->sex;
    $this->about = $user->about;
    $this->city = $user->city;
    $this->photo = $user->photo;
    $this->following = $user->following;
    $this->followers = $user->followers;
    $this->statu = $user->statu; 

}

And now I want to have a default constructor without parameters like this:

public function __construct() {

    $this->id = NULL;
    $this->nick = NULL;
    $this->email = NULL;
    $this->password = NULL;
    $this->birthDay = NULL;
    $this->sex = NULL;
    $this->about = NULL;
    $this->city = NULL;
    $this->photo = NULL;
    $this->following = NULL;
    $this->followers = NULL;
    $this->statu = NULL; 

}

But something is wrong and I get error like this:

Fatal error: Cannot redeclare User::__construct() in /Applications/MAMP/htdocs/xxx/Application/User.php on line 33

How can I have two constructors with parameters and without parameters at the same time?

Gumbo
  • 643,351
  • 109
  • 780
  • 844
Mehmet
  • 3,301
  • 8
  • 26
  • 36
  • 3
    While you're probably not working on this two years later you have an obvious SQL injection bug in this code – Casey Jul 27 '17 at 19:23

3 Answers3

22
  1. There is no overloading in PHP; you cannot have methods with the same names but different parameters

  2. Since all of your properties will default to null, there's no reason to do it yourself. I would suggest doing the following:

    public function __construct($nick = null) {
        if ($nick != null) {
            $query = "SELECT * FROM Users WHERE nick='".$nick."'";
            $result = App::runQuery($query);
            $user = $result->fetch_object();
    
            $this->id = $user->id;
            $this->nick = $user->nick;
            $this->email = $user->email;
            $this->password = $user->password;
            $this->birthDay = $user->birthDay;
            $this->sex = $user->sex;
            $this->about = $user->about;
            $this->city = $user->city;
            $this->photo = $user->photo;
            $this->following = $user->following;
            $this->followers = $user->followers;
            $this->statu = $user->statu; 
        }
    }
    
  3. An alternative to the above code is to have multiple, static constructor methods, and use a private constructor:

    private function __construct() {
    }
    
    public static function createFromNick($nick) {
        $self = new self();
    
        $query = "SELECT * FROM Users WHERE nick='".$nick."'";
        $result = App::runQuery($query);
        $user = $result->fetch_object();
    
        $self->id = $user->id;
        $self->nick = $user->nick;
        $self->email = $user->email;
        $self->password = $user->password;
        $self->birthDay = $user->birthDay;
        $self->sex = $user->sex;
        $self->about = $user->about;
        $self->city = $user->city;
        $self->photo = $user->photo;
        $self->following = $user->following;
        $self->followers = $user->followers;
        $self->statu = $user->statu;
    
        return $self;
    }
    
    public static function createEmpty() {
        return new self();
    }
    
  • 1
    Note that in PHP constructors are not allowed to throw any `Throwable`s such as `Exception`s. It will just crash the execution of the PHP script. Usually database queries in PHP are allowed to throw `Exception`s. But I'm not sure what this App:: thing is in this case. – Henk Poley Nov 27 '19 at 15:44
2
public function __construct() {
    // allocate your stuff
}

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

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

For details check this answer : Best way to do multiple constructors in PHP

Community
  • 1
  • 1
Md. Al-Amin
  • 1,423
  • 1
  • 13
  • 26
-10

Thank you very much for your answer. I have solved the problem with my way.

public function __construct($nick) {
    if($nick != NULL) {//for user 
        $query = "SELECT * FROM Users WHERE nick='".$nick."'";
        $result = App::runQuery($query);
        $user = $result->fetch_object();

        $this->id = $user->id;
        $this->nick = $user->nick;
        $this->email = $user->email;
        $this->password = $user->password;
        $this->birthDay = $user->birthDay;
        $this->sex = $user->sex;
        $this->about = $user->about;
        $this->city = $user->city;
        $this->photo = $user->photo;
        $this->following = $user->following;
        $this->followers = $user->followers;
        $this->statu = $user->statu; 
    }else {//for null
        $this->id = NULL;
        $this->nick = NULL;
        $this->email = NULL;
        $this->password = NULL;
        $this->birthDay = NULL;
        $this->sex = NULL;
        $this->about = NULL;
        $this->city = NULL;
        $this->photo = NULL;
        $this->following = NULL;
        $this->followers = NULL;
        $this->statu = NULL;
    }

}

It works!

Mehmet
  • 3,301
  • 8
  • 26
  • 36
  • 6
    I think this is not a good implementation – Kingalione Aug 01 '18 at 10:24
  • I think you missed the actual point of argument being optional which was addressed by @TimCooper here is the clue `public function __construct($nick = null)` – Mubashar Jul 12 '19 at 05:48
  • With PHP > 7.4 it should be `public function __construct($nick = null)`. – Alexander Behling Dec 10 '21 at 15:36
  • You code works because it only has one param. Also the else part can be omit, because it is the default value of the attributes. For a constructor which needs either zero or multiple params I could only think of handling this using an array. Then I could check if the param is an array and if so check the number of entries in the array. – Alexander Behling Dec 10 '21 at 15:49