Slim framework создаем блог. H Slim framework или как мы отказались от CMS в черновиках Из песочницы. Образец приложения Slim

Эта публикация будет интересна небольшим компаниям по разработкам сайтов с использованием CMS. Небольшая предыстория: мы — это небольшой отдел, который занимается разработкой веб-сайтов. Очень долгое время мы разрабатывали сайты только на системах управления (OpenCart, WordPress, MODX и самописная), которые по своей сути были простые и однотипные, но с лета прошлого года пришёл тренд на разработку сайтов, которые не просто были в интернете лицом компании, но одним из инструментов бизнеса.

Так, например, был заказ для транспортной компании, которая осуществляет рейсовые маршруты и хотела бы, чтобы всё управление (бронирование и оплата билета, в том числе через кассира) происходила через сайт.

Как вы можете догадываться, большой пользы от CMS тут ждать не приходится. Даже наоборот — любой алгоритм, которому она следовала, нам мешал. Через несколько дней на первом же таком сайте были одни костыли и практически вся обработка шла исключительно на javascript, а CMS использовалась как прослойка для записи и выборки из базы данных.

Терпеть такое мы долго не смогли и, посовещавшись, решили, что для таких проектов мы будем использовать miсroframework — и сразу же положили глаз на Slim.

Как гласит официальный сайт:

Slim — это микро фреймворк, который поможет вам быстро писать простые, но мощные веб-приложения.

И это действительно так, вы можете скачать его вручную архивом или воспользоваться Composer. После этого создайте index.php со следующим содержанием:

//Подключаем фреймворк require "Slim/Slim.php"; //Регистрируем автозагрузку \Slim\Slim::registerAutoloader(); $app = new \Slim\Slim(); $app->get("/hello/:name", function ($name) { echo "Привет, $name"; }); $app->run();
Это простое приложение которое выводит привет {{username}} при переходе на url.
Но как же мы были разочарованы, что на этом большинство статей в интернете заканчивается и на данном этапе многое остается для нас непонятным.

Сам Slim не задает чёткой системы распределений файлов на диске, поэтому мы не нашли лучшего способа, чем иклюдить каждый роутинг. На следующий день, поняв, что что-то идёт не так, было решено создать отдельную папку и класть туда файлы по группам. В файл index.php добавилось следующее

Foreach (glob("Routes/*.php") as $file) include($file);
Со временем каждый такой файл стал слишком большим, но посмотрев официальную документацию , ничего не обнаружили. Решение было найдено на github, где было сказано, что надо делать:

$app->get("post/:type/:id", "\Controller\Post:onePost");
Где \Controller\Post — класс, который, как я понимаю, добавлен в соответствии с RSP-0. А onePost — это его метод.
Таким образом наша файловая структура обновилась ещё одной директории Controller, в которую мы записывали действия, которые могли использовать сразу в нескольких вариантах роутинга. Я считаю хорошим примером данный роутинг, который заключён в группу, стиль, который почему-то не описан в той же документации.

$app->group("/", function () use ($app) { $app->get("post/:type/:id", "\Controller\Post:onePost") ->conditions(array("type" => "{3,}", "id" => "{1,}")) ->setParams(array("app" => $app, "type" => $type = NULL, "id" => $id = 0)) ->name("onePost"); });
Где conditions — валидация по регулярному выражению, setParams — передача параметров методу onePost, а name — имя для возможного редиректа на данную страницу (Например $app->redirectTo("onePost");)

Не лишним будет проводить проверку на доступность не в самом контроллере, а на уровне роутига, благодаря «Middleware». Например, для панели администратора сразу же можно поставить на целую группу такую как:

$app->group("/admin", $authenticateForRole($app, "admin"), function () use ($app) { ... });
Где вторым аргументом является присвоенная анонимная функция переменной. В моём случае она выглядит таким образом:

$authenticateForRole = function ($app, $role = "admin") { return function () use ($app, $role) { \Controller\Autch::chekUserRole($app, $role); }; };
К сожалению, а для некоторых, может, и к счастью, в slim нет встроенной работы с базой данных, но этот вопрос достаточно просто решается, когда мы создаём объект App. Мы можем передавать некоторые аргументы, которые будут им использоваться.

