Php function construct return false

Возврат значения в функции конструктора класса

функциональность loadUser – это поиск базы данных для определенного адреса электронной почты. Когда я устанавливаю идентификатор на какой-то адрес электронной почты, я уверен, что его нет в базе данных; первый IF будет принят, и переходит к первому ELSE. здесь конструктор должен возвращать FALSE; но вместо этого он возвращает объект класса со всеми значениями NULL!

как я могу предотвратить это? благодаря

спасибо всем за ответы. это было довольно быстро! Я вижу, что путь ООП заключается в том, чтобы выбросить исключение. Так что бросить один, мой вопрос меняется, что я должен делать с исключением? Руководство php.net довольно запутанно!

 // 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 !! >> 

Конструкторы не получают возвращаемых значений; они служат целиком для создания класса.

Не реструктурируя то, что вы уже делаете, вы можете использовать здесь исключение.

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

Теперь вы можете создать нового пользователя таким образом.

Конструктор предположительно создает объект. Поскольку в php булевы не считаются объектами, единственным вариантом является null. В противном случае используйте обходной путь, то есть напишите статический метод, который создает фактический объект.

public static function CheckAndCreate($identifier)< $result = self::loadUser(); if($result === true)< return new EmailClassNameHere(); >else < return false; >> 

Конструктор не может вернуть ничего, кроме объекта, который он пытается создать. Если экземпляр не будет выполнен правильно, вы останетесь с экземпляром класса, полным свойств NULL как вы обнаружили.

Читайте также:  Python row add column

Если объект загружается в неполном или ошибочном состоянии, я бы предложил установить свойство, чтобы указать это.

// error status property public $error = NULL; public function __construct ($identifier = NULL) < // Return me. if ( $identifier != NULL ) < $this->emailAddress = $identifier; if (!$this->loadUser() ) < // registered user requested , but not found ! $this->error = "user not found"; > > 

Когда вы создаете экземпляр объекта, вы можете проверить, имеет ли он статус ошибки:

$obj = new MyObject($identifier); if (!empty($obj->error)) < // something failed. > 

Другая (возможно, лучшая) альтернатива заключается в том, чтобы выдать исключение в конструкторе и обернуть экземпляр в try/catch .

Лучшее, что вы можете сделать, это то, что предложил Стив. Никогда не создавайте конструкторы, которые выполняют любую другую работу, а затем назначают параметры конструктора свойствам объекта, возможно, создают некоторые по умолчанию, но ничего больше. Конструкторы предназначены для создания полностью функционального объекта. Такой объект должен всегда работать так, как ожидалось, после его создания. У пользователя есть электронная почта, имя и, возможно, некоторые другие свойства. Когда вы хотите создать экземпляр объекта пользователя, дайте все эти свойства его конструктору. Выбросы исключений тоже не очень хорошие. Исключение должно быть выбрано в исключительных условиях. Просить пользователя по электронной почте ничего исключительного, даже если вы в конечном итоге выясните, что такого пользователя нет. Исключение может быть, например, если вы попросите пользователя по электронной почте = » (если только это не является обычным состоянием в вашей системе, но идентификатор скорее предполагает, что сообщения электронной почты являются нулевыми в этих случаях). Чтобы получить все эти свойства для объекта пользователя, у вас должен быть объект (или репозиторий, если вы предпочитаете) объект (да, объект – это плохая практика использовать статические все). Частный конструктор – это плохая практика (вы будете все равно нужен статический метод, и, как я уже сказал, статика очень плохая)

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

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('whatever@wherever.com'); if($user === null) < //show error or whatever you want to do in that case >else < //do the job with user object > 

Видеть? без статики, без исключения, простых конструкторов и очень читаемых, проверяемых и модифицируемых

Почему бы просто не передать результаты в конструктор, необходимый для создания объекта, а не пытаться иногда скомпрометировать конструктор?

Даже если вы иногда можете его терпеть, вам все равно нужно будет проверить после вызова конструктора, чтобы убедиться, что он действительно создал, и в этих строках вы можете просто вызвать -> loadUser () и передать результаты в конструктор.

Хороший намек, который кто-то мне сказал, «всегда дает конструктору то, что ему нужно для создания объекта, не заставляйте его искать его».

public function __construct ($emailInTheDatabase, $otherFieldNeeded) < $this->emailAddress = $emailInTheDatabase; $this->otherField = $otherFieldNeeded; > 

спасибо за все комментарии и решения. вот что я сделал, чтобы исправить проблему: (надеюсь, это поможет другим)

