Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a value in constructor function of a class

So far I have a PHP class with the constructor

public function __construct ($identifier = NULL) {  // Return me. if ( $identifier != NULL ) {   $this->emailAddress = $identifier;   if ($this->loadUser() )     return $this;         else   { // registered user requested , but not found !  return false;   } } 

the functionality of loadUser is to look up the database for a particular email address. When i set the identifier to some email that i'm sure it's not in the database; the first IF is get passed, and goes to the first ELSE. here the constructor should return FALSE; but instead, it returns an object of the class with all NULL values !

how do i prevent this? thanks

EDIT:

thank you all for the answers. that was quite fast ! I see that the OOP way is to throw an Exception. So a throw one, my question changes that what should i do with the exception?? php.net's manual is pretty confusing !

    // Setup the user ( we assume he is a user first. referees, admins are   considered users too )     try { $him = new user ($_emailAddress);     } catch (Exception $e_u) {        // try the groups database       try { $him = new group ($_emailAddress);        } catch (Exception $e_g) {           // email address was not in any of them !!           }     } 
like image 253
Anoosh Ravan Avatar asked Jul 27 '11 18:07

Anoosh Ravan


People also ask

Can we return a value from constructor?

A constructor can not return a value because a constructor implicitly returns the reference ID of an object, and since a constructor is also a method and a method can't return more than one values.

Should we return something from the function constructor?

You shouldn't return anything in a constructor. A constructor is used to initialize the object.

What does a constructor function return?

Return from constructors Usually, constructors do not have a return statement. Their task is to write all necessary stuff into this , and it automatically becomes the result. But if there is a return statement, then the rule is simple: If return is called with an object, then the object is returned instead of this .

What will happen if you want to return some value from a constructor?

By definition there is no possibility of returning a value from a constructor. A constructor does not support any return type. Not even void. The implicit return type by default is the class type in which it is declared.

What does the constructor of a function return?

The constructor returns the this object. By the Javascript spec, when a function is invoked with new, Javascript creates a new object, then sets the "constructor" property of that object to the function invoked, and finally assigns that object to the name this. You then have access to the this object from the body of the function.

How to return an object from a function in C++?

c++ - Returning object from function by Dinesh Thakur Category: Classes in C++ A function can also return objects either by value or by reference. When an object is returned by value from a function, a temporary object is created within the function, which holds the return value.

What happens when a constructor returns a primitive value?

Basically if your constructor returns a primitive value, such as a string, number, boolean, null or undefined, (or you don't return anything which is equivalent to returning undefined), a newly created object that inherits from the constructor's prototype will be returned.

Can a constructor return a null value?

A constructor cannot return anything but the object it is attempting to create. If the instantiation doesn't complete properly, you'll be left with a class instance full of NULL properties as you've discovered. If the object loads in an incomplete or error state, I would suggest setting a property to indicate that.


2 Answers

Constructors don't get return values; they serve entirely to instantiate the class.

Without restructuring what you are already doing, you may consider using an exception here.

public function __construct ($identifier = NULL) {   $this->emailAddress = $identifier;   $this->loadUser(); }  private function loadUser () {     // try to load the user     if (/* not able to load user */) {         throw new Exception('Unable to load user using identifier: ' . $this->identifier);     } } 

Now, you can create a new user in this fashion.

try {     $user = new User('[email protected]'); } catch (Exception $e) {     // unable to create the user using that id, handle the exception } 
like image 128
erisco Avatar answered Sep 28 '22 10:09

erisco


The best you can do is what Steve has suggested. Never create constructors that do any job other then assigning constructor parameters to the object properties, maybe create some default ones, but nothing else. Constructors are meant to create a fully functional object. Such an object must always work as expected after its instantiation. A user has email, name and probably some other properties. When you want to instantiate a user object, give all those properties to its constructor. Throwing exceptions is not a good way either. An exception is meant to be thrown under exceptional conditions. Asking for a user by email is nothing exceptional, even if you eventualy figure out that no such user exists. Exception could be for example if you ask for a user by email = '' (unless that is a regular state in your system, but id rather suggest emails to be null in those cases). To get all those properties for a user object you should have a factory (or a repository if you prefer) object (yes, an object - it is a bad practice to use static whatever) Private constructor is a bad practice either (you'll need a static method anyway and as i already stated, statics are very bad)

so the result should be something like this:

class User {   private $name;   private $email;   private $otherprop;    public function __construct($name, $email, $otherprop = null) {     $this->name = $name;     $this->email = $email;     $this->otherprop = $otherprop;   } }  class UserRepository {   private $db;    public function __construct($db) {     $this->db = $db; //this is what constructors should only do   }    public function getUserByEmail($email) {     $sql = "SELECT * FROM users WHERE email = $email"; //do some quoting here     $data = $this->db->fetchOneRow($sql); //supose email is unique in the db     if($data) {       return new User($data['name'], $data['email'], $data['otherprop']);     } else {       return null;     }   } }  $repository = new UserRepository($database); //suppose we have users stored in db $user = $repository->getUserByEmail('[email protected]'); if($user === null) {   //show error or whatever you want to do in that case } else {   //do the job with user object } 

See? no statics, no exception, simple constructors and very readable, testable and modificable

like image 33
slepic Avatar answered Sep 28 '22 12:09

slepic