PHP конструктор для возврата NULL - PullRequest
50 голосов
/ 07 февраля 2010

У меня есть этот код. Может ли конструктор объекта User каким-то образом потерпеть неудачу, чтобы $this->LoggedUser было присвоено значение NULL и объект был освобожден после возврата конструктора?

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

Ответы [ 6 ]

65 голосов
/ 07 февраля 2010

Если вы используете PHP 5, вы можете вызвать исключение в конструкторе:

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) {}
}

Для ясности, вы можете обернуть это статическим фабричным методом:

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']);

Кроме того, некоторые версии PHP 4 позволяли вам устанавливать $ this в NULL внутри конструктора, но я не думаю, что он был официально санкционирован, и «функция» была в конечном итоге удалена.

12 голосов
/ 07 февраля 2010

AFAIK это не может быть сделано, new всегда будет возвращать экземпляр объекта.

Что я обычно делаю, чтобы обойти это:

  • Добавление логического флага ->valid к объекту, который определяет, был ли объект успешно загружен или нет. Затем конструктор установит флаг

  • Создание функции-оболочки, которая выполняет команду new, возвращает новый объект в случае успеха или при ошибке уничтожает его и возвращает false

-

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

Мне было бы интересно услышать об альтернативных подходах, но я не знаю ни одного.

5 голосов
/ 07 февраля 2010

Считай это так.Когда вы используете new, вы получаете новый объект.Период.Что вы делаете, у вас есть функция, которая ищет существующего пользователя и возвращает его при обнаружении.Лучше всего выразить это, вероятно, статической функцией класса, такой как User :: findUser ().Это также расширяется, когда вы выводите свои классы из базового класса.

4 голосов
/ 13 мая 2012

Фабрика может быть полезна здесь:

class UserFactory
{
    static public function create( $id )
    {
        return (
            filter_var( 
                $id,
                FILTER_VALIDATE_INT, 
                [ 'options' => [ 'min_range' => 1, ] ]
            )
                ? new User( $id )
                : null
        );
  }
}
4 голосов
/ 07 февраля 2010

Когда конструктор завершается ошибкой по неизвестной причине, он не возвращает значение NULL или FALSE, но выдает исключение. Как и во всем с PHP5. Если вы не обработаете исключение, сценарий прекратит выполнение с ошибкой Uncaught Exception.

3 голосов
/ 07 февраля 2010

может быть что-то вроде этого:

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
...