PHP Conference Nagoya 2025

Выполнение PHP-файлов

В CLI SAPI есть три различных способа запуска PHP-кода:

  1. Указание конкретного файла для запуска.

    $ php my_script.php
    
    $ php -f my_script.php
    

    Оба способа (с указанием опции -f или без) запустят файл my_script.php. Нет ограничений, какой файл запускать; в частности, файлы не обязаны иметь расширение .php.

  2. Передать PHP-код напрямую в командной строке.

    $ php -r 'print_r(get_defined_constants());'
    

    Необходимо быть особо осторожным при использовании этого способа, т.к. может произойти подстановка переменных оболочки при использовании двойных кавычек.

    Замечание:

    Внимательно прочтите пример: в нем нет открывающих и закрывающих тегов! Опция -r просто в них не нуждается, и их использование приведёт к ошибке разбора.

  3. Передать запускаемый PHP-код через стандартный поток ввода (stdin).

    Это даёт мощную возможность создавать PHP-код и передавать его запускаемому файлу, как показано в этом (вымышленном) примере:

    $ some_application | some_filter | php | sort -u > final_output.txt
    
Вы не можете комбинировать любой из этих трёх способов запуска кода.

Как и любое другое консольное приложение бинарный файл PHP принимает аргументы, но PHP-скрипт также получает аргументы. PHP не ограничивает количество аргументов, передаваемых в скрипт (оболочка консоли устанавливает некоторый порог количества символов, которые могут передать; обычно этого лимита хватает). Переданные аргументы доступны в глобальном массиве $argv. Первый индекс (ноль) всегда содержит имя вызываемог из командной строкио скрипта. Учтите, что если код вызывается из командной строки на лету с опцией -r, значением элемента $argv[0] будет «Стандартный поток» (Standard input code); до PHP 7.2.0 это был дефис ("-"). То же самое верно и для кода, переданного через конвейер из STDIN.

Вторая зарегистрированная глобальная переменная — $argc, которая содержит количество элементов в массиве $argvне количество аргументов, которые передали скрипту).

Если передаваемые аргументы не начинаются с символа -, то особых проблем быть не должно. Передаваемый в скрипт аргумент, который начинается с - создаст проблемы, т.к. PHP решит, что он сам должен его обработать. Для предотвращения подобного поведения используйте разделитель списка аргументов --. После того, как этот разделитель будет проанализирован PHP, все последующие аргументы будут переданы в скрипт нетронутыми.

# Эта команда не запустит данный код, но покажет информацию об использовании PHP
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# Эта команда передаст аргумент '-h' в скрипт, предотвратив показ справки PHP
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

Однако, в Unix-системах есть ещё один способ использования PHP для консольных скриптов. Можно написать скрипт, первая строка которого будет начинаться с #!/usr/bin/php (или же другой корректный путь к бинарному файлу PHP CLI). После этой строки можно поместить обычный PHP-код, заключённый в открывающие и закрывающие теги PHP. Как только будут установлены корректные атрибуты запуска на файл (например, chmod +x test), скрипт может быть запущен как обычный консольный или perl-скрипт:

Пример #1 Запуск PHP-скрипта как консольного

#!/usr/bin/php
<?php
var_dump
($argv);
?>

Предполагая, что этот файл назван test и находится в текущей директории, можно сделать следующее:

$ chmod +x test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}

Как можно увидеть, в этом случае не нужно заботиться о передаче параметров, которые начинаются с -.

Исполняемый PHP-файл может использоваться для запуска PHP-скриптов независимо от веб-сервера. В случае работы в Unix-подобной системе, необходимо добавить в первую строку файла #! (называемый также "shebang") чтобы указать, какая из программ должна запускать скрипт. На Windows-платформах можно назначить обработчик php.exe для файлов с расширениями .php или создать пакетный (.bat) файл для запуска скриптов посредством PHP. Строка, добавляемая в начале скрипта для Unix-систем, не влияет на их работу в ОС Windows, таким образом можно создавать кросс-платформенные скрипты. Ниже приведён простой пример скрипта, который выполняется из командной строки:

Пример #2 Скрипт для запуска из командной строки (script.php)

#!/usr/bin/php
<?php

if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
?>

Это консольный PHP-скрипт, принимающий один аргумент.

Использование:
<?php echo $argv[0]; ?> <option>

<option> Любое слово, которое вы хотели бы
напечатать. Опции --help, -help, -h,
или -? покажут текущую справочную информацию.

