Контент


KO3: знакомство

Итак, мы скачали дистрибутив новой беты Kohana v3.0 и горим желанием создать новый супер-пупер-проект на ней. Впрочем, уже при первом взгляде на файлы дистрибутива становится понятно, что все будет не так просто. Вместо привычных нам папок controllers, models и т.д. мы видим непонятные classes и extensions. Почему-то в APPPATH появился файл bootstrap.php, который мы раньше видели в SYSPATH/core… В общем, давайте посмотрим, какие процессы происходят при работе новой версии фреймворка.

Для начала откроем фронтенд (файл index.php). Он сильно напоминает знакомый нам файл из ветки 2.3. Главные различия — в конце файла. Там мы видим новые подключаемые файлы:

// Load the base, low-level functions
require SYSPATH.'base'.EXT;
 
// Load the main Kohana class
require SYSPATH.'classes/kohana'.EXT;
 
// Bootstrap the application
require APPPATH.'bootstrap'.EXT;

Помимо упомянутого нами файла bootstrap.php подключаются скрипты base.php и classes/kohana.php. Первый содержит всего одну функцию __($string, array $values = NULL) для работы с i18n-ресурсами, второй по сути аналог класса Kohana_Core из core/kohana.php версии 2.3. Как и прежде, он отвечает за автозагрузку классов (метод auto_load()), работу с конфигами и т.д. Более подробно изменения в нем мы рассмотрим позже.

Итак, основные действия разворачиваются в файле bootstrap.php. Просматриваем его содержимое и обнаруживаем первые интересные строчки:

/**
 * Initialize Kohana, setting the default options.
 *
 * The following options are available:
 * - base_url:   path, and optionally domain, of your application
 * - index_file: name of your index file, usually "index.php"
 * - charset:    internal character set used for input and output
 * - profile:    enable or disable internal profiling
 * - caching:    enable or disable internal caching
 */
Kohana::init(array('charset' => 'utf-8', 'base_url' => '/ko3/'));

Как мы помним, ранее класс Kohana инициализировался без каких-либо дополнительных параметров, все подгружалось из многочисленных конфигов (в том числе из главного — config.php). Теперь основные параметры прописаны в классе Kohana по умолчанию как свойства, а мы можем их поменять, передав в массиве в метод Kohana::init().

  • profile — флаг, разрешающий или запрещающий профилирование (т.е. сохранение статистики выполнения задач фреймворка, например подгрузки модулей ядром, используется класс Profiler). По умолчанию свойство установлено в TRUE. В 2.3 статистика собиралась автоматически (с помощью класса Benchmark).
  • caching — флаг включения кэширования внутренних путей (т.е. повторно файлы искаться не будут, пути сохраняются к кэше). По умолчанию FALSE. В версии 2.3 использовался параметр $config['internal_cache'] для этих же целей.
  • charset — используемая кодировка. По умолчанию конечно же ‘utf-8‘. В 2.3 локаль выставлялась в юникод автоматически.
  • base_url — аналог параметра $config['site_domain'] в 2.3. По умолчанию ‘/‘, однако обратите внимание, что в поставляемом файле bootstrap.php это значение переопределяется строкой ‘/ko3/‘.
  • index_file — имя фронтенда, аналог $config['index_page']. Если вы используете .htaccess, можно этот параметр заменить на пустую строку.

Kohana::modules(array(
	// 'database'   => MODPATH.'database',   // Database access
	// 'image'      => MODPATH.'image',      // Image manipulation (not complete)
	// 'orm'        => MODPATH.'orm',        // Object Relationship Mapping (not complete)
	// 'pagination' => MODPATH.'pagination', // Paging of results (not complete)
	// 'paypal'     => MODPATH.'paypal',     // PayPal integration (not complete)
	// 'todoist'    => MODPATH.'todoist',    // Todoist integration
	));

Далее подгружаются модули, для этого был создан метод Kohana::modules(), принимающий их в виде массива ‘имя модуля‘ => ‘путь к модулю‘. Если переданный путь (абсолютный или относительный) не является директорией, модуль загружен не будет. Модули хранятся в переменной $_modules, а пути (т.к. в Kohana каскадная система, при изменении списка модулей пути тоже пересчитываются) — в $_paths. Пока что не вижу никаких способов добавить/удалить один конкретный модуль без передачи полного списка в метод modules(), что не очень удобно при попытке подключить модуль «на лету».

