Можно ли написать сайт на php без фреймворков
Делается с нуля, своими силамы, бес подглядываний, для демонстрации своего codeStyle и видения разработки ( поставил перд собой задачу: написать фреймворк своими силами - это же всегда интересно )
За основу была взята концепция фреймворка yii2.
framework в процессе разработки.
Проект в большей степени подражает структуре yii2, но не полностью.
для тех кто в теме и кому интересно что у фреймворка под лифчиком под капотом.
Используя консоль в связке с командой cd проникаете в дирректорию с будующим проектом и используете команду
При использовании web-сервера Apache
в корне проекта требуется наличие файла .htaccess с минимальным содержимым:
При использовании web-сервера Nginx
минимальные настройки:
Внутрение зависимости и настройка фремворка
- Namespace'ы начинаются с _ (нижнего подчёркивания)
- Всё "мясо" фреймворка лежит в дирректории app
- правила роутинга настрайваются в app/config/routes.php
- контроллеры/экшоны в routes.php указываются в lowercase , при имени контроллера/экшона CamelCase имя пишется через тире
Пример: роут uri => main-server/restart-now вызовит контроллер MainServerController экшон actionRestartNow - Настройки подключения для домена настрайваются в app/config/setups/ .php
- Models настледуется от BaseModels
- Controller настледуется от BaseController
- Имена Controller'ов имеют суфикс Controller
Пример: контроллер Main имеет имя файла класса MainController - Имена Action'ов имеют префикс action
Пример: экшон Login имеет имя метода actionLogin - экшон должен вернуть
-- для вывода HTML - результат render()
-- для вывода JSON - возвращать renderJson() либо return array
Из консоли используя cd направляемся в дирректорию app в ней используем для генерации файлов, следующие команды:
Генерация контроллера
_ create/controller MyProfile
Будет сгенерирован файл: /app/controllers/MyProfileController.php (шаблон)
Генерация представления/шаблона
_ create/view landingPage mainPAge
Будет сгенерирован файл: /app/views/landing-page/main-page.php (шаблон)
Генерация модели
_ create/model BestCar table_car
Будут сгенерированы 2 файла: /app/models/source/BestCar.php (шаблон), /app/models/BestCar.php (шаблон)
Генерация модуля
_ create/module Test
Будет сгенерирован файл: /app/modules/Test.php (шаблон)
Генерация миграций
_ create/migrate Skill
можно добавить дполнительные параматры Имя таблицы , Комментарий к таблице
Пример: _ create/migrate Skill table_name "Комментарий к таблице"
Будет сгенерирован файл: /app/migrations/m000000_000000_Skill.php (шаблон)
прикол в том что я не планировал вводить миграции, а в ходе работы вдруг захотелось. Пришлось их в прямом смысле слова - вкорячить. Бога ради не хотел я костыли делать, но один всёже пришлось связаный с CLI.
Реализованы методы модели
- one() - возвращает одну подходящюю под запрос моделб (Объект)
- all() - возвращает все подходящие под запрос модели (Объект)
- get() - возвращяет объект Record для дальнейшего вызова методов
- getAll() - возвращяет все записи из таблицы
- select() - указатель какие поля надо вернуть
- where() - усбовия выборки
- andWhere() - дополнительные условия
- limit() - установка limit в SQL запросе
- order() - установка order в SQL запросе
- asArray() - возвращает ответ в виде массива
- asArrayValue() - возвращает массив со значениями( без кючей )
- (позже будет добавлено) orWhere()
- (позже будет добавлено) leftJoin()
Запрос попадает в точку входа main.php
Создаёть экземпляр класса App()
Устанавливаются все свойства App()
В экземпляре класса Route()- Ищется подходящее правило в Route::$rules
- Из подхзодящего правила Задаются ID для: ::$controller ::$action
Создаёт экземпляр класса Controller()
- устанавливается свойство $id
- устанавливается свойство $target
- создаёт экземпляр класса Action()
- устанавливается свойство $id
- устанавливается свойство $target
Создаётся экземпляр пользовательского контроллера по имени Controller::$target. далее у пользовательского контроллера последовательно вызывается методы:
У меня есть для вас непростое задание. Когда в следующий раз начнёте новый проект, постарайтесь обойтись без PHP-фреймворка. Я не собираюсь перечислять недостатки фреймворков, и это не проявление синдрома неприятия чужой разработки: в этом руководстве мы будем использовать пакеты, написанные разработчиками нескольких фреймворков. Я всецело уважаю инновации в этой сфере.
Но эта статья не о них. Она о вас. О возможности стать лучше как разработчик.
Возможно, главным плюсом отказа от фреймворка станет знание, как всё работает под капотом. Вы будете видеть, что происходит, не полагаясь на фреймворк, который заботится о вас настолько, что вы не можете что-то отладить или до конца понять.
Возможно, ваша следующая работа не позволит вам насладиться запуском нового проекта без фреймворка. Многие важные, критические для бизнеса PHP-задачи подразумевают использование уже существующих приложений. И неважно, будет это приложение, построенное на современном фреймворке вроде Laravel или Symfony, на одной из старых платформ вроде CodeIgniter или FuelPHP — либо это удручающе широко распространённое легаси PHP-приложение с «include-oriented архитектурой»: если сейчас вы будете разрабатывать без фреймворка, то окажетесь лучше подготовлены к любому будущему PHP-проекту.
Но сегодня благодаря стараниям PHP-FIG в сфере автозагрузки и взаимной совместимости вы можете разрабатывать без фреймворка, не создавая его попутно. Существует множество замечательных, взаимно совместимых пакетов, написанных многочисленными разработчиками. И собрать их в единую систему гораздо проще, чем вы думаете!
Контроллер запросов
Вооружившись этим знанием, начнём с фронт-контроллера. Он представляет собой PHP-файл, обрабатывающий все запросы к вашему приложению. То есть это первый PHP-файл, в который попадает запрос, и (по сути) последний PHP-файл, через который проходит ответ приложения.
Давайте воспользуемся классическим примером с Hello, world!, обслуживаемым встроенным в PHP веб-сервером, чтобы проверить, всё ли настроено корректно. Если вы этого ещё не сделали, то удостоверьтесь, что в среде установлен PHP 7.1 или выше.
Создадим директорию проекта, в ней сделаем вложенную директорию public , а внутри неё — файл index.php с таким кодом:
Обратите внимание, здесь мы объявляем строгую типизацию — это нужно делать в начале каждого PHP-файла вашего приложения, — потому что подсказки типов (type hinting) важны для отладки и ясного понимания теми, кто будет заниматься кодом после вас.
Далее с помощью инструмента командной строки (вроде Terminal на MacOS) перейдём в директорию проекта и запустим встроенный в PHP веб-сервер.
Отлично. Переходим к следующему шагу!
Диспетчер middleware
Чтобы наше приложение стало работать с каким-либо промежуточным слоем, нам понадобится диспетчер.
PSR-15 — это стандарт, определяющий интерфейсы для middleware и диспетчеров (в спецификации они называются «обработчики запросов»), обеспечивающий взаимосовместимость широкого спектра решений. Нам лишь нужно выбрать диспетчер, совместимый с PSR-15, и он будет работать с любым совместимым middleware.
В качестве диспетчера установим Relay.
Подготовим Relay к приёму промежуточных слоев.
В строке 16 мы с помощью ServerRequestFactory::fromGlobals() будем собирать всю информацию, необходимую для создания нового запроса и передачи его Relay . Здесь запрос попадает в стек промежуточных слоев.
Теперь добавим FastRoute и обработчика запросов ( FastRoute определяет, валиден ли запрос и может ли он быть обработан нашим приложением, а обработчик запросов передаёт запрос тому обработчику, что сконфигурирован для этого маршрута).
А теперь определим маршрут для класса обработчика Hello, world. Здесь мы воспользуемся маршрутом /hello , чтобы продемонстрировать возможность использования маршрута, отличающегося от базового URI.
Чтобы всё заработало, нужно обновить HelloWorld , сделав его вызываемым классом, то есть чтобы этот класс можно было вызвать как функцию.
Обратите внимание на добавленный exit; в магическом методе __invoke() . Скоро вы поймёте, к чему это.
Middleware
Если представить приложение в виде луковицы, в которой запросы идут снаружи к центру, а ответы в обратном направлении, то middleware — это каждый слой луковицы, который получает запросы, вероятно, что-то делает с ответами и передаёт их в нижний слой либо генерирует ответ и отправляет в верхний слой. Такое случается, если промежуточный слой проверяет запросы на соответствие каким-то условиям вроде запроса несуществующего пути.
Если запрос проходит до конца, приложение обработает его и превратит в ответ. После этого каждый промежуточный слой в обратном порядке будет получать ответ, возможно, модифицировать его и передавать следующему слою.
Варианты использования промежуточных слоев:
- Отладка проблем при разработке.
- Постепенная обработка исключений в production.
- Ограничение частоты входящих запросов.
- Ответы на запросы неподдерживаемых медиатипов.
- Обработка CORS.
- Маршрутизация запросов в соответствующие обрабатывающие классы.
Промежуточный слой — это единственный способ реализации инструментов для обработки всех этих ситуаций? Вовсе нет. Но реализации middleware позволяют сделать цикл запрос/ответ гораздо понятнее, что сильно упростит отладку и ускорит разработку.
Мы воспользуемся промежуточным слоем для последнего сценария: маршрутизации.
Автозагрузка и сторонние пакеты
Когда вы впервые начали работать с PHP, то, вероятно, использовали выражения include или require для получения функциональности или конфигураций из других PHP-файлов. В целом этого лучше избегать, потому что другим людям потом будет гораздо труднее разобраться в коде и понять, где находятся зависимости. Это превращает отладку в кошмар.
Выход — автозагрузка. Это означает, что, когда вашему приложению нужно использовать какой-то класс, PHP знает, где его найти, и автоматически загружает в момент вызова. Эта возможность существует со времён PHP 5, но стала активно применяться только с появлением PSR-0 (стандарта автозагрузки, сегодня заменён PSR-4).
Можно было бы пройти через тягомотину написания собственного автозагрузчика, но раз мы выбрали Composer для управления сторонними зависимостями, а в нём уже есть очень удобный автозагрузчик, то его мы и будем использовать.
Проверьте, что у вас установлен Composer. Затем настройте его для своего проекта.
После этого пройдите через интерактивное руководство по генерированию конфигурационного файла composer.json . Затем откройте его в редакторе и добавьте поле autoload , чтобы получилось так, как показано ниже (тогда автозагрузчик будет знать, где искать ваши классы).
Теперь установите для этого проекта Composer, которые подтянет все зависимости (если они уже есть) и настроит для нас автозагрузчик.
Обновите public/index.php для запуска автозагрузчика. В идеале это одно из нескольких выражений include, которые вы используете в приложении.
Если перезагрузить приложение в браузере, вы не увидите никакой разницы. Однако автозагрузчик работает, просто он не делает ничего тяжёлого. Давайте перенесём пример с Hello, world! в автоматически загружаемый класс, чтобы проверить, как всё работает.
В корне проекта создадим папку src и вставим в неё файл HelloWorld.php с таким кодом:
Теперь в public/index.php замените выражение echo вызовом метода announce в классе HelloWorld .
Завершение
Мы углубились в некоторые технологии и аргументацию, но я надеюсь, вам очевидна простота программы начальной загрузки нового приложения без сопутствующего хлама фреймворка. Также надеюсь, что вы теперь лучше готовы к применению этих технологий в существующих приложениях.
Использованное в статье приложение лежит в репозитории, можете свободно форкать и скачивать.
У меня есть для вас непростое задание. Когда в следующий раз начнёте новый проект, постарайтесь обойтись без PHP-фреймворка. Я не собираюсь перечислять недостатки фреймворков, и это не проявление синдрома неприятия чужой разработки: в этом руководстве мы будем использовать пакеты, написанные разработчиками нескольких фреймворков. Я всецело уважаю инновации в этой сфере.
Но эта статья не о них. Она о вас. О возможности стать лучше как разработчик.
Возможно, главным плюсом отказа от фреймворка станет знание, как всё работает под капотом. Вы будете видеть, что происходит, не полагаясь на фреймворк, который заботится о вас настолько, что вы не можете что-то отладить или до конца понять.
Возможно, ваша следующая работа не позволит вам насладиться запуском нового проекта без фреймворка. Многие важные, критические для бизнеса PHP-задачи подразумевают использование уже существующих приложений. И неважно, будет это приложение, построенное на современном фреймворке вроде Laravel или Symfony, на одной из старых платформ вроде CodeIgniter или FuelPHP — либо это удручающе широко распространённое легаси PHP-приложение с «include-oriented архитектурой»: если сейчас вы будете разрабатывать без фреймворка, то окажетесь лучше подготовлены к любому будущему PHP-проекту.
Но сегодня благодаря стараниям PHP-FIG в сфере автозагрузки и взаимной совместимости вы можете разрабатывать без фреймворка, не создавая его попутно. Существует множество замечательных, взаимно совместимых пакетов, написанных многочисленными разработчиками. И собрать их в единую систему гораздо проще, чем вы думаете!
Как работает PHP?
Прежде всего важно понять, как PHP-приложения взаимодействуют с внешним миром.
PHP исполняет серверные приложения в цикле запрос/ответ. Всё взаимодействие с приложением — из браузера, командной строки или REST API — приходит в него в качестве запросов. При получении запроса приложение загружается, обрабатывает запрос и генерирует ответ, который передаётся обратно клиенту, а приложение закрывается. И так происходит при каждом обращении.
Контроллер запросов
Вооружившись этим знанием, начнём с фронт-контроллера. Он представляет собой PHP-файл, обрабатывающий все запросы к вашему приложению. То есть это первый PHP-файл, в который попадает запрос, и (по сути) последний PHP-файл, через который проходит ответ приложения.
Давайте воспользуемся классическим примером с Hello, world!, обслуживаемым встроенным в PHP веб-сервером, чтобы проверить, всё ли настроено корректно. Если вы этого ещё не сделали, то удостоверьтесь, что в среде установлен PHP 7.1 или выше.
Создадим директорию проекта, в ней сделаем вложенную директорию public , а внутри неё — файл index.php с таким кодом:
Обратите внимание, здесь мы объявляем строгую типизацию — это нужно делать в начале каждого PHP-файла вашего приложения, — потому что подсказки типов (type hinting) важны для отладки и ясного понимания теми, кто будет заниматься кодом после вас.
Далее с помощью инструмента командной строки (вроде Terminal на MacOS) перейдём в директорию проекта и запустим встроенный в PHP веб-сервер.
Отлично. Переходим к следующему шагу!
Контейнер внедрения зависимостей
Поскольку мы настроили Composer, установка PHP-DI пройдёт практически безболезненно. Для этого снова обратимся к командной строке:
Обновите public/index.php для конфигурирования и сборки контейнера.
Ничего особенного пока не произошло. Это лишь простой пример, где всё необходимое помещено в один файл для удобства наблюдения.
Мы конфигурируем контейнер, поэтому нужно явно объявить зависимости (а не использовать автоматическое внедрение или аннотации) и извлечь из контейнера объект HelloWorld .
Заметка на полях: автоматическое внедрение зависимостей может быть полезной фичей в начале создания приложения, но в дальнейшем оно усложняет сопровождение, поскольку зависимости остаются относительно скрытыми. К тому же возможно, что через несколько лет другой разработчик подключит какую-нибудь библиотеку, и в результате несколько библиотек будут реализовывать один интерфейс. Это сломает автоматическое внедрение зависимостей и приведёт к непредсказуемому потоку багов. Разработчик, внёсший изменение, может их вообще не заметить.
Давайте ещё больше всё упростим, импортировав пространства имён там, где это возможно.
Пока что выглядит всё так, словно мы устроили суматоху ради выполнения того, что уже делали раньше.
Не беспокойтесь, контейнер нам пригодится, когда добавим несколько других инструментов, помогающих передавать запросы напрямую через приложение. Эти инструменты будут использовать контейнер для загрузки правильных классов по мере необходимости.
Как работает PHP?
Прежде всего важно понять, как PHP-приложения взаимодействуют с внешним миром.
PHP исполняет серверные приложения в цикле запрос/ответ. Всё взаимодействие с приложением — из браузера, командной строки или REST API — приходит в него в качестве запросов. При получении запроса приложение загружается, обрабатывает запрос и генерирует ответ, который передаётся обратно клиенту, а приложение закрывается. И так происходит при каждом обращении.
Клей, который всё скрепляет вместе
Проницательный читатель заметит, что DI-контейнер, несмотря на все трудности его конфигурирования и сборки, на самом деле ничего не делает. Диспетчер и промежуточное ПО могут работать и без контейнера.
Так зачем он нужен?
А что, если — как это почти всегда бывает в реальных приложениях — у класса HelloWorld есть зависимость?
Давайте её добавим и посмотрим, что произойдёт.
Перезагрузим браузер, и.
Это происходит потому, что для функционирования HelloWorld требуется при его создании внедрить строковое значение, а у нас это повисло в воздухе. И здесь на помощь приходит контейнер.
Давайте определим зависимость в контейнере и передадим его в RequestHandler для разрешения.
Вуаля! При перезагрузке браузера вы должны увидеть Hello, bar world!.
Помните, я упомянул о выражении exit в HelloWorld ?
Это простой способ удостовериться, что мы получили простой ответ, но всё же это не лучший способ отправки выходных данных в браузер. Такой грубый подход заставляет HelloWorld делать лишнюю работу по отдаче отчетов — а этим должен заниматься другой класс, — что слишком усложняет отправку заголовков и кодов статуса, а также приводит к закрытию приложения, не давая шансов запуститься промежуточному ПО, идущему после HelloWorld .
Обновим HelloWorld для возвращения Response .
Обновим определение контейнера, чтоб HelloWorld предоставлялся со свежим объектом Response .
Если мы сейчас обновим страницу, то получим пустой экран. Приложение возвращает из диспетчера промежуточных слоев правильный объект Response , а потом… что?
Просто ничего с ним не делает.
Нам нужен ещё один инструмент: эмиттер. Он находится между приложением и веб-сервером (Apache, nginx и т. д.) и отправляет ваш ответ клиенту, сгенерировавшему запрос. Эмиттер просто берёт объект Response и преобразует в инструкции, доступные для понимания серверным API.
Для простоты примера мы используем здесь очень простой эмиттер. Хотя он может быть гораздо сложнее, но в случае больших загрузок реальное приложение должно быть сконфигурировано для автоматического использования потокового эмиттера. Это хорошо описано в блоге Zend.
Обновим public/index.php для получения Response от диспетчера и передачи в эмиттер.
В строке 15 заканчивается цикл запрос/ответ и вступает в работу веб-сервер.
Контейнер внедрения зависимостей
Поскольку мы настроили Composer, установка PHP-DI пройдёт практически безболезненно. Для этого снова обратимся к командной строке:
Обновите public/index.php для конфигурирования и сборки контейнера.
Ничего особенного пока не произошло. Это лишь простой пример, где всё необходимое помещено в один файл для удобства наблюдения.
Мы конфигурируем контейнер, поэтому нужно явно объявить зависимости (а не использовать автоматическое внедрение или аннотации) и извлечь из контейнера объект HelloWorld .
Заметка на полях: автоматическое внедрение зависимостей может быть полезной фичей в начале создания приложения, но в дальнейшем оно усложняет сопровождение, поскольку зависимости остаются относительно скрытыми. К тому же возможно, что через несколько лет другой разработчик подключит какую-нибудь библиотеку, и в результате несколько библиотек будут реализовывать один интерфейс. Это сломает автоматическое внедрение зависимостей и приведёт к непредсказуемому потоку багов. Разработчик, внёсший изменение, может их вообще не заметить.
Давайте ещё больше всё упростим, импортировав пространства имён там, где это возможно.
Пока что выглядит всё так, словно мы устроили суматоху ради выполнения того, что уже делали раньше.
Не беспокойтесь, контейнер нам пригодится, когда добавим несколько других инструментов, помогающих передавать запросы напрямую через приложение. Эти инструменты будут использовать контейнер для загрузки правильных классов по мере необходимости.
Что такое внедрение зависимостей?
Внедрение зависимостей — это методика, при которой каждая зависимость предоставляется объекту, которому она требуется, вместо того чтобы объект обращался наружу за получением какой-то информации или функциональности.
Допустим, методу класса нужно считать из базы данных. Для этого надо к ней подключиться. Обычно новое подключение создаётся с учётными данными, полученными из глобального пространства.
Но это не лучшее решение. На чуждый метод возлагается ответственность за создание объекта нового подключения к БД, получения учётных данных и обработки любых проблем в случае сбоя подключения. В результате в приложении дублируется масса кода. А если вы попытаетесь прогнать этот класс через модульное тестирование, то не сможете. Класс тесно взаимосвязан со средой приложения и базой данных.
Давайте с самого начала не будем усложнять работу с тем, что требуется классу. Просто в первую очередь потребуем, чтобы объект PDO был внедрён в класс.
Получилось гораздо чище и проще для понимания, меньше вероятность ошибок. Благодаря подсказке типов и внедрению зависимостей метод объявляет именно то, что ему нужно для выполнения задачи, и получает необходимое без вызова из себя внешней зависимости. А когда речь пойдёт о модульном тестировании, мы окажемся готовы к моделированию подключения к БД и спокойно пройдём тест.
Контейнер внедрения зависимости — это инструмент, в который вы обёртываете всё ваше приложение ради создания и внедрения этих самых зависимостей. Контейнер не является необходимым, но значительно облегчает жизнь по мере роста и усложнения вашего приложения.
Мы воспользуемся самым популярным DI-контейнером для PHP с изобретательным названием PHP-DI. (Надо отметить, что в его документации внедрение зависимостей описано иначе, и кому-то так будет понятнее.)
Завершение
Мы углубились в некоторые технологии и аргументацию, но я надеюсь, вам очевидна простота программы начальной загрузки нового приложения без сопутствующего хлама фреймворка. Также надеюсь, что вы теперь лучше готовы к применению этих технологий в существующих приложениях.
Использованное в статье приложение лежит в репозитории, можете свободно форкать и скачивать.
Многие говорят, что для разработки нормального сайта(а я хочу сделать многостраничный сайт с авторизацией, комментированием, админкой итд.) нужно использовать какой-нибудь фреймворк, например yii2. В чем преимущества и недостатки сайта на обычном php без использования фреймворков? Просто я могу написать что-то толковое на php, а вот опыта работы с фреймворками у меня нет. Стоит ли тратить время на изучение того же yii или можно все писать просто на php?
- Вопрос задан более трёх лет назад
- 3023 просмотра
Стоит 100%, к тому же если Вы знаете хорошо php уйдет на это минимум времени. Думаю, что изучение yii2 и написание на нем Вашего не сложного проекта в сумме займет меньше времени, чем написание на голом php. Я конечно не беру во внимание случай если Вы решили забить на безопасность и планируете написать 4 php файла, которые пишут в базу все подряд, не используют кеш и т.д.
Единственное преимущество - теоретически меньшая ресурсоемкость. Теоретически, потому что все зависит от кривости рук программиста и его желании делать хорошо и правильно.
Многие говорят, что для разработки нормального сайта(а я хочу сделать многостраничный сайт с авторизацией, комментированием, админкой итд.) нужно использовать какой-нибудь фреймворк, например yii2.
Это те, кто считает, что лучше, чем сделали они - вряд ли кто-нибудь сделает.
Это обычное продвижение проекта через "своих" евангелистов.Пока сами не напишите - так и будете вечно надеяться на "пряморукость" фреймворкеров (ну там ежедневные патчи и исправления безопасности, слышали наверное :) и Ваш прогресс, как профессионала в PHP, остановится.
Мой совет: учитесь - на исходном коде фреймворков (архитектура, модульность, проверка данных, защита от SQL-инъекций, кэширование и прочее), а пишите - сами.PS: Если нужно сделать быстро - берёте популярную CMS (я обычно работаю с CMS Joomla!), учите пару строк фреймворка и "запиливаете" функционал.
Мой совет: учитесь - на исходном коде фреймворков (архитектура, модульность, проверка данных, защита от SQL-инъекций, кэширование и прочее), а пишите - сами.
А потом новый человек, который придёт заниматься проектом будет голову ломать, где документация на всё это, как оно работает, как расширять и поддерживать.Нет, делать нужно не быстро, я хочу написать "правильный" сайт, своими руками. А еще такой вопрос, насчет обучения на исходном коде фреймворков, как разобраться во всей этой куче кода на github'e? Тысячи строк, десятки каталогов, как в этом всем ориентроваться? Одно дело, когда писал сам или в команде, а когда другие люди..
Если я правильно понял, то это сарказм? Да, надо делать сайты на самописном говне, которое будет в куче дыр. На разработку уходит больше времени из-за велосипедирования, трудно уловимые баги и прочее включено. Ведь один человек лучше, чем целая команда. Один человек сразу пишет без багов, ошибок, дыр. Ведь у фреймворка всего-то проверка не одним годом.
TAnonim: как ориентироваться: читаете документацию фреймворка, ищите определение класса в коде (поиском подстроки по файлам, которые загрузили с github) и далее смотрите те методы, которые Вас интересуют.
xmoonlight: А какой фреймворк вы советуете для написания хорошего, функционального, многостраничного сайта?
для разработки нормального сайта не обязательно нужно использовать какой-нибудь фреймворк
фреймворк=шаблон
это готовый архитектурный шаблон - ты можешь сам свою архитектуру сделать если ума хватает, или использовать готовую, или подсмотреть-стырить идеи у других и сделать свою подобнуюЕсть разница между чистым PHP и спагетти кодом.
Если Вы сделаете качественную кодовую базу, которая будет написана с грамотным использованием шаблонов проектирования, будет читаема и отвечать максимальному числу PSR - пишите сами, однако, в таком случае Вы напишите процентов 70 от того же фреймворка.
Возможно, Вам стоит задуматься о использовании компонентов Symphony, если Вам так критично уменьшить число прослоек.
Если же, тут дело в том, что просто не знаете фреймворк - рекомендую освоить. Очень многое может разложить по полочкам в голове и ускорить в последующем разработку приложений.
Да, я просто не знаю фреймворк. А какой фреймворк вы можете посоветовать? yii или lavarel или какой нибудь другой?
TAnonim: Смотрите в сторону Laravel 5 или Yii2, если время есть - то стоит осилить Symfony. Просто сайт фигануть проще на Laravel, если бизнес-логика сложная мне удобнее было использовать Yii2. Symfony круче их обоих вместе взятых, правда тяжелее и порог вхождения выше, зато после него на Laravel и Yii2 не очень охота смотреть)
Если хотите писать свое родное.С самого начала нужно наработать алгоритмическую базу, что бы при уходе вашей любимой технологии или фреймворка в небытие, вы не были выгнаны на мороз с голой жопой. А уже потом брать сначала язык программирования (притворимся что вы взяли не php) и напилить костылей своих с велосипедами, по общим задачкам (строки, данные, графы, хэш таблицы и т.д.), пробуете сортировать без встроенных функций. Вы спросите, а нафиг оно мне нужно? Я крутой прогер хочу сайты клепать, а не ваши алгоритмы учить. Сделано это для того что бы быть программистом а не кодером , и при надобности скакать по технологиям которые вам нужны (как по пикам, или что там вам по душе) с минимальными затратами на изучение. После этого вы пишите своего франкенштейна с руками из сфинктора и глазами на них же(свой MVC фреймворк) костылям позавидует трвмпунк, потом смотрите на чужие костыли в виде фреймворков(в отличии от ваших костылей, эти отлажаны как нужно и протестированы не одну сотню раз, а так же признаны и используються в широком кругу) и допилить свои костыли до вменяемого состояния. Но не советую, используйте отлажаные и протестированые костыли. Время на изучение, с лихвой окупятся и не только временем но и деньгами.
Изучать что-то новое - необходимо и полезно.
Если есть работа, которая требует здесь и сейчас - пишите как можете.
Если есть работа, занимаясь которой можно парралельно изучить новое - изучайте обязательно.Разобравшись в каком-то фреймворке, вы сможете не только делать на нем проекты, но и поддерживать чужие, которые кто-то на этом фреймворке писал. Круг возможного заработка увеличивается.
Популярные CMS и фреймворки пишут люди с хорошим опытом, изучая их можно почерпнуть идеи и интересные решения.Ну а писать на чистом PHP конечно можно, в этом есть и свои преимущества.
Можно ли в 1С 8.2 обойтись без мастеров, при конфигурировании?
Пишу довольно сносно в 1с 7.7, решил в 8.2 поразбираться, скачал самоучитель (Радченко автор) так.Как при восстановлении hdd можно обойтись без комплекса pc-3000?
Сам понемногу занимаюсь ремонтом пк в глубинке. Есть несколько дохлых hdd (bad Сектора, Некоторые.Можно ли обойтись без вспомогательного массива при подсчете различных чисел в массиве
программа подсчитывает различные числа в массиве. Можно ли обойтись без вспомогательного массива.При обновлении страницы в базу заносится пустая строка. Можно ли обойтись без редиректа?
На странице добавляю записи в базу, но при обновлении в базу заносится пустая строка, как лучше.Влияют. При прочих равных условиях сайт на фреймворке будет тормознее. Зато на них быстрее клепать ширпотреб.
Безусловно да. Но зато вы с коробки получаете множественные преимущества в разработке, защиту от взломов упрощение работы с БД, структурированный код (если руки не из ж) и тд.. И дабы добиться этого на чистом PHP прийдёться не раз себе ноги поотстреливать дабы добиться желаемого результата и особенно без большого опыта в разработке на чистом языке.
Добавлено через 2 минуты
Ширпотреб быстрее на wordpress клепать, но ней дай бог потом вам разбираться в этой каши после програмистов писавших этот ширпотреб.
Вопрос в принципе не корректен. В сферическом вакууме ты можешь обойтись не только без фреймворков, но и вовсе без программировния, без компьютера и даже без электричества. Но зачем?
Если ты хочешь устроиться на хорошую работу с хорошей зарплатой - то без знания фреймворков тебе никак не обойтись. А если тебе нужно своять собственный говносайтик - то вообще пофиг как ты это будешь делать.
В целом, я пару лет назад говорил о том, что фреймворки - это, в прошлом и сейчас море библиотек и собрать каркас можно без труда, и это легче будет поддерживаться в компании. С выходом Симфони 4 все залепетали, что "вот, все теперь можно самому собирать", а пару лет назад говном закидали меня. =)
Можно обойтись без, а можно и не обойтись. Смотря какая задача. Какая компания. Какие сроки. Много нюансов.
Если нужно по быстрей и нет требований к архитектуре, то это ускоряет процесс. Ну, и еще юные разработчики видят на примерах, как это работает все вместе.
В целом да, но в наших реалиях эта нагрузка абсолютно незаметна.
Тормознее на мистические миллисекунды. Их никто не заметит в наше время.
зависит от задачи. Если простой сайт визитка - зачем фреймворк? можно и кмс или мини-фреймворк вроде silex.
Симфони Yii я бы выбрал для сайта с большим количеством сущностей. Doctrine, ActiveRecord незаменимысомнительное утверждение. Yii-шные тяжеловесные activerecord и нагруженный проект со сложной нормализованной базой данных - это просто две несовместимые вещи
Yii-шные тяжеловесные activerecord и нагруженный проект со сложной нормализованной базой данных - это просто две несовместимые вещи
если вы не в курсе в 80х не было yii. Даже php не было. Однако сайт на yii2 выводящий страницу с контентом из базы данных отдает эту страницу в разы медленнее сайта, который берет контент готовым запросом переданным в PDO. Это простой запрос. А если нужно выводить данные из связанных таблиц скорость падает в 10ки раз. Безусловно, для сайта с единственным посетителем раз в год, тысячные доли секунды и сотые - без разницы.
Клей, который всё скрепляет вместе
Проницательный читатель заметит, что DI-контейнер, несмотря на все трудности его конфигурирования и сборки, на самом деле ничего не делает. Диспетчер и промежуточное ПО могут работать и без контейнера.
Так зачем он нужен?
А что, если — как это почти всегда бывает в реальных приложениях — у класса HelloWorld есть зависимость?
Давайте её добавим и посмотрим, что произойдёт.
Перезагрузим браузер, и.
Это происходит потому, что для функционирования HelloWorld требуется при его создании внедрить строковое значение, а у нас это повисло в воздухе. И здесь на помощь приходит контейнер.
Давайте определим зависимость в контейнере и передадим его в RequestHandler для разрешения.
Вуаля! При перезагрузке браузера вы должны увидеть Hello, bar world!.
Помните, я упомянул о выражении exit в HelloWorld ?
Это простой способ удостовериться, что мы получили простой ответ, но всё же это не лучший способ отправки выходных данных в браузер. Такой грубый подход заставляет HelloWorld делать лишнюю работу по отдаче отчетов — а этим должен заниматься другой класс, — что слишком усложняет отправку заголовков и кодов статуса, а также приводит к закрытию приложения, не давая шансов запуститься промежуточному ПО, идущему после HelloWorld .
Обновим HelloWorld для возвращения Response .
Обновим определение контейнера, чтоб HelloWorld предоставлялся со свежим объектом Response .
Если мы сейчас обновим страницу, то получим пустой экран. Приложение возвращает из диспетчера промежуточных слоев правильный объект Response , а потом… что?
Просто ничего с ним не делает.
Нам нужен ещё один инструмент: эмиттер. Он находится между приложением и веб-сервером (Apache, nginx и т. д.) и отправляет ваш ответ клиенту, сгенерировавшему запрос. Эмиттер просто берёт объект Response и преобразует в инструкции, доступные для понимания серверным API.
Для простоты примера мы используем здесь очень простой эмиттер. Хотя он может быть гораздо сложнее, но в случае больших загрузок реальное приложение должно быть сконфигурировано для автоматического использования потокового эмиттера. Это хорошо описано в блоге Zend.
Обновим public/index.php для получения Response от диспетчера и передачи в эмиттер.
В строке 15 заканчивается цикл запрос/ответ и вступает в работу веб-сервер.
Диспетчер middleware
Чтобы наше приложение стало работать с каким-либо промежуточным слоем, нам понадобится диспетчер.
PSR-15 — это стандарт, определяющий интерфейсы для middleware и диспетчеров (в спецификации они называются «обработчики запросов»), обеспечивающий взаимосовместимость широкого спектра решений. Нам лишь нужно выбрать диспетчер, совместимый с PSR-15, и он будет работать с любым совместимым middleware.
В качестве диспетчера установим Relay.
Подготовим Relay к приёму промежуточных слоев.
В строке 16 мы с помощью ServerRequestFactory::fromGlobals() будем собирать всю информацию, необходимую для создания нового запроса и передачи его Relay . Здесь запрос попадает в стек промежуточных слоев.
Теперь добавим FastRoute и обработчика запросов ( FastRoute определяет, валиден ли запрос и может ли он быть обработан нашим приложением, а обработчик запросов передаёт запрос тому обработчику, что сконфигурирован для этого маршрута).
А теперь определим маршрут для класса обработчика Hello, world. Здесь мы воспользуемся маршрутом /hello , чтобы продемонстрировать возможность использования маршрута, отличающегося от базового URI.
Чтобы всё заработало, нужно обновить HelloWorld , сделав его вызываемым классом, то есть чтобы этот класс можно было вызвать как функцию.
Обратите внимание на добавленный exit; в магическом методе __invoke() . Скоро вы поймёте, к чему это.
Маршрутизация
Маршрутизатор применяет информацию из запроса, чтобы понять, какой класс должен его обработать (например, URI /products/purple-dress/medium должен быть обработан с помощью класса ProductDetails::class с передаваемыми в качестве аргументов purple-dress и medium ).
Наше приложение будет использовать популярный маршрутизатор FastRoute через реализацию промежуточного слоя, совместимого с PSR-15.
Автозагрузка и сторонние пакеты
Когда вы впервые начали работать с PHP, то, вероятно, использовали выражения include или require для получения функциональности или конфигураций из других PHP-файлов. В целом этого лучше избегать, потому что другим людям потом будет гораздо труднее разобраться в коде и понять, где находятся зависимости. Это превращает отладку в кошмар.
Выход — автозагрузка. Это означает, что, когда вашему приложению нужно использовать какой-то класс, PHP знает, где его найти, и автоматически загружает в момент вызова. Эта возможность существует со времён PHP 5, но стала активно применяться только с появлением PSR-0 (стандарта автозагрузки, сегодня заменён PSR-4).
Можно было бы пройти через тягомотину написания собственного автозагрузчика, но раз мы выбрали Composer для управления сторонними зависимостями, а в нём уже есть очень удобный автозагрузчик, то его мы и будем использовать.
Проверьте, что у вас установлен Composer. Затем настройте его для своего проекта.
После этого пройдите через интерактивное руководство по генерированию конфигурационного файла composer.json . Затем откройте его в редакторе и добавьте поле autoload , чтобы получилось так, как показано ниже (тогда автозагрузчик будет знать, где искать ваши классы).
Теперь установите для этого проекта Composer, которые подтянет все зависимости (если они уже есть) и настроит для нас автозагрузчик.
Обновите public/index.php для запуска автозагрузчика. В идеале это одно из нескольких выражений include, которые вы используете в приложении.
Если перезагрузить приложение в браузере, вы не увидите никакой разницы. Однако автозагрузчик работает, просто он не делает ничего тяжёлого. Давайте перенесём пример с Hello, world! в автоматически загружаемый класс, чтобы проверить, как всё работает.
В корне проекта создадим папку src и вставим в неё файл HelloWorld.php с таким кодом:
Теперь в public/index.php замените выражение echo вызовом метода announce в классе HelloWorld .
Что такое внедрение зависимостей?
Внедрение зависимостей — это методика, при которой каждая зависимость предоставляется объекту, которому она требуется, вместо того чтобы объект обращался наружу за получением какой-то информации или функциональности.
Допустим, методу класса нужно считать из базы данных. Для этого надо к ней подключиться. Обычно новое подключение создаётся с учётными данными, полученными из глобального пространства.
Но это не лучшее решение. На чуждый метод возлагается ответственность за создание объекта нового подключения к БД, получения учётных данных и обработки любых проблем в случае сбоя подключения. В результате в приложении дублируется масса кода. А если вы попытаетесь прогнать этот класс через модульное тестирование, то не сможете. Класс тесно взаимосвязан со средой приложения и базой данных.
Давайте с самого начала не будем усложнять работу с тем, что требуется классу. Просто в первую очередь потребуем, чтобы объект PDO был внедрён в класс.
Получилось гораздо чище и проще для понимания, меньше вероятность ошибок. Благодаря подсказке типов и внедрению зависимостей метод объявляет именно то, что ему нужно для выполнения задачи, и получает необходимое без вызова из себя внешней зависимости. А когда речь пойдёт о модульном тестировании, мы окажемся готовы к моделированию подключения к БД и спокойно пройдём тест.
Контейнер внедрения зависимости — это инструмент, в который вы обёртываете всё ваше приложение ради создания и внедрения этих самых зависимостей. Контейнер не является необходимым, но значительно облегчает жизнь по мере роста и усложнения вашего приложения.
Мы воспользуемся самым популярным DI-контейнером для PHP с изобретательным названием PHP-DI. (Надо отметить, что в его документации внедрение зависимостей описано иначе, и кому-то так будет понятнее.)
Middleware
Если представить приложение в виде луковицы, в которой запросы идут снаружи к центру, а ответы в обратном направлении, то middleware — это каждый слой луковицы, который получает запросы, вероятно, что-то делает с ответами и передаёт их в нижний слой либо генерирует ответ и отправляет в верхний слой. Такое случается, если промежуточный слой проверяет запросы на соответствие каким-то условиям вроде запроса несуществующего пути.
Если запрос проходит до конца, приложение обработает его и превратит в ответ. После этого каждый промежуточный слой в обратном порядке будет получать ответ, возможно, модифицировать его и передавать следующему слою.
Варианты использования промежуточных слоев:
- Отладка проблем при разработке.
- Постепенная обработка исключений в production.
- Ограничение частоты входящих запросов.
- Ответы на запросы неподдерживаемых медиатипов.
- Обработка CORS.
- Маршрутизация запросов в соответствующие обрабатывающие классы.
Промежуточный слой — это единственный способ реализации инструментов для обработки всех этих ситуаций? Вовсе нет. Но реализации middleware позволяют сделать цикл запрос/ответ гораздо понятнее, что сильно упростит отладку и ускорит разработку.
Мы воспользуемся промежуточным слоем для последнего сценария: маршрутизации.
Маршрутизация
Маршрутизатор применяет информацию из запроса, чтобы понять, какой класс должен его обработать (например, URI /products/purple-dress/medium должен быть обработан с помощью класса ProductDetails::class с передаваемыми в качестве аргументов purple-dress и medium ).
Наше приложение будет использовать популярный маршрутизатор FastRoute через реализацию промежуточного слоя, совместимого с PSR-15.
Читайте также: