Создание веб-приложений на PHP: полное руководство

Раздел: Веб-разработка -> Разработка веб-приложений

Основные подходы к разработке веб-приложений на PHP

Как создать современное веб-приложение с использованием фреймворка Laravel?

Laravel – наиболее эффективное решение для разработки веб-приложений на PHP, так как предоставляет готовую архитектуру MVC, удобный ORM (Eloquent), мощную систему шаблонов Blade, встроенную аутентификацию и множество инструментов для тестирования.

Установка: composer create-project laravel/laravel example-app

composer create-project laravel/laravel example-app --prefer-dist
cd example-app
php artisan serve

Php веб интерфейс (создание веб-интерфейса на php)

Пример создания маршрута и контроллера:

// routes/web.php
Route::get('/hello', [App\Http\Controllers\HelloController::class, 'index']);

// app/Http/Controllers/HelloController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HelloController extends Controller
{
    public function index()
    {
        return view('hello', ['name' => 'Мир']);
    }
}

// resources/views/hello.blade.php
<h1>Привет, {{ $name }}!</h1>

разработка web приложений php (разработка веб-приложений на php)

Привет, Мир!

управление сайтом php (управление сайтом на php)

Работа с базой данных через Eloquent:

// Создание модели и миграции
php artisan make:model Post -m

// миграция database/migrations/..._create_posts_table.php
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('content');
    $table->timestamps();
});

// использование в контроллере
use App\Models\Post;
$posts = Post::where('id', '>', 5)->get();
foreach ($posts as $post) {
    echo $post->title;
}

Типичные проблемы при работе с Laravel:

  • Ошибка доступа к storage: выполнить php artisan storage:link и установить права 775 на директории storage и bootstrap/cache.
  • Забытая миграция: проверьте файлы в database/migrations и выполните php artisan migrate:fresh --seed.
  • Проблемы с зависимостями: используйте composer update --no-dev для продакшена.

Цели:

  • Быстрая разработка сложных приложений с готовыми решениями.
  • Командная работа благодаря единому стандарту кода.
  • Высокая производительность за счёт кэширования и оптимизации.

Как создать собственный MVC без фреймворка на чистом PHP?

Самописный MVC полезен для понимания внутренней архитектуры PHP-приложений. Используется в учебных целях или при жёстких ограничениях на использование внешних библиотек.

// .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/?url=$1 [QSA,L]

// index.php (фронт-контроллер)
require_once 'Router.php';
$router = new Router();
$router->addRoute('GET', '/', 'HomeController@index');
$router->addRoute('GET', '/user/(\d+)', 'UserController@show');
$router->dispatch($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);

// Router.php
class Router {
    private $routes = [];
    public function addRoute($method, $pattern, $handler) {
        $this->routes[] = ['method' => $method, 'pattern' => $pattern, 'handler' => $handler];
    }
    public function dispatch($method, $uri) {
        foreach ($this->routes as $route) {
            if ($route['method'] === $method && preg_match('#^' . $route['pattern'] . '$#', $uri, $matches)) {
                list($controller, $action) = explode('@', $route['handler']);
                $controller = new $controller();
                call_user_func_array([$controller, $action], array_slice($matches, 1));
                return;
            }
        }
        http_response_code(404);
        echo '404 Not Found';
    }
}

Распространённые ошибки:

  • Некорректные регулярные выражения в маршрутах – используйте preg_match с явными захватывающими группами.
  • Отсутствие автозагрузки – подключите через spl_autoload_register или Composer.
  • Уязвимость к SQL-инъекциям – обязательно применяйте подготовленные выражения (PDO).

Случаи использования: обучение, простые сайты без необходимости в расширенном функционале.

Как построить REST API с помощью микрофреймворка Slim?

Микрофреймворки (Slim, Flight, Silex) удобны для создания быстрых API, микросервисов и приложений с минимальным оверхедом.

composer require slim/slim"^4.0"
composer require slim/psr7

// index.php
use Slim\Factory\AppFactory;
require __DIR__ . '/vendor/autoload.php';
$app = AppFactory::create();
$app->get('/users/{id}', function ($request, $response, $args) {
    $id = $args['id'];
    $data = ['id' => $id, 'name' => 'Пользователь ' . $id];
    $response->getBody()->write(json_encode($data));
    return $response->withHeader('Content-Type', 'application/json');
});
$app->run();
curl http://localhost/users/42
Response: {"id":"42","name":"Пользователь 42"}

Добавление middleware для авторизации:

$app->add(function ($request, $handler) {
    $auth = $request->getHeaderLine('Authorization');
    if ($auth !== 'Bearer secret-token') {
        $response = new \Slim\Psr7\Response();
        $response->getBody()->write('Unauthorized');
        return $response->withStatus(401);
    }
    return $handler->handle($request);
});

Проблемы:

  • Отсутствие встроенной валидации – используйте библиотеку Respect/Validation.
  • Сложность с наследованием шаблонов – Slim не предоставляет собственного шаблонизатора (можно подключить Twig).
  • Ручная обработка CORS – добавьте middleware для установки заголовков.

Цели: создание лёгких API, прототипов, интеграций.

Как построить веб-приложение на базе WordPress?

WordPress – CMS, но её можно использовать как основу для веб-приложения благодаря системе плагинов и хуков. Подходит для быстрого создания функциональных сайтов с административной панелью.

// Добавление кастомного типа записи в functions.php
function create_post_type() {
    register_post_type('book',
        array(
            'labels' => array('name' => 'Книги'),
            'public' => true,
            'has_archive' => true,
            'supports' => array('title', 'editor', 'thumbnail')
        )
    );
}
add_action('init', 'create_post_type');

// Использование WP_Query для вывода книг
$query = new WP_Query(array('post_type' => 'book', 'posts_per_page' => 5));
if ($query->have_posts()) {
    while ($query->have_posts()) { $query->the_post(); ?>
        <h2><?php the_title(); ?></h2>
        <p><?php the_excerpt(); ?></p>
    <?php }
    wp_reset_postdata();
}

Проблемы:

  • Перегруженность кода – используйте дочерние темы и избегайте изменений в ядре.
  • Низкая производительность при большом числе запросов – используйте объектное кэширование (Redis).
  • Безопасность – регулярно обновляйте ядро и плагины, используйте nonce для форм.

Случаи использования: веб-приложения с контентом, интернет-магазины (WooCommerce), системы управления.

Расширенные примеры программного кода

1. Маршрутизация с регулярными выражениями в самописном MVC

Пример
class Router {
    private $routes = [];

    public function addRoute($methods, $pattern, $handler) {
        $methods = (array)$methods;
        $pattern = preg_replace('/\//', '\/', $pattern);
        $pattern = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[\w-]+)', $pattern);
        $this->routes[] = ['methods' => $methods, 'pattern' => '/^' . $pattern . '$/i', 'handler' => $handler];
    }

    public function match($uri, $method) {
        foreach ($this->routes as $route) {
            if (!in_array($method, $route['methods'])) continue;
            if (preg_match($route['pattern'], $uri, $matches)) {
                $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
                return ['handler' => $route['handler'], 'params' => $params];
            }
        }
        return false;
    }

    public function dispatch() {
        $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        $method = $_SERVER['REQUEST_METHOD'];
        $match = $this->match($uri, $method);
        if ($match) {
            list($class, $action) = explode('@', $match['handler']);
            $controller = new $class();
            call_user_func_array([$controller, $action], $match['params']);
        } else {
            http_response_code(404);
            echo '404';
        }
    }
}

// Использование:
$router = new Router();
$router->addRoute('GET', '/post/{slug}', 'PostController@show');
$router->addRoute(['GET', 'POST'], '/contact', 'ContactController@form');
$router->dispatch();
При GET /post/hello-world вызовется PostController::show(['slug' => 'hello-world'])

2. Подготовленные запросы PDO с транзакциями и обработкой ошибок

Пример
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8mb4';
$user = 'root';
$pass = '';
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
    $pdo->beginTransaction();

    $stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
    $stmt->execute([':name' => 'Иван', ':email' => 'ivan@example.com']);
    $userId = $pdo->lastInsertId();

    $stmt2 = $pdo->prepare('INSERT INTO profiles (user_id, bio) VALUES (:uid, :bio)');
    $stmt2->execute([':uid' => $userId, ':bio' => 'Разработчик']);

    $pdo->commit();
    echo 'Пользователь создан с ID ' . $userId;
} catch (PDOException $e) {
    $pdo->rollBack();
    echo 'Ошибка: ' . $e->getMessage();
}
Пользователь создан с ID 42

3. Компоненты Laravel: Queues и Events

Пример
// Создание задания
php artisan make:job ProcessPayment

// app/Jobs/ProcessPayment.php
class ProcessPayment implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $order;

    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    public function handle()
    {
        // Обработка платежа
        logger('Оплата заказа ' . $this->order->id);
    }
}

// Использование в контроллере
ProcessPayment::dispatch($order)->onQueue('payments');

// Событие и слушатель (EventServiceProvider)
protected $listen = [
    OrderPlaced::class => [
        SendOrderConfirmation::class,
        UpdateInventory::class,
    ],
];

// Классы событий и слушателей генерируются artisan make:event / make:listener
Обработка уходит в очередь (redis/database). Лог: "Оплата заказа 1"

4. Использование Twig в Slim для шаблонизации

Пример
composer require slim/twig-view

// index.php
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;

$twig = Twig::create(__DIR__ . '/templates', ['cache' => false]);
$app->add(TwigMiddleware::create($app, $twig));

$app->get('/hello/{name}', function ($request, $response, $args) {
    return $this->get('view')->render($response, 'hello.twig', ['name' => $args['name']]);
});

// templates/hello.twig
<h1>Привет, {{ name }}!</h1>
GET /hello/Вася → отображается страница с заголовком "Привет, Вася!"

5. Кастомный middleware для проверки CSRF в чистом PHP

Пример
session_start();

class CsrfMiddleware
{
    public static function generateToken()
    {
        if (empty($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
        return $_SESSION['csrf_token'];
    }

    public static function validateToken($token)
    {
        if (!empty($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token)) {
            return true;
        }
        return false;
    }
}

// Использование в форме
$token = CsrfMiddleware::generateToken();
echo '<input type="hidden" name="csrf_token" value="' . $token . '">';

// Валидация на сервере
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!CsrfMiddleware::validateToken($_POST['csrf_token'] ?? '')) {
        die('CSRF token недействителен');
    }
}
При отправке формы с неверным токеном выводится сообщение об ошибке

Разработка веб-приложений на PHP - comments

En
разработка web приложений php (php)