Подписка

Шустрые фреймворки-расширения

PHP язык расширяемый, причем расширять можно не только путем создания кастомных классов и библиотек, но и дописывая расширения (extensions) на языке C, которые подключаются непосредственно к интерпретатору. Естественно, такие расширения работают намного быстрее PHP кода, так как не нуждаются в интерпретации, а сразу выполняются.
Существует несколько фреймворков, реализованных в виде расширений, об одном из которых пойдет речь дальше.

PhalconPHP

PhalconPHP реализован в виде расширения, поддерживающего MVC и обеспечивающего достаточный, для небольшого приложения, набор функций (документация). Ничем особенным, как фреймворк, PhalconPHP не выделяется, вот только очень интересна реализация в виде раширения. Ведь получается, что отбрасываются многочисленные инклуды и интерпритация PHP файлов при каждом запросе - все нужное уже скомпилировано и готово к использованию.
Я не удержался и решил написать небольшое приложение, чтобы протестировать на скорость и поведение при высоких нагрузках.
Приложение - простой блог, состоящих из списка постов с пейджинатором, простых комментариев и 4 блоков:
1. Последние посты
2. Случайные посты
3. Последние комментарии
4. Случайные комментарии
Для тестирования результата, создал аналог типичного VPS c 512Mb памяти и Ubuntu server на борту.
Ниже описан процесс разработки и полученые результаты. Исходники можно взять тут: github.com/kooler/PhalconBlog

Что нам стоит блог построить

Описанный выше блог будет состоять из довольно простых элементов: 2 моделей (Post и Comment) и 2 контроллеров (IndexController - список постов и PostContoller - страница поста).

Подготовка приложения

Начнем с начала - создадим скелет PhalconPHP приложения:
phalcon_blog/
  app/
    controllers/
    models/
    views/
  public/
    css/
    img/
    javascript/
Предназначение папок очевидно, поэтому на нем останавливаться не буду.

Следующий шаг - создание index.php, который будет загружать модели и маршрутизировать запросы:
try {
   $front = Phalcon_Controller_Front::getInstance();

   //Setting up framework config
   $config = new Phalcon_Config(array(
      "database" => array(
      "adapter" => "Mysql",
      "host" => "localhost",
      "username" => "root",
      "password" => "pass",
      "name" => "phalcon"
   ),
   "phalcon" => array(
      "controllersDir" => "../app/controllers/",
      "modelsDir" => "../app/models/",
      "viewsDir" => "../app/views/"
   )
   ));
   $front->setConfig($config);

   //Printing view output
   echo $front->dispatchLoop()->getContent();
} catch(Phalcon_Exception $e) {
   echo "PhalconException: ", $e->getMessage();
}
В строках 6-12 указаны параметры подключения к базе данных.

Ну и последний подготовительный этап - создадим .htaccess, который будет перенаправлять все запросы на index.php:

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?_url=$1 [QSA,L]

Модели

Модель в PhalconPHP представлена в виде PHP класса наследующего Phalcon_Model_Base и лежащего в папке app/models. Создадим два таких класса Post и Comment:
app/models/Post.php
class Post extends Phalcon_Model_Base {
   function initialize(){
      $this->setSource("posts");
      $this->hasMany("id", "Comment", "post_id");
   }
}
app/models/Comment.php
class Comment extends Phalcon_Model_Base {
   function initialize(){
      $this->setSource("comments");
      $this->belongsTo("post_id", "Post", "id");
   }
}
Каждый класс может содержать метод initialize(), который запускается перед инициализацией модели. В нем мы указали название таблиц и связь с другими моделями.
Создадим таблицы в MySQL:
CREATE TABLE  `posts` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `name` VARCHAR( 255 ) NOT NULL ,
 `body` TEXT NOT NULL ,
 `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = MYISAM;

CREATE TABLE  `comments` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `body` TEXT NOT NULL ,
 `post_id` int(10) NOT NULL,
 KEY `post_id` (`post_id`)
) ENGINE = MYISAM;
Свойства модели можно не задавать явно, они автоматически подтягиваются с описания MySQL таблицы.

Контроллеры

Контроллер, аналогично модели, представляет собой класс наследующий базовый Phalcon_Controller. Название котроллера вместе с названием метода формируют ссылку, например метод profileAction в котроллере MyContoller будет доступен по ссылке my/profile.
Создадим контроллер, который выведет список постов и будет использоваться по умолчанию (как главная страница).
app/controllers/IndexController.php
class IndexController extends Phalcon_Controller {
   public function indexAction(){
      $this->view->setVar('posts', Post::find(array("order" => "created DESC")));
   }
}
IndexContoller - контроллер, indexAction которого используется по умолчанию для главной страницы.
Используя класс модели Post, мы получили список всех постов отсортированных по дате создания и при помощи метода setVar объекта view (являющегося связью с видом), создали переменную posts со списком всех постов.
Теперь создадим папку "index" для view контроллера в app/views и в ней создадим view который выведет список постов:
app/views/index/index.phtml

Super blog

<?php foreach($posts->items as $item): ?>    

<?=Phalcon_Tag::linkTo("post/?id=".$item->id, $item->name) ?>

   
<?php echo $item->body ?>
   
<?php print count($item->getComment());?> comments
<?php endforeach; ?>
Для генерации ссылки используем хелпер Phalcon_Tag::linkTo, а для получения количества комментариев метод $item->getComment(), который автоматически получает комментарии используя связи указанные в настройке модели (из метода initialize()).

В результате вышеописанных манипуляций получим главную страницу со списком постов и количеством комментариев к каждому:

На этом пока всё. В следующей статье доделаем функционал и конечно же поизмеряем качество результата.

Если пост понравился, можете нажать на гугловский аналог Like, мне будет приятно.
@kkooler

@kkooler

Занимаюсь разработкой высоконагруженных проектов и распределенных систем на PHP.
В свободное время разрабатываю нано-проекты:

Следить за блогом

RSS канал Twitter