Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Я лично разделяю обоих на подклассы Zend_Db_Table_Abstract
и Zend_Db_Table_Row_Abstract
. Основное различие между моим кодом и Ваш - то, которые явно рассматривают подкласс Zend_Db_Table_Abstract
как "таблица" и Zend_Db_Table_Row_Abstract
как "строка". Очень редко делайте я вижу прямые вызовы для выбора объектов, SQL или созданного в методах базы данных ZF в моих контроллерах. Я пытаюсь скрыть логику запроса определенных записей на призывы позади Zend_Db_Table_Abstract
как так:
class Users extends Zend_Db_Table_Abstract {
protected $_name = 'users';
protected $_rowClass = 'User'; // <== THIS IS REALLY HELPFUL
public function getById($id) {
// RETURNS ONE INSTANCE OF 'User'
}
public function getActiveUsers() {
// RETURNS MULTIPLE 'User' OBJECTS
}
}
class User extends Zend_Db_Table_Row_Abstract {
public function setPassword() {
// SET THE PASSWORD FOR A SINGLE ROW
}
}
/* CONTROLLER */
public function setPasswordAction() {
/* GET YOUR PARAMS */
$users = new Users();
$user = $users->getById($id);
$user->setPassword($password);
$user->save();
}
Существуют многочисленные способы приблизиться к этому. Не думайте, что это - единственное, но я пытаюсь следовать за намерением дизайна ZF. (Вот больше моих мыслей и ссылок на предмет.) Этот подход действительно получает немного тяжелого класса, но я чувствую, что это сохраняет контроллеры сфокусированными на обработке входа и координировании с представлением; отъезд модели, чтобы сделать специализированную работу.
Я работал на Пехлеви и сделал довольно мало работы над компонентом Zend_Db_Table.
Платформа Зенда не дает много указаний на понятии "Модели" относительно шаблона Модели предметной области. Нет никакого базового класса для Модели, потому что Модель инкапсулирует некоторую часть бизнес-логики, характерной для Вашего приложения. Я записал блог об этом предмете более подробно.
Персистентность к базе данных должна быть внутренней деталью реализации Модели. Модель обычно использование один или несколько Представляет в виде таблицы. Это - общий, но неподходящий объектно-ориентированный дизайн для рассмотрения Модели как расширение Таблицы. Другими словами, мы должны сказать, что Модель ИМЕЕТ - Таблица - не Образцовая Таблица ISA.
Это - пример ISA:
class MyModel extends Zend_Db_Table_Abstract
{
}
Это - пример, ИМЕЕТ - A:
class MyModel // extends nothing
{
protected $some_table;
}
В реальной модели предметной области, Вы были бы использование $some_table в методах MyModel.
можно также читать, Martin Fowler берут шаблон разработки Модели предметной области и его описание Анемичный антишаблон Модели предметной области , который является, сколько разработчиков, к сожалению, приближается к программированию OO.
Никогда не используйте Zend_Db_Table в качестве своей модели. Это просто получает Вас в проблему. Или Вы пишете свои собственные образцовые классы, которые используют Zend_Db_Table, чтобы говорить с Вашей базой данных, или можно считать мое сообщение в блоге здесь для взлома, который позволяет Вам несколько комбинировать "Образцовый" класс и Zend_Db_Table.
главное к не состоит в том, что при использовании Zend_Db_Table непосредственно в контроллерах Вы заканчиваете тем, что делали то же самое в нескольких местах. Если необходимо внести изменение в часть той логики, необходимо внести изменение в нескольких местах. Не хороший. Мой первый профессиональный проект был сделан как это, потому что я был тем в компании, которая должна была изучить, как использовать ZF, и это - общая путаница теперь.
я также склонен писать функции помощника в свои классы для сложных выборок. Somthing как $table-> doNameFetchAll () или $table-> doOrderFetchAll ().
Я проводил некоторое исследование на Моделях для ZF и столкнулся с интересным рядом статей Matthew Weier O'Phinney, которые определенно стоит проверить:
Это не "производственный код", и много оставляют воображению, но это - хорошее чтение и помогло мне вполне немного.
Пропустите ZF для части моделей, существуют намного лучшие решения. "M" в "MVC" ZF в значительной степени отсутствует. При чтении их документов, они действительно не упоминают модели вообще - который является хорошей вещью, это означает, что можно использовать примерно что-либо, что Вы хотите, не пишущий много кода адаптера.
Смотрят на Доктрина для моделей вместо этого. Это быстро становится фактическим ORM для PHP.
Можно сделать более сложные запросы, проверить Усовершенствованное использование раздел в Zend_Db_Table
страница руководства.
$select = $table->select();
$select->from($table,
array('COUNT(reported_by) as `count`', 'reported_by'))
->where('bug_status = ?', 'NEW')
->group('reported_by');
можно расширить класс Zend_Db_Table_Abstract и добавить некоторые полезные методы к нему. например, можно добавить changePassword () метод к пользовательскому классу и управлять, это - данные. или можно изменить значение по умолчанию __ toString () метод класса, таким образом, у Вас будет специализированное __ toString () метод, что, скажем, возвращает целую контактную информацию пользователя (имя, адрес, номер телефона) в хорошо отформатированной строке. в Вашем конструкторе Вы могли заполнить свои данные в свойства Вашего объекта. тогда используйте их как:
public function __toString() {
$data = $this->_name . ', ' . $this->_adderss . ', call: ' . $this->_phone;
return $data;
}
Ваша модель расширяет Zend_Db_Table_Abstract только для упрощения процесса доступа к его данным, но функциональность, которую Вы могли иметь на тех данных, является всем на Вашей креативности и потребности. Я рекомендую Вам книгу "руководство php|architect по программированию с платформой зенда" Cal Evans. книга очень информативна и легка читать. главы 4 и 6 будут полезными для этого вопроса.
Объект базы данных не является единственным видом образцового компонента. По сути, действительно не имеет смысла говорить о моделях (во множественном числе) - Ваше приложение имеет одно модель, которая содержит множество компонентов. Некоторые из этих компонентов могли быть шлюзами таблицы (И таким образом расшириться от Zend_Db
), в то время как другие не будут.
я рекомендую овладеть книжным Доменом Управляемый Дизайн Eric Evans, который делает превосходное задание объяснения, как создать объектную модель.
Я использую, Продвигают 1.3 вместо Zend_Db_Table. Это хитро для установки, но потрясающий. Это может исследовать Вашу базу данных и автоматически сгенерировать все Ваши модели. Это на самом деле генерирует 2 уровня и 2 типа модели.
Примеры для 'пользовательской' таблицы:
Уровень 1: BaseModel & BasePeer: они перезаписываются каждый раз, когда Вы повторно создаете свой ORM. т.е. BaseUser.php & уровень 2 BaseUserPeer.php
: StubModel & StubPeer: они не становятся перезаписанными. Они - те, Вы настраиваете. т.е. User.php & тип 1 UserPeer.php
: Модель - для основных операций CRUD, не запросов т.е. Типа 2 User.php: Одноранговый узел - для запросов. Это статические объекты. т.е. UserPeer.php
Так для создания пользователя:
$derek = new User();
$derek->setFirstName('Derek');
$derek->save();
Для нахождения всего dereks:
$c = new Criteria();
$c->add(UserPeer::FIRST_NAME, 'Derek');
$dereks = UserPeer::doSelect($c);
http://zfsite.andreinikolov.com/2008/08/zend_db_table-time-overhead-about-25-percents/
Небольшая уловка 22, Zend_Table в принципе хорош, но вызывает некоторые накладные расходы на производительность ( без кеширования) ...