Уже можно использовать две новые библиотеки из будущей PHPixie 3

    PHPixie framework
    Пока еще только ведутся работы над третьей версией фреймворка PHPixie, но уже можно точно сказать что он сильно изменится в лучшую (как по мне) сторону:

    • Полный переход на стандарт PSR-2
    • Поскольку фреймворк будет являть собой набор библиотек, то его компоненты можно будет использовать в любом проекте без самого PHPixie.
    • 100% покрытия кода тестами. При чем в данном случае 100% не просто фигуральное слово а реально просчитанный «code coverage», то есть отношение строк которые вызываются при исполнении тестов ко всем строкам кода, кстати у Laravel это всего-лишь 53%.


    Вчера стали доступны две библиотеки которые войдут в PHPixie 3, они полностью готовы и их уже можно использовать с любым проектом. Это сделано Подробнее об этом можно почитать в посте на сайте, а я здесь опишу то что мне больше всего в них нравится.



    Кстати библиотеки таки действительно покрыты тестами на 100%, убедится можно тут и тут.

    PHPixie Config



    Отрезки конфигурации (Config Slices)

    Позволяют отделить опции для частей системы от самой системы, тем самым делая их более агностическими и независимыми. Для примера, рассмотрим такие настройки уровня какой-то игры в какой игрок пробует захватить замок:
    array(
        'battlefield' => array(
            'background' => 'forest',
            'castle' => array(
                'turrets' => array(
                    'amount' => 5
                )
            )
        ),
        'attackers' => array(
            'knight' => array(
                'attack' => 6
            ),
            'paladin' => array(
                'attack' => 4,
                'spell'  => 'heal'
            )
        )
    );
    


    Мы уже привыкли использовать '.' для чтения таких массивов, например используя $config->get('battlefield.castle.turrets.amount'), но использовать такой код в классе Castle было бы некорректно, так как ему надо тогда знать весь путь к тому месту где начинается его конфигурация. Можно конечно в родительском классе передавать все turrets_amount прямо в конструктор, но есть лучший путь:

    class Level {
        public function __construct($slice){
            $this->battlefield = new Battlefield($config->slice('battlefield');
        }
    }
    
    class Battlefield {
        public function __construct($slice){
            $this->background = new Background($config->get('background'));
            $this->castle = new Castle($config->slice('castle'));
        }
    }
    
    class Castle {
        public function __construct($slice){
            $this->background = new Background($config->get('turrets.amount'));
        }
    }
    $level = new Level($config);
    


    Как видите все классы теперь полностью независимы от самого пути конфигурации, как раз для этого и придуман slice().

    Разбиение конфигурации на папки

    Возможность создавать отдельные файлы для частей конфигурации позволяет например легко коммитить только настройки самого приложение и включить в .gitignore файл с конфигурацией чего-то специфического ( например конекта к базе данных). Также как написано на сайте PHPixie позволяет на своей базе легко создать файлы с переводом текста на сайте на разные языки. Для примера возьмем такую структуру файлов:
    config.php
    config/
    +-forest.php
      +-forest/
          +-meadow/
               +-fairy.php
    


    Теперь если мы будем искать опцию forest.meadow.fairy.name, поиск будет идти в таких местах:

    1) 'name' в config/forest/meadow/fairy.php
    2) 'fairy.name' в config/forest/meadow.php
    3) 'meadow.forest.name' в config/forest.php
    4) 'forest.meadow.forest.name' в config.php

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

    PHPixie Database


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

    Condition Placeholders

    Всем нам знакомы разные строители запросов (query builders), которые позволяют добавлять условия вот так:
    $query
        ->where('type', 'elf')
        ->orWhere(function($q){
             $q
                 ->_and('name', 'Trixie')
                 ->_and('type', 'fairy')
        });
    
    // WHERE type = 'elf' OR (name = 'Trixie' and type = 'fairy')
    

    Здесь ничего нового нет, но у них есть маленькая проблема: что делать если потом понадобится в тот OR ( ) добавить еще одно условие, уже в другом месте/классе? В PHPixie можно создать контрольную точку в которую потом добавлять условия, например:
    $placeholder = null;
    $query
        ->where('type', 'elf')
        ->orWhere(function($q){
             $q
                 ->_and('name', 'Trixie')
                 ->_and('type', 'fairy');
             $placeholder = $q->addPlaceholder('and');
        });
    
    $placeholder->_and('status', 'active');
    
    // WHERE type = 'elf' OR (name = 'Trixie' and type = 'fairy' and status='active')
    


    Для построение сложных запросов использование таких точек очень полезно.

    Упрощенное добавление условий


    Поскольку для SQL запросов кроме WHERE условий можно добавлять еще и HAVING и ON условия, то для каждого из них есть свой набор методов: orWhereNot, xorHaving… итд. Чтобы ускорить написание условий можно использовать сокращенные версии, которые будут добавлять условия последнего добавленного типа:
    //Вместо
    $query
        ->where('type', 'elf')
        ->orWhere('id', 5)
        ->having('count', 5)
        ->xorHaving('max', 6);
    
    //Можно
    $query
        ->where('type', 'elf')
        ->_or('id', 5)
    
        ->having('count', 5)
        ->_xor('max', 6);
    


    Поддержка вложенных $or для MongoDB


    Известный баг что MongoDB не будет использовать индексы если вы напишете слишком сложный запрос используя вложенные $or. PHPixie сама исправит это для вас превратив такие запросы в развернутую форму, которая уже будет использовать индексы. Все это работает из коробки.

    Особенные операторы для сравнения

    Часто приходится сравнивать одну колонку с другой, проблема в том что если написать вот так:
    $query
        ->where('amount','>', 'minAmount');
    


    то на самом деле значение колонки amount будет сравниваться со стрингом «minAmount», для того чтобы указать что значение есть названием колонки в базе надо просто приставить звездочку к оператору:
    $query
        ->where('amount','>*', 'minAmount');
    


    Просто, понятно и лаконично.

    Если вам интересно...

    Чтобы увидеть как это все работает в действии вот тут приведен пример кода который работает с MongoDB и MySQL а также показывает как это все настроить без самого фреймворка всего в несколько строк кода.

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 3

      0
      Без примеров использования (а их нет ни в исходниках, ни в статье на сайте, ни у вас) все прелести класса не столь очевидны. А ведь класс конфига очень даже не плох (особенно DirStorage). Вроде много слов, а Гюльчатай так личико и не показала…

      Не понятно куда по-дефолту конфиг будет сохранять «forest.meadow.fairy.name», в вашем примере после persist()

      Я бы добавил 10-12 строк с кодом для снижения порога входа.
        +1
        По дефолту сохраняет в том же порядке: то есть в самой глубокой папке которую сможет найти.
        На сайте был пример, но там больше уклон как раз на класс базы данных а не на конфиг.

        Ну я попробую написать пример как раз для DirectoryStorage:
        Например если у нас есть директория /assets в которой будут наши конфиги лежать вот так:

        assets/ config.php config/ forest.php forest/ meadow.php

        $pixieConfig = new \PHPixie\Config;
        $config = $pixieConfig->directoryStorage('/assets/', 'config', 'php');
        /*
           /assets/ - директория контейнер
           'config' - названия корневого файла/поддиректории
           'php' - дефолтный формат файлов которые создавать, пока есть только php
        */
        


        Теперь представим что у нас в /assets/config/forest/meadow.php есть:

        return array(
            'fairies' => 5
        );
        


        Мы можем сделать:

        $config->get('forest.meadow.fairies'); //5
        $config->get('forest.meadow.not_existing_property', 6); // 6
        
        $config->set('forest.meadow.pixies' ,7); // запишется в /assets/config/forest/meadow.php (после persist())
        $config->set('forest.flowers' ,3); // запишется в /assets/config/forest.php
        $config->set('sky' ,3); // запишется в /assets/config.php
        $config->set('sky.clouds.birds' ,3); // запишется в /assets/config.php, так как само создавать папки не станет
        $config->persist(); //провести запись
        


        Надеюсь теперь понятнее =)
          0
          Плохо отобразилось дерево директории, должно быть:
          assets/
             config.php
             config/
                forest.php
                forest/
                   meadow.php 
          

      Only users with full accounts can post comments. Log in, please.