Рубрики
Uncategorized

Создайте свой собственный фреймворк MVC с помощью PHP

Автор оригинала: David Wong.

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

I. Что такое MVC

Model-View-Controller (MVC) – это модель архитектуры программного обеспечения в программной инженерии. Он делит программную систему на три основные части: модель, представление и контроллер.

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

  • Контроллер – отвечает за пересылку запросов и обработку запросов.

  • (Просмотр) – Дизайнеры интерфейсов разрабатывают графические интерфейсы.

  • (Модель) – Функция, с помощью которой программисты должны писать программы (реализовывать алгоритмы и т.д.), специалисты по базам данных для управления данными и проектирования баз данных (для достижения определенных функций).

Модель: Модель используется для инкапсуляции данных, связанных с бизнес-логикой приложения, и для обработки данных. “Модель” имеет прямой доступ к данным, таким как доступ к базам данных. “Модель” не зависит от “Представления” и “Контроллера”, то есть модели все равно, как она будет отображаться или управляться. Однако изменения в данных в модели, как правило, раскрываются с помощью механизма обновления. Для реализации этого механизма представления, используемые для мониторинга модели, должны быть предварительно зарегистрированы в модели, чтобы представление могло понять изменения, произошедшие в модели данных.

Просмотр: Слой просмотра может отображать данные целенаправленно (теоретически в этом нет необходимости). Обычно в представлении отсутствует программная логика. Чтобы обновить представление, представление должно получить доступ к модели данных, которую оно отслеживает, поэтому оно должно заранее зарегистрироваться с данными, которые оно отслеживает.

Контроллер: Контроллеры играют организационную роль на разных уровнях для управления потоком приложений. Он обрабатывает события и реагирует. События включают изменения в поведении пользователей и моделях данных.

2. Зачем самостоятельно разрабатывать MVC-фреймворк

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

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

Начните разрабатывать свой собственный фреймворк MVC

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

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

Приложение – Хранит конфигурацию программного кода – Конфигурация вкладчика или конфигурация базы данных БД – Используется для хранения библиотеки содержимого резервной копии базы данных – Хранит общедоступный код платформы — Хранит статические файлы сценариев – Хранит инструменты командной строки TMP – Хранит временные данные После настройки каталога давайте вернемся к некоторым спецификациям кода.

Таблицы MySQL должны быть строчными и множественными, например, элементы, имена модулей автомобилей должны быть прописными и единственными, например, Элемент, Контроллеры автомобилей должны быть прописными, множественными и добавлять “Контроллер” к их именам, например, Контроллер элементов, Контроллер автомобилей. Представления принимают форму множественного числа и добавляют действия в виде файлов после них, например элементы/представление. php , cars/buy.php

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

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


RewriteEngine on
RewriteRule    ^$    public/    [L]
RewriteRule    (.*) public/$1    [L]

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


RewriteEngine On
# Direct access to the directory if the file exists without RewriteRule
RewriteCond %{REQUEST_FILENAME} !-f
# Direct access to the directory if it exists without RewriteRule
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule ^(.*)$ index.php?url=$1 [PT,L]

Основными причинами этого являются:

  • Это может сделать программу с одной записью и перенаправить все программы, кроме статических программ, на index. php.

  • Его можно использовать для создания URL-адресов для SEO. Для лучшей настройки URL-адресов маршрутизация URL-адресов может потребоваться позже. Я не буду вводить его здесь.

После выполнения вышеуказанной операции мы должны знать, что нам нужно делать, верно! Добавить в общий каталог index.php Содержание документа выглядит следующим образом:

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

В индексе. php, мы правы библиотека Под папкой bootstrap.php Когда делается запрос, то bootstrap.php Что именно содержит этот файл запуска?

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

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

Следует сказать, что конфигурация. PHP не требует многого, но некоторые базовые настройки данных, давайте рассмотрим общие файлы в разделе библиотека. shared.php Как мне это написать?

 is post, $_POST ['user_name'] and $_POST ['user_pass']) should be used. 
 * When register_globals = On, the next program can accept values directly with $user_name and $user_pass.
 * As the name implies, register_globals means to register as a global variable, so when On, the passed value will be registered directly as a global variable and used directly by Off.
 * Sometimes, we need to go to a specific array to get it. So, friends who encounter the problem of not getting the value above should first check your register_globals settings and
 * Does the way you get the value match?
 *
 * So why do we use Off?
 * There are two reasons: 
 * 1. The new version of PHP will use Off by default. Although you can set it to On, when you can't control the server, the compatibility of your code becomes a big problem, so
 * You'd better start programming in Off style from now on. 2. Here are two articles about why you want Off instead of On 
 */
function unregisterGlobals()
{
    if(ini_get('register_globals'))
    {
         $array = array('_SESSION','_POST','_GET','_COOKIE','_REQUEST','_SERVER','_ENV','_FILES');
           foreach ($array as $value)
           {
                 // GLOBALS prints all global variables
               foreach ($GLOBALS[$value] as $key => $var)
               {
                  if ($var === $GLOBALS[$key])
                  {
                      unset($GLOBALS[$key]);
                  }
               }
           }
    }

}

