Русская документация Symfony2 на SymfonyGuru
Дата последнего обновления: 2012-05-20.
Дата последнего обновления: 2012-05-20.
Поздравляем! Начав изучение Symfony2, вы встали на правильный путь, чтобы стать более продуктивным, всесторонне развитым и популярным веб-разработчиком (хотя последнее - на ваше усмотрение). Symfony2 создан, чтобы предоставлять базовые, низкоуровневые инструменты, позволяющие вам разрабатывать быстрее, создавать более надёжные приложения, но при этом быть в строне от вашего собственного пути. Symfony построен на лучших идеях, заимствованных из различных технологий: инструменты и концепции, которые вы готовитесь изучить - представлены усилиями тысяч и тысяч людей на протяжении многих лет. Другими словами, вы не только изучаете “Symfony”, вы изучаете основы web, лучшие практики разработки, а также способы использования многих замечательных PHP-библиотек в составе Symfony2 или не зависимо от него. Итак, приготовьтесь.
Следуя философии Symfony2, эта глава начинается с объяснения основной концепции, типичной для web-разработки: HTTP. Не зависимо от вашего опыта или любимого языка программирования, эта глава обязательна к прочтению всем.
HTTP (Hypertext Transfer Protocol или просто Протокол Передачи Гипертекста) - это текстовый язык, позволяющий двум компьютерам обмениваться сообщениями друг с другом. Вот и всё! Например, когда мы хотим посмотреть новенький комикс xkcd, имеет место (примерно) такой диалог:
И пока используется реальный язык, хотя он и несколько более формальный, он остаётся предельно простым. HTTP - это термин, используемый для описания этого простого текстового языка. И не важно, как именно вы разрабатываете в web, целью вашего сервера всегда является понять простой текстовый запрос и вернуть простой текстовый ответ.
Symfony2 возвышается над этой реальностью. Что бы вы ни делали, HTTP - это то, что вы используете ежедневно. С помощью Symfony2 вы узнаете, как управлять им.
Любой диалог в сети начинается с запроса. Запрос - это текстовое сообщение, создаваемое клиентом (например браузером или iPhone приложением и т.д.) в особом формате, также известном как HTTP. Клиент отправляет этот запрос серверу, и ожидает ответ.
Взгляните на первую часть взаимодействия (запрос) между браузером и веб-сервером xkcd:
На языке HTTP этот запрос будет выглядеть примерно так:
GET / HTTP/1.1
Host: xkcd.com
Accept: text/html
User-Agent: Mozilla/5.0 (Macintosh)
Это простое сообщение содержит всю необходимую информацию о том, какой именно ресурс запрашивает клиент. Первая строка HTTP запроса наиболее важна - она содержит 2 вещи: запрошенный URI и HTTP-метод.
URI (например /, /contact, и т.д.) - это уникальный адрес или место, которое определяет запрошенный клиентом ресурс. HTTP-метод (например GET) определяет, что именно вы хотите сделать с запрошенным ресурсом. HTTP методы это глаголы в запросе и они определяют несколько типичных путей, которыми вы можете взаимодействовать с запрошенным ресурсом:
| GET | Получить ресурс с сервера |
| POST | Создать ресурс на сервере |
| PUT | Обновить ресурс на сервере |
| DELETE | Удалить ресурс с сервера |
Запомнив эти типы HTTP-методов, вы можете представить себе, как будет выглядеть HTTP-запрос на удаление записи в блоге:
DELETE /blog/15 HTTP/1.1
Примечание
На самом деле всего существует девять HTTP-методов, определённых в спецификации протокола HTTP, но многие из них очень мало распространены или же ограниченно поддерживаются. К примеру, многие современные браузеры не поддерживают методы PUT и DELETE.
В дополнение к первой строке, HTTP-запрос всегда содержит несколько информационных строк, именуемых заголовками (headers). Заголовки могут предоставлять различную информацию, такую как запрошенный Host, форматы ответа, которые поддерживает клиент (Accept) и приложение, используемое клиентом для выполнения запроса (User-Agent). Существует также много других заголовков, перечень которых вы можете найти в Википедии на странице List of HTTP header fields.
С того момента как сервер получил запрос, он точно знает, какой ресурс нужен клиенту (основываясь на URI) и что клиент хочет с этим ресурсом сделать - на основании HTTP-метода. Например, в случае GET-запроса, сервер подготовит запрошенный ресурс и возвратит его в виде HTTP-ответа. Рассмотрим ответ от web сервера xkcd:
Переведённый в формат HTTP, ответ, отправленный обратно в браузер, будет выглядеть примерно так:
HTTP/1.1 200 OK
Date: Sat, 02 Apr 2011 21:05:05 GMT
Server: lighttpd/1.4.19
Content-Type: text/html
<html>
<!-- HTML for the xkcd comic -->
</html>
HTTP-ответ содержит запрошенный ресурс (в данном случае это HTML-код страницы), а также дополнительные данные о самом ответе. Первая строка особенно важна - она содержит HTTP статус-код (в данном случае 200). Статус-код сообщает о результате выполнения запроса, направляемом клиенту. Был ли запрос успешен? Была ли в ходе выполнения запроса ошибка? Одни статус-коды обозначают успешные запросы, другие - ошибки, третьи сообщают, что клиент должен выполнить что-либо (например перенаправление на другую страницу). Полный список вы можете найти странице List of HTTP status codes в Википедии.
Подобно запросу, HTTP-ответ содержит дополнительную информацию, называемую HTTP-заголовками. Например, важным заголовком HTTP-ответа является Content-Type. Тело одного и того же ресурса может быть возвращено во множестве различных форматов, включая HTML, XML или JSON. Заголовок Content-Type сообщает клиенту, какой именно формат используется в данном ответе.
Существует много различных заголовков, некоторые из них предоставляют большие возможности. Например, некоторые заголовки могут быть использованы для создания системы кэширования.
Обмен запросами-ответами - это фундаментальный процесс, который движет все коммуникации во всемирной сети. И насколько важен этот процесс, настолько он прост.
Наиболее важным является следующий факт: вне зависимости от того, какой языка программирования вы используете, какое приложение создаёте (web, мобильное, JSON API) и даже какой философии следуете в разработке ПО, конечной целью приложения всегда будет приём и разбор запроса и создание соответствующего ответа.
Symfony спроектирован исходя из этих реалий.
Совет
Для того чтобы узнать больше про спецификацию HTTP, прочитайте оригинал HTTP 1.1 RFC или же HTTP Bis, который является инициативой по разъяснению оригинальной спецификации. Замечательный инструмент для проверки заголовков запроса и ответа при сёрфинге - это расширение для Firefox Live HTTP Headers.
Как же вы обрабатываете “запрос” и создаете “ответ” при использовании PHP? На самом деле PHP немного абстрагирует вас от процесса:
<?php
$uri = $_SERVER['REQUEST_URI'];
$foo = $_GET['foo'];
header('Content-type: text/html');
echo 'The URI requested is: '.$uri;
echo 'The value of the "foo" parameter is: '.$foo;
Как бы странно это ни звучало, но это крохотное приложение получает информацию из HTTP-запроса и использует её для создания HTTP-ответа. Вместо того, чтобы парсить необработанный HTTP-запрос, PHP подготавливает суперглобальные переменные, такие как $_SERVER и $_GET, которые содержат всю информацию о запросе. Аналогично, вместо того, чтобы возвращать текст ответа, форматированный по правилам HTTP, вы можете использовать функции header() для создания заголовков ответов и просто вывести на печать основной контент, который станет контентным блоком ответа. В заключении PHP создаст правильный HTTP-ответ и вернет его клиенту:
HTTP/1.1 200 OK
Date: Sat, 03 Apr 2011 02:14:33 GMT
Server: Apache/2.2.17 (Unix)
Content-Type: text/html
The URI requested is: /testing?foo=symfony
The value of the "foo" parameter is: symfony
Symfony предоставляет альтернативу прямолинейному подходу из PHP посредством двух классов, которые позволяют взаимодействовать с HTTP-запросом и ответом самым простейшим способом. Класс Symfony\Component\HttpFoundation\Request - это простое объектно-ориентированное представление сообщения HTTP-запроса. С его помощью вы имеете все данные из запроса “на кончиках пальцев”:
<?php
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
// запрошенный URI (на пример /about) без query parameters
$request->getPathInfo();
// получаем GET и POST переменные соответственно
$request->query->get('foo');
$request->request->get('bar');
// получаем экземпляр UploadedFile определяемый идентификатором foo
$request->files->get('foo');
$request->getMethod(); // GET, POST, PUT, DELETE, HEAD
$request->getLanguages(); // массив языков, принимаемых клиентом
В качестве бонуса, класс Request выполняет большой объём работы в фоновом режиме, так что вам не придется заботиться о многих вещах. Например, метод isSecure() проверяет три различных значения в PHP, которые указывают, что пользователь подключается по защищенному протоколу (https).
Symfony также предоставляет класс Response: простое РHP-представление HTTP-ответа. Это позволяет вашему приложению использовать объектно-ориентированный интерфейс для конструирования ответа, который нужно вернуть клиенту:
<?php
use Symfony\Component\HttpFoundation\Response;
$response = new Response();
$response->setContent('<html><body><h1>Hello world!</h1></body></html>');
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'text/html');
// prints the HTTP headers followed by the content
$response->send();
Если бы Symfony ничего вам не предлагала, вы всегда должны были бы иметь набор инструментов для того чтобы можно было просто и быстро получить доступ к информации из запроса и объектно-ориентированный интерфейс для создания ответа. Даже если вы освоите более мощные возможности в Symfony, всегда держите в голове, что цель вашего приложения всегда заключается в том, чтобы интерпретировать запрос и создать соответствующий ответ, основываясь на логике вашего приложения
Совет
Классы Request и Response являются частью самостоятельного компонента HttpFoundation. Этот компонент может быть использован независимо от Symfony и он также предоставляет классы для работы с сессиями и загрузки файлов.
Как и HTTP-протокол, объекты Request и Response достаточно просты. Самая сложная часть создания приложения заключается в написании процессов, которые происходят между получением запроса и отправкой ответа. Другими словами, реальная работа заключается в написании кода, который интерпретирует информацию запроса и создает ответ (логика приложения).
Ваше приложение может иметь много функций, например, отправлять email’ы, обрабатывать отправленные формы, сохранять что-то в базу данных, отображать HTML-страницы и защищать контент правилами безопасности. Как управляться со всем этим и чтобы при этом код оставался хорошо организованным и поддерживаемым?
Symfony создана специально для решения этих проблем, значит, вам не придется их решать.
Традиционно приложения создавались таким образом, чтобы каждая “страница” имела свой собственный файл:
index.php
contact.php
blog.php
При таком подходе имеется целый ряд проблем, включая жёсткие URLы (что если вам потребуется изменить blog.php на news.php и при этом сохранить все ваши ссылки?), а также необходимость вручную включать в каждый файл кучу файлов, включающих безопасность, работу с базами данных.
Много более удачным является подход с использованием front controller, единственного PHP-файла, который отвечает за каждый запрос к вашему приложению. Например:
| /index.php | выполняет index.php |
| /index.php/contact | выполняет index.php |
| /index.php/blog | выполняет index.php |
Совет
С использованием модуля mod_rewrite для Apache (или эквивалента для других web-серверов) URLы легко очистить от упоминания фронт-контроллера, т.е. останется лишь /, /contact и /blog.
Теперь, каждый запрос обрабатывается однообразно. Вместо того чтобы каждый URL соответствовал отдельному PHP-файлу - фронт-контроллер выполняется всегда и посредством маршрутизатора вызывает различные части вашего приложения, в зависимости от URL. Это решает многие проблемы, которые порождал традиционный подход. Практически все современные приложения используют этот подход, например WordPress.
Итак, мы внутри вашего фронт-контроллера. Но как мы узнаем, какая страница должна быть отображена и как её сформировать? В любом случае вам нужно проверить входящий URI и выполнить какую-то из частей вашего кода, в зависимости от этого значения. Это можно сделать быстро и весьма коряво:
<?php
// index.php
$request = Request::createFromGlobals();
$path = $request->getPathInfo(); // запрошенный URL
if (in_array($path, array('', '/')) {
$response = new Response('Welcome to the homepage.');
} elseif ($path == '/contact') {
$response = new Response('Contact us');
} else {
$response = new Response('Page not found.', 404);
}
$response->send();
Решить же эту проблему достаточно сложно. К счастью, Symfony создана именно для этого.
Когда вы даёте возможность Symfony обрабатывать запросы, жизнь становится много проще. Symfony следует простому шаблону при обработке каждого запроса:
Входящие запросы интерпретируются маршрутизатором и передаются в функцию-контроллер, которая возвращает объект Response.
Каждая “страница” вашего сайта должна быть определена в конфигурации маршрутизатора, чтобы распределять различные URL по различным PHP-функциям. Обязанность каждой такой функции, называемой controller, используя информацию из запроса - а также используя прочий инструментарий, доступный в Symfony, создать и вернуть объект Response. Другими словами, контроллер содержит ваш код: именно там вы должны превратить запрос в ответ.
Это не сложно! Давайте-ка взглянем:
Не закапываясь глубоко в детали, давайте посмотрим на этот процесс в действии. Предположим, вы хотите добавить страницу /contact к вашему Symfony приложению. Во-первых, надо добавить конфигурацию маршрутизатора для /contact URI:
contact:
pattern: /contact
defaults: { _controller: AcmeDemoBundle:Main:contact }
Примечание
Этот пример использует YAML для того чтобы определить конфигурацию маршрутизатора. Конфигурацию можно также задавать и в других форматах - таких как XML или PHP.
Когда кто-либо посещает страницу /contact, URI совпадает с маршрутом и указанный нами ранее контроллер выполняется. Как вы узнаете в из главы Маршрутизация, строка AcmeDemoBundle:Main:contact это короткая форма записи, которая указывает на особый метод contactAction, определённый в классе MainController:
<?php
class MainController
{
public function contactAction()
{
return new Response('<h1>Contact us!</h1>');
}
}
В этом очень простом примере, контроллер создает объект Response, содержащий лишь простенький HTML-код “<h1>Contact us!</h1>”. В главе Контроллер, вы узнаете, как контроллер может отображать шаблоны, позволяя “представлению” существовать раздельно от кода в файлах шаблонов. Это дает возможность сосредоточиться в контроллере на работе с базами данных, обработке отправленных пользователем данных или отправке email сообщений.
Теперь вы знаете, что цель вашего приложения заключается в интерпретации входящих запросов и создании адекватного ситуации ответа. По мере роста приложения становится все труднее содержать свой код в порядке. Без сомнений, эта же задача будет повторяться снова и снова: сохранение данных в базу, отображение и повторное использование шаблонов, обработка форм, отправка emails, валидация данных, введённых пользователем и безопасность.
Хорошие новости заключаются в том, что эти проблемы не уникальны. Symfony предоставляет Фреймворк, полный инструментов, которые позволят вам создать ваше собственное приложение, а не ваши инструменты. При помощи Symfony2 вы использовать Фреймворк целиком или же только его часть.
Что же собой представляет Symfony2? Прежде всего, Symfony2 - это коллекция более чем 20 независимых библиотек, которые могут быть использованы в любом PHP-проекте. Эти библиотеки, называемые Symfony2 Components, содержат полезные методы практически на любой случай жизни, не зависимо от того как именно ваш проект разрабатывается. Вот некоторые из них:
Каждый из этих компонентов независим и может быть использован в любом PHP-проекте, не зависимо от Symfony2.
Ну так что же это такое - Symfony2 Framework? Symfony2 Framework это PHP библиотека, которая решает 2 различных задачи:
Цель фреймворка - интеграция независимых инструментов и обеспечение их совместной работы. Сам фреймворк представляет собой Symfony Bundle (плагин), который можно конфигурировать или даже заменить.
Symfony2 предоставляет замечательный набор инструментов для быстрой разработки web-приложений, ничего не навязывающий непосредственно вашему приложению. Разработчик может быстро приступить к разработке, используя дистрибутив Symfony2, который предоставляет скелетон с типовыми настройками. А для пытливых умов... у неба нет потолка! )