// Setup the user ( we assume he is a user first. referees, admins are considered users too ) try < $him = new user ($_emailAddress); // check the supplied password $pass_ok = $him->auth($_Password); // check the activation status $active_ok = $him->makeActive(); > catch (Exception $e_u) < // try the groups database try < $him = new group ($_emailAddress); // check the supplied password $pass_ok = $him->auth($_Password); //var_dump ($pass_ok); // check the activation status $active_ok = $him->makeActive(); > catch (Exception $e_g) < // email address was not in any of them !! $pass_ok = false; $active_ok = false; >> 

Я бы не стал слишком много в конструкции. Вы должны рассмотреть статический функционал, который создает пользователя (фабрику) вместо того, чтобы помещать все в конструктор. Таким образом, вы все равно можете использовать свой пользовательский объект, не требуя неявной функции загрузки. Это избавит вас от боли.

public function __construct()<> public function setIdentifier($value)< $this->identifier = $value; > public function load() < // whatever you need to load here //. throw new UserParameterNotSetException('identifier not set'); // . // if user cannot be loaded properly throw new UserNotFoundException('could not found user'); >public static function loadUser($identifier)< $user = new User(); $user->setIdentifier($identifier); $user->load(); return $user; > 
$user = new User(); try< $user->setIdentifier('identifier'); $user->load(); > catch(UserParameterNotSetException $e) < //. >catch(UserNotFoundException $e) < // do whatever you need to do when user is not found >// With the factory static function: try < $user2 = User::loadUser('identifier'); >catch(UserParameterNotSetException $e) < //. >catch(UserNotFoundException $e)< // do whatever you need to do when user is not found > 

Я очень удивлен, что в течение 4 лет ни один из 22-ки зрителей не предложил создать частный конструктор и метод, который пытается создать такой объект:

class A < private function __construct () < echo "Created!\n"; >public static function attemptToCreate ($should_it_succeed) < if ($should_it_succeed) < return new A(); >return false; > > var_dump(A::attemptToCreate(0)); // bool(false) var_dump(A::attemptToCreate(1)); // object(A)#1 (0) <> //! new A(); - gives error 

Таким образом вы получаете либо объект, либо false (вы также можете вернуть его null). Ловить обе ситуации сейчас очень легко:

$user = User::attemptToCreate('email@example.com'); if(!$user) < // or if(is_null($user)) in case you return null instead of false echo "Not logged."; >else < echo $user->name; // eg > 

Вы можете проверить это прямо здесь: http://ideone.com/TDqSyi

Я считаю, что мое решение более удобно использовать, чем бросать и ловить исключения.

Источник

Вернуть false из __constructor

Действительно ли это правильно, т. Е. Будет ли $ ftp_sftp var быть ложным или удерживать класс в зависимости от результата метода __construct, или это полностью неправильная логика?

Нет. Конструкторы не имеют возвращаемых значений. Если вам требуется получить какой-то результат от конструктора, вы можете сделать несколько вещей:

Если вам нужно вернуть значение, используйте метод для тяжелого подъема (обычно называемый init() ).

public static function init( $host, $username, $password, $connection_type )< //setting the classes vars $this->host = $host; $this->username = $username; $this->password = $password; $this->connection_type = $connection_type; //now set the connection into this classes connection $this->connection = $this->connect(); //check the connection was set else return false if($this->connection === false) < return false; >> $ftp_sftp = ftp_sftp::init(); 

Сохраните результаты в переменной-члене и проверьте ее значение после вызова конструктора.

function __construct( $host, $username, $password, $connection_type )< //setting the classes vars $this->host = $host; $this->username = $username; $this->password = $password; $this->connection_type = $connection_type; //now set the connection into this classes connection $this->connection = $this->connect(); > $ftp_sftp = new ftp_sftp( $host, $uname, $pword, $connection_type ); if ($ftp_sftp->connection !== false) < // do something > 

Вы можете использовать метод connect() для исключения. Это немедленно прекратит выполнение и перейдет в ваш блок catch :

private method conntect() < // connection failed throw new Exception('connection failed!'); >try < $ftp_sftp = new ftp_sftp( $host, $uname, $pword, $connection_type ); >catch (Exception $e) < // do something > 

Конструкторы не могут возвращать значения. Вы можете сделать исключение в этой должности:

Затем вы можете создать экземпляр переменной в блоке try-catch.

Я думаю, вы можете создать объект снаружи и напрямую использовать свой метод connect () и протестировать там

$ftp_sftp = new ftp_sftp( $host, $uname, $pword, $connection_type ); $ftp_sftp->connect(); 

Есть интересный вопрос о том, почему конструкторы не имеют возвращаемых значений. Почему конструкторы не возвращают значения? ,

Кроме того, кажется, что, возвращая «False», вы хотите отрицать создание объекта. Если это так, я бы предположил, что вы исключили исключение, если соединение завершилось неудачей, и таким образом создание объекта завершится неудачно.

Источник

Оцените статью