/**
 * Request method, the main purpose of which is to split URL requests
 *
 * Relevant learning:
 * Call the callback function and take an array parameter as the parameter of the callback function
 * call_user_func_array(array($obj, $method_name), $params);
 * call_user_method_array ( string $method_name , object &$obj , array $params )
 */
function callHook()
{
    global $url;

    $urlArray   = array();
    $urlArray   = explode('/', $url);

    // Get the controller of the controller
    $controller = $urlArray[0];

    // Delete the first element
    array_shift($urlArray);

    // Get action action
    $action = $urlArray[0];

    array_shift($urlArray);

    $queryString = $urlArray;
    $controllerName = $controller;
    $controller = ucwords($controller);
    $model = rtrim($controller, 's');

    $controller .= 'Controller';

    $dispatch = new $controller($model, $controllerName, $action);
    If ((int) method_exists ($controller, $action)/// Check whether a method of a class exists (class or object names can be passed)
    {
        call_user_func_array(array($dispatch, $action), $queryString);
    }
    else
    {
        /* Generate error code*/
        Exit ('This controller does not exist:'. $controller);
    }
}

/**
 * Automatic Loading Controller and Model
 */
function __autoload($className)
{
    
    if(file_exists(ROOT . DS . 'library' . DS . strtolower($className) . '.class.php'))
    {
        // Loading the core library
        require_once(ROOT . DS . 'library' . DS . strtolower($className) . '.class.php');
    } 
    else if(file_exists(ROOT . DS . 'application' . DS . 'controllers' . DS . strtolower($className) . '.php'))
    {
        // Load controller application directory
         require_once(ROOT . DS . 'application' . DS . 'controllers' . DS . strtolower($className) . '.php');
    }
    else if(file_exists(ROOT . DS . 'application' . DS . 'models' . DS . strtolower($className) . '.php'))
    {
        // Load controller application directory
         require_once(ROOT . DS . 'application' . DS . 'models' . DS . strtolower($className) . '.php');
    }
    else
    {
         /* Generate error code*/
        Exit ("Class name does not exist:" $className);
    }

}


 setReporting();
 removeMagicQuotes();
 unregisterGlobals();
 callHook();

Следующим шагом является настройка программы в библиотеке. базовый класс , включая Базовые классы Контроллеров, моделей и Представлений

Базовым классом нового контроллера является controller.class.php Основной функцией контроллера является общая диспетчеризация. Конкретное содержание заключается в следующем:

_controller =  $controller;
            $this->_action     =  $action;
            $this->_model      =  $model;
            $this - > $model = & new $model; // PHP defaults to pass-by, and here defaults to address pass-by, referring to the same object
            $this->_template   =& new Template($controller, $action);
        }

        function set($name,$value)
        {
            $this->_template->set($name,$value);
        }

        function __destruct()
        {
            // Put it in a destructor to execute the following methods when releasing instantiations
            $this->_template->render();
        }
    }

Базовым классом нового контроллера является model.class.php Учитывая, что модели необходимо обработать базу данных, можно создать новый базовый класс базы данных. sqlquery.class.php Модель для наследования sqlquery.class.php

Недавно построенная sqlquery.class.php Код выглядит следующим образом:

_dbHandle = @mysql_connect($address, $account, $pwd);

            if ($this->_dbHandle != 0)
            {
               if (mysql_select_db($name, $this->_dbHandle))
               {
                   return 1;
               }
               else
               {
                   return 0;
               }
            }
            else
            {
               return 0;
            }
         }

        / ** Interrupt database connection**/
        function disconnect()
        {
             if (@mysql_close($this->_dbHandle) != 0)
             {
                 return 1;
             }
             else
             {
                 return 0;
             }
        }

        / ** Query all data table contents**/
        function selectAll()
        {
            $query = 'select * from `'.$this->_table.'`';
            return $this->query($query);
        }

        / ** Query data table specified column content**/
        function select($id)
        {
            $query = 'select * from `'.$this->_table.'` where `id` = \''.mysql_real_escape_string($id).'\'';
            return $this->query($query, 1);
        }

        / ** Custom SQL Query Statement**/
        function query($query, $singleResult = 0)
        {
            $this->_result = mysql_query($query, $this->_dbHandle);
            if (preg_match("/select/i", $query))
            {
                 $result = array();
                 $table  = array();
                 $field  = array();
                 $tempResults = array();
                 $numOfFields = mysql_num_fields($this->_result);

                 for ($i = 0; $i < $numOfFields; ++$i)
                 {
                      array_push($table, mysql_field_table($this->_result, $i));
                      array_push($field, mysql_field_name($this->_result, $i));
                 }
                 while ($row = mysql_fetch_row($this->_result))
                 {
                     for ($i = 0;$i < $numOfFields; ++$i) {
                        $table[$i] = trim(ucfirst($table[$i]),"s");
                        $tempResults[$table[$i]][$field[$i]] = $row[$i];
                     }
                     if ($singleResult == 1) {
                         mysql_free_result($this->_result);
                         return $tempResults;
                     }
                     array_push($result,$tempResults);
                 }
                 mysql_free_result($this->_result);
                 return($result);
             }
          }

         / ** Number of rows returned to result set**/
        function getNumRows()
        {
            return mysql_num_rows($this->_result);
        }

        / ** Release Result Set Memory**/
        function freeResult()
        {
            mysql_free_result($this->_result);
        }

       / ** Return MySQL operation error message**/
       function getError()
       {
           return mysql_error($this->_dbHandle);
       }
    }

