Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll

1.4. Приступаем к написанию MVC-фреймворка

08/12/2019, by Ivan

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

Скачать денвер с PHP 5.5.20 вы можете с этой страницы:

https://drupalbook.org/ru/drupal/denwer-obnovlenie-php

или с github'a

https://github.com/levmyshkin/denwer-php-5.5.20

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

MVC

Реализация паттернов

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

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

Теперь создайте файл Registry/registry.class.php. В этом файле мы напишем класс нашего реестра.

<?php
/**
 * Объект реестра
 * Реализует паттерн Реестра и Единичный класс
 *
 */
class Registry {
     
    /**
     * Массив наших объектов
     * @access private
     */
    private static $objects = array();
     
    /**
     * Массив наших настроек
     * @access private
     */
    private static $settings = array();
     
    /**
     * Человекочитаемое название нашего фреймворка
     * @access private
     */
    private static $frameworkName = 'Framework version 0.1';
     
    /**
     * Экземпляр нашего реестра
     * @access private
     */
    private static $instance;
     
    /**
     * Конструктор для нашего реестра
     * @access private
     */
    private function __construct()
    {
     
    }
         
    /**
     * метод единичного класса для доступа к объекту
     * @access public
     * @return
     */
    public static function singleton()
    {
        if( !isset( self::$instance ) )
        {
            $obj = __CLASS__;
            self::$instance = new $obj;
        }
         
        return self::$instance;
    }
     
    /**
     * предотвращение копирования нашего объекта: проблем с E_USER_ERROR если это произошло
     */
    public function __clone()
    {
        trigger_error( 'Cloning the registry is not permitted', E_USER_ERROR );
    }
     
    /**
     * хранит объект в нашем реестре
     * @param String $object the name of the object
     * @param String $key the key for the array
     * @return void
     */
    public function storeObject( $object, $key )
    {
        require_once('objects/' . $object . '.class.php');
        self::$objects[ $key ] = new $object( self::$instance );
    }
     
    /**
     * получение объекта из нашего реестра
     * @param String $key the array key
     * @return object
     */
    public function getObject( $key )
    {
        if( is_object ( self::$objects[ $key ] ) )
        {
            return self::$objects[ $key ];
        }
    }
     
    /**
     * Хранит настройки нашего реестра
     * @param String $data
     * @param String $key the key for the array
     * @return void
     */
    public function storeSetting( $data, $key )
    {
        self::$settings[ $key ] = $data;
 
 
    }
     
    /**
     * Получение настроек нашего реестра
     * @param String $key the key in the array
     * @return void
     */
    public function getSetting( $key )
    {
        return self::$settings[ $key ];
    }
     
    /**
     * Получение имени фреймворка
     * @return String
     */
    public function getFrameworkName()
    {
        return self::$frameworkName;
    }
     
     
}
 
?>

Так как же работает наш Реестр и как он хранит наши объекты?

  • Объекты хранятся в виде массива
  • Когда новый объект добавлен в реестр, файл класса также добавляется, создается экземпляр объекта и добавляется в массив
  • Объект возвращаются с помощью передачи ключа объекта методу getObject

Как предотвращается создание другой копии объекта реестра?

  • Конструктор является private, что позволяет предотвратить создание объектра напрямую
  • Клонирование объекта вызовет ошибку
  • Если вы хотите получить доступ к объекту реестра из нашего Фреймворка, и это невозможно из того файла, который сейчас отрабатывает, вы можете использовать статический метод singleton (Registry::singleton()) для получения экземляра Реестра.

Теперь когда у нас есть Реестр, давайте напишем index.php, чтобы вызывать работу фреймворка и обращаться к Реестру.

Index.php

Index.php -  это стартовая точка работы нашего фреймворка.

Далее мы еще добавим возможность создавать ЧПУ, с помощью файла .htaccess. А пока давайте разберем код index.php:

<?php
/**
 * Framework
 * Framework loader - acts as a single point of access to the Framework
 *
 */
  
// стартуем сессию
session_start();
 
// задаем некоторые константы
// Задаем корень фреймворка, чтобы легко получать его в любом скрипте
define( "APP_PATH", dirname( __FILE__ ) ."/" );
// Мы будем использовать это, чтобы избежать вызов скриптов не из нашего фреймворка
define( "FW", true );
 
/**
 * Магическая функция автозагрузки
 * позволяет вызвать необходимый -controller- когда он нужен
 * @param String the name of the class
 */
function __autoload( $class_name )
{
    require_once('Controllers/' . $class_name . '/' . $class_name . '.php' );
}
 
// подключаем наш реестр
require_once('Registry/registry.class.php');
$registry = Registry::singleton();
 
// выводим имя фреймворка, чтобы проверить, что все работает
print $registry->getFrameworkName();
 
exit();
 
?>

Если все правильно, то должно быть выведено сообщение с именем нашего фреймворка:

Framework version 0.1

 Давайте разберемся как работает наш index.php на данный момент:

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