External variables (variables outside PHP) Using PHP from the command line

Lecture



Web programming for the most part is just the processing of various data entered by the user - that is, the processing of HTML forms .
Perhaps there is no other language like PHP that would make your task of processing and parsing so much easier. external variables i.e. variables that came from HTML forms (from the user's browser). The fact is that all necessary features are built into the PHP language, so you don’t even have to think about the features of the HTTP protocol and think about how to send and receive POST forms or even download files. PHP developers have foreseen everything.

Here we will not dwell on the mechanics of the HTTP protocol, which is responsible for delivering data from the browser to the server and back; a special section PHP and HTTP is devoted to this. The principles of working with HTML-forms are also deeply considered.

Now we will consider these mechanisms only from applied positions, without delving into theory.

In order to receive data from users, we need interactive interaction with them.

And now let's try to write a script that takes the username in the parameters and displays:

"Hello, <name>!".

First, consider the easiest way to pass a name to a script — is it directly typed into the URL after the sign ? - for example, in the format name = name . Here is an example:

http://localhost/script.php? name=имя

Our script should recognize the name parameter. That is, to put it simply, the script (script) must accept the name parameter as a variable name , and then display the string "Hello, <name>!" In the user's browser. You can do it this way:

We write a script that takes the name parameter and displays the result in the user's browser, and then saves it as script.php :

<?php
echo "Привет, $_GET['name'] !";
?>

In our example, we used the predefined variable $ _GET ['name'] to "accept" the name parameter. Now, passing the parameter name = Sasha through a GET request, we get the following result:

Привет, Саша !

And now let's try to pass the name parameter not from the browser's request string, but through the HTML form. Create an HTML document as follows:

<form action="http://localhost/script.php" method="GET">
Name: <input type=text name=name><br><input type=submit value="GO!">
</form>

Now we will save this HTML document on our test server (localhost) under the name send.html in the same directory where we already saved the script script.php .

Now run the HTML document in the browser:

http://localhost/send.html

Enter the name in the field and press the button "GO!". The form will transfer the name parameter to our script.php via the GET request. If you did everything correctly and your web server is working properly, you will see the name you entered in the form field! In the address bar of the browser you will see the path and the parameter name you passed.

Now we need to understand how we can transfer a lot of parameters, for a start, at least two .

So, we need the script to output the following:

"Hello, <name>! You are <age> years old!".

That is, we need to transfer 2 parameters to the script: name and age .

Now we will write a script.php script that takes two parameters: name and age , as well as an HTML document with a form that will pass these two parameters to our new script:

<?php
echo "Привет, $_GET['name'] ! Вам $_GET['age'] лет !";
?>

And here is the HTML document send.html , with which we pass the name and age parameters to our script:

<html><body>
<form action="script.php">
Введите имя: <input type=text name="name"><br>
Введите возраст: <input type=text name="age"><br>
<input type=submit value="GO!">
</form>
</body></html>

Now our script takes two parameters name and age and displays the result of the format in the browser: "Hello, <name>! You are <age> years old!".

Pay attention to the address bar of the browser after passing the parameters to the script, it will look something like this (without the Cyrillic URL-coding):

http://localhost/script.php?name=Саша&age=23

Depending on your interpreter’s settings, there are several ways to access data from your HTML forms. Here are some examples:

<?php
// Доступно, начиная с PHP 4.1.0

echo $_GET['username'];
echo $_POST['username'];
echo $_REQUEST['username'];

import_request_variables('p', 'p_');
echo $p_username;

// Доступно, начиная с PHP 3. Начиная с PHP 5.0.0, эти длинные предопределенные
// переменные могут быть отключены директивой register_long_arrays.

echo $HTTP_GET_VARS['username'];

// Доступно, если директива PHP register_globals = on. Начиная
// с PHP 4.2.0, значение по умолчанию register_globals = off.
// Использование/доверие этому методу непредпочтительно.

echo $username;
?>

Here's how it usually happens: We need to write a tiny console backup script that can be run from the crown, and at the same time the script must accept parameters for connecting to the database.

Argv and argc functions

The simplest thing we start to write will look something like this:

cli-argv-argc.php

  <? php
 // Expect the script to be called with the following parameters:
 // php backup.php dbuser dbpassword database host

 if ($ argc! = 5) {
     die (PHP_EOL. 'Use: php backup.php dbuser dbpassword database host'. PHP_EOL);
 }

 $ dbuser = $ argv [1];
 $ dbpassword = $ argv [2];
 $ database = $ argv [3];
 $ host = $ argv [4];

 $ mysql = mysql_connect ($ host, $ dbuser, $ dbpassword);
 mysql_select_db ($ database, $ mysql);
 // ...

Here we used the system variable args to get the number of all parameters. Remember that the zero parameter (script name) is also taken into account here.

And the system variable argv with an array of all parameters.

For the simplest script, this is enough, but what if we want to support and give this script to other developers?

Most likely there will be a lot of swearing in our direction, because it is very easy to make a mistake and interchange the password and database and notice the error will be extremely difficult. Take a look:

  php backup.php dbuser database dbpassword host 

Parse the parameters with the getopt function

This is where an extremely convenient parameter parsing function comes to our rescue: getopt

The main power of getopt is that it allows us to use flags, required and optional parameters in arbitrary order.

Let's write a simple but very expressive example of using getopt, and then, look how people used to suffer with regulars to parse the command line :)

backup.php

  <? php

 // Two forms of writing arguments are shown here: short and full
 // At the same time, if after the parameter there are two colons, then the parameter is optional,
 // and if one colon means mandatory.
 // all parameters that are not specified in the configuration will be ignored
 $ params = array (
     '' => 'help',
     'h ::' => 'host ::',
     'u:' => 'user:',
     'p ::' => 'password ::',
     'd:' => 'database:',
 );

 // Default values
 $ host = 'localhost';
 $ user = 'root';
 $ password = null;
 $ database = '';
 $ errors = array ();

 $ options = getopt (implode ('', array_keys ($ params)), $ params);

 if (isset ($ options ['host']) || isset ($ options ['h']))
 {
     $ host = isset ($ options ['host'])?  $ options ['host']: $ options ['h'];
 }

 if (isset ($ options ['user']) || isset ($ options ['u']))
 {
     $ port = isset ($ options ['user'])?  $ options ['user']: $ options ['u'];
 }
 else
 {
     $ errors [] = 'user required';
 }

 if (isset ($ options ['password']) || isset ($ options ['p']))
 {
     $ socket = isset ($ options ['password'])?  $ options ['password']: $ options ['p'];
 }

 if (isset ($ options ['database']) || isset ($ options ['d']))
 {
     $ database = isset ($ options ['database'])?  $ options ['database']: $ options ['d'];
 }
 else
 {
     $ errors [] = 'database required';
 }

 if (isset ($ options ['help']) || count ($ errors))
 {
     $ help = "
 usage: php backup.php [--help] [-h | --host = 127.0.0.1] [-u | --user = root] [-p | --password = secret] [-d | --database ]

 Options:
             --help Show this message
         -h --host Server hostname (default: localhost)
         -u --user User
         -p --password Password (default: no password)
         -d --database Database
 Example:
         php backup.php --user = root --password = secret --database = blog
 ";
     if ($ errors)
     {
         $ help. = 'Errors:'.  PHP_EOL.  implode ("\ n", $ errors).  PHP_EOL;
     }
     die ($ help);
 }

 $ mysql = mysql_connect ($ host, $ user, $ password);
 mysql_select_db ($ database, $ mysql);

 // .... 

Now let's run our script with the –help parameter and rejoice that a well-supported and understandable program is so easy to write

  php backup.php --help 

In short, getopt takes all the arguments from the command line and adds valid parameters to the $ options array. And from the resulting array, we can get all the arguments and, depending on them, produce the result.

Let's add the final touch, which should be in all of our scripts:
1. You can remove the php extension
2. At the beginning of each script, add an option for the interpreter #! / Usr / bin / env php
3. Let's make our scripts executable chmod + x backup.php

After that, you can use the resulting script as a real Unix program:

  ./backup --help 

or

  ./backup --user = ukko --password = password --database = db1 




Chapter 24. Using PHP from the command line

Starting from version 4.3, PHP supports the new SAPI type (Server Application Programming Interface) called CLI , which means Command Line Interface . As the name implies, the main task of this SAPI- type is to develop shell / shell (or desktop) applications using PHP. There are very small differences between CLI SAPI and other SAPIs , which will be further discussed in this chapter.

The CLI SAPI was released for the first time with PHP 4.2.0 , but then it was an experiment, and you had to explicitly turn it on with the --enable-cli command when starting ./configure . Beginning with PHP 4.3.0 , the CLI SAPI is no longer experimental and is always embedded and installed as a binary php executable (called php.exe in Windows).

Significant differences of CLI SAPI from other SAPI :

  • Unlike CGI SAPI , no headers are written to the output.

    Although CGI SAPI has a way to suppress HTTP headers, there is no equivalent switch for including them in CLI SAPI .

  • There are certain php.ini directives that are redefined in the SAPI CLI , since they do not make sense in the shell environment:

Table 24-1. Override php.ini directives
Directive CLI SAPI - default value Comment
html_errors FALSE It can be quite difficult to read the error message in the shell, filled with all these meaningless HTML tags, so the default value of this directive is FALSE .
implicit_flush TRUE It is desirable that any output from print () , echo () and the company is immediately recorded in the output, and not sent to any buffer. You can still use output buffering if you want to work with standard output.
max_execution_time 0 (unlimited) Due to the infinitely large possibilities of using PHP in a shell environment, the maximum execution time is not limited. While applications written for the web run for fractions of a second, shell applications try to take the maximum time to complete.
register_argc_argv TRUE PHP global variables $ argc (the number of arguments passed to the application) and $ argv (array of current arguments) are always recorded and populated with the appropriate values ​​when using the CLI SAPI .

Note: These directives cannot be initialized with a different value from the php.ini configuration file or a special file (if specified). This is a limitation, since these defaults apply after parsing all configuration files. However, their value can be changed at runtime (which does not make sense for all other directives, for example, register_argc_argv).

  • It is easier to work in the shell environment when the following constants are defined:

    Table 24-2. Specific CLI Constants
    Constant Description
    STDIN Already open stream in stdin . She keeps discovering her.
      $ stdin = fopen ('php: // stdin', 'r'); 
    STDOUT Already open stream to stdout . She keeps discovering her.
      $ stdout = fopen ('php: // stdout', 'w'); 
    STDERR Already open stream to stdout . She keeps discovering her.
      $ stderr = fopen ('php: // stderr', 'w'); 

    Having all this, you should not, for example, independently open a stream for stderr , but simply use a constant instead of a stream resource:

      php -r 'fwrite (STDERR, "stderr \ n");' 

    You do not need to explicitly close these threads; it is done automatically by PHP.

  • CLI SAPI does not change the current directory to the directory of the executable script!

    An example showing the difference CGI SAPI :

      <? php
         / * Simple testing application * /
         echo getcwd (), "\ n";
     ?> 

    When using the CGI version, the output will be:

      $ pwd
     / tmp
    
     $ php-cgi -f another_directory / test.php
     / tmp / another_directory 

    This clearly shows that PHP changes its current directory to the directory of the executable script.

    Using CLI SAPI provides:

      $ pwd
     / tmp
    
     $ php -f another_directory / test.php
     / tmp 

    This gives more flexibility when writing command line utilities in PHP .

    Note: CGI SAPI supports the CLI SAPI behavior using the -C switch when starting from the command line.

A list of command line options for the PHP executable can be obtained at any time by running PHP with the -h option :

  Usage / Usage: php [options] [-f] <file> [args ...]
        php [options] -r <code> [args ...]
        php [options] [- args ...]
   -s Displays source text with different colors.
   -w Displays source text without comments and spaces.
   -f <file> Parses <file>.
   -v Version number.
   -c <path> | <file> Searches for a php.ini file in this directory.
   -a Run interactively.
   -d foo [= bar] Define an INI-entry foo with a value of 'bar'.
   -e Generate extended information for the debugger / profiler.
   -z <file> Download Zend <file> extensions.
   -l Check syntax only (lint).
   -m Show compiled modules.
   -i PHP information.
   -r <code> Run PHP <code> without using script tags <? ..?>
   -h This help.

   args ... Arguments passed to the script.  Use - args when
                    the first argument starts with - or the script is read from stdin 

CLI SAPI has three different ways to get the PHP code to execute:

  1. Tell PHP to execute a specific file.

      php my_script.php
    
     php -f my_script.php 

    Both methods (with / without using the -f switch) execute this my_script.php file. You can choose to execute any file, the names of your PHP script files do not have to end with the .php extension, but may have any name or extension.

  2. Send PHP code to run directly from the command line.

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

    Special attention requires the replacement of shell variables and the use of quotes.

    Note: Look at the example carefully, there are no start and end tags! The -r switch is simply not needed. Using them in this case will lead to a parser error.

  3. Provide PHP code for execution via standard input ( stdin ).

    This allows you to dynamically create a PHP code and transfer it to the executable, as shown in this (contrived) example:

      $ some_application |  some_filter |  php |  sort -u> final_output.txt 

You cannot combine these three methods when executing code.

As with any shell application, not only PHP itself, but your PHP scripts also take arguments. The number of arguments passed to the script in PHP is not limited (the shell has a limit on the number of characters to be transferred).
The arguments passed to your script are accessible through the global $ argv array. The zero index always contains the name of the script (which is a character - in the case when the PHP code comes from standard input or using the –r command line option ).
The second global variable to be registered is $ argc , which contains the number of elements in the $ argv array (and not the number of arguments passed to the script).

If the arguments that you want to pass to the script do not begin with a hyphen (-) character, you do not need to observe anything specifically. Passing to the script an argument starting with - will create problems, because PHP thinks it should handle them. To prevent this, use as a list argument separator - . After the argument is parsed by PHP , each subsequent argument is passed to your script unchanged / not parsed.

  # This will not execute this code, but will demonstrate the use of PHP
 $ php -r 'var_dump ($ argv);'  -h
 Usage: php [options] [-f] <file> [args ...]
 [...]

 # The argument '-h' will be passed to your script, which will prevent PHP from showing it.
 $ php -r 'var_dump ($ argv);'  - -h
 array (2) {
   [0] =>
   string (1) "-"
   [1] =>
   string (2) "-h"
 } 

However, here is another way to use PHP for shell scripting. You can write a script, the first line of which begins with #! / Usr / bin / php , and then comes the normal PHP code contained between the PHP start and end tags and the file execution attributes are set accordingly. In this way, it can be executed as a normal shell script or perl:

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

Assuming that the file is called test and is located in the current directory, we can execute:

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

As you can see, nothing special needs to be done when passing parameters to the script, which begins with - .

Table 24-3. Command line options
Option Description
-s

Display syntax in color.

This option uses the internal file parsing mechanism, produces its colored HTML version and writes it to the standard output. Notice that only the <code> [...] </ code> HTML tags block is generated without the HTML header.

Note: This option does not work with the -r option.

-w

Display source code without comments and spaces.

Note: This option does not work with the -r option.

-f

Parses and executes this file. This switch is optional and may be omitted. It is enough to provide the name of the file to execute.

-v

Writes PHP, PHP SAPI and Zend versions to standard output, for example:

  $ php -v
 PHP 4.3.0-dev (cli), Copyright (c) 1997-2002 The PHP Group
 Zend Engine v1.2.1, Copyright (c) 1998-2002 Zend Technologies 
-c

Using this option, you can either specify a directory for php.ini search, or a special INI file directory (which is not necessarily called php.ini ), for example:

  $ php -c / custom / directory / my_script.php

 $ php -c /custom/directory/custom-file.ini my_script.php 
-a

Runs PHP interactively.

-d

This option allows you to set a special value for each configuration directive that is allowed in php.ini . The syntax is:

  -d configuration_directive [= value] 

Examples:

  # The omission of the value part will set this configuration directive to "1"
 $ php -d max_execution_time -r '
 $ foo = ini_get ("max_execution_time");  var_dump ($ foo); '
 string (1) "1"

 # Passing the empty part of the value will set this configuration directive to ""
 php -d max_execution_time = -r '
 $ foo = ini_get ("max_execution_time");  var_dump ($ foo); 'string (0) ""

 # The configuration directive will set what
 # passed after the '=' character
 $ php -d max_execution_time = 20 -r '
 $ foo = ini_get ("max_execution_time");  var_dump ($ foo); '
 string (2) "20"
 $ php -d max_execution_time = doesntmakesense -r '
 $ foo = ini_get ("max_execution_time");  var_dump ($ foo); '
 string (15) "doesntmakesense" 
-e

Generates extended information for debugger / profiler.

-z

Loads the Zend extension. If only the file name is specified, PHP attempts to load this extension from the current default path to the library on your system (usually specified as /etc/ld.so.conf on Linux systems). Transferring a filename with an absolute path will not use the system library search path. A relative filename with directory information will tell PHP to try to load the extension relative to the current directory.

-l

This option provides a convenient way to perform syntax checking for this PHP code. If successful, the text No syntax errors detected in <filename> is written to the standard output, and the return code of the shell is 0 . If unsuccessful, the text Errors parsing <filename> together with the internal message of the parser about the error is written to the standard output, and the return code of the shell will be 255 .

This option will not find fatal errors (like undefined functions). Use -f if you also want to check for fatal errors.

Note: This option does not work with -r .

-m

Using this option, PHP prints embedded (and loaded) PHP and Zend modules for output:

  $ php -m
 [PHP Modules]
 xml
 tokenizer
 standard
 session
 posix
 pcre
 overload
 mysql
 mbstring
 ctype

 [Zend Modules] 
-i This command line option calls phpinfo () and prints the output to the output. If PHP is not working correctly, we recommend running php -i and see if error messages are displayed before or instead of the information tables. Keep in mind that the output will be in HTML and, therefore, rather messy.
-r

This option allows PHP to run directly on the command line. PHP start and end tags ( <? Php and ?> ) Are not needed and cause parser errors.

Note: Care must be taken when using this form of PHP so that there are no contradictions with the replacement of command line variables by the shell.

An example that displays a parser error:

  $ php -r "$ foo = get_defined_constants ();"
 Command line code (1): Parse error - parse error, unexpected '=' 

The problem here is that sh / bash replaces the variable even when using double quotes. " Since the $ foo variable is hardly defined, it doesn’t expand to anything, which results in the code passed to PHP for execution, actually read:

  $ php -r "= get_defined_constants ();" 

It is correct to use single quotes ' . Variables in strings enclosed in single quotes are not expanded when sh / bash is running.

  $ php -r '$ foo = get_defined_constants ();  var_dump ($ foo); '
 array (370) {
   ["E_ERROR"] =>
   int (1)
   ["E_WARNING"] =>
   int (2)
   ["E_PARSE"] =>
   int (4)
   ["E_NOTICE"] =>
   int (8)
   ["E_CORE_ERROR"] =>
   [...] 

If you use the shell other than sh / bash, you may have new questions. Send a bug report or mail to phpdoc@lists.php.net. You can easily run into problems when trying to get variable shells in code or using backslashes (/) to replace / escaping.
You have been warned ...

-h With this option you can get information about the current list of command line options and a small description of their work.

Исполняемый файл PHP может быть использован для запуска PHP-скриптов абсолютно независимо от web-сервера.
Если вы работаете под Unix, вы должны добавлять специальную первую строчку в ваши PHP-скрипты и делать их исполняемыми, чтобы система знала, какая программа должна выполнять эти скрипты.
Под Windows вы можете ассоциировать php.exe с опцией двойного щелчка по файлам .php либо сделать batch-файл (.bat) для запуска скрипта через PHP. Строка, добавленная в начало скрипта для работы под Unix, не помешает под Windows, поэтому вы можете писать таким образом межплатформенные программы. Ниже дан пример простой РНР-программы для выполнения из командной строки.

Пример 24-1. Скрипт, предназначенный для запуска из командной строки (script.php)
 #!/usr/bin/php
 <? php

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

This is a command line PHP script with one option.

  Usage:
  <?php echo $argv[0]; ?> <option>

  <option> can be some word you would like
  to print out. With the --help, -help, -h,
  or -? options, you can get this help.

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

Здесь мы используем специальную первую строку для указания на то, что этот файл должен быть запущен в PHP. Здесь мы работаем с CLI-версией, поэтому не выполняется вывод HTTP-шапок/header. Имеются две переменные, которые вы можете использовать при написании РНР-приложений для командной строки: $argc и $argv . Первая - это количество аргументов плюс 1 (имя запущенного скрипта). Вторая - это массив аргументов, начиная с имени скрипта с индексом ноль ( $argv[0] ).

Мы проверяем, имеется ли менее или более одного аргумента. Также, если аргумент был --help , -help , -h или -? , мы печатаем help-сообщение, выводя имя скрипта динамически. Если мы получили какой-либо другой аргумент, мы выводим его (echo).

Если вы хотите выполнить вышеприведённый скрипт под Unix, вам необходимо сделать его executable и просто вызвать как script.php echothis или script.php -h . Под Windows вы можете создать batch-файл для выполнения этой задачи:

Пример 24-2. Пакетный/Batch-файл для запуска PHP-скрипта в командной строке (script.bat)
 @c:\php\php.exe script.php %1 %2 %3 %4 

Assuming that you called the program script.php and that your php.exe is in c: \ php \ php.exe , this batch file will launch it with the options you added: script.bat echothis or script.bat -h .


Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Running server side scripts using PHP as an example (LAMP)

Terms: Running server side scripts using PHP as an example (LAMP)