Например:

$app = new \Slim\Slim(array("templates.path" => "Views", "debug" => TRUE, "mode" => "development", "BDbase" => "localhost", "BDuser" => "username", "BDpassword" => "password", "BDname" => "basename"));
После этого мы сможем спокойно воспользоваться Dependency Injection для работы с базой данных, обращаясь к параметрам, переданным при создании с помощью метода $app-config("Имя");

$app->database = new mysqli($app->config("BDbase"), $app->config("BDuser"), $app->config("BDpassword"), $app->config("BDname")); if ($app->database->connect_errno) { echo "Не удалось подключиться к MySQL: (" . $app->database->connect_errno . ") " . $app->database->connect_error; die(); } $app->database->query("SET NAMES "utf8""); $app->database->query("SET CHARACTER SET "utf8""); $app->database->query("SET SESSION collation_connection = "utf8_general_ci"");
Все остальные возможности Slim достаточно хорошо описаны в документации. В заключении хочу сказать, что для нашей команды, которая никогда раньше не работала с различными framrwork"ами, это был хороший опыт, который мы уже используем в проектах. Возвращаться на какую-либо CMS желания не возникает.

Slim – один из популярнейших открытых микрофреймворков, доступных для PHP. Он очень эффективный, быстрый и простой в использовании. Данный фреймворк идеально подходит для разработки малых и средних веб-приложений, а также позволяет достаточно быстро разрабатывать крупные масштабируемые PHP-приложения.

Slim обладает следующими (достаточно предсказуемыми как для фреймворка) функциями:

  • простота в использовании, мощный и гибкий маршрутизатор;
  • просмотр визуализации шаблонов;
  • безопасные файлы cookie;
  • HTTP-кэширование;
  • простота обработки ошибок и отладки;
  • простота настройки.

Требования

Это руководство продемонстрирует, как установить и настроить Slim на виртуальном выделенном сервере. Выполнив все изложенные здесь инструкции, вы получите полностью настроенный и готовый к работе фреймворк со структурой папок, в которой можно разместить ​​проект.

Если разрабатываемому приложению не нужна СУБД MySQL, можете не устанавливать ее. Как минимум, понадобятся веб-сервер Apache (с модулем Mod_Rewrite) и PHP 5.3+.

Быстрая установка требований

1: Установка Apache

apt-get update
apt-get install apache2

2: Установка PHP

apt-get install php5 libapache2-mod-php5 php5-mcrypt

3: Активация mod_rewrite

4: Редактирование конфигурационного файла Apache

В конфигурационном файле Apache нужно изменить AllowOverride None на AllowOverride All. В зависимости от настроек сервера этот файл может находиться в:

  • /etc/apache2/apache2.conf
  • /etc/apache2/sites-enabled/000-default
  • /etc/apache2/sites-available/default

В конфигурационном файле найдите раздел, который выглядит следующим образом:



AllowOverride None
Require all granted

Отредактируйте его следующим образом и сохраните изменения:


Options Indexes FollowSymLinks
AllowOverride All
Require all granted

5: Перезапуск Apache

service apache2 restart

Установка Slim

