Введение в создание CMS без фреймворка
В мире веб-разработки PHP остаётся мощным и универсальным языком для создания динамических веб-сайтов и приложений. В то время как фреймворки вроде Laravel и Symfony могут ускорить процесс разработки, есть определённое удовлетворение в создании чего-то с нуля без использования готовых фреймворков. В этой статье мы подробно рассмотрим процесс создания простой системы управления контентом (CMS) с использованием чистого PHP, выделим ключевые компоненты и предоставим пошаговые инструкции вместе с примерами кода.
Зачем создавать без фреймворка?
Прежде чем углубляться, стоит задать вопрос: зачем вам может понадобиться создавать CMS без фреймворка? Вот несколько причин:
- Обучение: Создание с нуля помогает понять основные механизмы PHP и веб-разработку.
- Кастомизация: Вы полностью контролируете каждый аспект своего приложения.
- Лёгкость: Нет ненужных накладных расходов от полноценного фреймворка.
- Вызов: Это интересное и полезное испытание для разработчиков, желающих проверить свои навыки.
Настройка проекта
Чтобы начать, создайте новый проект со следующей структурой:
project/
├── public/
│ ├── index.php
│ └── .htaccess
├── src/
│ ├── App/
│ │ ├── Lib/
│ │ │ ├── App.php
│ │ │ └── Router.php
│ │ └── Models/
│ │ └── Post.php
│ └── Config/
│ └── config.php
├── composer.json
└── composer.lock
Composer и автозагрузка
Несмотря на то, что мы не используем фреймворк, Composer по-прежнему невероятно полезен для управления зависимостями и настройки автозагрузки.
Создайте файл composer.json
в корне вашего проекта:
{
"require": {
"monolog/monolog": "1.25.1"
},
"autoload": {
"psr-4": {
"App\\": "src/App/"
}
}
}
Запустите composer install
, чтобы настроить автозагрузчик и установить зависимости.
Фронт контроллер
Фронт-контроллер является центральным входом в ваше приложение. Он обрабатывает каждый входящий запрос и направляет его к соответствующей части вашего приложения.
Создайте public/index.php
со следующим кодом:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use App\Lib\App;
App::run();
Маршрутизация
Маршрутизация имеет решающее значение для направления запросов к нужным частям вашего приложения. Вот простой класс маршрутизатора для начала работы.
Создайте src/App/Lib/Router.php
:
<?php
declare(strict_types=1);
namespace App\Lib;
class Router
{
private $routes = [];
public function addRoute(string $method, string $path, callable $callback)
{
$this->routes[] = [
'method' => $method,
'path' => $path,
'callback' => $callback,
];
}
public function dispatch()
{
$uri = $_SERVER['REQUEST_URI'];
$method = $_SERVER['REQUEST_METHOD'];
foreach ($this->routes as $route) {
if ($route['method'] === $method && $route['path'] === $uri) {
return call_user_func($route['callback']);
}
}
http_response_code(404);
echo 'Page not found';
}
}
Загрузочный код приложения
Теперь давайте создадим класс App
, который будет запускать наше приложение и использовать маршрутизатор.
Создайте src/App/Lib/App.php
:
<?php
declare(strict_types=1);
namespace App\Lib;
use App\Lib\Router;
class App
{
public static function run()
{
$router = new Router();
// Пример маршрутов
$router->addRoute('GET', '/', function () {
echo 'Добро пожаловать в нашу CMS!';
});
$router->addRoute('GET', '/posts', function () {
// Логика для списка сообщений
echo 'Список сообщений';
});
$router->dispatch();
}
}
База данных и модели
Для простоты мы будем использовать файл JSON в качестве базы данных. Это не подходит для продакшена, но хорошо работает для небольшого примера.
Создайте src/App/Models/Post.php
:
<?php
declare(strict_types=1);
namespace App\Models;
class Post
{
private $id;
private $title;
private $body;
public function __construct(int $id, string $title, string $body)
{
$this->id = $id;
$this->title = $title;
$this->body = $body;
}
public function getId(): int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function getBody(): string
{
return $this->body;
}
public static function loadPosts(): array
{
$posts = json_decode(file_get_contents('posts.json'), true);
return array_map(function ($post) {
return new self($post['id'], $post['title'], $post['body']);
}, $posts);
}
public static function savePost(Post $post)
{
$posts = self::loadPosts();
$posts[] = [
'id' => $post->getId(),
'title' => $post->getTitle(),
'body' => $post->getBody(),
];
file_put_contents('posts.json', json_encode($posts));
}
}
Обновите класс App
для включения маршрутов для сообщений:
// В src/App/Lib/App.php
use App\Models\Post;
// ...
$router->addRoute('GET', '/posts', function () {
$posts = Post::loadPosts();
foreach ($posts as $post) {
echo "ID: {$post->getId()}, Title: {$post->getTitle()}, Body: {$post->getBody()}\n";
}
});
$router->addRoute('POST', '/posts', function () {
$data = json_decode(file_get_contents('php://input'), true);
$post = new Post(
time(), // Простой генерация ID
$data['title'],
$data['body']
);
Post::savePost($post);
echo 'Сообщение сохранено успешно';
});
Тестирование приложения
Чтобы протестировать приложение, запустите встроенный веб-сервер PHP:
php -S localhost:8080 -t public/
Перейдите по адресу http://localhost:8080/
в браузере, чтобы увидеть приветственное сообщение. Вы также можете использовать такие инструменты, как Postman или curl
, чтобы протестировать POST-конечную точку.
curl -X POST http://localhost:8080/posts -H 'Content-Type: application/json' -d '{"title":"Мой пост","body":"Это мой пост"}'