<?php
} else {
echo
$argv[1];
}
?>

В приведённом выше скрипте в первой строке содержится shebang, указывающий что этот файл должен запускаться PHP. Работа ведётся с CLI-версией, поэтому не будет выведено ни одного HTTP-заголовка.

Скрипт сначала проверяет наличие обязательного одного аргумента (в дополнение к имени скрипта, который также подсчитывается). Если их нет, или если переданный аргумент был --help, -help, -h или -?, выводится справочное сообщение с использованием $argv[0], которое содержит имя выполняемого скрипта. В противном случае просто выводится полученный аргумент.

Для запуска приведённого примера в Unix-системе, нужно сделать его исполняемым и просто выполнить в консоли script.php echothis или script.php -h. В Windows-системе можно создать пакетный файл:

Пример #3 Пакетный файл для запуска PHP-скрипта из командной строки (script.bat)

@echo OFF
"C:\php\php.exe" script.php %*

Предполагая, что вышеприведённый скрипт называется script.php, а полный путь к CLI php.exe находится в C:\php\php.exe, этот пакетный файл запустит его с переданными параметрами: script.bat echothis или script.bat -h.

Также можно ознакомиться с модулем Readline для получения дополнительных функций, которые можно использовать для улучшения консольного PHP-скрипта.

В Windows запуск PHP можно настроить без необходимости указывать C:\php\php.exe или расширение .php. Подробнее эта тема описана в разделе Запуск PHP из командной строки в Microsoft Windows.

Замечание:

В Windows рекомендуется запускать PHP под актуальной учётной записью пользователя. При работе в сетевой службе некоторые операции не будут выполнены, поскольку "сопоставление имён учётных записей и идентификаторов безопасности не выполнено".

Добавить

Примечания пользователей 5 notes

up
59
php at richardneill dot org
11 years ago
On Linux, the shebang (#!) line is parsed by the kernel into at most two parts.
For example:

1: #!/usr/bin/php
2: #!/usr/bin/env php
3: #!/usr/bin/php -n
4: #!/usr/bin/php -ddisplay_errors=E_ALL
5: #!/usr/bin/php -n -ddisplay_errors=E_ALL

1. is the standard way to start a script. (compare "#!/bin/bash".)

2. uses "env" to find where PHP is installed: it might be elsewhere in the $PATH, such as /usr/local/bin.

3. if you don't need to use env, you can pass ONE parameter here. For example, to ignore the system's PHP.ini, and go with the defaults, use "-n". (See "man php".)

4. or, you can set exactly one configuration variable. I recommend this one, because display_errors actually takes effect if it is set here. Otherwise, the only place you can enable it is system-wide in php.ini. If you try to use ini_set() in your script itself, it's too late: if your script has a parse error, it will silently die.

5. This will not (as of 2013) work on Linux. It acts as if the whole string, "-n -ddisplay_errors=E_ALL" were a single argument. But in BSD, the shebang line can take more than 2 arguments, and so it may work as intended.

Summary: use (2) for maximum portability, and (4) for maximum debugging.
up
6
email at alexander-bombis dot de
3 years ago
For Windows:

After the years I also have the fact that I have to use double quotation marks after php -r on Windows shell.

But in the Powershell you can use single or double quotation!
up
4
gabriel at figdice dot org
8 years ago
Regarding shebang:

In both Linux and Windows, when you execute a script in CLI with:

php script.php

then PHP will ignore the very first line of your script if it starts with:

#!

So, this line is not only absorbed by the kernel when the script file is executable, but it is also ignored by the PHP engine itself.

However, the engine will NOT ignore the first #! line of any included files withing your "outer" script.php.
Any "shebang" line in an included script, will result in simply outputting the line to STDOUT, just as any other text residing outside a <?php ... ?> block.
up
3
david at frankieandshadow dot com
8 years ago
A gotcha when using #!/usr/bin/php at the start of the file as noted above:

if you originally edited the file on Windows and then attempt to use it on Unix, it won't work because the #! line requires a Unix line ending. Bash gives you the following error message if it has DOS line endings:
"bash: /usr/local/bin/wpreplace.php: /usr/bin/php^M: bad interpreter: No such file or directory"

(In Emacs I used "CTRL-X ENTER f" then type "unix" and ENTER to convert)
up
2
spencer at aninternetpresence dot net
13 years ago
If you are running the CLI on Windows and use the "-r" option, be sure to enclose your PHP code in double (not single) quotes. Otherwise, your code will not run.
To Top