Создание фреймворка на php с нуля
Вместо того что бы использовать низкоуровневые компоненты, вы можете использовать полномасштабный фреймворк который базируется на этих компонентах — Symfony2… Или, вы можете написать свой собственный. Эта серия статей о последнем.
Зачем вам нужен собственный фреймворк? (Why would you like to create your own framework?)
Во-первых, почему вы хотите создать собственный фреймворк? Ведь, если посмотреть, все вам скажут, что не стоит изобретать велосипед, а использовать уже готовое решение. И в большинстве случаев они будут правы, но есть несколько причин что бы начать разработку своего фреймворка:
- Что бы изучить низкоуровневую архитектуру современных веб-ориентированных фреймворков, в частности Symfony2 и ее компонентов.
- Что бы создать фремворк «под ключ» для ваших специфических нужд. (Только прежде убедитесь, что ваши нужды действительно специфические)
- Для эксперимента ради удовольствия ( научился и забил )
- Для рефакторинга уже существующих приложений, которые нуждаются в более современных и устоявшихся практических решениях.
- Что бы доказать что вы это можете (… пусть и с небольшой помощью)
И конечно же, на каждом шаге вы будете узнавать больше про Symfony2 и ее компоненты.
- Если у вас нет времени для прочтения полного цикла статей, или вы хотите приступить к разработке уже сейчас, обратите свое внимание на Silex, это микро-фреймворк основанный на компонентах Symfony2.
Много современных фремворков базируют себя как MVC фреймворки. В этой серии статей мы не будем обсуждать MVC-модель, так как на основе компонентов Symfony2 вы можете создать фреймоворк не основанный на этой модели. Во-всяком случае, если вы посмотрите на построение MVC — эта часть будет про то, как создать часть Contoller'а в данной архитектуре.
Для Model и View все зависит от ваших предпочтений и я даю возможность вам использовать любые библиотеки (например: Doctrine, Propel или старый добрый PDO для Model и/или PHP, Twig для View).
Прежде чем начнем (Before we start)
Недостаточно просто прочитать о создании фреймворка. Вам действительно нужно будет писать код примеров которые мы рассматриваем. Для этого вам понадобится PHP (версия 5.3.8 или более новая), веб-сервер (Apache или Nginx), хорошие познания в PHP и ООП.
Ну что, готовы? Тогда начнем.
Начальная загрузка (Bootstrapping)
Прежде чем мы начнем думать о своем фреймворке, нам нужно оговорить несколько соглашений: где мы будем хранить код, как мы будем называть наши классы, как мы будем подключать/обрабатывать внешние зависимости.
Для размещения фреймворка создайте директорию где-то на вашем сервере:
Стандарты написания кода (Coding Standards)
Перед тем как кто-то начнет холивор по поводу этого, давайте признаем что для примера совершенно не принципиально какие стандарты использовать. Поэтому в серии этих статей мы будем применять «Symfony2 Coding Standards».
Установка компонентов (Components Installation)
Для установки необходимых компонентов нашего фреймворка мы будем использовать Composer, менеджер зависимостей проекта для PHP. Первый вариант, который мы опишем в composer.json, будет выглядеть так:
Здесь мы объявляем что наш проект использует компонент Symfony2 ClassLoader версии 2.1.0 или выше. Что бы загрузить и установить зависимости проекта выполним следующее:
После выполнения команды install вы увидите директорию vendor которая содержит код компонента Symfony2 ClassLoader.
- Я рекомендую использовать вам Composer, хотя вы можете скачать архивированный компонент или использовать Git submodules. Решать вам.
Именование и Автозагрузка (Naming Conventions and Autoloading)
Мы будем применять autoload для всех наших классов. Без автозагрузки вам придется делать require нужного файла перед использованием его функционала. Но сейчас мы дадим PHP делать это за нас.
Symfony2 следует стандартам де-факто для PHP, в частности PSR-0, для именования классов и автозагрузчика. Компонент Symfony2 ClassLoader обеспечивает стандарт PSR-0 и в большинстве случаев все что вам нужно — это загрузить этот компонент.
Создайте пустой менеджер автозагрузки в файле: autoload.php:
Сейчас вы можете выполнить этот файл с помощью консоли, он не выполняет никаких действий и не должен выдавать ошибку(-и):
- Вы можете больше узнать о компоненте ClassLoader на сайте Symfony2.
Наш проект
Вместо создания фреймворка с шаблона мы будем писать простейшее приложение снова и снова, добавляя по одному уровню абстракции каждый раз. Начнем с простейшего web-приложения на PHP:
Цель данной статьи — поделиться опытом по написанию простого ООП MVC PHP фреймворка. Так же хочу предоставить сообществу исходный код и попросить критики, одобрения, замечаний и поддержки.
Точка входа
Любой сайт, CMS или фреймворк начинается с точки входа. Обычно это index.php в корне сайта. Но мы не будем так делать. Чтобы программист, который работает с нашим фреймворком сразу разобрался, что все данные идут через точку входа, назовем файл main.php. Тогда будет очевидно - все запросы перенаправляются через .htaccess
Дальнейшие манипуляции с разбором URL производятся с помощью PHP. Это распространенный прием, вы легко можете воспользоваться им в других системах. Так работает и Yii. Но наш фреймворк в отличие от Yii без .htaccess работать не сможет.
Файл main.php не должен делать много, он лишь определит константы путей, подключит фреймворк и запустит приложение
Улучшения и планы на будущее
В качестве адаптера для коннекта к БД я использовал PDO. В ходе работы PDO мне не очень понравился — сложно отлаживать запросы, хочется комфорта использования ORM. Можно установить Eloquent ORM — это современное и готовое решение (применяется в фреймворке Laravel), да и к тому же оно хорошо документировано и может быть установлено из composer за несколько минут.
Так же думал о расширении базового функционала фреймворка: хотел добавить поддержку модулей. Т.е. чтобы можно было написать например, блог как отдельный модуль (со своими контроллерами, вьюверами, моделями и т.п.). И потом подключать этот модуль в любом месте приложения.
Можно расширять и базовый «джентельменский» набор классов в ядре, усложнять систему логирования, обработки ошибок, конфигурирования, писать полноценный демо-сайт со всем функционалом и т.д.
Анализ требований
Все начинается с анализа требований и пожеланий к итоговой системе.
Фреймворк должен:
- позволять быстро создать сайт «с нуля»
- иметь в себе ряд уже реализованных базовых технических решений и инструментов
- содержать разделенный frontend и backend
- отвечать современным требования по коду, технологиям, применяемым техническим решениям и т.п.
- содержать уже в базовой комплектации демо-приложение, на основе которого можно вести свою разработку
- быть модульным и расширяемым
- иметь понятную документацию, техподдержку (в идеале — сообщество)
Введение
По ходу эксплуатации различных современных фреймворков я понял, что недостаточно понимаю, как все устроено внутри; не осознаю, почему разработчики выбрали то или иное решение; обращаю внимание только на текущую задачу и не смотрю «выше, глубже и дальше». И, как вариант для профессионального роста, я выбрал создание собственного проекта.
Как показала дальше практика: читать, знать, слышать о чем-либо, и уметь самому это реализовать — совершенно разные вещи. Теоретизировать можно бесконечно, но только настоящее практическое задание позволяет понять, на каком уровне ты находишься. Всвязи с этим и было начато «написание собственного велосипеда». Каким он получился — судить вам.
Введение
По ходу эксплуатации различных современных фреймворков я понял, что недостаточно понимаю, как все устроено внутри; не осознаю, почему разработчики выбрали то или иное решение; обращаю внимание только на текущую задачу и не смотрю «выше, глубже и дальше». И, как вариант для профессионального роста, я выбрал создание собственного проекта.
Как показала дальше практика: читать, знать, слышать о чем-либо, и уметь самому это реализовать — совершенно разные вещи. Теоретизировать можно бесконечно, но только настоящее практическое задание позволяет понять, на каком уровне ты находишься. Всвязи с этим и было начато «написание собственного велосипеда». Каким он получился — судить вам.
Маршрутизация
В папке core создаем класс Router.php и начнем писать код:
Мы создали переменную routes, в котором будут храниться все маршруты в таком формате:
Теперь нужно создать класс Request.php для получения урлов, методов запроса и так далее:
Тут мы создаем экземпляр Request'а и метод resolve, который возвращает то, что вернул callback.
Возвратимся в класс Application и создаем метод run, который запустит Роутер:
Теперь, можем протестировать текущий функционал. Создадим папку public и в ней файл index.php:
В этой же папке запустим команду php -S localhost:8080 (или любой другой порт). Зайдем на localhost:8080 в браузере и о чудо! Мы увидим надпись Hello, habr!
Процесс разработки
Разработка фреймворка велась следующим образом: изначально было некое простейшее веб-приложение, которое дорабатывалось, переписывалось, меняло структуру, обрастало новыми классами и компонентами и т. д. Несколько месяцев назад у меня появилось свободное время, много энтузиазма и решительности таки доделать фреймворк «по-серьезному». На написание данной версии я потратил в совокупности 3-4 недели (работая в среднем 1-3 часа в день, 3-4 дня в неделю).
По мере разработки стандарты и требования я сознательно завышал для себя, искал оптимальные решения много раз переписывал код. Так, например, работу с конфигурацией я переделывал раз 5-6 (причем несколько раз кардинально), роутинг — 3-4 раза. В качестве примеров я брал код из статей, публикаций, руководств, фреймворков (Yii2, CodeIgniter, Zend, Phalcon, Bun) и т. п.
Заключение
Буду рад услышать критику кода, архитектуры, изначальных требований и прочего. Комментарии буду активно читать, постараюсь ответить на вопросы.
Так же хотелось бы реализовать какой-либо проект на базе данного фреймворка. Так сказать опробовать инструмент в работе. Понятно, что поиск заказчиков — это совсем не к данному разделу, но хотел бы услышать, можно ли на данном решении стартовать реальный проект? Популярные фреймворки «из коробки» дают функционал в 50-100 раз качественнее и масштабнее, конкурировать с ними сложно.
Привет, хабр! В этой статье я хочу написать о том, как сделать PHP-приложение с помощью схемы разделения данных приложения MVC.
Для работы нам нужна функция под названием autoload. Она избавляет нас от бесконечных require'ов. Мы можем вручную написать скрипт, но эта функция есть у знаменитого пакетного менеджера composer.
После установки инициализируем его в главной папке нашего мини-фреймворка командой composer init. на всех вопросах нажимаем ENTER.
Далее заходим в появившийся файл composer.json. Удаляем все и добавляем это:
И наконец, выполняем команду composer update. На этом настройка composer завершена.
Теперь, создадим папку core и файл .htaccess. Еще нужно создать папку public и создать в ней файл index.php - точку входа в приложение.
В файл .htaccess нужно вписать следующее:
Все, что делает этот файл - переадресовывает любые запросы в index.php.
Потом, в папке core создаем класс Application. Помещаем в него этот код:
Здесь мы создаем пока что пустой класс и пространством имен app\core.
На этом этапе структура должна выглядеть так:
│ .htaccess
│ composer.json
│ composer.lock
│
├───core
│ Application.php
│
├───public
│ index.php
│
└───vendor
Отлично. Теперь давайте выполним первую задачу: маршрутизацию.
Похожие статьи:
Структура папок
Приведу структуру файлов и папок в фреймворке (также можно посмотреть код на GitHub):
В приложении есть одна единственная точка входа. Привожу код файла index.php из корневой публичной папки веб-сервера.
Код метода run($config) из класса \framework\core\Application(). Производится загрузка необходимых классов приложения и производится вызов соответствующего контроллера (в методе execute()).
Код метода execute() из класса \framework\core\Application(). Нужный контроллер на данном этапе уже выбран, производим инициализацию этого контроллера, обработку хеадеров, вывод контента. В случае ошибки — бросаем 404 Not Found.
Разработка веб-приложения на PHP
Скачайте видеокурс и узнайте, как создать веб-приложение на PHP
Структура
Теперь продумаем структуру нашего фреймворка. Удобно, чтобы его файлы лежали в отдельной папке. Сделаем такую структуру
в папке ideal будет лежать наш идеальный =) движок, а в папке application файлы пользователя.
в файле framework.php определим автозагрузчики классов, для того чтобы не писать руками каждый раз include 'classname.php'; Я уже писал про эту технику
в этом файле будут еще и другие системные действия. Но пока хватит и этого.
Автозагрузчики срабатывают при использовании класса. Сперва ищется в папке фреймворка, потом в папке контроллеров, затем в моделях. Соответственно называть контроллер также, как и класс, или модуль нельзя.
Теперь опишем класс App, он находится в папке classes движка.Его метод start и будет запускать наше приложение.
Класс наследует абстрактный класс Singleton. Удобство в том, что экземпляр любого класса, который наследует от Singleton, можно получить из любого места программы через его метод gi() К примеру, экземпляр нашего приложения можно получить App::gi(). Этот метод вернет единственный экземпляр класс App. Один экземпляр может создать проблему, когда нужно использовать несколько баз данных. Поэтому к классу db его лучше не применять.
В коде появляются класс Router. Он будет парсить переменную $_GET['route'] и и возвращать контроллер и action - т.е. метода этого контроллера. Так как пока мы пишем лишь каркас, то этот класс ничего делать не будет. Лишь заполнит свои соответствующие поля.
Далее используя метод App::gi() как фабрику, создается экземпляр класса контроллера. А затем вызывается его метод. Класс контроллера наследуется от класса classes/Controller.php
Каркас фреймворка готов. Теперь создадим один жизненно важный контроллер application/controllers/UserController.php
Пользователи нужны в любой системе.
Он пока ничего не делает. Лишь создает модель User и выводит свое представление на экран. Модель User наследует класс classes/Model.php
и код модели application/models/User.php
Как видите он тоже ничего особого не делает.
Содержание application/views/user/index.php может быть любым. Но чтобы продемонстрировать взаимодействие контроллера и представления оно будет таким
Таким образом структура нашего фреймворка примет такой вид
Запустив в адресной строке
Вам сейчас кажется, что все это ерунда и можно было сделать все это проще. Но если вдуматься, у нашего фреймворка огромные возможности. Он полностью структурирован. Расширить его возможности не составит большого труда. Добавляем класс для работы с БД и класс для работы с шаблонами и вот у нас полноценный фреймоворк. Самое важное, что вы поймете написав такой велосипед, это принцип работы MVC фреймворков таких как Zend или Yii. А понимание принципов работы это 99% процентов успеха в любой разработке.
Давно хотелось создать что-нибудь подобное. В дальнейшем планирую развивать его, добавляя новые функции и сделать действительно удобный функционал.
Данный цикл статей продолжиться. Следите за новостями. Желаю удачных велосипедов.
Комментарии (17)
А зачем папка nbproject?
Это служебная папка, которую автоматически создал мой редактор NetBeans при создании проекта. К фреймворку она никак не относится, можете ее удалить, если она мешает.
Спасибо за ответ. Подскажите пожалуйста сколько будет всего уроков?
По количеству уроков. Честно — не знаю. У меня даже и плана нет конкретного, пишу пока пишется А писать можно на самом деле много при желании и наличии вдохновения.
вот что выдает при подключении к базе данных, помогите решить
В самом начале ошибки сообщается: «Unknown database fw» — это переводится как «Неизвестная база данных fw». Соответственно, у Вас нет такой БД, поэтому нужно проверить настройки подключения и создать такую БД или указать другую БД для работы.
интересно то что данная база есть и я проверял даже на разных компьютерах, таже самая ошибка
и почему phpstorm подсвечивает dbname непонятно
и не понятно почему когда напишешь скажем db_name то ошибка пропадает и выводит уже bool (false)
Значит, скорее всего, есть и другие ошибки в коде. Попробуйте взять код из исходников — там ошибок нет.
вот именно просто копирую Ваши исходники и вставляю и вот такая ерунда выходит
Ну значит, проблема все же в БД, о чем и сообщается в ошибке. В коде урока точно все в порядке, поскольку Вы первый кто столкнулся с такой проблемой. Если не разберетесь — тогда можете выложить сайт на хостинг и написать мне в личку доступ к сайту, чтобы я мог его посмотреть, другим способом решить проблему не получится.
код использую именно с Вашего урока Создание собственного фреймворка. Модель и работа с БД. Часть 1. Урок 5
а в этих исходниках ошибка пропадает Создание собственного фреймворка. Модель и работа с БД. Часть 2. Урок 6 значит где то я невнимательно писал код
Создание собственного фреймворка. Модель и работа с БД. Часть 1. Урок 5 странно почему в первой части вылазит ошибка, а во второй уже нет
а проблема в том что надо создать таблицу posts в базе данных и все сразу работает тогда и в первой части урока
Эта таблица создается в уроке на 27-ой минуте)
я уже понял спасибо, я просто уроком вчера занимался уже в 23 00 поэтому не заметил ее создание устал наверное
В сети большое количество мануалов по созданию сайтов на готовой CMS или фреймворке. Однако, работая фрилансером, часто встречаю сайты на самописных системах. Программисты пишут их не от хорошей жизни. В зависимости от степени простоты(сложности) проекта чрезмерно или наоборот недостаточно, применение готовой системы, и на ее переделки уходит больше времени, чем на создание сайта с нуля. К примеру, для сайта одностраничника не нужно тяжелой системы типа Joomla или фреймворка типа Yii, а у CMS типа Texpattern может не хватить функционала. Плюс задачи, которые ставит заказчик, могут быть весьма специфичными, и достаточно тяжело реализуемыми на готовой системе.
Для примера можно взять работы с моделями в Yii. Речь идет об ActiveRecord. У Yii на официальном сайте есть отличный мануал по созданию блога. Если придерживаться его, и делать все, как написано, то через пару часов изучения, можно получить полноценный блог. С категориями, метками, пользователями и административной панелью.
Проблемы начинаются тогда, когда вы попытаетесь сделать что-то, что не входит в мануал. Вывести под статьей похожие материалы. Для этого, надо составлять реляционную модель, гораздо более сложную, чем представлена в примерах.
Как сказал один наш комик - "тут начинается вестерн". То, что в SQL бы заняло 3 строчки кода, в Active Record займет пару ночей чтения мануалов, и экспериментов. Потому что, на первый взгляд тривиальная задача, вдруг вызывает необъяснимый баг Yii, о котором слышали полтора человека и оба китайцы. Пример не надуманный, те кто программировал на Yii используя Actve Record поддержат.
Эта методология работы с данными очень удобна, когда дело касается одной таблицы. Или даже двух, когда связь идет один ко многим, по одному полю. Настоящий ад начинается, когда нужно получить данные из нескольких таблиц.
В мире CMS тоже далеко ходить не надо. При работе над модулем Яндекс карт для Joomla нужно было подключить в админке сайта javascript файл. Недельное изучение системы ничего не дало. Такого функционала в модулях попросту нет. Надо сказать, что я выкрутился используя функционал расширенных полей подключил нужный файл. Но то, сколько времени у меня на это ушло, несоизмеримо с тем, если бы система была построена по моим законам, и я знал, что и где в ней подключается.
Об этом расскажу в этой статье. Как написать php фреймворк с нуля. Опишем основные техники проектирования MVC фреймворков на чистом php без использования сторонних библиотек.
Фреймворки пишут такие же программисты, как и вы. Нет ничего невозможного. Написать для себя каркас на котором потом можно будет строить конструкции нетипичных сайтов.
Хочу предостеречь вас, не стоит писать свой велосипед, без особой надобности и опыта. Большую часть кода придется писать руками. Тут не будет готовых модулей и расширений.
Однако и плюсы тоже есть, система будет полностью под вашим контролем. Никаких ограничений API и требований системы. Только чистый vanilaPHP и ничего лишнего.
Оставим лирику, приступим наконец к коду.
Исходные материалы к статье скачать и посмотреть на github. Статьи по этой теме будут публиковаться с тегом ideal, а последнюю версию фреймворка можно будет найти на gihub
Итоги
На этом первая часть подходит к концу. В ней мы задали каркас нашего будущего фреймворка. В следующей части мы реализуем View и Контроллеры
Это моя первая статья на Хабре, поэтому буду рад любой критике. Спасибо за прочтение и удачи!
От автора: приветствую вас, друзья. Продолжим создание собственного PHP фреймворка. По итогу мы должны получить вполне функциональное решение, а заодно познакомиться с принципами работы современных PHP фреймворков. В этом уроке мы приступим к реализации компонента модели, а также создадим необходимый класс для работы с базой данных.
В видео версии урока вы найдете ответы на такие вопросы:
Что такое модель?
Бесплатный курс по PHP программированию
Освойте курс и узнайте, как создать веб-приложение на PHP с полного нуля
Как реализовать шаблон Singleton?
Как работать с PDO?
Как настроить подключение к БД, используя PDO?
Как реализовать простую отладочную панель?
Применяемые технологии
Список таких решений напрямую зависит от того, о чём знаете и что применяете в своей реальной практике. Т.е. подходим к необходимости постоянного мониторинга новинок и изменений в сфере ИТ.
Практики и технологии:
- Язык программирования: PHP >= 5.5.* или PHP >= 7.*
- База данных: MySql >=5.4.*
- Менеджер пакетов: Composer
- Автозагрузка: PSR-4, кодирование: PSR-2, логирование: PSR-3
- Используем функционал языка: неймспейсы, трейты, магические функции и т.п.
- Применяем паттерны при построении структуры классов, реализации задач
- Верстаем html-код с использованием Twitter Bootstrap
- Пользуемся лучшими подходами в программировании: SOLID, DRY, KISS, YAGNI
- Покрываем код PhpUnit-тестами (тестирование работы базовых классов приложения)
- покрываем функционал Codeception-тестами (приемочное тестирование)
Комментарии Вконтакте:
Читайте также: