Хочу поделиться с Хабром простым PHP-фреймворком, выросшим из идей минимализма и нацеленным на быструю разработку простых сайтов.


Не хочу показаться зазывалой, впаривающим вам очередной фреймворк, потому все ссылки для быстрого ознакомления с проектом оставляю над катом:



Пример страницы просмотра статьи
<?php
$sp = [
  'layout' => [
    'title' => 'Статья',
  ],
  'input' => [
    INPUT_GET => [
      'id' => [
        FILTER_SANITIZE_NUMBER_INT,
        [
          'filter' => FILTER_VALIDATE_INT,
          'options' => ['min_range' => 1],
          'comment' => 'Идентификатор должен быть положительным, целым числом'
        ]
      ],
    ],
  ],
  'pdo' => [
    'queries' => [
      'article' => [
        'SELECT * FROM article WHERE id = :id',
        'params' => [
          'id' => &$_GET['id'],
        ],
      ],
    ],
  ],
];
include('../../sp.php');
$article = $article->fetch();
?>
<h1>
    <?= $article->title ?>
</h1>
<div>
    <?= $article->content ?>
</div>
<ul>
    <li>
        <a href="/articles/edit?id=<?= $article->id ?>">edit</a>
    </li>
    <li>
        <a href="/articles/delete.php?id=<?= $article->id ?>">delete</a>
    </li>
</ul>

Пример экшена удаления статьи
<?php
<?php
if($_SERVER['REQUEST_METHOD'] != 'GET'){
  http_response_code(404);
  exit;
}
$sp = [
  'input' => [
    INPUT_GET => [
      'id' => [
        FILTER_SANITIZE_NUMBER_INT,
        [
          'filter' => FILTER_VALIDATE_INT,
          'options' => ['min_range' => 1],
          'comment' => 'Идентификатор должен быть положительным, целым числом'
        ]
      ],
    ],
  ],
  'pdo' => [
    'queries' => [
      [
        'DELETE FROM article WHERE id = :id',
        'params' => [
          'id' => &$_GET['id'],
        ],
      ]
    ],
  ],
];
include('../sp.php');
header('Location: /articles', 302);

Для заинтересовавшихся, под катом будет краткое описание возможностей проекта, его преимуществ и пример использования.


Краткое введение


Если вы знакомы с Jekyll, то вы уже познакомились с большей частью возможностей SimplePage, а именно:


  • Конфигурация системы на уровне конкретной страницы и всего сайта

<?php
$sp = [ // Вводные страницы заменяют дефолтные конфигурации сайта
  'layout' => [
    'title' => 'Редактор статьи',
  ],
];

include('../../sp.php');
?>
<form action="/articles/create.php" method="POST">
    <div>
      <input type="text" name="title" placeholder="Заголовок"/>
    </div>
    <div>
      <textarea name="content"></textarea>
    </div>
    <div>
        <input type="submit" value="Сохранить"/>
    </div>
</form>

  • Роутинг на уровне веб-сервера

? articles/
  ? _locale/
  ? create/
  ? edit/
      index.php // Страница редактирования статьи
  ? view/
    create.php // Экшен создания статьи
    delete.php
    edit.php
    index.php // Страница со списком статей
  index.php // Главная страница

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

Преимущества и недостатки


Преимущества:


  • Очень низкий порог входа — если вы умеете HTML/CSS и немного PHP, вы можете использовать этот фреймворк
  • Очень прост в установке — достаточно скопировать несколько PHP-скриптов, и фреймворк готов к работе
  • Очень прост в использовании — каждая страница сайта это отдельный PHP-скрипт, содержащий как логику для обработки запроса, так и HTML-шаблон для генерации ответа

Недостатки:


  • Процедурный код и global — с увеличением проекта, поддержка может заметно усложниться
  • Низкоуровневая инфраструктура — используются возможности самого PHP, без дополнительных слоев абстракции и интерфейсов

Плагины и модули


Для расширения функционала фреймворка и разработки прикладных решений с его помощью используются плагины и модули соответственно. Первые, как правило, представляют собой инфраструктурные и вспомогательные компоненты приложения, а вторые прикладные решения.


Для подключения плагина, достаточно указать его в конфигурации:


return [
  'plugins' => [
    '_plugins/autoload.php',
    '_plugins/input.php',
    '_plugins/middleware.php',
    '_plugins/i18n.php',
    '_plugins/error.php',
    '_plugins/pdo.php',
    '_plugins/acl.php',
    '_plugins/layout.php',
    '_plugins/hook.php',
  ],
  ...
];

По умолчанию фреймворк поставляется со следующими плагинами:


  • Acl — разграничение прав доступа к страницам сайта
  • Autoload — загрузка классов с использованием прямых ссылок или путей PSR-4
  • Error — обработка ошибок и исключений
  • Hook — модель событий (хуков)
  • I18n — интернационализация
  • Input — фильтрация ввода
  • Layout — HTML-обертки
  • Middleware — модель последовательной обработки ввода-вывода
  • Pdo — декларативная работа с БД

Разработчик может дополнять эти плагины собственными, в том числе используя внешние зависимости и composer:


return [
  'plugins' => [
    'vendor/autoload.php',
    '_plugins/markdown.php',
    ...
  ],
  ...
];

В отличии от плагинов, модули представлены набором PHP-скриптов и даже страниц, решающих прикладные задачи проекта, такие как "Панель администратора" или "Форум".


Пример простого блога


Рассмотрим пример создания блога с использованием данного фреймворка.


Для начала реализуем общую конфигурацию сайта, создав файл config.php в корне проекта:


<?php
return [
  'plugins' => [
    '_plugins/input.php',
    '_plugins/middleware.php',
    '_plugins/i18n.php',
    '_plugins/error.php',
    '_plugins/pdo.php',
    '_plugins/layout.php',
  ],
  'layout' => [
    'title' => 'SimplePage',
    'layout' => '_layout/default.html',
  ],
  'pdo' => [
    'dsn' => [
      'mysql',
      'dbname' => 'sp',
      'charset' => 'UTF8',
    ],
    'username' => 'root',
    'password' => 'root',
    'options' => [
      PDO::ATTR_PERSISTENT => true
    ],
  ],
];

Далее реализуем layout, создав шаблон _layout/default.html, который будет применяться ко всем страницам сайта:


<!DOCTYPE html>
<html>
    <head>
        <title><?= i18n($title) ?></title>
        <meta charset="utf-8" />
        <link href="/_css/style.css" rel="stylesheet">
    </head>
    <body>
        <?= $content ?>
    </body>
</html>

Пришло время создать главную страницу сайта, для этого запишем в файл index.php следующее:


<?php include('sp.php') ?>
<h1>Hello world</h1>
<p>
  Моя главная страница
<p>
<ul>
    <li>
        <a href="/articles">Статьи</a>
    </li>
</ul>

Далее создадим страницу со списком статей (предполагается, что таблицы для этого модуля уже созданы в БД), для этого запишем в файл articles/index.php следующий код:


<?php
$start = isset($_GET['start'])? (int) $_GET['start'] : 0;
$offset = isset($_GET['offset'])? (int) $_GET['offset'] : 2;

$sp = [
  'layout' => [
    'title' => 'Articles',
  ],
  'pdo' => [
    'queries' => [
      'articles' => [
        'SELECT * FROM article LIMIT :start, :offset',
        'params' => [
          'start' => $start,
          'offset' => $offset,
        ],
      ],
      'articlesCount' => [
        'SELECT COUNT(*) FROM article',
      ],
    ],
  ],
];
include('../sp.php');
$articlesCount = $articlesCount->fetchColumn();
?>
<h1>Статьи</h1>
<p>
  <ul>
      <?php foreach($articles as $article): ?>
          <li>
              <a href="/articles/view?id=<?= $article->id ?>">
                  <?= $article->title ?>
              </a>
          </li>
      <?php endforeach; ?>
  </ul>
  <ul>
      <li>
          Всего <?= i18n_plural($articlesCount, '%d article') ?>
      </li>
      <li>
        <a href="/articles/create"><?= i18n('create') ?></a>
      </li>
      <li>
        <a href="/articles?start=<?= $start - $offset ?>"><?= i18n('prev') ?></a>
      </li>
      <li>
        <a href="/articles?start=<?= $start + $offset?>"><?= i18n('next') ?></a>
      </li>
  </ul>
</p>

Как можно заметить, в шаблоне страницы используется интернационализация. Следовательно необходимо создать файл articles/_locale/ru_RU.php для ее корректной работы:


<?php
return [
  '' => [
    'plural_forms' => function($n){
      if($n % 10 == 1 && $n % 100 != 11){
        return 0;
      }
      elseif($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20)){
        return 1;
      }
      else{
        return 2;
      }
    },
  ],
  '%d article' => [
    '%d статья',
    '%d статьи',
    '%d статей',
  ],
  'Articles' => 'Статьи',
  'create' => 'создать',
  'prev' => 'назад',
  'next' => 'вперед',
];

На последок рассмотрим экшен создания новой статьи в блоге, для этого создадим файл articles/create.php:


<?php
if($_SERVER['REQUEST_METHOD'] != 'POST'){
  http_response_code(404);
  exit;
}

$sp = [
  'pdo' => [
    'queries' => [
      [
        'INSERT INTO article (title, content) VALUES (:title, :content)',
        'params' => [
          'title' => $_POST['title'],
          'content' => $_POST['content'],
        ],
      ],
    ],
  ],
];