Недавно построенная model.class.php Код выглядит следующим образом:

connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
            $this->_model = get_class($this);
            $this->_table = strtolower($this->_model)."s";
        }

        function __destruct()
        {

        }
    }

Новый базовый класс представления-это template.class.php Код выглядит следующим образом:

_controller = $controller;
           $this->_action =$action;
       }

       /* Setting variables*/
       function set($name,$value)
       {
            $this->variables[$name] = $value;
       }

       /* Display Template*/
       function render()
       {
           extract($this->variables);
           if (file_exists(ROOT.DS. 'application' .DS. 'views' .DS. $this->_controller .DS. 'header.php')) {
               include(ROOT.DS. 'application' .DS. 'views' .DS. $this->_controller .DS. 'header.php');
           } else {
               include(ROOT.DS. 'application' .DS. 'views' .DS. 'header.php');
           }
           include (ROOT.DS. 'application' .DS. 'views' .DS. $this->_controller .DS. $this->_action . '.php');
           if (file_exists(ROOT.DS. 'application' .DS. 'views' .DS. $this->_controller .DS. 'footer.php')) {
               include (ROOT.DS. 'application' .DS. 'views' .DS. $this->_controller .DS. 'footer.php');
           } else {
               include (ROOT.DS. 'application' .DS. 'views' .DS. 'footer.php');
           }
        }
    }

IV. Рамочное приложение

Выполнив так много операций, в основном вышла вся структура MVC. Теперь пришло время сделать наш сайт. Сайт, который мы хотим создать, на самом деле очень прост, это программа для выполнения задач.

Первый находится в нашем /приложении/контроллере/ Новый класс контроллера сайта в каталоге Элемент управления Назван itemscontroller.php Содержание выглядит следующим образом:

set('title',$name.' - My Todo List App');
           $this->set('todo',$this->Item->select($id));
       }
       function viewall() {
           $this->set('title','All Items - My Todo List App');
           $this->set('todo',$this->Item->selectAll());
       }
       function add() {
           $todo = $_POST['todo'];
           $this->set('title','Success - My Todo List App');
           $this->set('todo',$this->Item->query('insert into items (item_name) values (\''.mysql_real_escape_string($todo).'\')'));
       }
       function delete($id) {
           $this->set('title','Success - My Todo List App');
           $this->set('todo',$this->Item->query('delete from items where id = \''.mysql_real_escape_string($id).'\''));
       }
    }

Следующий шаг-сначала создать модель сайта. В нашем каталоге/application/model/мы сначала создаем класс модели сайта под названием Item. Содержимое напрямую наследует модель. Код выглядит следующим образом:

Последним шагом является настройка раздела просмотра нашего сайта. Теперь мы создаем новую папку элементов в каталоге/приложение/представления/, а затем создаем те же файлы, что и повторное действие контроллера в папке элементы, а именно представление. php, просмотр всех. php, добавить. php, удалить. php. Учитывая, что такой странице может потребоваться общий доступ к началу и концу страницы, мы создаем два новых файла с именем him. Adr.php, footer.php, код для каждого файла выглядит следующим образом:

View.php файл: Просмотр одной незавершенной транзакции

Viewall.php файл: просмотр всех незавершенных транзакций

Add.php файл: Добавление незавершенных транзакций

Delete.php файл: удаление транзакций

Header.php: Файл заголовка



<?php echo $title?>



My Todo-List App

Footer.php: Страница И Файл

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

CREATE TABLE IF NOT EXISTS `items` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `item_name` varchar(255) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;

До сих пор был разработан веб-сайт, разработанный с использованием MVC. Теперь вы можете просмотреть новый сайт, посетив http://localhost/Frame/items/….

Краткое описание Основных рамок:

1. Принцип Единого Входа

Написать. файл htaccess в структуре проекта в общий каталог, а затем перепишите модуль экспорта в общий каталог. htaccess указывает индекс. PHP файл

Таким образом, пока вы получаете доступ к проекту, вы указываете его в Frame/public/index.php справочник

2. Загрузка файла начальной конфигурации

Определите корневые пути, разделители и константы, определяющие(“ОТЛАДКА”, TRUE);

3. Инкапсуляция Основных Классов sql.php Модель. PHP (этот класс наследует sql. php) controller.php

4. Другие классы наследуют основные классы

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