Ние изграждаме нашата PHP рамка върху компоненти на Symfony
Като PHP разработчик най-вероятно сте се сблъсквали със Symfony. Е, поне сте чували за него. Това, което може би не знаете е, че Symfony в основата си се състои от набор от отделни библиотеки, наречени компоненти, които могат да се използват отделно във всяко PHP приложение.
Например популярната рамка Laravel е разработена с помощта на няколко компонента на Symfony. В нашия урок ние също ще ги използваме. Следващата версия на популярния Drupal CMS също е изградена върху някои от основните компоненти на Symfony.
Тук ще разгледаме как да изградим малка PHP рамка с помощта на тези компоненти и как те могат да си взаимодействат, за да създадат основната структура на всяко уеб приложение.
Имайте предвид, че в тази статия няма да покрия всеки компонент на Symfony и техните възможности. Ще покрия само основните неща, които са необходими, за да се изгради минимално функционираща рамка. Ако искате да се запознаете по-добре с компонентите на Symfony - препоръчвам ви да се обърнете към документацията.
Създайте проект
Нека започнем от нулата, с прост файл index.php в основата на проекта и да използваме Composer за инсталиране на зависимости.
На този етап нашият файл ще съдържа прост код:
Този код просто съпоставя искания URL фрагмент (съдържащ се в $_SERVER['PATH_INFO']) със съответния ехо оператор. Това е много, много прост рутер.
Компонент HttpFoundation
HttpFoundation играе ролята на абстракция от високо ниво за работа с HTTP потока. Неговите най-важни входни точки са класовете Request и Response.
Заявката ви позволява да работите с информация за HTTP заявка, като например заявения URI или клиентски заглавки,е добавка за суперглобалните масиви на PHP ($_GET, $_POST и т.н.). Отговорът се използва за изпращане на HTTP заглавки и данни към клиента, вместо да се използва стандартното заглавие и ехо, какъвто би бил случаят в "класическия" PHP.
Инсталирайте с композитор:
Тази команда ще постави компонента в директорията на доставчика. Сега поставете този код във вашия файл index.php:
Това, което направихме тук, не е нищо особено:
- Създайте екземпляр на Request с помощта на статичен метод createFromGlobals. Вместо да създава празен обект, той попълва обекта Request с данните на текущата заявка;
- Проверяваме получената стойност чрез метода getPathInfo.
Можем също да заменим ехо конструкциите с използване на обекта Response за съхраняване на изхода и да използваме метода за изпращане, за да изпратим отговора на клиента (който всъщност отпечатва заглавките и съдържанието в изходния буфер).
Използваме HttpKernel като обвивка върху ядрото на рамката
В момента имаме най-простия случай - цялата логика на рамката се намира в нашия преден контролер - файла index.php. Ако искаме да добавим повече код, по-добре е да го отделим в друг клас, който ще стане „ядрото“ на нашата рамка.
Компонентът HttpKernel е създаден точно за тези цели. Той е проектиран да работи с HttpFoundation, обектът Request се преобразува в обект Response и също така предоставя няколко класа за постигане на това. Сега ще използваме HttpKernelInterface. Този интерфейс дефинира само един метод: handle.
Този метод приема обект Request като аргумент и очаква да върне обект Response. Така че всеки клас, който имплементира този интерфейс, може да обработи заявкатаЗаявка и връщане на отговор.
Нека създадем основния клас на нашата рамка, който имплементира интерфейса HttpKernelInterface. Създайте файл Core.php в директорията lib/Framework.
Забележка : Методът handle също приема два незадължителни аргумента: типа на заявката и булев аргумент, указващ дали ядрото трябва да хвърли изключение при грешка. Няма да ги използваме в тази статия, но трябва да имплементираме метода точно както е описан в интерфейса HttpKernelInterface, в противен случай PHP ще изведе грешка.
Единственото нещо, което направихме в този фрагмент, беше да преместим кода в метода handle. Сега можем да се отървем от този код във файла index.php и вместо това да използваме прясно създаден клас:
Подобрена система за маршрутизиране
Нашият клас все още има проблем: той все още обработва маршрутизиране в цялото приложение. Ако трябва да добавим нови URL адреси, ще трябва да променим кода вътре в рамката, което определено не е добра идея. Освен това, това ще изисква добавяне на нови блокове за всеки нов маршрут. Не, определено не искаме да се спускаме по този хлъзгав склон.
Решението е да добавите система за маршрутизиране към рамката. Можете да направите това, като създадете метод за карта, който картографира URI към PHP затваряне, което ще бъде изпълнено, ако URI съответства на маршрута.
Сега маршрутите могат да се добавят директно в предния контролер:
Имаме нужда от по-гъвкава и мощна система за маршрутизиране, поради което трябва да използваме компонента Routing.
Използването на компонента Routing ще ни позволи да предадем обекти Route към UrlMatcher, който ще съпостави заявения URI със съответния маршрут. Този обект Route може да съдържа всякакви атрибути, които ще помогнатда изпълним желаната част от приложението. В нашия случай такъв обект ще съдържа затваряне, което трябва да се изпълни в случай на съвпадение на маршрута. Освен това всеки динамичен параметър, съдържащ се в URL адреса, ще присъства в списъка с атрибути на маршрута.
За да приложим тази система, трябва да направим следните промени:
- заменете масива с маршрути с екземпляр на RouteCollection, за да запазите нашите маршрути;
- промяна на логиката на метода map, така че да регистрира екземпляр на Route в тази колекция;
- създайте обект UrlMatcher и му кажете как да търси съвпадения на маршрут в предадения URI, като посочите подходящия контекст с помощта на обекта RequestContext.
Методът за съпоставяне ще се опита да намери съвпадащ маршрут, даден на дадения URL адрес, и ако успее, ще върне съответните атрибути на маршрута. В противен случай ще хвърли ResourceNotFoundException, което можем да уловим и да покажем страница 404.
Сега можете да използвате компонента за маршрутизиране, за да обработвате всякакви параметри. След като се отървете от атрибута на контролера, можете да извикате всяко затваряне, като му предадете параметри като аргументи (с помощта на функцията call_user_func_array):
Сега можем да обработваме динамични URL адреси на формата с лекота:
Обърнете внимание, че тук правим нещо много подобно на това, което прави самата рамка на Symfony: инжектираме URL параметрите в контролера, от който се нуждаем.
Ние се намесваме в процеса на рамката
Рамката на Symfony също предоставя редица опции за инжектиране и модифициране на жизнения цикъл на заявката. Добър пример е защитен слой, който прихваща заявка, която се опитва да получи достъп до защитен URL адрес.
Всичко това е възможно благодарение на компонента EventDispatcher, който позволяваразлични компоненти на приложението комуникират помежду си чрез прилагане на шаблона за проектиране Observer.
В основата на този компонент е класът EventDispatcher, който абонира абонатите за отделни събития. Когато диспечерът бъде уведомен за събитие, се извикват всички известни абонати на това събитие. Абонат може да бъде всяка валидна функция или метод за обратно извикване.
Можем да приложим това поведение за себе си, като добавим свойство dispatcher, което ще съхранява обекта EventDispatcher, както и on метод, който ще обвърже събитието с PHP функцията за обратно извикване. Ще използваме диспечера за регистриране на функция за обратно извикване и за последващо генериране на събития в рамката.
Вече имаме възможността да регистрираме абонати, което е проста функция за обратно извикване. Сега нека напишем пожарен метод, който казва на диспечера да уведоми всички абонати, които знае, че е настъпило някакво събитие.
В по-малко от десет реда код добавихме хубава система за обработка на събития към нашата рамка, благодарение на компонента EventDispatcher.
Методът за изпращане също приема втори аргумент, обектът на събитието. Всяко събитие наследява от общия клас Event и е предназначено да съхранява всяка информация, свързана със събитието.
Нека напишем клас събитие RequestEvent, който ще бъде незабавно извикан веднага щом рамката обработи заявката. Разбира се, това събитие трябва да има достъп до текущата заявка чрез атрибут, който ще съдържа текущата инстанция на заявката.
Сега можем да добавим кода в метода handle, така че да генерира събитие RequestEvent всеки път, когато получим заявка.
По този начин всички абонати на товаще има достъп до обекта RequestEvent, както и до текущия екземпляр на Request. В момента не сме написали такъв абонат, но можете лесно да си представите манипулатор, който ще провери дали заявеният URL адрес е ограничен, преди да изпълни основния код.
Това е най-простата система за сигурност, но можете да внедрите каквото искате, тъй като сега имате възможност да се намесвате в рамката по всяко време, което значително разширява нейните възможности.
Заключение
Можете да видите от тази статия, че компонентите на Symfony са страхотни самостоятелни библиотеки. Освен това те могат да взаимодействат помежду си, за да образуват заедно рамка, която отговаря на вашите нужди. Има много други компоненти, които без съмнение са много интересни - например компонентите DependencyInjection или Security.
Разбира се, пълноразмерни рамки като Symfony или Laravel използваха тези компоненти до пълния им потенциал, за да създадат мощните инструменти, които имаме днес.
Този урок е подготвен за вас от екипа на ruseller.com Източник на урока: http://www.sitepoint.com/build-php-framework-symfony-components/ Превод: Станислав Протасевич Урокът е създаден: 23 октомври 2014 г. Прегледан: 15727 Правила за препечатване
5 последни урока от рубриката "PHP"
Филтриране на данни с zend-filter
Когато става въпрос за сигурност на уебсайтове, фразата „филтрирай всичко, проверявай всичко“ винаги ще бъде актуална. Днес ще говорим за филтриране на данни.
Контекстуално избягване с zend-escaper
Свързване на Zend модули към Expressive
Expressive 2 поддържа възможността за свързване на други ZF компоненти по специален начин. Не всеки харесва това решение. В тази статия ще ви разкажем как подобрихме процеса на свързване на няколко модула.
Съвет: Подаване на информация към Google Analytics чрез API
Да предположим, че трябва да изпратите някаква информация до Google Analytics от сървърен скрипт. Как да го направим. Отговорът е в тази публикация.
Селекция от PHP пясъчници
Селекция от няколко типа PHP пясъчници. На някои можете да тествате кода си онлайн, но има и решения, които можете да приложите на сайта си.