include('../sp.php');
header('Location: /articles/view?id=' . pdo_build($sp['pdo'])->lastInsertId(), 302);
Поделиться с друзьями
-->

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


  1. ErickSkrauch
    04.05.2017 14:25
    +6

    image




    А если серьёзно, то больше всего порадовало наличие в проекте composer.json. То есть автор как бы в курсе, что это такое, но при этом реализации i18n, autoloader, acl, взаимодействия с бд и всех остальных фишек, описанных в самой статье сделана вручную, при чём далеко не самым лучшим образом.


    Стоит ещё отдельно спросить про то, зачем, собственно, там autoloader, если в проекте вообще нет ООП?


    1. Delphinum
      04.05.2017 14:31
      +2

      но при этом реализация i18n, autoloader, acl и вот всех остальных фишек, описанных в самой статье сделана вручную

      Целью проекта был минимализм. О каком минимализме может быть речь, если для установки фреймворка потребуется тянуть зависимостей весом в десяток раз больше, чем сам фреймворк? ) Другими словами, плагины, идущие в комплекте с фреймворком это минималистичные решения для распространенных инфраструктурных задач. Если же вы задумываетесь о подключении какого нить Zend-i18n, то я бы посоветовал еще раз подумать об использовании другого фреймворка.

      Стоит ещё отдельно спросить про то, зачем, собственно, там autoloader, если в проекте вообще нет ООП?

      Во фреймворке нет ООП, но это не значит, что вы не можете его использовать в своих модулях, ведь так? Варианта два:
      • Либо используйте composer autoload generator, и тогда просто поключайте vendor/autoload.php в качестве плагина
      • Либо, если не хотите composer, но хотите использовать ООП (собственные классы для каких либо целей), используете этот плагин


      1. ErickSkrauch
        04.05.2017 14:37
        +1

        Возьмём тот же i18n. Как поведёт себя ваш фреймворк, если в строке будет 2 переменные с плюральной формой? Что делать, если нужно вставить подстроку вроде "Привет {username}"?


        1. Delphinum
          04.05.2017 14:39

          Как поведёт себя ваш фреймворк, если в строке будет 2 переменные с плюральной формой?

          Можно примерчик такой строки?

          Что делать, если нужно вставить подстроку вроде «Привет {username}»?

          Скорее всего решение будет будет каким то таким:
          <?= i18n('hello') ?> <?= $currentUser->name ?>
          


          Поймите, фреймворк минималистичен, но если вас не устраивают встроенные плагины, то подключить сторонние библиотеки не составит вообще никакого труда. Если вам интересно, могу привести пример генерации страниц сайта через markdown с использованием стороннего пакета.


          1. ErickSkrauch
            04.05.2017 14:43

            Можно примерчик такой строки?

            У вас {n} друзей и {n} подписчиков.


            Скорее всего решение будет будет каким то таким:
            <?= i18n('hello') ?> <?= $currentUser->name ?>

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


            en: {username} profile
            uk: Профіль {username}
            vi: H? so c?a {username}
            be: Профіль {username}
            pt: {username} perfil
            ru: Профиль {username}


            1. Delphinum
              04.05.2017 14:50

              У вас {n} друзей и {n} подписчиков.

              У вас <?= i18n_plural($n, '%d friends') ?> и <?= i18n_plural($n, '%d subscribers') ?>
              

              Ожидаемо. Но если рассмотреть чуть более сложный кейс

              <?= sprintf(i18n('profile %s'), $currentUser->name) ?>
              


              Вообще это не про данный фреймворк, а скорее про интернационализацию в целом.


              1. ErickSkrauch
                04.05.2017 14:56

                Я просто тонко подвожу к той мысли, что подобные проекты скорее всего эффективно могут быть использованы только их авторами. Публикация подобных проектов на хабре как-то возвращает в давние года развития PHP и мешает поверить людям в то, что на PHP уже давно можно писать гораздо более серьёзные проекты.


                1. Delphinum
                  04.05.2017 14:59

                  На хабре любят тонко подводить к определенным мыслям, бегло читая то что над катом. Зная это я сразу добавил статью в соответствующий хаб ;)

                  на PHP уже давно можно писать гораздо более серьёзные проекты

                  Вы зря беспокоитесь о репутации PHP.


                  1. ErickSkrauch
                    04.05.2017 15:28

                    Зная это я сразу добавил статью в соответствующий хаб ;)

                    Я сейчас напишу какую-то дичь, а потом буду орать "it's a prank, man, it's a prank!".


                    1. Delphinum
                      04.05.2017 15:29

                      а потом буду орать

                      Не потом, а сразу. В «ненормальном программировании» статья была с момента публикации.


                      1. ErickSkrauch
                        04.05.2017 15:31

                        Не, я про то, что, как мне казалось, в тег "Ненормальное программирование" попадают частично юмористические статьи, либо же статьи с крайне "альтернативным" подходом к решению банальных задач. Ваша же задача была решена уже несколько сотен раз, в том числе и на хабре и прикрываться хабом ненормального программирования как-то… неправильно.


                        1. Delphinum
                          04.05.2017 15:34

                          статьи с крайне «альтернативным» подходом к решению банальных задач

                          Этот фреймворк примерно из этой категории. Понимаете, сегодня в среде программистов такие настроения: «global в коде? Сжечь его!» — учитывая такую реакцию, я сразу огородился от такого рода критики соответствующим хабом )


                          1. ErickSkrauch
                            04.05.2017 15:37

                            Понимаете, сегодня в среде программистов такие настроения: «global в коде? Сжечь его!»

                            Возможно (но это не точно), это связано с тем, что люди уже поняли, как легко и быстро писать на PHP плохой код и жаждят зрелищ в лице качественных и интересных решений, а не очередного решения со всё теми же "хорошо горящими" решениями, вроде использование глобальных переменных, прямого чтения из $_GET, явных include, отсутствия тестов или хотя бы шансов на них и так далее.


                            1. Delphinum
                              04.05.2017 15:40
                              -1

                              Жаждущим людям советую приглядеться к таким решениям, как Symphony и Zend. Новичкам же, и людям, желающим побыстрому набросать простой сайт — SimplePage вполне себе вариант.

                              Да, вы легко можете выстрелить себе в ногу с его помощью, потому либо учтите это, либо будьте достаточно опытным чтобы этого не сделать.


      1. redfs
        04.05.2017 18:24

        Если же вы задумываетесь о подключении какого нить Zend-i18n, то я бы посоветовал еще раз подумать об использовании другого фреймворка.
        А чем вам gettext не угодил? Вы же написали свой велосипед, пусть и минималистичный, а ведь можно было его вообще не писать, взяв готовое решение «из коробки».


        1. Delphinum
          04.05.2017 18:30

          Мне не нравится gettexte своим синтаксисом. Да, многие к нему привыкли, но мне он кажется излишне сложным (компиляция и все такое) для минималистичного фреймворка. Конечно никто не запрещает заменить им предложенный плагин.


          1. redfs
            04.05.2017 19:07

            На самом деле проще пареной репы. Даю наводку — poedit. И изменения в проекте ищет, и .po => .mo и еще много чего.


            1. Delphinum
              04.05.2017 19:08

              Да, poedit крутая штука, но минимализм же )


      1. franzose
        05.05.2017 01:07

        Только недавно была статья про очередной фреймворк...


        1. Delphinum
          05.05.2017 01:11

          Но явно не было статьи про такой хороший фреймворк, как этот, ведь правда?


          1. franzose
            05.05.2017 01:36

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


            1. Symfony — хорошо
            2. Laravel — неплохо
            3. Yii — с пивом покатит
            4. … — что это было?


            1. Delphinum
              05.05.2017 01:37

              А где в этом списке Zend?


              1. franzose
                05.05.2017 01:48

                Я не писал на нём.


                1. Delphinum
                  05.05.2017 01:50

                  Ну вы и на моем фреймворке не писали, но вывод ведь какой то сделали, что вам мешает сделать вывод и о Zend?


                  1. franzose
                    05.05.2017 01:51

                    Я сделал вывод, что писать на обоих не буду. Для совсем простых сайтов есть WordPress, для чего-то сложного — Symfony или Laravel.


                    1. Delphinum
                      05.05.2017 01:55

                      Так WordPress это CMS, а не фреймворк


                      1. franzose
                        05.05.2017 01:59

                        Я в курсе)


                        1. Delphinum
                          05.05.2017 12:42

                          А что если сайт совсем простой, но выходит за рамки возможностей конкретной CMS?


                          1. wendel
                            05.05.2017 18:03
                            +1

                            Тогда возьмите микрофреймворк! Silex/Slim/Lumen/Expressive/Aura. Да, будет несколько зависимостей, но если вы хотите без зависимостей пишите на голом PHP. Сложно ваше творение назвать фреймворком, не более чем набор хелперов, имхо.


                            1. Delphinum
                              05.05.2017 18:05
                              -1

                              Так я и предлагаю чистый PHP. И про хелперы вы правильно сказали, SimplePage оно и есть. Вы прям сразу в корень зрите )

                              Ну можно назвать его хеплером, если для названия «фреймворка» нужные какие то особые критерии.


              1. maxru
                05.05.2017 13:29

                Zend всё ещё обрабатывает запрос, подождите.


    1. http2
      04.05.2017 15:21

      зачем, autoloader, если в проекте нет ООП

      А должно быть ООП головного мозга? :)


      1. ErickSkrauch
        04.05.2017 15:23

        Composer, присутствующий в проекте, прекрасно умеет работать со стандартами PSR-0 и PSR-4, а так же со статическими include, если уж так хочется. Зачем изобретать свой велосипед (куда менее гибкий), если в Composer уже давным давно это всё написано и имеются средства для оптимизации в production?


        1. Delphinum
          04.05.2017 15:25

          Composer (который присутствует в этом проекте)

          Просто возьмите, и используйте Composer, если вам этого хочется. Никаких ограничений, кроите проект как вам удобно, все в ваших руках!


  1. Delphinum
    04.05.2017 14:46

    del


  1. oxidmod
    04.05.2017 15:17
    +2

    Каждый раз, когда вы используете глобалы, инклуды и читаете прямо с гета гдето в мире грустит котенок…


    1. maxru
      04.05.2017 15:20
      +2

      <sarcasm>Потому что PSR-7 - это не минималистично</sarcasm>


    1. Delphinum
      04.05.2017 15:23

      Если вас очень беспокоит психологическое состояние котят, рекомендую задуматься об Zend-Expressive в качестве средства для быстрого прототипирования (и не только).


  1. lnroma
    04.05.2017 16:16
    -3

    Возьмём тот же i18n. Как поведёт себя ваш фреймворк, если в строке будет 2 переменные с плюральной формой?


    как можно спорить с человеком который в одной строке написал два одинаковых по смыслу слова? для особо не понятливых «плюральной» = «2 переменные». Не используйте непонятные слова глупо выглядит. А так фреймворк по минимуму решает задачу «получение — отображения данных» значит имеет смысл быть. А писать 10 классов, с использованием патернов программирования для hello world! как минимум глупо.


  1. vlreshet
    04.05.2017 17:21
    +2

    А чем кроме наличия композера данный фреймворк отличается от классического говнокодного стиля 200х годов, за который все так ненавидят PHP?


    1. Delphinum
      04.05.2017 17:23
      -1

      Архитектурой


      1. vlreshet
        04.05.2017 18:58

        Архитектурой тут и не пахнет. Наляпать «лишь бы работало», и назвать это архитектурой…


        1. Delphinum
          04.05.2017 19:03

          Почему вы так считаете? Во фреймворке заложена рекомендованная архитектура. Сводится она к декларативной конфигурации страницы, последующей обработки деклараций, выполнения дополнительной логики и шаблонизации.


          1. vlreshet
            04.05.2017 19:47

            Потому что это можно назвать архитектурой лишь формально. Точно так же как деревенский сарай формально имеет какую-то архитектуру. Вот так и тут — оно построено чтобы работало, а уже потом названо архитектурой, тут нет каких-то осознанных решений, шаблонов проектирования, структуры. Каждая «часть архитектуры» может быть заменена в другом виде и ничего от этого не изменится. Потому что массив с ключами «pdo», «layouts», «plugins» — это не архитектура, это просто «а хранить всё будем в одном массиве, чтобы доступ легче был». Да и вообще — какая тут осознанная структура если есть код типа

            include('../sp.php');
            
            ? Архитектура в которой даже нет корневой папки, и нужно хардкодить все пути инклудов? Создал папку в папке — и пиши потом «include('../.../ тааак… а мы на втором уровне… ага, не, на третьем, надо трижды вернуться ../../../». Замечательно.


            1. Delphinum
              04.05.2017 19:50

              Мне кажется вы путаете понятие архитектуры с понятием «модная архитектура», а include('../sp.php') просто немного залил вам граза кровью ) Во фреймворке есть архитектура и я ее описал в предыдущем комменте


              1. vlreshet
                05.05.2017 09:12
                +1

                Можно написать криворукое поделие (ну типа такого как в посте), а потом детально описать его архитектуру. Мол «вьюшки складываем вот под этот вот костыль, а с базой работаем на этом велосипеде». Формально — это будет архитектура. А по факту — это просто структура проекта. Потому что архитектура должна решать какие-то проблемы проектирования, задавать стандарты, отвечать на вопросы. Архитектура — это не просто расположение разных файлов и название ключей массива. Массив с ключами и указание что куда ложить — это не архитектура.

                А вообще вы не воспринимаете обоснованную критику. Закончим дискуссию, это бесполезно.


                1. Delphinum
                  05.05.2017 12:44

                  Я вам указал на архитектуру проекта, а вы мне говорите, что это структура и не сумев аргументировать свое мнение, пытаетесь съехать на том, что я не воспринимаю «обоснованную» критику )) На хабре от года к году все веселее и веселее )


                  1. sspat
                    05.05.2017 14:03
                    +3

                    А вы сможете изобразить архитектуру вашего проекта в виде диаграммы? Хотя бы flow обработки request-response? Мне кажется на диаграмме будет один блок примерно похожий на это:
                    image


                    1. Delphinum
                      05.05.2017 14:11

                      Я привык к диаграммам последовательности, потому, если вы не против, изображу на ней:
                      image


                      1. vlreshet
                        05.05.2017 14:27

                        Следовательно этой диаграмме запрос (request) прилетает прямиком во вьюв (зачем отображению запрос? что ему с ним делать? О_о), потом есть какой-то компонент SP который детально описывает что он мержит 2 конфига (ах как сложно), зато всю обработку реквеста лаконично описывает одной стрелочкой run (run чего? бегун завёлся в коде?). Потом в роботу вступает какой-то плагин (какой?), который, если я правильно понимаю, данные никуда не отдаёт. Честно говоря, диаграмма у вас так себе.


                        1. Delphinum
                          05.05.2017 14:31
                          +1

                          прилетает прямиком во вьюв

                          Не во вью, а в «контроллер страницы» (есть такой паттерн по Фаулеру), который декларирует начальные условия обработки.
                          потом есть какой-то компонент SP

                          Это сам фреймворк.
                          который детально описывает что он мержит 2 конфига (ах как сложно)

                          Вы любите, чтоб все было сложно? )) На деле он расширяет декларацию страницы общей декларацией приложения.
                          зато всю обработку реквеста лаконично описывает одной стрелочкой run (run чего? бегун завёлся в коде?)

                          А он больше ничего и не делает по сути, собирает декларацию, передает управление плагинам (если необходимо) и буферизирует вывод.
                          Потом в роботу вступает какой-то плагин (какой?)

                          Это уже решает контроллер страницы, а не фреймворк.
                          данные никуда не отдаёт

                          Верно, данные не отдаются, плагины работают через декларации. Фреймворк то декларативный.
                          Честно говоря, диаграмма у вас так себе

                          Зато столько вопросов сразу решает ) Вы еще забыли про стрелочку postRun, она очень важна.


                          1. vlreshet
                            05.05.2017 14:56
                            -1

                            Не во вью, а в «контроллер страницы»
                            Извините, но я чётко вижу элемент с названием «ActionView». Почему контроллер называется вьювом?

                            Это сам фреймворк.
                            Куда именно он принимает запрос? Прям в ядро, в специальный обработчик, или как? Если это файлик на пару функций, который по факту мержит два конфига да запускает буферизацию — это скорее библиотека чем фреймворк. И почему вопросами отображения (буферизация вывода) занимается фреймворк на начальном этапе, а не вьюшка перед моментом своего рендера?

                            Это уже решает контроллер страницы, а не фреймворк.
                            Почему контроллер дёргает какой-то плагин? Это уже роутер получается, а не контроллер.

                            Присоединяюсь к sspat по поводу почтения за UML, но диаграмма не выдерживает критики.


                            1. Delphinum
                              05.05.2017 15:01
                              +1

                              Вообще контроллер не имеет имени, там просто файл вида articles/view/index.php, я в диаграмме его так назвал, чтоб возможно было отличить контроллер страницы (который в том числе содержит View), от остальных частей системы.

                              Нет, запрос принимает и обрабатывает контроллер страницы, не фреймворк. Вообще я не люблю термин «фреймворк», но зачем то его использую. Я считаю что это не просто библиотека, так как он имеет архитектуру. Другими словами в моем понимании фреймворк = библиотека + архитектура.

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

                              Нет, контроллер не дергает плагин, контроллер декларирует фреймворку, какие плагины ему нужны для обработки запроса. К примеру у вас есть страница «О проекте», там не нужен плагин для работы с БД, потому контроллер не запрашивает подключение этого плагина, а вот контроллер страницы «Статья» уже запрашивает, так как ему нужно обратиться к базе данных.


                      1. sspat
                        05.05.2017 14:36

                        Обратите внимание, что на вашей диаграмме названия ролей это названия файлов которые вы инклюдите а не каких-то обособленных структур в коде, вроде классов или функций. Включение процедурного кода через include контекст не меняет и ответственность не делегирует, все что у вас там внутри происходит все равно тесно связано в один неделимый клубок. Невозможно изменить что-то в одной части системы не повредив другую — зависимость полная, причем зависимость на названия ключей массивов обьявленных в каком-то там из файлов. У вас по сути процедурный Page Controller распиханный на несколько файлов чтобы хоть как-то побороть копипасту, вот и вся архитектура.

                        А за владение UML позвольте выразить свое почтение.


                        1. Delphinum
                          05.05.2017 14:42

                          Вы совершенно правы, во фреймворке нет «единой точки входа», все как в бородатые 2000е, каждый файл — контроллер.

                          Если говорить о контексте и разделении ответственности, то очень коротко можно сказать так — за обработку запроса и возврат ответа отвечает конкретная страница, фреймворк же просто предоставляет вспомогательные инструменты для этого. Это не классический MVC и даже не ООП с разделением ответственности и вызовами, это один процедурный код, отвечающий за обработку запроса через декларации.

                          По поводу гибкости системы, я пошел по пути минимализма не случайно. Идея в том, чтобы фреймворк был настолько простым, чтобы не требовать изменений в своей архитектуре или интерфейсах вовсе. Да и он нацелен на прототипирование, о какой изменчивости вы говорите? )


                          1. sspat
                            05.05.2017 14:52

                            Мне понятна идея и цели которые вы преследовали, но непонятна реализация. Не понятно, почему явно более выигрышному в такой задаче обьектному подходу вы предпочли процедурный, причем в его наименее удобном воплощении, тем более, что с ооп у вас судя по всему все в порядке. Было бы все то же самое на обьектах, завязано на интерфейсы и декларативно собиралось через обьект-конфигуратор с fluent interface как бы все красиво и удобно было.


                            1. Delphinum
                              05.05.2017 14:53

                              Есть уже Slim и Zend-Expressive для этих целей, а ЦА у меня частично не умеет ООП.


                              1. sspat
                                05.05.2017 15:02

                                Навыки ООП тут от клиента и не требуются, начейнить вызовов методов конфигуратора даже проще, чем с мануалом наперевес городить многомерный массив, который развалится как карточный домик при любой ошибке во вложенности. Как плюс — вы дадите своей целевой аудитории верное направление для развития, когда они захотят сделать что-то нестадартное и начнут разбирать как там все устроено. А так вы их сразу загоняете в яму, а потом удивляемся, почему у PHP такая репутация.


                                1. Delphinum
                                  05.05.2017 15:06

                                  Начну с конца )

                                  Не беспокойтесь о репутации PHP.

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

                                  В качестве верного направления для развития ЦА я ссылаюсь на Zend и Symphony, и другие мои поделки, это же прикладной, а не учебный проект.


                                  1. sspat
                                    05.05.2017 15:18

                                    Не беспокойтесь о репутации PHP.

                                    Я в данном случае беспокоюсь о себе и своем психическом здоровье через несколько лет, когда начну сталкиваться с кадрами взрощенными на фоне повышенного в данный момент интереса к профессии. Не хочу опять флешбеков из начала 2000-х.


                                    1. Delphinum
                                      05.05.2017 15:19

                                      Если вы столкнетесь с кадром, который использует этот фреймворк в качестве средства прототипирования и понимает, для каких задач следует применять его, а для каких Zend или Drupal, радуйтесь, а не печальтесь )


  1. sspat
    04.05.2017 23:41
    +2

    Такой Array Oriented Programming даже разработчкиам Yii в кошмарном сне не снился :)
    Работать с таким API, где нужно постоянно вспоминать нужные названия ключей массивов — жуткая боль.
    Не понимаю, что мешает весь тот же функционал оформить в виде простых обьектов — и копипаста снизится и хотя бы какой-то толк появится от подсказок IDE. Тот же декларативный подход в сборке страницы можно сохранить применив Fluent Interface.


    1. Delphinum
      04.05.2017 23:47
      -1

      Вспоминать не нужно, обычно оно отпечатывается в памяти через пару часов использования, но если работать с кодом без подсказок IDE не представляется возможным, то конечно лучше смотреть в сторону чего то более объектно-ориентированного, ну либо запилить плагин под IDE (если не страшно)


  1. sspat
    05.05.2017 00:12

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

    «Очень низкий порог входа» — только кажется. Фреймворк не интуитивный совершенно, самодокументация кода исходников — нулевая.

    «Очень прост в установке» — не проще чем composer require.

    «Отсутствие зависимостей» — а в чем тут собственно преимущество? Даже когда вы пишете на голом PHP, под ним более низкоуровневых зависимостей столько, что пытаться что-то экономить не используя composer в 2017-м году выглядит глупо, вы все равно будете зависеть от сотен других программных продуктов. Это не более чем попытка оправдания велосипедостроения.


    1. Delphinum
      05.05.2017 00:19

      Зачем вам исходники, есть официальная документация, ее и нужно выкурить в первую очередь.

      Composer require требует composer, что явно сложнее, чем его отсутствие )

      То есть чем больше зависимостей, тем лучше?


      1. sspat
        05.05.2017 00:25
        +1

        Зачем вам исходники, есть официальная документация, ее и нужно выкурить в первую очередь.

        Затем, что нажать в IDE на какой-то класс фреймворка и посмотреть код зачастую намного быстрее, чем открывать браузер, заходить на сайт, искать там нужный раздел документации по определнному классу и т.д. Хороший код не требует документации вообще.

        То есть чем больше зависимостей, тем лучше?

        Чем больше задач можно решить быстрее и надежнее использовав уже готовый, протестированный продукт — тем выгоднее и эффективнее разработка. Если мы конечно не рассматриваем случаи когда главный мотиватор это «потому что я могу». При грамотном подходе и зависимости на интерфейсы вы фактически даже не будете зависеть от этих сторонних библиотек. Сломалось что-то — заменили своей реализацией или встроили другую библиотеку через адаптер — нет проблем.


        1. Delphinum
          05.05.2017 00:29

          Вы сильно зависите от IDE )) Ну это ваше право, конечно.

          Я не претендую на хорошесть кода, я претендую на простоту в установке и использовании.

          Вы понимаете что тут речь идет о прототипировании, а не о полноценной разработке? )


          1. sspat
            05.05.2017 00:36

            Вы сильно зависите от IDE )) Ну это ваше право, конечно.

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

            Вы понимаете что тут речь идет о прототипировании, а не о полноценной разработке? )

            Только проблема в том, что прототип потом придется полностью выкинуть, т.к. полноценная разработка на его основе невозможна. Я бы такое не купил.


            1. Delphinum
              05.05.2017 00:38

              Нет, достаточно начать использования инструмента с его изучения, а не тыканья в него палкой в надежде, что оно само заработает )

              Эмм… Ну обычно прототип полностью и выкидывают, на то он и прототип, а не готовый продукт. Да и я его не продаю.


              1. maxru
                05.05.2017 13:33

                Да и я его не продаю.

                А были планы?


                1. Delphinum
                  05.05.2017 13:34
                  +1

                  Продавать чистый PHP с вкраплениями фассадов? Я разве похож на MS?


  1. kruslan
    05.05.2017 00:33

    ох ты-ж… давно не видел такой жести… года с 2002-го… даже вот это выглядит куда лучше ;)


    1. Delphinum
      05.05.2017 00:34

      Мое решение проще )


      1. maxru
        05.05.2017 13:32

        Нахерачить код вперемешку с вёрсткой вообще без include ещё проще.


        1. Delphinum
          05.05.2017 13:34

          Тогда не будет архитектуры и сложнее будет работать с кодом


          1. maxru
            05.05.2017 14:07

            Так называемой "архитектуры".


            1. Delphinum
              05.05.2017 14:12

              Точнее будет: не модной «архитектуры» — но вполне себе архитектуры. Современные программисты очень бояться отходить от модного и молодежного, называя все остальное велосипедом )


          1. vlreshet
            05.05.2017 14:21

            Как это не будет архитектуры? Если следовать вашим же примерам, то архитектура будет полагаться в том что php код следует размещать в средине файла, конфиг — вверху файла, html-вверху и снизу. Отличие от вашего кода будет только в том что у вас код тянется инклудами, а там он будет уже сразу на месте. И докажите чем это будет не архитектура, у вас — архитектура? В чём будет принципиальная разница?


            1. Delphinum
              05.05.2017 14:22

              Поправлю себя — тогда это будет более сложная и запутанная архитектура


              1. kruslan
                05.05.2017 14:35

                Вообще — нет, «архитектура» будет намного проще, т.к. нет вообще никаких зависимостей.
                Раз уж используете внешние файлы и composer — избавьтесь от include, это-же элементарно…


                1. Delphinum
                  05.05.2017 14:37

                  Архитектура будет слабо прослеживаться, от того будет сложнее.

                  Я не использую composer, наличие файла composer.json не говорит о том, что он используется. Если вы посмотрите внимательнее, то заметите, что применить автозагрузку классов там не к чему.


                  1. kruslan
                    05.05.2017 23:43

                    Так может стоит использовать?) А в автозагрузку не только классы можно добавлять ;)


                    1. Delphinum
                      06.05.2017 00:39

                      повторю в 16 раз — цель проекта «минимализм». Composer это не из этой оперы


                      1. kruslan
                        07.05.2017 15:47
                        +1

                        минимализм?)) нуу, ок… странное у вас понятие термина «минимализм», если честно.


  1. SbWereWolf
    06.05.2017 06:48
    +1

    Мне вот тоже не понятно почему автор отказался от ООП. Подсказки IDE экономят память, которую лучше загрузить бизнес логикой.
    В остальном для прототопирования сгодиться что угодно. Это же фреймворк не для разработки, а чисто что бы накидать на коленке.
    Но тоже не понятно, что эти байты экономить, когда для накидать на коленке годиться тот же Slim, весит он пол мегабайта, у него есть тот же самый PhpRenderer, если очень хочется использовать родную шаблонизацию PHP.

    Композер это толсто? Композер это 30 килобайт.
    вам же эти 30 кб не руками набивать. не грузить в какой то микроконтроллер что бы каждый байт считать, зачем такой ультра минимализм? что бы попасть в книгу рекордов Гиннесса?

    Почему «хорошо» — это использовать общепринятые инструменты типа Композера и Slim?
    Что бы посторонним было проще разобраться в коде вашего проекта или ваши наработок (прототипов).

    но если хочется повелосипедить, то чем бы дитя не тешилось :)


    1. Delphinum
      06.05.2017 12:19

      Мне вот тоже не понятно почему автор отказался от ООП

      для накидать на коленке годиться тот же Slim

      Вот вы сами и отвечаете на свой вопрос.