\documentclass[openany,a4paper,12pt]{article}

\usepackage[french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{tabularx}

\title{PHP Command Line Interface}
\author{D.Moreaux}

\begin{document}
\maketitle
\pagestyle{plain}
\pagenumbering{roman}
\tableofcontents

\newpage
\pagestyle{headings}
\pagenumbering{arabic}

\section*{Introduction}
Si il est principalement utilisé dans le contexte du Web, le langage
PHP peut aussi être utilisé en ligne de commande pour réaliser des
programmes tournant sur la console.

L'utilisation en ligne de commande présente quelques différences par
rapport à l'utilisation au travers d'un serveur web :
\begin{itemize}
\item durée d'exécution illimitée
\item permet de passer des paramètres sur la ligne de commande comme
  un programme en C (ou autre)
\item permet un programme interactif (lecture du clavier)
\item ne demande pas de serveur web
\end{itemize}

\section{Installation}
\subsection{Sous Linux}
Sous Linux, il suffit d'installer le package \verb|php-cli|. La
commande \verb|php| se trouvera dans le répertoire \verb|/usr/bin| et
sera donc accessible directement.

Le fichier de configuration se trouvera dans \verb|/etc|, souvent dans
un répertoire \verb|php|.

Il faudra penser à installer les modules désirés et généralement,
l'installeur se chargera de les activer automatiquement.

Si on désire qu'un programme s'exécute directement en PHP, il suffit
de le faire commencer par une ligne
\begin{verbatim*}
#!/usr/bin/php
\end{verbatim*}
et de lui donner les droits d'exécution \verb|chmod 755 xxx.php|. A
noter que le fichier n'a pas besoin d'avoir l'extension \verb|.php|
pour que cela fonctionne.

\subsection{MS Windows}
L'installation sous MS Windows est un peu plus compliquée :
\begin{itemize}
\item Aller à \verb|http://php.net/downloads| et cliquer sur {\bf
  Windows downloads}.
\item Télécharger l'archive \verb|.zip| de la dernière version de PHP
  {\bf Non Thread Safe} pour la plateforme désirée (32 ou 64 bits).
\item Décompresser l'archive dans une sous répertoire (pour l'exemple,
  nous prendrons \verb|C:\PHP| mais il est possible d'utiliser un
  autre nom ou un autre répertoire)
\item Dans le pannneau de Contrôle, choisir {\bf System} et  {\bf
  Advanced System Settings}.  Demander à changer les variables
  d'environnement et changer le \verb|PATH| système (onglet inférieur)
  pour ajouter le répertoire d'installation (\verb|C:\PHP|).
\item Ouvrir une ligne de commande en mode administrateur et taper
  \verb|PATH| pour s'assurer que le répertoire se trouve bien dans le
  texte affiché.
\item Taper \verb|php -v| et s'assurer que le numéro de version
  affiché est bien correct (et que le programme se lance bien)
\item Pour associer l'interpréteur PHP aux fichiers PHP, taper les
  deux commandes suivantes dans la ligne de commande administrateur :
\begin{verbatim*}
assoc .php=phpfile
ftype  phpfile="C:\PHP\php.exe" -f "%1" -- %~2
\end{verbatim*}
Une fois cela fait, il suffira de double cliquer sur un fichier PHP
pour l'exécuter (attention, la fenêtre se ferme automatiquement en fin
de programme).
\end{itemize}

Pour faire des modifications dans le fichier de configuration (par
exemple activer des extensions), il faudra copier le fichier
php.ini-development sous le nom php.ini dans le répertoire
d'installation.

Il faudra ensuite chercher la ligne \verb|extension_dir| en
commentaire et y ajouter une ligne
\begin{verbatim*}
extension_dir = "C:\PHP\ext"
\end{verbatim*}

Pour activer une extension, chercher la ligne \verb|extension=|
correspondant à l'extension à activer et décommenter (en retirant le
\verb|;|.

\section{Accès aux fichiers}
Les accès aux fichiers se feront à l'aide de fonctions similaires aux
instructions du langage C.

Exemple :
\begin{verbatim*}
$fh=fopen("monfichier","r");
while (($s=fgets($fh))!== FALSE) {
  echo $s;
}
fclose($fh);
\end{verbatim*}

\subsection{fopen}
\begin{verbatim}
$fh=fopen("test.txt","rb");
\end{verbatim}

Pour ouvrir un fichier, on utilisera \verb|fopen|. Cette fonction
prend deux paramètres semblables à ceux en langage C : le nom du
fichier et le mode.

Pour le mode, il est possible d'ajouter un caractère \verb|t| ou
\verb|b| à la fin pour spécifier si on manipule  un fichier texte ou
binaire. En mode texte, une conversion des retours de fin de ligne se
fait automatiquement.

Il est cependant conseillé de n'utiliser que le mode binaire pour une
meilleure compatibilité entre systèmes.

Les modes possibles sont dans le tableau suivant :
\begin{table}[htbp]
  \center
  \begin{tabular}{|l|l|l|l|}
    \hline
    Mode & R/W & position &  \\
    \hline
    r & R & début & \\
    r+ & RW & début & \\
    w & W & début & crée ou tronque \\
    w+ & RW & début & crée ou tronque \\
    a & W & fin & \\
    a+ & RW & fin & \\
    x & W & début & exclusif, erreur si le fichier existe \\
    x+ & RW & début & exclusif, erreur si fichier existe \\
    c & W & début & crée \\
    \hline
  \end{tabular}
\end{table}

La fonction \verb|fopen| retourne un {\em file handle} qui sera
utilisé par les autres fonctions d'accès aux fichiers.

\subsection{fclose}
\begin{verbatim}
fclose($fh);
\end{verbatim}

