Я пишу веб-приложение (PHP) для своего друга и решил использовать мой ограниченный тренинг OOP с Java.
Мой вопрос – это лучший способ отметить в моем классе / приложении, что определенные критические вещи не удались, не нарушив мою страницу.
Моя проблема заключается в том, что у меня есть объект SummerCamper, который принимает camper_id, поскольку это аргумент для загрузки всех необходимых данных в объект из базы данных. Скажите, что кто-то указывает camper_id в строке запроса, которая не существует, я передаю ее в конструктор объектов и сбой загрузки. В настоящее время я не вижу способа вернуть false из конструктора.
Я прочитал, что могу сделать это с помощью Исключения, выбрасывая исключение, если в базе данных нет записей, или если какая-либо проверка не выполняется при вводе camper_id из приложения и т. Д.
Тем не менее, я действительно не нашел отличный способ предупредить мою программу о том, что загрузка объекта не удалась. Я попытался вернуть false из CATCH, но Object по-прежнему сохраняется на моей php-странице. Я понимаю, что могу поместить переменную $ is_valid = false, если загрузка не удалась, а затем проверить объект с помощью метода get, но я думаю, что могут быть лучшие способы.
Каков наилучший способ достижения существенного завершения объекта, если сбой нагрузки? Должен ли я загружать данные в объект извне конструктора? Есть ли какая-то модель дизайна, на которую я должен смотреть?
Любая помощь будет оценена по достоинству.
function __construct($camper_id){ try{ $query = "SELECT * FROM campers WHERE camper_id = $camper_id"; $getResults = mysql_query($query); $records = mysql_num_rows($getResults); if ($records != 1) { throw new Exception('Camper ID not Found.'); } while($row = mysql_fetch_array($getResults)) { $this->camper_id = $row['camper_id']; $this->first_name = $row['first_name']; $this->last_name = $row['last_name']; $this->grade = $row['grade']; $this->camper_age = $row['camper_age']; $this->camper_gender = $row['gender']; $this->return_camper = $row['return_camper']; } } catch(Exception $e){ return false; } }
Конструктор в PHP всегда будет возвращать void
. Эта
public function __construct() { return FALSE; }
не будет работать. Выбрасывание исключения в конструкторе
public function __construct($camperId) { if($camperId === 1) { throw new Exception('ID 1 is not in database'); } }
прекратит выполнение скрипта, если вы не поймаете его где-нибудь
try { $camper = new SummerCamper(1); } catch(Exception $e) { $camper = FALSE; }
Вы можете переместить вышеуказанный код в статический метод SummerCamper для создания экземпляров, вместо того, чтобы использовать new
ключевое слово (которое распространено в Java, которое я слышал)
class SummerCamper { protected function __construct($camperId) { if($camperId === 1) { throw new Exception('ID 1 is not in database'); } } public static function create($camperId) { $camper = FALSE; try { $camper = new self($camperId); } catch(Exception $e) { // uncomment if you want PHP to raise a Notice about it // trigger_error($e->getMessage(), E_USER_NOTICE); } return $camper; } }
Таким образом, вы можете сделать
$camper = SummerCamper::create(1);
и получить FALSE
в $camper
когда $camper_id
не существует. Поскольку статика считается вредной , вместо этого вы можете использовать Factory.
Другим вариантом было бы полностью SummerCamper
доступ к базе данных от SummerCamper
. В принципе, SummerCamper
– это Сущность, которая должна SummerCamper
только о вещах SummerCamper
. Если вы даете ему знания о том, как упорствовать, вы фактически создаете ActiveRecord или RowDataGateway . Вы можете использовать подход DataMapper :
class SummerCamperMapper { public function findById($id) { $camper = FALSE; $data = $this->dbAdapter->query('SELECT id, name FROM campers where ?', $id); if($data) { $camper = new SummerCamper($data); } return $camper; } }
и ваше лицо
class SummerCamper { protected $id; public function __construct(array $data) { $this->id = data['id']; // other assignments } }
DataMapper несколько сложнее, но он дает вам развязанный код, который в конце концов является более удобным и гибким. Осмотритесь вокруг, есть несколько вопросов по этим темам.
Чтобы добавить к ответам других людей, имейте в виду, что вы можете использовать различные типы исключений из одного метода и обрабатывать их по-разному:
try { $camper = new SummerCamper($camper_id); } catch (NoRecordsException $e) { // handle no records } catch (InvalidDataException $e) { // handle invalid data }
Вероятно, правильным решением является выброс исключения из конструктора. Вы можете поймать это в соответствующем месте и предпринять необходимые действия (например, отобразить страницу с ошибкой). Поскольку вы не показывали какой-либо код, неясно, где вы ловили свое исключение или почему это не работает.
try { $camper = new SummerCamper($id); $camper->display(); } catch (NonexistentCamper $ex) { handleFailure($ex); }