Запуск PHP-скриптов: веб, консоль и eval

Раздел: Разработка на PHP -> Выполнение PHP и команд

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

Основные способы выполнения PHP-кода

Как выполнить PHP-скрипт в production-окружении?

Наиболее эффективное решение - запуск через веб-сервер с PHP-FPM (FastCGI Process Manager). Веб-сервер (Nginx или Apache) передаёт запросы на выполнение PHP-файлов процессу PHP-FPM, который обрабатывает их и возвращает результат клиенту. Этот подход обеспечивает высокую производительность, изоляцию процессов и поддержку множества одновременных соединений.

Пример настройки Nginx + PHP-FPM:

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

После настройки файл index.php в корне сайта будет исполняться при обращении к домену. Для проверки создайте файл с кодом <?php phpinfo(); ?> - в браузере отобразится информация о PHP.

Проблема:

Браузер возвращает содержимое файла как текст, а не исполняет его. Это указывает на то, что PHP не обрабатывается сервером. Решение: убедитесь, что PHP-FPM запущен и сокет (или порт) указан верно, а также что конфигурация Nginx корректно подхвачена (перезапустите nginx).

Как выполнить PHP-код без установленного веб-сервера?

Для разработки и тестирования удобен встроенный сервер PHP, запускаемый из командной строки. Он не предназначен для production, но идеален для локальной работы.

Пример запуска:

php -S localhost:8000

Сервер обслуживает текущую директорию. Указав файл-роутер, можно обрабатывать все запросы через один скрипт:

php -S localhost:8000 index.php

Пошаговое пояснение:

  • -S - запуск встроенного сервера.
  • localhost:8000 - адрес и порт.
  • index.php - файл, который будет выполняться для всех запросов (роутер).

Возможная ошибка:

Сервер не запускается, если порт занят. Решение: укажите другой порт, например php -S localhost:8080.

Как запустить PHP-скрипт на сервере через терминал?

Исполняемые файлы PHP можно запускать напрямую из командной строки (CLI). Это используется для фоновых заданий, cron-скриптов и обработки данных.

Базовая команда:

php /path/to/script.php

Пример скрипта count.php:

<?php
$lines = file('data.txt');
echo 'Количество строк: ' . count($lines);
?>

Результат выполнения:

Количество строк: 42

Для передачи аргументов скрипту используйте массив $argv:

php count.php data.txt

Внутри файла $argv[1] будет содержать data.txt.

Проблема:

Команда php не найдена. Решение: добавьте путь к интерпретатору в переменную окружения PATH или используйте полный путь, например /usr/bin/php.

Как выполнить строку PHP-кода внутри другого скрипта?

Для динамического выполнения кода существует функция eval(). Она принимает строку с PHP-кодом и исполняет её в текущей области видимости. Применяется с осторожностью из-за риска внедрения вредоносного кода.

Пример:

<?php
$code = 'return 2 + 2;';
$result = eval($code);
echo $result;
?>

Результат:

4

Важно: код, передаваемый в eval, должен быть синтаксически корректным. Используйте try..catch с Error для отлова ошибок:

<?php
try {
    eval('echo $undefined;');
} catch (Error $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
?>

Ошибка синтаксиса:

Если строка содержит ошибку, eval возвращает false и генерирует фатальную ошибку. Используйте error_reporting(0) с последующей проверкой, но лучший подход - валидировать код перед выполнением или заменить eval на безопасные альтернативы (например, анонимные функции).

Как выполнить код из другого файла?

Конструкции include, require, include_once и require_once подключают и выполняют код из указанного файла. Это основной способ повторного использования кода.

Пример:

<?php
require 'config.php';   // выполняет код из config.php
include 'functions.php'; // если файл не найден, выдаёт warning, но скрипт продолжается
?>

Отличие include от require: при ошибке include генерирует предупреждение, require - фатальную ошибку. _once версии предотвращают повторное включение.

Ошибка:

Файл не найден, и скрипт завершается (если require). Решение: проверяйте пути с помощью __DIR__ и используйте абсолютные пути для критичных файлов.

Расширенные примеры выполнения PHP-кода

1. Встроенный сервер с роутером

Можно создать единую точку входа (роутер), которая обрабатывает все запросы. Это удобно для разработки приложений без необходимости настройки виртуальных хостов.

Файл router.php:

Пример
<?php
if (preg_match('/\.(?:png|jpg|jpeg|gif|css|js)$/', $_SERVER['REQUEST_URI'])) {
    return false;   // отдать статичный файл как есть
}

$path = __DIR__ . '/app' . $_SERVER['REQUEST_URI'] . '.php';
if (file_exists($path)) {
    require $path;
} else {
    http_response_code(404);
    echo 'Страница не найдена';
}
?>

Запуск:

Пример
php -S localhost:8000 router.php

Результат: при запросе /users будет выполнен файл app/users.php, если он существует.

2. CLI-скрипт с аргументами и опциями

Сценарий командной строки может принимать множество параметров с помощью getopt().

Пример
<?php
$options = getopt('f:', ['file:', 'help']);

if (isset($options['help'])) {
    echo 'Использование: php convert.php --file input.txt' . PHP_EOL;
    exit(0);
}

$filename = $options['file'] ?? $options['f'] ?? null;
if (!$filename) {
    fwrite(STDERR, 'Не указан файл' . PHP_EOL);
    exit(1);
}

$content = file_get_contents($filename);
echo 'Прочитано ' . strlen($content) . ' байт' . PHP_EOL;
?>

Пример выполнения:

Пример
php convert.php --file=document.txt
Прочитано 1024 байт

При неверном параметре выводится сообщение в STDERR и скрипт завершается с кодом 1.

3. eval() с ограничением ресурсов

Для безопасного выполнения динамического кода можно устанавливать лимиты времени и памяти.

Пример
<?php
$code = 'for(;;);'; // бесконечный цикл

set_time_limit(2);   // ограничение 2 секунды
$maxMemory = 32 * 1024 * 1024; // 32 MB
memory_limit($maxMemory);

try {
    $result = eval($code);
    var_dump($result);
} catch (Throwable $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
?>

Результат: через 2 секунды скрипт будет прерван из-за таймаута, и будет выброшено исключение (если настроено). Обратите внимание: memory_limit() можно изменить только если ini_set не запрещён.

4. include с обработкой ошибок

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

Пример
<?php
set_error_handler(function ($severity, $message, $file, $line) {
    throw new ErrorException($message, 0, $severity, $file, $line);
});

try {
    include 'nonexistent.php';
} catch (ErrorException $e) {
    echo 'Не удалось подключить файл: ' . $e->getMessage();
}

restore_error_handler();
?>

Результат:

Не удалось подключить файл: include(nonexistent.php): Failed to open stream: No such file or directory

Этот подход позволяет централизованно обрабатывать ошибки подключения.

5. Запуск PHP-скрипта как отдельного процесса с pcntl_exec

В Linux-среде можно заменить текущий процесс на другой PHP-скрипт через pcntl_exec(). Это полезно для выполнения «тяжёлых» задач в изолированном процессе.

Пример
<?php
$pid = pcntl_fork();
if ($pid == -1) {
    die('Не удалось создать процесс');
} elseif ($pid) {
    // родительский процесс
    pcntl_wait($status);
    echo 'Дочерний процесс завершён с кодом ' . pcntl_wexitstatus($status);
} else {
    // дочерний процесс
    pcntl_exec('/usr/bin/php', ['/var/scripts/worker.php', '--option=value']);
}
?>

Примечание: функция pcntl_* доступна только при PHP с опцией --enable-pcntl и не работает на Windows. Используйте с осторожностью.

6. Выполнение кода через php://input

PHP поддерживает поток php://input для чтения сырых данных запроса. Можно выполнить код, переданный в POST-запросе (только для образовательных целей; в реальных проектах это небезопасно).

Пример
<?php
$code = file_get_contents('php://input');
if (!empty($code)) {
    eval($code);
} else {
    echo 'Нет кода для выполнения';
}
?>

Пример отправки через curl:

Пример
curl -X POST -d 'echo "Hello from POST";' http://localhost:8000/
Hello from POST

Этот метод крайне опасен из-за возможности удалённого выполнения кода (RCE). Применяйте только в изолированной тестовой среде.

Выполнение PHP-кода - comments

En
Php выполнение кода (php)