La fonction \verb|fclose| permet de fermer un fichier ouvert par
\verb|fopen|. Cela effectuera les écritures qui étaient encore au
niveau des buffers et n'auraient pas encore été transcrites sur le
disque dur.

\subsection{fflush}
\begin{verbatim}
fflush($fh);
\end{verbatim}

La fonction \verb|fflush| permet de forcer l'écriture sur le disque
dur des données qui sont dans les buffers.

\subsection{feof}
\begin{verbatim}
if (!feof($fh)) ...
\end{verbatim}

La fonction \verb|feof| retournera TRUE si on est arrivé à la fin du
fichier (lors de lectures).

\subsection{fseek}
\begin{verbatim}
fseek($fh,$pos);
fseek($fh,$pos,SEEK_SET);
\end{verbatim}

La fonction \verb|fseek| permet de positionner le pointeur dans le
fichier avant des lectures ou écritures.

Le deuxième paramètre indique la position (positive ou négative) par
rapport à la référence indiquée en 3eme paramètre.

La référence sera \verb|SEEK_SET| pour fournir une position par
rapport au début du fichier, \verb|SEEK_END| pour une position par
rapport à la fin du fichier et \verb|SEEK_CUR| pour une position par
rapport à la position courante. Si la référence n'est pas indiquée, la
valeur \verb|SEEK_SET| sera utilsée par défaut.

\subsection{ftell}
\begin{verbatim}
$pos=ftell($fh);
\end{verbatim}

La fonction \verb|ftell| permet de récupérer la position courante dans
le fichier.

\subsection{fgetc}
\begin{verbatim}
$c=fgetc($fh);
\end{verbatim}

La fonction \verb|fgetc| permet de lire un caractère dans le
fichier. Si on est arrivé à la fin du fichier, retourne FALSE (tester
avec ===).

\subsection{fgets}
\begin{verbatim}
$s=fgets($fh);
$s=fgets($fh,$maxlen);
\end{verbatim}

La fonction \verb|fgets| permet de lire une chaîne de caractère dans
le fichier.

La chaîne s'arrête quand une des conditions suivantes est atteinte :
fin de fichier, retour à la ligne (inclus dans la chaîne retournée) ou
\verb|$maxlen|-1 caractères lus

Si on est à la fin du fichier, retourne FALSE.

Contrairement à la version du langage C, la version PHP de
\verb|fgets| est sûre à l'emploi (pas de risque de buffer overflow).

\subsection{fread}
\begin{verbatim}
$s=fread($fh,$len);
\end{verbatim}

La fonction \verb|fread| permet de lire \verb|$len| octets dans le
fichier. Cette fonction est {\em binary safe} (elle gère correctement
les octets à 0 ou autres valeurs spéciales).

\subsection{fwrite}
\begin{verbatim}
fwrite($fh,$s);
\end{verbatim}

La fonction \verb|fwrite| permet d'écrire une chaîne dans une
fichier. Elle est binary safe.

\subsection{file}
\begin{verbatim}
$a=file("test.txt"};
$a=file("test.txt",FILE_IGNORE_NEW_LINES);
\end{verbatim}

La fonction \verb|file| permet de lire la totalité d'un fichier dans
un tableau. Chaque ligne du fichier sera sauvé comme une ligne dans le
tableau de chaînes retourné.

L'option \verb|FILE_IGNORE_NEW_LINES| permet d'éviter que les retours
de chariot ne soient inclus dans les chaînes du tableau.

\section{Console}
\subsection{Paramètres}
Lorsque le programme est exécuté, les paramètres transmis sont sauvés
dans le tableau \verb|$argv| et le nombre de paramètres dans
\verb|$argc|. Le nom de l'exécutable se trouve dans le paramètre 0.

Si on désire passer des paramètres qui pourraient être interprétés par
le moteur PHP, il suffit de commencer la liste de paramètres par un
double tiret \verb|--|

\begin{verbatim*}
php test.php -- -a 123 -b -c
\end{verbatim*}

\subsection{Entrée clavier}
Dans un programme en ligne de commande, on peut utiliser les {\em
  file handlers} \verb|STDIN|, \verb|STDOUT| et \verb|STDERR| pour
accéder à la console. Plus particulièrement, une lecture sur
\verb|STDIN| se traduira par une lecture au clavier (en attendant
l'appui de Enter)

Il est également possible d'ouvrir \verb|stdin| à l'aide de
l'instruction
\begin{verbatim}
$stdin=fopen("php://stdin","r");
\end{verbatim}

\subsection{Séquences ANSI}
Il est possible d'effacer l'écran ou de positionner le curseur à
l'écran à l'aide de séquences de code ANSI. De nombreuses séquences
existent et permettent de changer la couleur, de déplacer le curseur
ou d'effacer une partie de l'écran.

Effacer l'écran :
\begin{verbatim}
echo "\033[2J";
\end{verbatim}

Positionner à l'écran :
\begin{verbatim}
echo "\033[".$row.";".$col."H";
\end{verbatim}

On peut trouver une liste de codes à 
\begin{verbatim}
https://en.wikipedia.org/wiki/ANSI_escape_code#Terminal_output_sequences
\end{verbatim}

Sous certaines versions de MS Windows, il sera nécessaire d'activer
les codes ANSI. Cela peut être fait en créant une entrée dans la base
de registre : 

Branche : \verb|HKCU\Console|
Clé : \verb|VirtualTerminalLevel|
Valeur : \verb|0x1|

Attention, cela affectera tous les terminaux ouvert et pourrait poser
problème avec certaines applications. Avant de faire cette opération,
vérifier si les séquences ANSI sont reconnues.


\end{document}
