Приємно використовувати хороші інструменти, проте Ви повинні бути впевнені, що використовуєте їх належним чином, а не просто кодувати "начебто працює, ну й добре". З цієї причини я і вирішив написати список речей, які я завжди тримаю в голові, коли приймаю на підтримку чийсь топроект або консультую як почати.
Це твердження найбільш очевидно, однак, повірте мені, я знаходив помилки в кожному проекті, в якому брав участь (більш ніж 10 з Zend Framework за останні півроку).
Якщо це контролер, в ньому не повинно бути бізнес-логіки, якщо це модель, в ній не повинно бути обробки POST параметрів і т.д.
Логіка повинна бути на своєму місці і повинна бути відокремлена від форм, bootstrap'а, уявлень, помічників і т.д.
Перенесіть всю логіку з контролера в модель або сервіс (service). Використовуйте форму тільки для перевірки і фільтрації даних, які не обробляйте в формах дані.
Приховуйте сесії і ідентифікацію користувачів, виконуйте всі необхідні операції в одному місці і надавайте API-функції для використання в інших частинах проекту.
Я можу продовжувати і продовжувати, однак сподіваюся, що ідея стає зрозумілою. В кінці-кінців Ви зрозумієте, що щось не те, коли начнететестіровать код: коли щоб всього лише протестувати форму, Вам доведеться налаштувати frontController. request, cookie і поштовий сервер.
І знову я хочу згадати про легкість тестування, оскільки це те, про що Ви постійно повинні пам'ятати, розробляючи програму. Тест не повинен модифікувати глобальні змінні. Для отримання значення тест повинен користуватися методами об'єктів, які повертають необхідні значення (наприклад IP). Zend Framework надає дуже зручні класи для доступу до всіх глобальних змінних, гріх ними не користуватися.
Користуйтеся значеннями форми, а не запиту
Цією рекомендації дуже легко слідувати.
Подивіться на наступний приклад коду:
Після того як форма перевірена (а значить і значення відфільтровані), все одно використовуються сирі дані запиту $ this -> _ request-> getPost (). Ви просто втрачаєте багато цікавих функцій Zend_Form. наприклад, ігноровані елементи (кнопки "submit"). Більш того, форма не використовує фільтри, а Ви ж налаштовуєте фільтри, чи не так? Крім того, я можу передати в модель що завгодно, і модель сама повинна виконати перевірки даних. А значить в методі $ form-> getValues () повинен бути реалізований не тільки функціонал перевірок, але і фільтрів.
У цьому прикладі надмірно використовується метод форми populate (). Цей метод розроблений для установки початкових значень форми. У разі помилки метод isValid () сам встановить потрібні значення, тому в додатковій функції для установки значень немає потреби.
Перше, що я роблю, це видаляю всі виклики exit () і переробляю їх з використанням винятків або виразу return. Існує дуже малослучаев, коли використання однієї з цих функцій можна вважати виправданим. Для прикладу давайте розглянемо такий код дії контролера:
Перша проблема - думати, що $ this -> _ redirect () викличе exit () і таким чином виконання дії буде закінчено. Хоча це дійсно так і є, Ви повинні уникати подібні випадки. Такі виклики унеможливлюють генерацію подій post *. Більш того це робить тестування неможливим або некоректним. Zend_Test відключає виклик exit () в помічниках контролера, таким чином під час тестування Ви не можете протестувати перевірку прав. Щоб виправити цю проблему, просто додайте return перед виконанням перенаправлення (return $ this -> _ redirect ( '/')) і все буде в порядку.
Більш того, другий exit () абсолютно даремний і робить код не придатним для тестування. Щоб виправити ситуацію, досить додати return, це не дасть виконати наступний код, подання не буде перерисовано, тому що помічник viewRenderer контролює всі перенаправлення, і якщо виявить таке, нічого не робить. Виходячи з мого досвіду, після збереження даних форми, в код досить помістити тільки перенаправлення, звичайно без exit ().
Використовуйте framework замість PHP
Спочатку це може здатися трохи дивним, проте якщо Ви використовуєте framework (в даному випадку це Zend Framework), що не начінайтепереносіть прийоми і методи з програми PHP п'ятирічної давності. Як, наприклад, тут (дію контролера):
Я навіть і не знаю з чого тут почати. Вся ця логіка вже вставлена в об'єкт відповіді (response), тобто Ви можете зробити наступне:
Ці два фрагмента можуть здатися однаковими, але це не так. Ви можете в цьому дуже легко переконатися, код не працює з глобальними змінними (header () - це функція глобальної змінної) і обробка запиту не переривається. Контролер не виводить ніякі дані (тому й не використовується echo), він просто отримує об'єкт запиту та відправляє об'єкт відповіді, і це все. Висновок даних контролером точно так же перериває виконання процесу як і виклик exit (). тому не забудьте переконатися, що ви не перервали цей потік.
І ще невеликі доповнення
У Application.ini описано властивість includePaths. яке використовується для додавання додаткових шляхів в змінну path. Хоча це і чудово працює, я рекомендую не використовувати цю можливість, тому що ці шляхи додаються щоразу, коли ви створюєте новий екземпляр додатку (це так в 1.9, але може змінитися в майбутньому). Якщо Ви тестируете контролери, то напевно щоразу перед початком створюєте новий екземпляр. Проробивши сотню-іншу тестів, Ви виявите, що швидкодія раз від разу все нижче і нижче.
Щоб знайти і виправити помилку мені треба було кілька годин, я до сих пір все це пам'ятаю.
Це всього лише невелика частина тих проблем і завдань, з якими я зіткнувся в своїй практиці, у мене є ще, що розповісти. Сподіваюся, що Ви теж поділіться своїми секретами. Хочеться вірити, що я дав Вам кілька корисних ідей як правильно працювати з Zend Framework, і Ваш код стане красивіше, а час розробки скоротиться, оскільки все буде прозоро і найкращим чином організовано.
Якщо інформація була корисною для вас, ви можете підтримати сайт.