Процесс установки фреймворка Slim состоит из трех этапов:

  • распаковка zip-файлов;
  • копирование Slim Framework в общедоступное место.
  • 1: Загрузка Slim

    Скачать Slim Framework можно при помощи команды:

    wget https://github.com/codeguy/Slim/zipball/master

    Данная команда извлечет архив фреймворка и сохранит его в текущем каталоге под именем master.

    2: Распаковка zip-файла

    Содержимое zip-файла можно извлечь с помощью следующей команды:

    unzip master -d ./

    Примечание : если появилось сообщение о том, что инструмент unzip не установлен, его можно установить с помощью команды apt-get install unzip, а затем снова выполнить предыдущую команду.

    Данная команда извлечет файлы в папку с именем вроде codeguy-Slim-3a2ac72, которая содержит папку по имени Slim, папку фреймворка.

    3: Копирование Slim Framework в общедоступное место

    Теперь нужно скопировать папку codeguy-Slim-3a2ac72/Slim в общедоступное место системы (например, в /usr/local/Slim), откуда фреймворк Slim будет доступен для всех проектов на этом сервере, которым он необходим. Это позволит избежать дублирования и предотвратит любые проблемы обслуживания, которые могут возникнуть из-за дублирования программы.

    Скопируйте папку с помощью следующей команды:

    cp -r ./codeguy-Slim-3a2ac72/Slim /usr/local/Slim

    Примечание : имя извлеченной папки (в данном случае codeguy-Slim-3a2ac72) может несколько отличаться в случае загрузки другой версии фреймворка. Убедитесь, что в команде указано верное имя папки.

    Как только это будет сделано, любой из проектов, использующих Slim Framework, сможет получить доступ к нему.

    Важно! Многие руководства советуют установить фреймворк в общую папку/document root (например, в /var/www/Slim). Имейте в виду: установка файлов инфраструктуры за пределами общей папки/document root (как это сделано в данном руководстве) позволяет немного обезопасить приложение, поскольку файлы фреймворка не будут доступны в браузере.

    Разработка проекта Slim

    Как правило, проект Slim состоит из трех основных каталогов:

    1. Каталог фреймворка Slim.

    Он содержит файлы фреймворка (каталог, который был скопирован в предыдущем разделе).

    1. Каталог проекта.

    В этом каталоге содержатся файлы проекта (маршрутизаторы, виды, модели и т.д.). Будучи микрофреймворком, Slim не навязывает никакой конкретной структуры проекта. Это означает, что разработчик может самостоятельно структурировать файлы проекта любым удобным для него способом. Это особенно полезно, если разработчик уже привык к определенной структуре папок.

    Данный каталог может находиться в любой точке сервера; единственное условие: в идеале он не должен располагаться в доступном из сети месте. Его можно разместить в /usr/local или домашней папке. К примеру, если проект находится в папке HelloSlim, то такую папку можно поместить в /usr/local/HelloSlim или ~/HelloSlim.

    Файлы в этой папке можно расположить следующим образом:

    HelloSlim
    |- Routes
    | |- route1.php
    | |- route2.php
    |- Models
    | |- model1.php
    | |- model2.php
    |- Views
    | |- footer.php
    | |- header.php
    | |- sidebar.php
    | |- view1.php
    | |- view2.php
    |- Class
    | |- class1.php
    | |- class2.php
    |- routes.php //contains "include" statements for all routes in the "Routes" folder
    |- includes.php //contains "include" statements for all models/classes in the "Models/Class" folders

    Такую структуру папок можно создать при помощи следующих команд:

    mkdir /usr/local/HelloSlim
    mkdir /usr/local/HelloSlim/Routes
    mkdir /usr/local/HelloSlim/Models
    mkdir /usr/local/HelloSlim/Views
    mkdir /usr/local/HelloSlim/Class

    Примечание : необязательно использовать именно такую структуру папок; ее можно изменять согласно потребностям проекта или разработчика.

    1. Document root, или общая папка.

    Это папка, доступная в сети (как правило, расположена в /var/www). В ней содержится всего два файла, связанные со Slim:

    • index.php
    • .htaccess

    Данная папка также содержит все скрипты, графические файлы и стили проекта. Во избежание «засорения» папки можно создать в ней отдельные каталоги scripts, styles и images для хранения соответствующих файлов.

    Вот пример структуры папки document root:

    Document Root (eg. /var/www/)
    |- scripts
    | |- jquery.min.js
    | |- custom.js
    |- styles
    | |- style.css
    | |- bootstrap.min.css
    |- images
    | |- logo.png
    | |- banner.jpg
    |- .htaccess
    |- index.php

    Содержимое файла

    Предположим, проект имеет структуру, заданную выше; в таком случае нужно заполнить файлы.htaccess и index.php (в document root, root-каталоге сайта) следующим образом:

    .htaccess

    RewriteEngine On


    index.php



    require "$projectDir/includes.php"; //include the file which contains all the project related includes
    $app = new \Slim\Slim(array(
    "templates.path" => "/usr/local/HelloSlim/Views"


    $app->run(); //load the application

    Предполагая, что проект организован в соответствии со структурой папок, определенной в предыдущем разделе, файлы routes.php и includes.php (в каталоге проекта) должны иметь следующее содержание:

    require "/usr/local/HelloSlim/Routes/route1.php";
    require "/usr/local/HelloSlim/Routes/route2.php";

    Примечание : вместо того, чтобы добавлять другие файлы с маршрутами, можно добавить маршруты непосредственно в данный файл. Однако, определение маршрутов в отдельных, логически сгруппированных файлах упростит обслуживание проекта.

    includes.php

    require "/usr/local/HelloSlim/Class/class1.php";
    require "/usr/local/HelloSlim/Class/class2.php";
    require "/usr/local/HelloSlim/Models/model1.php";
    require "/usr/local/HelloSlim/Models/model2.php";

    Образец приложения Slim

    Теперь можно приступить к созданию простого приложения, которое:

    • обрабатывает статические маршруты (GET & POST);
    • обрабатывает динамические маршруты;
    • использует виды.

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

    Для начала нужно наметить требования этого примера приложения:

    Данному проекту требуются следующие файлы в папке приложения (/usr/local/HelloSlim/):

    HelloSlim
    |- Routes
    | |- getRoutes.php
    | |- postRoutes.php
    |- Views
    | |- footer.php
    | |- header.php
    | |- hello.php
    | |- greet.php
    |- routes.php

    Ниже показано, как будет работать общая папка.

    Вот пример структуры document root:

    Document Root (eg. /var/www/)
    |- .htaccess
    |- index.php

    Теперь нужно заполнить данные файлы следующим образом:

    1. /var/www/.htaccess

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php

    2. /var/www/index.php

    require "/usr/local/Slim/Slim.php"; //include the framework in the project
    \Slim\Slim::registerAutoloader(); //register the autoloader
    $projectDir = "/usr/local/HelloSlim"; //define the directory containing the project files
    $app = new \Slim\Slim(array(
    "templates.path" => "/usr/local/HelloSlim/Views"
    )); //instantiate a new Framework Object and define the path to the folder that holds the views for this project
    require "$projectDir/routes.php"; //include the file which contains all the routes/route inclusions
    $app->run(); //load the application

    3. /usr/local/HelloSlim/Routes/getRoutes.php

    $app->get("/", function(){
    echo "This is a simple starting page";
    });
    //The following handles any request to the /hello route
    $app->get("/hello", function() use ($app){
    // the following statement invokes and displays the hello.php View
    $app->render("hello.php");
    });
    //The following handles any dynamic requests to the /hello/NAME routes (like /hello/world)
    $app->get("/hello/:name", function($name) use ($app){
    // the following statement invokes and displays the hello.php View. It also passes the $name variable in an array so that the view can use it.
    $app->render("hello.php", array("name" => $name));
    });

    4. /usr/local/HelloSlim/Routes/postRoutes.php

    //The following handles the POST requests sent to the /greet route
    $app->post("/greet", function() use ($app){
    //The following statement checks if "name" has been POSTed. If it has, it assigns the value to the $name variable. If it hasn"t been set, it assigns a blank string.
    $name = (null !== $app->request->post("name"))?$app->request->post("name"):"";
    //The following statement checks if "greeting" has been POSTed. If it has, it assigns the value to the $greeting variable. If it hasn"t been set, it assigns a blank string.
    $greeting = (null !== $app->request->post("greeting"))?$app->request->post("greeting"):"";
    // the following statement invokes and displays the "greet.php" View. It also passes the $name & $greeting variables in an array so that the view can use them.
    $app->render("greet.php", array(
    "name" => $name,
    "greeting" => $greeting
    ));
    });

    5. /usr/local/HelloSlim/Views/footer.php

    Copyright notice...

    6. /usr/local/HelloSlim/Views/header.php




    Sample Slim Application

    7. /usr/local/HelloSlim/Views/hello.php

    ***

    ***

    Hello