В текущей «бете» из модулей доступен лишь модуль Database с драйвером MySQL. Ядро максимально облегчено, так что ожидаем очередной виток сравнений производительности фреймворков Kohana и Yii при выводе ‘hello, world!‘. ;)

/**
 * Attach the file write to logging. Any Kohana_Log object can be attached,
 * and multiple writers are supported.
 */
Kohana::$log->attach(new Kohana_Log_File(APPPATH.'logs'));

Этот кусок кода отвечает за «прикручивание» логирования в папке APPPATH/logs/ с помощью метода attach(). Свойство Kohana::$log представляет собой объект Kohana_Log, управляющий записью в различные логи. В качестве ресурса для ведения логов создан абстрактный класс Kohana_Log_Writer, от которого должны наследоваться все создаваемые ресурсы. В поставке дистрибутива присутствует класс для работы с файловыми логами (Kohana_Log_File).

/**
 * Set the routes. Each route must have a minimum of a name, a URI and a set of
 * defaults for the URI.
 */
Route::set('default', '(<controller>(/<action>(/<id>)))')
	->defaults(array(
		'controller' => 'welcome',
		'action' => 'index',
		'id' => NULL));

Дальше добавляются настройки роутинга. Вместо конфиг-файлов routes.php предлагается добавлять маршруты через Route::set() и Route::defaults(). Первый метод добавляет в таблицу роутинга именованный маршрут (имя маршрута => URI), причем URI записан в несколько непривычной для нас форме: элементы-переменные маршрута заключены в угловые скобки, необязательные элементы сгруппированы в скобки. Так, в приведенном выше примере параметры action и id являются необязательными. Значения по умолчанию для используемых ключей устанавливаются методом Route::defaults().

Наверное вы обратили внимание на параметр action. Это по сути имя метода, но в дистрибутиве KO3 слово «метод» не используется, далее поймете почему.

/**
 * Execute the main request using PATH_INFO. If no URI source is specified,
 * the URI will be automatically detected.
 */
echo Request::instance($_SERVER['PATH_INFO'])
	->execute()
	->send_headers()
	->response;

Данным вызовом выполняется обработка текущего URI (вычисление контроллера и экшена), собственно выполнение и вывод результата. Дело в том, что вместо класса Router (как это было в 2.3), анализ введенного URL и создание/выполнение нужного метода контроллера производит класс Request (это уже не маленький хэлпер request, как раньше). Метод execute() вычисляет имя контроллера и экшена и инициирует их выполнение. По сравнению с 2.3 есть определенные нюансы:

      Имена контроллеров начинаются с префикса ‘Controller_‘ (в 2.3 используется суффикс ‘_Controller‘).
      Знаки подчеркивания в имени контроллера преобразовываются в слэши, т.е. ‘Controller_Test_Me‘ будет ассоциирован с файлом /classes/controller/test/me.php.
      Конструктор контроллера на входе принимает экземпляр класса Request.
      Имена методов определяются с помощью префикса ‘action_‘ (отсюда название action для параметров Route). Например, http://localhost/welcome/index будет обращаться к контроллеру Controller_Welcome, метод action_index().
      До вызова экшена выполняется метод before(), а после — метод after(). Таким образом, в контроллере можно выполнять какие-то действия, которые не будут выполнены в его потомках (как если бы мы использовали конструктор/деструктор).

Метод Request::send_headers() наверное покажется знакомым (в 2.3 есть событие ‘system.send_headers‘), он отсылает HTTP-ответ и прочие заголовки.

А что хранится в свойстве Request->response? Это собственно результат работы контроллера. Придется привыкнуть, что все наши представления необходимо «вкладывать» в эту переменную, например как $this->request->response = new View(‘index’);.

