views:

373

answers:

6

Is it possible to exit gracefully out of a constructor in php? Something to the effect of

class Foo { 

 function __construct()
 {

   $active = false;

   if(!$active)
   {
    return false;
   }

 }

}

I'm trying to accomplish this because I want to check to see if any of the methods in the class should run based on a configuration file. I don't want to have to check the configuration file in every method to see if the methods should be running.

+5  A: 

That depends on what you mean by "gracefully". If you want your constructor to fail you can throw an exception, or you can use the factory pattern:

class FooFactory {
    function makeFoo() {
        return $someConstraint ? null : new Foo();
    }
}

Maybe you can elaborate a bit on what exactly it is you want to accomplish.

n3rd
I'm calling this class from another file. If I set $active to be false, I would want none of the methods to run, and for the other page to load normally. For example, if I put a die; in the construct, it will die for every page that has called that object.
In that case you could use the factory pattern to return a dummy object if $active is false and the "real" object if it is not. This isn't the most elegant solution but it would do the trick nicely.
n3rd
A: 

I think N3rd suggested a very cool solution but here is another simpler method.

class Foo {

    private $active = TRUE;

    function __construct() {

     $this->check ( $active ); 

            //OR
            //if ($this->check ( $active )) { do something } 
    }

    function check($var) {
     if (! $var) {
      $this->active = FALSE;
      return FALSE;
     }
     return TRUE;

    }
}
Iman Samizadeh
Does not work. I don't think it's possible to return a value in the construct. :/
It Dose work. As you can call the function like if ($this->check ( $active )) { do something }
Iman Samizadeh
+1  A: 

If your constructor fails, you should throw an exception, not return a false value. Unless you're using a language like C in which exceptions in the construction of the object means it can never be deconstructed.

The reason for this is because an exception forces the program to deal with it, and it give you the bad data. If you return a value, say -1 or whatever, the program can continue silently and ignore that until it causes a problem later down the road. Throwing an exception prevents these silent bugs from entering the code. You may know that it returns false if it failed to construct properly, but your co-worker may not and may happily try to use an object he thought was what he constructed to find out that it's really a boolean.

Malfist
+1  A: 

Make it blow up. There is no such thing as a graceful failure in a constructor. Perhaps in the calling code, but not in the constructor. Throw an exception and handle it appropriately.

+1  A: 

I can smell the Proxy pattern coming your way. What you are trying to achieve is not having the constructor fail gracefully but not allowing methods to be called on an object based on some $active criterion.

This might point you in the right direction. Or maybe not (=>> I don't quite like the page I linked in, but it was the best I could find for PHP). Do give Proxy a read, from other sources too perhaps. Basically, your ProxyObject will have a reference to a real object that will execute methods. Your client code will be calling methods on the ProxyObject as if it were the real thing, and the ProxyObject would decide whether it's active or not, whether to pass the message on to the real thing or to return nothing or nulls or dummy values. Sounds good?

Peter Perháč
A: 

If the constructor does so much logic, then it's not well designed. Leave it empty, pass the configuration to it via a setter method and let it fail there.

It is not OO programming:

$o = new myObject();
if (!is_object($o)) // then what???
Csaba Kétszeri