Manuel PHP
Précédent |  | Suivant

# Chapitre 43. Utiliser PHP en ligne de commande

Depuis la version 4.3.0, PHP supporte un nouveau type de SAPI (Server Application Programming Interface, c'est-à-dire Interface de Programmation d'Applications Serveur) appelé CLI, ce qui signifie Command Line Interface et se traduit par Interface de Ligne de Commande. Comme son nom l'indique, ce type SAPI cible les applications shell (ou desktop), écrites en PHP. Il y a un certain nombre de différences entre le type CLI SAPI et les autres SAPI expliqués dans ce chapitre. Il convient de préciser que CLI et CGI sont des SAPI différentes, bien qu'ils partagent des comportements similaires.

Le CLI SAPI a été publié pour la première fois avec la version PHP 4.2.0, mais il était expérimental, et devait être explicitement activé avec l'option --enable-cli lorsque vous exécutez le script ./configure. Depuis PHP 4.3.0, le CLI SAPI n'est plus expérimental, et l'option --enable-cli est activée par défaut. Vous pouvez utiliser l'option --disable-cli pour le désactiver.

Depuis PHP 4.3.0, le nom, l'emplacement et l'existence des binaires CLI/CGI vont dépendre de la façon dont PHP est installé sur votre système. Par défaut, en exécutant make, les deux binaires CGI et CLI sont compilés et nommés respectivement `sapi/cgi/php` et `sapi/cli/php` dans votre répertoire source PHP. Vous remarquerez que les deux se nomment php. Ce qui se passe ensuite pendant le make install dépend de votre ligne de configuration. Si un module SAPI, apxs par exemple, a été choisi pendant la configuration, ou que l'option --disable-cgi a été activée, le CLI est copié dans `{PREFIX}/bin/php` pendant le make install. Si, par exemple, --with--apxs figure dans votre ligne de configuration, le CLI est copié dans `{PREFIX}/bin/php` pendant le make install, sinon c'est le CGI qui y est placé. Si vous voulez forcer l'installation du binaire CGI, lancez make install-cli après le make install. Sinon, vous pouvez aussi spécifier --disable-cgi dans votre ligne de configuration.

> Note : Du fait que les deux options --enable-cli et --enable-cgi sont activées par défaut, avoir simplement --enable-cli dans votre ligne de configuration n'implique pas nécessairement que le CLI soit renommé en `{PREFIX}/bin/php` pendant le make install.

Les paquets Windows entre PHP 4.2.0 et PHP 4.2.3 installaient le CLI en tant que `php-cli.exe` et laissaient le CGI en tant que `php-cli.exe` dans le même répertoire. Depuis PHP 4.3.0, le paquet Windows installe le CLI en tant que `php.exe` dans un répertoire à part nommé `cli`, donc `cli/php.exe`. Depuis PHP 5, le CLI est installé dans le répertoire principal en tant que `php.exe`. La version CGI est nommée quand à elle `php-cgi.exe`.

Depuis PHP 5, un nouveau fichier `php-win.exe` est installé. C'est l'équivalent de la version CLI à ceci près qu'il n'affiche rien et ainsi ne fait pas apparaître de console (aucune fenêtre "dos" n'apparaît à l'écran). Ce comportement est similaire à celui de php-gtk. Vous pouvez l'activer avec l'option --enable-cli-win32.

> Quel SAPI est installé ? : À partir d'un interpréteur de commande, lancer php -v vous dira si `php` est en version CGI ou CLI. Vous pouvez aussi consulter la fonction php_sapi_name() et la constante `PHP_SAPI`.

> Note : Une page man de manuel Unix a été ajoutée avec PHP 4.3.2. Vous pouvez la consulter en tapant man php dans votre interpréteur de commande.

Les différences les plus notables entre le CLI SAPI et les SAPI sont :

- Contrairement au CGI SAPI, aucun en-tête HTTP n'est écrit dans le résultat.

  Bien que le CGI SAPI fournisse un moyen de supprimer les en-têtes HTTP, il n'y a pas moyen d'activer les en-têtes HTTP dans le CLI SAPI.

  CLI est lancé en mode silencieux par défaut, bien que les options -q et --no-header soient gardées pour rester compatible avec les anciennes versions CGI.

  Il ne change pas le répertoire courant en celui du script. (les options -C et --no-chdir sont gardées par souci de compatibilité)

  Messages d'erreurs en texte brut (pas de formatage HTML).

- Il y a plusieurs directives du `php.ini` qui sont ignorées par le CLI SAPI, car elles n'ont pas de sens en environnement shell :

  Tableau 43-1. Directives `php.ini` ignorées

  Directive | Valeur par défaut pour CLI SAPI | Commentaire
  --- | --- | ---
  html_errors | `FALSE` | Il peut être bien difficile de lire les messages d'erreur sur un terminal lorsqu'ils sont noyés dans des balises HTML sans grand intérêt. Par conséquent, cette directive est forcée à `FALSE`.
  implicit_flush | `TRUE` | Il est souhaitable que tout affichage en provenance de print(), echo() et consorts, soit immédiatement affiché dans le terminal, et non pas placé dans un buffer quelconque. Vous pouvez toujours utiliser la bufferisation de sortie si vous voulez retarder un affichage, ou bien en manipuler le contenu une dernière fois.
  max_execution_time | 0 (sans limite) | Étant données les possibilités infinies de PHP en environnement shell, le temps d'exécution maximal d'un script PHP a été rendu illimité. Alors que les scripts destinés au web doivent s'accomplir en une fraction de seconde, il arrive que les scripts shell requièrent bien plus de temps.

  register_argc_argv

  `TRUE`

  En donnant la valeur de `TRUE` à cette directive, vous aurez toujours accès à la variable argc (représentant le nombre d'arguments passés à l'application) et argv (le tableau contenant les arguments passés) dans le CLI SAPI.

  Depuis PHP 4.3.0, les variables $argc et $argv sont définies et remplies avec les valeurs appropriées, en utilisant CLI SAPI. Avant cette version, la création de ces variables était liée au comportement des versions CGI et MODULE, qui requièrent l'activation de la directive register_globals. Indépendamment de la version ou de la valeur de register_globals, vous pouvez toujours accéder à $_SERVER et $HTTP_SERVER_VARS. Par exemple : $_SERVER['argv']

  > Note : Ces directives ne peuvent pas être initialisées avec d'autres valeurs dans le fichier `php.ini` ou par une autre méthode. C'est une limitation, car ces valeurs par défaut s'appliquent une fois que tous les autres fichiers de configuration ont été analysés. Cependant, ces valeurs peuvent être modifiées durant l'exécution (ce qui n'est pas logique pour certaines directives, comme register_argc_argv).

- Pour faciliter le travail en environnement shell, les constantes suivantes sont définies :

  Tableau 43-2. Constantes spécifiques au CLI

  Constante | Description
  --- | ---

  `STDIN`

  Un descripteur de fichier déjà disponible vers stdin. Cela évite de l'ouvrir avec

  `<?php $stdin = fopen('php://stdin', 'r'); ?>`

  Si vous voulez lire une seule ligne depuis stdin, vous pouvez utiliser :

  `<?php $line = trim(fgets(STDIN)); // lit une seule ligne depuis STDIN fscanf(STDIN, "%d\n", $number); // lit les nombres depuis STDIN ?>`

  `STDOUT`

  Un descripteur de fichier déjà disponible vers stdout. Cela évite de l'ouvrir avec

  `<?php $stdout = fopen('php://stdout', 'w'); ?>`

  `STDERR`

  Un descripteur de fichier déjà disponible vers stderr. Cela évite de l'ouvrir avec

  `<?php $stderr = fopen('php://stderr', 'w'); ?>`

  Étant donné ce qui précède, vous n'avez pas besoin d'ouvrir un flux vers stderr par vous-même, mais vous pouvez utiliser cette constante directement, comme un descripteur de fichier :

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

  Vous n'avez pas non plus à fermer explicitement ces fichiers, PHP s'en chargera automatiquement à la fin du script.

- Le CLI SAPI ne transforme pas le dossier courant en dossier d'exécution du script !

  Exemple de différence entre CGI SAPI et CLI SAPI:

  `<?php // Un test simple : affiche le dossier d'exécution */ echo getcwd(), "\n"; ?>`

  Lorsque vous utilisez la version CGI, l'affichage sera :

      $ pwd
      /tmp

      $ php-cgi -f autre_dossier/test.php
      /tmp/autre_dossier

  Cela montre clairement que PHP modifie le dossier courant, et utilise le dossier du script exécuté.

  En utilisant le CLI SAPI, on obtient :

      $ pwd
      /tmp

      $ php -f autre_dossier/test.php
      /tmp

  Cela donne beaucoup plus de souplesse lorsque vous rédigez des scripts shell avec PHP.

  > Note : Le CGI SAPI se comporte de la même façon que le CLI SAPI, en lui passant l'option -C, lorsque vous l'invoquez en ligne de commande.

La liste des options de ligne de commande fournies par PHP est disponible à n'importe quel moment en exécutant PHP avec l'option -h :

    Usage: php [options] [-f] <file> [--] [args...]
              php [options] -r <code> [--] [args...]
              php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
              php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
              php [options] -- [args...]
              php [options] -a

    -a               Run interactively
    -c <path>|<file> Look for php.ini file in this directory
    -n               No php.ini file will be used
    -d foo[=bar]     Define INI entry foo with value 'bar'
    -e               Generate extended information for debugger/profiler
    -f <file>        Parse <file>.
    -h               This help
    -i               PHP information
    -l               Syntax check only (lint)
    -m               Show compiled in modules
    -r <code>        Run PHP <code> without using script tags <?..?>
    -B <begin_code>  Run PHP <begin_code> before processing input lines
    -R <code>        Run PHP <code> for every input line
    -F <file>        Parse and execute <file> for every input line
    -E <end_code>    Run PHP <end_code> after processing all input lines
    -H               Hide any passed arguments from external tools.
    -s               Display colour syntax highlighted source.
    -v               Version number
    -w               Display source with stripped comments and whitespace.
    -z <file>        Load Zend extension <file>.

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

Le CLI SAPI dispose de trois moyens pour lire le code du script PHP que vous voulez exécuter :

1. Indiquer à PHP d'exécuter un fichier donné :

       php mon_script.php

       php -f mon_script.php

   Les deux méthodes (en utilisant -f ou pas) exécutent le script contenu dans le fichier `mon_script.php`. Vous pouvez choisir n'importe quel fichier, et ces fichiers ne sont pas tenus d'utiliser l'extension .php. N'importe quelle extension peut faire l'affaire.

2. Donner du code PHP à exécuter directement en ligne de commande.

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

   Une attention particulière doit alors être apportée aux variables d'environnement, qui seront remplacées, et aux guillemets, qui ont des significations spéciales en ligne de commande.

   > Note : Lisez l'exemple attentivement, il n'y a ni balise d'ouverture, ni balise de fermeture ! L'option -r rend caduque l'utilisation de celles-ci, et les ajouter conduirait alors à une erreur d'analyse syntaxique.

3. Alimenter l'entrée standard en code PHP (stdin).

   Cela donne la possibilité de créer dynamiquement du code PHP, puis de le fournir à PHP, et enfin, de le traiter à nouveau en shell. Voici un exemple fictif :

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

Il n'est pas possible de combiner ces trois modes d'exécution.

Comme toute application shell, l'exécutable PHP accepte des arguments, et votre script PHP peut aussi les recevoir. Le nombre d'arguments n'est pas limité par PHP (le shell a une limite en terme de nombre de caractères qui peuvent être passés. Généralement, vous n'atteindrez pas cette limite). Les arguments passés au script seront transmis via la variable tableau $argv. L'index zéro contiendra toujours le nom du script appelé (qui sera - dans le cas où le code PHP arrive de l'entrée standard ou depuis la ligne de commande, passé -r). L'autre variable globale fournie est $argc qui contient le nombre d'éléments dans le tableau $argv (ce nombre est différent du nombre d'arguments passés au script).

Tant que les arguments que vous passez à votre script ne commencent pas par le caractère -, il n'y a rien de spécial à surveiller. Si vous passez des arguments à votre script qui commencent par -, cela posera des problèmes car PHP va penser qu'il doit les interpréter. Pour éviter cela, utilisez le séparateur --. Après cet argument, tous les arguments suivants seront passés à votre script sans être modifiés ou analysés par PHP.

    # Cela ne va pas exécuter le code, mais afficher l'aide de PHP
    $ php -r 'var_dump($argv);' -h
    Usage: php [options] [-f] <file> [args...]
    [...]

    # Cela va passer l'argument '-h' à votre script, et éviter que PHP ne le traite
    $ php -r 'var_dump($argv);' -- -h
    array(2) {
      [0]=>
      string(1) "-"
      [1]=>
      string(2) "-h"
    }

Cependant, il y a une autre méthode pour utiliser PHP en script shell. Vous pouvez aussi utiliser la ligne #!/usr/bin/php en tout début de votre script, suivie de code PHP compris entre balise ouvrantes/fermantes. Après avoir mis les droits d'exécution sur votre script (chmod +x test), il peut être exécuté comme un script shell ou perl habituel :

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

En supposant que ce fichier s'appelle `test`, dans le dossier courant, nous pouvons alors faire ceci :

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

Comme vous le voyez, aucune précaution n'est nécessaire pour passer des paramètres qui commencent par - à votre script.

Les options longues sont disponibles depuis PHP 4.3.3.

Tableau 43-3. Options de ligne de commande

Option | Option longue | Description
--- | --- | ---

-a

--interactive

Lance PHP de façon interactive. Si vous compilez PHP avec l'extension Readline (qui n'est pas disponible sous Windows), vous aurez un shell joli, incluant la fonctionnalité de complétion (e.g. vous pouvez commencer à taper un nom de variable, taper la touche TABULATION et PHP complètera son nom) et un historique de ce que vous entrez au clavier qui peut être consulté en utilisant les touches fléchées. Cet historique est sauvegardé dans le fichier `~/.php_history`.

> Note : Les fichiers incluent dans auto_prepend_file et auto_append_file sont analysés dans ce mode avec quelques restrictions - par exemple, les fonctions doivent être définies avant d'être appelées.

-c

--php-ini

Avec cette option, vous pouvez spécifier le nom du dossier dans lequel se trouve le fichier `php.ini`, ou encore vous pouvez spécifier un fichier de configuration (INI) directement (qui ne s'appelle pas obligatoirement `php.ini`) :

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

    $ php -c /custom/directory/custom-file.ini mon_script.php

Si vous ne spécifiez pas cette option, le fichier est recherché dans les endroits par défaut.

-n | --no-php-ini | Ignore complètement php.ini. Cette option est disponible depuis PHP 4.3.0.

-d

--define

Cette option permet de modifier n'importe quelle directive de configuration du fichier `php.ini`. La syntaxe est :

    -d configuration_directive[=value]

Exemples :

    # L'omission de la valeur conduit à donner la valeur de "1"
    $ php -d max_execution_time -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
    string(1) "1"

    # Passer une valeur vide conduit à donner la valeur de ""
    php -d max_execution_time= -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
    string(0) ""

    # La directive de configuration sera n'importe quelle valeur passée après le caractère '='
    $  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 | --profile-info | Génère des informations étendues pour le profilage et le débogage.
-f | --file | Analyse et exécute le fichier donné après l'option -f. Cette option est facultative, et peut être omise. Le seul nom du fichier est suffisant.
-h et -? | --help | Avec cette option, vous pouvez obtenir des informations sur la liste courante des options de la ligne de commande, ainsi que leur description.
-i | --info | Cette option appelle la fonction phpinfo(), et affiche le résultat. Si PHP ne fonctionne pas correctement, il est recommandé d'utiliser la commande php -i et de voir s'il n'y a pas d'erreurs affichées avant ou après la table d'information. N'oubliez pas que le résultat de cette option, si vous utilisez le mode CGI, est au format HTML, et donc de taille conséquente.

-l

--syntax-check

Cette option permet de faire une vérification syntaxique sur le code PHP fourni. En cas de réussite, le message No syntax errors detected in <filename> (Aucunes erreurs de syntaxe n'ont été détectées dans <nom_de_fichier> est affiché sur la sortie standard, et le script shell retourne 0. En cas d'erreur, le message Errors parsing <filename> (Erreurs d'analyse dans le fichier <filename>) est affiché, en plus des messages d'erreurs détectés par l'analyseur lui-même. Le script shell retourne le code 255.

Cette option ne détecte pas les erreurs fatales (par exemple les fonctions non définies). Utilisez -f si vous voulez tester aussi ces erreurs.

> Note : Cette option ne fonctionne pas avec l'option -r.

-m

--modules

Cette option liste les extensions PHP et Zend compilées (et chargées) :

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

    [Zend Modules]

-r

--run

Cette option permet l'exécution de PHP directement dans la ligne de commande. Les balises de PHP (<?php et ?>) ne sont pas nécessaires, et causeront une erreur d'analyse si elles sont présentes.

> Note : Une attention toute particulière doit être portée lors de l'utilisation de cette option de PHP, pour qu'il n'y ait pas de collision avec les substitutions de variables en ligne de commande, réalisées par le shell.

> Exemple conduisant à une erreur d'analyse :

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

> Le problème ici est que le shell (sh/bash) effectue une substitution de variables, même avec les guillemets doubles ". puisque la variable $foo n'est probablement pas définie dans le shell, elle est remplacée par rien, ce qui fait que le code passé à PHP pour l'exécution est :

>     $ php -r " = get_defined_constants();"

> La solution de ce problème est d'utiliser les guillemets simples '. Les variables de ces chaînes ne seront pas substituées par leurs valeurs par le shell.

>     $ 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"]=>
>     [...]

> Si vous utilisez un shell différent de sh/bash, vous pouvez rencontrer d'autres problèmes. N'hésitez pas à ouvrir un rapport de bogues à http://bugs.php.net/. Il est toujours très facile d'avoir des problèmes lorsque vous essayez d'inclure des variables shell dans le code, ou d'utiliser les anti-slash pour l'échappement. Vous aurez été prévenu.

> Note : -r est disponible avec le CLI SAPI et pas avec le CGI SAPI.

> Note : Cette option est utilisée pour des choses vraiment de base. Ainsi, quelques directives de configuration (par exemple auto_prepend_file et auto_append_file) sont ignorées dans ce mode.

-B | --process-begin | PHP code to execute before processing stdin. Added in PHP 5.
-R | --process-code | Code PHP à exécuter pour chaque ligne en entrée. Ajouté en PHP 5. Il y a deux variables spéciales de disponibles dans ce mode : $argn et $argi. $argn doit contenir la ligne PHP traitée à ce moment donné, tandis que $argi doit contenir le numéro de la ligne.
-F | --process-file | Fichier PHP à exécuter pour chaque ligne en entrée. Ajouté en PHP 5.

-E

--process-end

Code PHP à exécuter après avoir effectué l'entrée. Ajouté en PHP 5.

Exemple d'utilisation des options -B, -R et -E pour compter le nombre de lignes d'un projet.

    $ find my_proj | php -B '$l=0;' -R '$l += count(@file($argn));' -E 'echo "Total Lines: $l\n";'
    Total Lines: 37328

-s

--syntax-highlight et --syntax-highlighting

Affiche le code avec la colorisation syntaxique.

Cette option utilise le mécanisme interne pour analyser le fichier, et produire une version colorisée du code source, au format HTML. Notez que cette option ne fait que générer un bloc HTML, avec les balises HTML <code> [...] </code>, sans en-têtes HTML.

> Note : Cette option ne fonctionne pas avec l'option -r.

-v

--version

Affiche les versions de PHP, PHP SAPI, et Zend sur la sortie standard. Par exemple :

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

-w

--strip

Affiche la source sans les commentaires et les espaces.

> Note : Cette option ne fonctionne pas avec l'option -r.

-z

--zend-extension

Charge une extension Zend. Si et seulement si un fichier est fourni, PHP essaie de charger cette extension dans le dossier courant par défaut des bibliothèque sur votre système (généralement spécifié avec `/etc/ld.so.conf` sous Linux). Passer un nom de fichier avec le chemin complet fera que PHP utilisera ce fichier, sans recherche dans les dossiers classiques. Un chemin de dossier relatif indiquera à PHP qu'il doit chercher les extensions uniquement dans ce dossier.

L'exécutable PHP peut être utilisé pour exécuter des scripts indépendants du serveur web. Si vous êtes sur un système Unix, il est recommandé d'ajouter la ligne spéciale (prononcer "shebang") en début de script, de le rendre exécutable de manière à ce que le système sache quel programme doit exécuter le script. Sous Windows, vous pouvez associer l'exécutable php.exe avec le double-clic sur les fichiers d'extension .php, ou bien vous pouvez faire un fichier batch pour exécuter le script grâce à PHP. La première ligne utilisée dans le monde Unix ne perturbera pas l'exécution sous Windows, ce qui rend les scripts facilement portables. Un exemple complet est disponible ci-dessous :

Exemple 43-1. Script prévu pour être exécuté en ligne de commande (script.php)

`#!/usr/bin/php <?php if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) { ?> C'est une ligne de commande à une option. Utilisation : <?php echo $argv[0]; ?> <option> <option> peut être un mot que vous souhaitez afficher. Avec les options --help, -help, -h, et -?, vous obtiendrez cette aide. <?php } else { echo $argv[1]; } ?>`

Dans le script ci-dessus, nous utilisons la première ligne pour indiquer que le fichier doit être exécuté par PHP. Nous travaillons avec une version CLI, donc aucun en-tête HTTP n'est affiché. Il y a deux variables que vous pouvez utiliser avec les applications de ligne de commande : $argc et $argv. La première est le nombre d'arguments plus un (le nom du script qui est exécuté). La seconde est un tableau contenant les arguments, commençant avec le nom du script en élément 0 ($argv[0]).

Dans notre exemple, nous avons vérifié qu'il y a plus ou moins d'un argument. De plus, si cet argument est --help, -help, -h ou -?, nous affichons un message d'aide, ainsi que le nom du script. Si nous recevons un autre argument, celui-ci est affiché dans le terminal.

Pour exécuter le script ci-dessus sous Unix, vous devez le rendre exécutable, puis l'appeler avec une commande comme : script.php echothis ou script.php -h. Sous Windows, vous pouvez faire un fichier batch pour cela :

Exemple 43-2. Fichier batch pour exécuter un script PHP en ligne de commande (script.bat)

    @C:\php\php.exe script.php %1 %2 %3 %4

Si vous avez nommé le programme ci-dessus `script.php`, et que vous avez votre exécutable `php.exe` situé à `C:\php\php.exe`, ce fichier batch l'exécutera avec les options que vous lui passez : script.bat echothis ou script.bat -h.

Voir aussi l'extension Readline, qui dispose de nombreuses fonctions pour améliorer la convivialité de vos applications en ligne de commande.

Précédent | Sommaire | Suivant
Fonctions désactivées par le Safe Mode | Niveau supérieur | Référence des fonctions