开发者

PHP constructor to return a NULL

开发者 https://www.devze.com 2022-12-19 22:01 出处:网络
I have this code. Is it possible for a User object constructor to somehow fail so that $this->开发者_运维知识库LoggedUser is assigned a NULL value and the object is freed after constructor returns?

I have this code. Is it possible for a User object constructor to somehow fail so that $this->开发者_运维知识库LoggedUser is assigned a NULL value and the object is freed after constructor returns?

$this->LoggedUser = NULL;
if ($_SESSION['verbiste_user'] != false)
  $this->LoggedUser = new User($_SESSION['verbiste_user']);    


Assuming you're using PHP 5, you can throw an exception in the constructor:

class NotFoundException extends Exception {}

class User {
    public function __construct($id) {
        if (!$this->loadById($id)) {
             throw new NotFoundException();
        }
    }
}

$this->LoggedUser = NULL;
if ($_SESSION['verbiste_user'] != false) {
    try {
        $this->LoggedUser = new User($_SESSION['verbiste_user']);
    } catch (NotFoundException $e) {}
}

For clarity, you could wrap this in a static factory method:

class User {
    public static function load($id) {
        try {
            return new User($id);
        } catch (NotFoundException $unfe) {
            return null;
        }
    }
    // class body here...
}

$this->LoggedUser = NULL;
if ($_SESSION['verbiste_user'] != false)
    $this->LoggedUser = User::load($_SESSION['verbiste_user']);

As an aside, some versions of PHP 4 allowed you to set $this to NULL inside the constructor but I don't think was ever officially sanctioned and the 'feature' was eventually removed.


AFAIK this can't be done, new will always return an instance of the object.

What I usually do to work around this is:

  • Adding a ->valid boolean flag to the object that determines whether an object was successfully loaded or not. The constructor will then set the flag

  • Creating a wrapper function that executes the new command, returns the new object on success, or on failure destroys it and returns false

-

function get_car($model)
      {
        $car = new Car($model);
        if ($car->valid === true) return $car; else return false;
     } 

I'd be interested to hear about alternative approaches, but I don't know any.


Consider it this way. When you use new, you get a new object. Period. What you're doing is you have a function that searches for an existing user, and returns it when found. The best thing to express this is probably a static class function such as User::findUser(). This is also extensible to when you're deriving your classes from a base class.


A factory might be useful here:

class UserFactory
{
    static public function create( $id )
    {
        return (
            filter_var( 
                $id,
                FILTER_VALIDATE_INT, 
                [ 'options' => [ 'min_range' => 1, ] ]
            )
                ? new User( $id )
                : null
        );
  }
}


When a constructor fails for some unknown reason, it won't return a NULL value or FALSE but it throws an exception. As with everything with PHP5. If you don't handle the exception then the script will stop executing with an Uncaught Exception error.


maybe something like this:

class CantCreateException extends Exception{
}

class SomeClass {
    public function __construct() {
       if (something_bad_happens) {
          throw ( new CantCreateException());
       }
    }
}

try{
  $obj = new SomeClass();
}
catch(CantCreateException $e){
   $obj = null;
}
if($obj===null) echo "couldn't create object";
//jaz303 stole my idea an wrap it into a static method
0

精彩评论

暂无评论...
验证码 换一张
取 消