Итоги

  • На данный момент фреймворк практически голый, не хватает множества привычных модулей и библиотек (например, ORM и Pagination).
  • Расположение папок и файлов поменялось. Теперь все библиотеки, хэлперы, модели и контроллеры лежат в папке classes. Причем контроллеры и модели в папках controller и model соответственно, а вот библиотеки и хэлперы в корне (чем они теперь отличаются, я пока не могу понять, разве что регистром слов в названии класса).
  • Имена классов тоже поменялись, но не все. Если библиотеки продолжают называться именами типа Session_Core, а хэлперы — arr_core, то контроллеры и модели начинаются с префиксов ‘controller_‘ и ‘model_‘ соответственно.
  • Хуков и событий я не увидел ВООБЩЕ. Даже не знаю, что и думать, возможно удастся обойтись упомянутыми ранее методами before() и after() контроллеров?
  • Конфиги тоже сильно поменялись. Например, так теперь выглядит конфигурационный файл с настройками подключения к базе данных MySQL (возможно, он неполный, т.к. нет информации о необходимых параметрах, все на основе анализа исходников):

    // Файл APPPATH/config/database.php
    return array(
    'default' => array
    (
    	'persistent'    => FALSE,
    	'type'     => 'mysql',
    	'username'     => 'user',
    	'password'     => 'password',
    	'hostname'     => 'host',
    	'database' => 'dbname',
    	'charset' => 'utf8',
    )
    );

  • Есть подозрения, что ORM будет создан с нуля (сейчас его вообще нет), а не портирован с 2.4. Соответственно, будут новые баги, глюки и просьбы о помощи…
  • Кэширование в виде отдельной библиотеки отсутствует, есть метод Kohana::cache() для работы с файловым кэшем (причем складироваться файлы кэша будут жестко в APPPATH/cache/).
  • Напоследок — самое «вкусное»: никакой документации (кроме исходников), вся доступная помощь скорее всего может быть получена только в IRC-канале #kohana. Да и вместо привычных «тикетов» в dev.kohanaphp.com придется обращаться на github.com.

В общем, если нет желания поучаствовать в создании перспективной ветки Коханы, оставайтесь на 2.3, в крайнем случае тестируйте 2.4 (там хоть изменения не настолько коренные). А романтики без претензий на комфортную работу — присоединяйтесь, будем помогать. :)

UPDATE. Изменения в архитектуре фреймворка, связанные с появлением библиотеки Request, предоставили возможность сколько угодно раз выполнять различные методы контроллеров без лишних http-запросов. Т.е. обычный вызов Request::factory($url)->execute() вернет результат выполнения метода X контроллера Y, вычисленных на основе анализа URL, указанного в переменной $url. По сути, получаем готовый HMVC уже в каркасе фреймворка.

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в Kohana3.

Теги: .


Комментарии (7)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. Slaver пишет:

    Мммм, даже не знаю, что и сказать.

  2. jleft.ru/ пишет:

    Что-то мне это не нравится. Без хуков, это вообще грустно. Event’ов получается нет?

    Единственное: Request::factory($url)->execute() нравится.

    Только вернулся к Kohana, решил небольшой сайтик написать, думаю всетаки буду на 2.3.4 писать.

  3. BIakaVeron пишет:

    Я подозреваю, что события и хуки будут доступны в виде отдельного модуля (скорее всего их кто-нибудь по-быстрому портирует в KO3).
    А поддержка HMVC уже на уровне ядра не может не радовать :)

    Я вот лично жду ORM и Cache (особенно для Database)

  4. jleft.ru/ пишет:

    У меня кстати есть несколько оч интересных идеек по поводу того, что в принципе можно добавить в кохану, чтобы удобней было работать.

    Неее, события и хуки они ж ядро и составляли. В бутстрапе как все делалось: евенты заносились, вешались на них действия и все поочередно работало, а тут если их нет изначально то и вряд ли будет (:

    пс: дай свой jabber/icq ?:)

  5. BIakaVeron пишет:

    Да, я помню, схема была удобная и гибкая. Видимо в погоне за быстрыми секундами решили из ядра все это выкинуть.

    Теперь вместо system.ready придется использовать before() или конструктор базового контроллера. А вот с событиями приложения можно запросто разобраться, внедрив модуль Events, тут ИМХО ничего сложного. Например, я чаще использовал именно события приложения. А ядро пусть будет легким, не всем же нужны события или базы данных ;)

  6. spirit пишет:

    Even with google translator, this post was a good read. Thanks! See you around the forum :D

  7. BIakaVeron пишет:

    @jleft
    Кстати, также перед загрузкой модуля есть возможность выполнить какие-то настройки, для этого система проверяет модуль на наличие скрипта init.php, и выполняет его если находит.



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.