# Programmation PHP/Version imprimable1

* Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
* Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
* Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.
Une version à jour et éditable de ce livre est disponible sur Wikilivres, une bibliothèque de livres pédagogiques, à l'URL : https://fr.wikibooks.org/wiki/Programmation_PHP

# Introduction
## Historique

PHP est un langage de script créé par Rasmus Lerdorf en 1995. Principalement utilisé pour la programmation Web, on pourrait le situer entre les SSI (Server Side Includes) et le langage de script Perl. Il est utilisable sur tous les systèmes d'exploitation, donc sur Windows, MacOS, GNU-Linux ou autre Unix commercial, ce qui en fait un langage très portatif.
La sortie de PHP 5 en 2004 a permis au langage d'atteindre une certaine maturité, pour être reconnu comme un serveur d'application à part entière tel que JEE ou .Net.
PHP a ensuite acquis une place incontournable dans le développement Web Open Source. Sa popularité vient de sa syntaxe, proche du C, de sa vitesse et de sa simplicité. En 2013, on estime qu'il y a plus de 244 millions de serveurs qui utilisent le langage. En 2016 il est utilisé dans plus de 80 % des sites Internet, et toujours 77,5 % en août 2022.

### PHP 5

Les nouvelles fonctionnalités du PHP 5 (paru en 2004) concernent surtout la programmation orientée objet :
* interfaces
* classes abstraites
* constructeurs et destructeurs de classes (ainsi que d'autres méthodes magiques)
* portée des attributs et méthodes (public, protected, private)
* attributs et méthodes statiques
* attributs et méthodes finaux
* type hinting de classe.

### PHP 7

Les principales fonctionnalités apportées par PHP 7 (depuis 2015) sont :
* typage strict par classe
* paramètres typés
* retours de méthode typés
* opérateur de coalescence null (??)
* opérateur vaisseau spatial (<=>)
* tableaux de constantes
* classes anonymes
* groupage des déclarations (use, avec des accolades).

### PHP 8

Nouvelles fonctionnalités du PHP 8.0 en 2020 :
* paramètres nommés
* types d'union (X|Y)
* propriétés promues (déclarations dans le constructeur)
* autorisation d'une virgule de fin dans les paramètres
* autorisation des méthodes abstraites dans les traits
* autorisation des indices négatifs dans les tableaux autoincrémentés
* l'instruction match
* opérateur null-safe (?->)
* fonction str_contains
* fonction str_starts_with et str_ends_with
* fonction get_debug_type : il s'agit d'un gettype plus précis, car il renvoie le nom de la classe au lieu de "object"
* exécution juste-à-temps (JIT), pour améliorer les performances : plus de 20 % de requêtes en plus par seconde.

#### 8.1

Pour PHP 8.1, sorti en novembre 2021 :
* types d'intersection (X&Y)
* type de retour never
* constantes de classe finales
* énumérations
* fibres (threads virtuels pilotés par la classe Fiber)
* fonction array_is_list
* attributs en lecture seule (readonly).

#### 8.2

PHP 8.2 est sorti le 8 décembre 2022 :
* classes en lecture seule : readonly class signifie que tous les arguments de son constructeur son implicitement en readonly.
* types null, true et false.
* constantes dans les traits.
* Forme normale disjonctive de type (combinaison de l'union et de l'intersection).

#### 8.3

PHP 8.3 sort le 23 novembre 2023 :
* classes anonymes en lecture seule.
* constantes typées.
* fonction "json_validate".

## Sites Web statiques ou dynamiques

À l'origine du Web, les sites Web étaient des sites statiques : constitués d'un ensemble de pages écrites dans le langage HTML. L'information présente sur ces pages était toujours identique et leur mise à jour était particulièrement fastidieuse. Le serveur Web se contentait de diffuser les pages telles quelles à l'utilisateur. L'interaction entre le site et l'utilisateur était très sommaire : l'utilisateur demandait une page web et le serveur la lui fournissait.
Aujourd'hui la plupart des sites sont dynamiques : à l'intérieur des pages HTML, le concepteur du site a inséré des programmes. Ces programmes permettent une plus grande souplesse dans la gestion du site, sa mise à jour et ses fonctionnalités. La possibilité d'insérer des programmes a permis de décupler les fonctionnalités des sites Web.
Pour vous en convaincre prenons quelques exemples :
* Vous voulez écrire un site qui présente une centaine de produits. Vous n'allez pas écrire 100 pages différentes, une pour chacun des produits ! Mais plutôt une seule page (page type) permettant de présenter n'importe quel produit. Cette page va contenir un programme qui interagira avec une base de données. Dans la base de données, seront stockées les informations utiles pour chaque produit : le nom du produit, sa présentation, sa référence, son prix, etc. Le programme aura donc pour rôle d'aller chercher l'information utile dans la base de données et de l'afficher en HTML. De plus, pour ajouter un produit, il suffira d'ajouter un élément dans la base de données. Il est même possible d'avoir des programmes permettant de passer une commande pour vos différents produits !
* Vous voulez diffuser rapidement des informations sur Internet : vous voulez avoir un outil convivial qui vous permet d'ajouter un article, de le modifier, de le supprimer... Vous allez donc écrire un programme permettant de modifier à volonté les différents articles. Un exemple bien connu de ce type de programme est le blog : il s'agit d'un programme permettant à n'importe quel utilisateur non informaticien de gérer ses différents articles.
* L'encyclopédie Wikipédia est réalisée avec un programme (en PHP d'ailleurs) qui permet à chaque utilisateur de créer et de modifier les articles tout en gardant un historique complet des différentes versions des articles.
* les forums de discussion sont des lieux d'échange permettant une interaction étroite entre le serveur et l'utilisateur. Grâce aux programmes qu'ils utilisent, il est possible de se connecter, de consulter les messages des différents forums, d'y répondre. Les modérateurs de ces forums peuvent modifier les messages, les supprimer, interdire un utilisateur indélicat.
Dans chacun des exemples précédents il a été nécessaire d'incorporer un programme à l'intérieur des pages du site afin de réaliser des fonctionnalités de haut niveau. Aujourd'hui la quasi-totalité des sites professionnels sont dynamiques et il est quasi inconcevable de réaliser un site statique. Le langage PHP est un des langages utilisables pour réaliser facilement les sites Web dynamiques, ne serait-ce que parce qu'il est disponible sur la plupart des serveurs hébergeant des sites.

## Possibilités

Si vous êtes déjà allés sur un site qui vous demandait de vous connecter, vous avez utilisé un script côté serveur. Ce script était certainement écrit en PHP, en raison de la popularité de ce dernier.
PHP transforme une page statique (fichier HTML par exemple), en une suite d'instructions interprétables par PHP, installée sur un serveur Web comme Apache - ça peut-être simplement un "Hello World" 50 fois dans une colonne, ou une interaction avec un système de base de données, comme MySQL, fréquemment couplé à PHP.
Mais PHP peut aussi servir à programmer des batchs sans page web aucune.
Les premières versions de PHP étaient faiblement typées, mais depuis la version 7 il est possible de forcer un typage fort dans un fichier en lui ajoutant :

## Références

* ↑ https://w3techs.com/technologies/details/pl-php
* ↑ https://www.web24.com.au/tutorials/features-of-php5
* ↑ https://www.php.net/manual/fr/migration70.new-features.php
* ↑ https://kinsta.com/fr/blog/php-8/
* ↑ https://php.developpez.com/actu/335682/PHP-8-2-est-disponible-en-beta-2-Cette-version-propose-null-true-et-false-en-tant-que-types-autonomes-ainsi-que-des-constantes-dans-les-traits/
* ↑ https://thecodingmachine.com/php-8-nouveautes-compatibilites-migration/
* ↑ https://stitcher.io/blog/new-in-php-82
* ↑ https://www.phparch.com/2023/08/whats-new-and-exciting-in-php-8-3/

# Installer PHP
## Principe

Dans la cadre d'un apprentissage, des sites comme http://phpfiddle.org/ ou Tutorialspoint permettent d'exécuter ponctuellement des petits scripts PHP sans rien installer.
Par ailleurs, installer PHP seul permet d'exécuter des commandes shell (ex : php -v donne la version, et php -i toutes les infos telles que les paramètres de limite mémoire), mais le réel intérêt est d'installer PHP en complément d'un serveur HTTP, pour y publier des sites web.

## Unix / Linux
### LAMP

Logiciel tout-en-un pour Linux (Apache + MySQL + PHP), comme WAMP pour Windows.

### Installation manuelle
#### Apache sur Debian / Ubuntu

Le service peut ne pas être lancé par défaut, mais même s'il l'est on peut quand-même essayer de l'activer avec :
On peut ensuite tester le serveur, pour voir si une page s'affiche ou s'il refuse la connexion :
Cette adresse est le rebouclage, elle peut aussi être rentrée directement dans tout navigateur web.
Si Apache était déjà installé vérifier le fichier pour indiquer le démarrage automatique d'Apache 2 /etc/default/apache2 :

##### Installer PHP

On distingue principalement deux versions de PHP : celle dont le binaire est appelé par le serveur Web, et php-fpm qui possède son propre service daemon (aussi appelé par le serveur Web) testable ainsi :
FPM signifie FastCGI Process Manager, puisque le processus PHP-fpm écoute les requêtes CGI. Cela peut se traduire soit par des requêtes TCP/IP, soit par un socket Unix (.sock dans le vhost).
PHP peut-être installé avec toutes les déclinaisons de la distribution Debian (stable, testing, unstable). Il suffit pour cela d'insérer vos lignes préférées dans le fichier /etc/apt/sources.list :
Ce qui suit suppose que le serveur Web a bien été installé ; exécuter les commandes suivantes :
Une fois ces commandes exécutées, redémarrer le serveur Web. Dans le cas d'Apache cela s'effectue avec la commande suivante :
Si tout s'est bien passé, vous disposez maintenant d'un serveur Web qui a la capacité d'exécuter des scripts PHP dans votre navigateur.
Testons :
Pour débugger :

###### Mise à jour

Pour PHP 7 ou 8 sur Ubuntu :
Sur Debian :
Puis :
Une fois les serveurs Web installés, ils se lancent automatiquement à chaque démarrage de la machine, ce qui est souhaitable pour un serveur, mais pas toujours pour un PC. Pour éviter cela, il suffit d'y désactiver les daemons :

###### Bibliothèques

Voici une liste de bibliothèques fréquemment utilisées dans les applications :
D'autres s'installent avec pecl au lieu de apt.
Pour les activer après installation, on peut éditer le php.ini ou lancer : phpenmod nom_du_module_php. Ex : sudo phpenmod gd.
Pour les désactiver : phpdismod nom_du_module_php
Pour détecter l'emplacement du php.ini de la version de PHP par défaut : php --ini.

##### Désinstaller PHP

Pour éviter de désinstaller tous les paquets PHP un par un (par exemple après une bascule de PHP7.0 vers PHP7.1), il existe "ppa-purge" :

#### Apache sur Gentoo

Premièrement il faut installer Apache :
Ensuite, il faut installer PHP :
Puis il faut qu'apache utilise PHP dans sa configuration.
* Code : Configuration de apache
* # nano -w /etc/conf.d/apache2
* APACHE2_OPTS="-D PHP5"

#### MySQL seul

MySQL est disponible sur http://dev.mysql.com/downloads/gui-tools/5.0.html au format :
* .msi (Windows)
* .dmg (Mac)
* .rpm (Linux)
* .tar
En l'absence de gestionnaire de paquets, utiliser le .tar ainsi :

#### APT
##### Variante

La dénomination des paquets mentionnés peut varier légèrement selon la version. Dans un terminal, entrez :
et confirmez.
(Remarque : il semblerait qu'en installant le paquet "mysql-server-5.0", au lieu du paquet mentionné plus haut, certaines personnes rencontrent des problèmes. Il est donc préférable d'installer ce paquet, ou d'installer la dernière version 4 stable avec : $ sudo apt-get install mysql-server-4.1. Consultez le forum pour plus d'informations : )
Lancez ensuite la commande :
Appuyez sur Entrée lorsqu'il vous demande le mot de passe root MySQL : pour le moment il n'y en a pas.
Le script vous demande alors si vous voulez mettre un mot de passe pour l'utilisateur root. Répondez Y, et entrez (2 fois le nouveau mot de passe du root MySQL). Il vous pose ensuite une série de questions. Si vous ne savez pas quoi répondre, acceptez les choix par défaut en appuyant simplement sur Enter.
Votre serveur MySQL est prêt. Par défaut il se lance à chaque démarrage du système, si vous ne le souhaitez pas, il vous suffit de lancer :
et de répondre "Non" à la question du démarrage systématique de MySQL.

#### Sur Gentoo
### Modules

De nombreux modules complémentaires peuvent être installés sur Apache.
Pour les lister, on utilise apachectl (parfois apache2ctl) :
ou
Pour activer un module :
Un fichier est alors créé dans /etc/apache2/mods-enabled/.
Exemple pour la réécriture d'URL :
Pour le désactiver :
La configuration du module reste toutefois disponible dans /etc/apache2/mods-available/.

### Sites

Pour lister les sites du serveur :
Pour activer un site :
Le fichier du site est alors visible dans /etc/apache2/sites-enabled/.
Pour le désactiver :
Le site est dans /etc/apache2/sites-available/.

## Problème d'encodage d'Apache2

Si vous rencontrez un problème d'encodage des caractères de vos pages, par exemple les caractères accentués apparaissant sous la forme "�" (<?>), c'est probablement parce qu'Apache2 déclare dans les en-têtes HTTP qui accompagnent les pages visionnées un encodage par défaut en Unicode (UTF-8) :
Tandis que les pages visionnées utilisent un autre encodage des caractères, comme par exemple Latin1 (ISO-8859-1). Même si vos documents indiquent le jeu de caractères utilisé, le paramètre donné par le serveur dans les en-têtes HTTP est prioritaire !
Pour corriger ce problème, il faudra éditer /etc/apache2/apache2.conf :

#### Encodage par défaut en Latin1 (ISO-8859-1)

Cherchez la ligne suivante :
Décommentez-la en enlevant le # :
Pour ceux qui ont la locale iso-8859-15 (sinon vous pouvez faire "sudo dpkg-reconfigure locales" pour l'ajouter) et qui désirent l'utiliser par défaut, ajoutez un 5 en fin de ligne :
ainsi que la ligne suivante dans le paragraphe en-dessous :
Il ne vous reste plus qu'à mettre "fr" en première position dans la ligne LanguagePriority (juste au-dessus), et à demander à apache de relire sa configuration :

#### Aucun encodage par défaut

Il est également possible de s'affranchir de tout encodage par défaut, de la manière suivante :
Cherchez la directive AddDefaultCharset :
Remplacez l'attribut par la valeur Off :
Là encore, on demandera à Apache de relire sa configuration :
Maintenant, les en-têtes HTTP ne contiendront plus d'indication d'encodage des caractères. Attention : il faudra alors que chaque page indique l'encodage utilisé, car s'en remettre à la détection automatique par les navigateurs peut s'avérer assez aléatoire !

## Windows
### Tout-en-un

Des logiciels tout-en-un (serveur Web, base de donnée MySQL, et PHP) permettent de s'affranchir d'une installation fastidieuse et rédhibitoire pour le débutant :
* EasyPHP : n'a pas vocation à être installé pour de la production, mais pour le développement. Il stocke les bases de données dans C:\Program Files (x86)\EasyPHP\binaries\mysql\data.
* WAMP : est du même type qu'EasyPHP : ce logiciel installe facilement un serveur Web Apache, une base de données MySQL et PHP 4 et 5. Il a l'avantage de permettre de passer facilement de PHP 4 à PHP 5, sans avoir à refaire une installation ou une compilation. Tout comme EasyPHP, c'est un environnement de développement, et non un environnement de production. Attention : la résolution des noms d'hôtes se réalise séparément. Les installations WAMP servent à tester en local sur votre PC. Dans la plupart des cas, il suffit d'utiliser le fichier Hosts local, comme on le ferait sur une machine Linux, afin de lier des noms aux adresses IP. Dans Windows XP, Vista et 7, ce fichier se trouve dans le répertoire systemroot\System32\Drivers\Etc. Il peut se faire que le service ait déjà été configuré. Lorsque vous vous en doutez, contactez votre administrateur réseau. Remarque : vous trouverez une liste des possibilités de résolution de noms avec MS Windows sur Microsoft.com.
* XAMPP : est du même type qu'EasyPHP ou WAMP, le deuxième P étant pour Perl. Son usage est recommandé avec PHPEclipse, et il fournit aussi un serveur Apache Tomcat par défaut.
* The Uniform Server : en anglais seulement avec Apache2, Perl5, PHP5, MySQL5, phpMyAdmin.
Sur Windows 10 pro, le serveur IIS est installé par défaut, et oblige Apache à changer de port (888 au lieu de 80) lors de l'installation. Pour résoudre cela il suffit de décocher Internet Information Services dans Programmes et fonctionnalités, Activer ou désactiver des fonctionnalités Windows.
De même, le port MySQL est susceptible de passer de 3306 à 3388.
Sur Windows 10, EasyPHP development server (alias Devserver, la version rouge) ne fonctionne pas (il manque MSVCR110.dll), mais EasyPHP hosting server (alias Webserver, la bleue) tourne normalement. Or, elle se lance automatiquement à chaque démarrage, ce qui le ralentit significativement. Pour éviter cela, exécuter services.msc, puis passer les trois services ci-dessous en démarrage manuel. Ensuite pour les lancer à souhait (en tant qu'administrateur), créer un script MySQL.cmd contenant les lignes suivantes :

#### Message d'erreur relatif à SSL

Pour l'instant, WAMP ne supporte pas encore le Secure Socket Layer (SSL). L'installation se finit par un message qui vous informe de ce fait. Afin de pouvoir travailler sans problèmes, éditez le fichier c:\windows\php.ini. Cherchez dans ce fichier la ligne qui commence avec extension=php_openssl.dll. Commentez cette ligne en la faisant précéder d'un point-virgule :
;extensions=php_openssl.dll
Si tout se passe bien, vous pouvez ouvrir la page de test dans votre navigateur.

### Installation manuelle

* Apache est disponible sur le site Web de Apache Software Foundation apache.org.
* PHP est téléchargeable sur le site officiel de php. Choisissez le fichier au format ZIP.
* Enfin, vous trouverez MySQL sur mysql.com.

#### Installer Apache

Pour installer Apache, double-cliquez sur le fichier exécutable, et suivez les instructions d'installation automatique.
Si vous installez Apache sur un ordinateur de développement, renseignez le champ "nom de domaine" avec la valeur localhost.
Si vous installez un serveur de production et que vous disposez d'un nom de domaine, vous devriez disposer des informations nécessaires concernant votre nom de domaine, fournies par le registrar.
Une fois l'installation terminée, il faut encore indiquer à Apache qu'il doit fonctionner conjointement avec PHP, car il ne sait pas les traiter par défaut. Pour cela, il faut modifier les informations de configuration d'Apache, contenues dans le fichier httpd.conf, qui se trouve dans le dossier d'installation d'Apache, dans le sous-dossier conf.

#### Installer PHP

Une fois l'archive téléchargée, décompressez-la à la racine de votre disque dur et renommez le dossier en 'PHP'. Dans le dossier PHP, vous trouverez deux fichiers: php.ini-dist et php.ini-recommended. Copiez php.ini-recommended dans votre dossier C:\Windows ou C:\winnt (le nom du dossier dépend de la version de votre système. renommez-le en php.ini.
Ce fichier est le fichier de configuration qui contrôle les options dont vous disposerez. Par exemple :
| PHP.ini | PHP | Rôle |
| error_reporting E_ALL | error_reporting(E_ALL); | Affiche tous les avertissements et erreurs directement sur le site. C'est utile pour la préproduction car cela évite de rechercher d'éventuels messages dans les logs, mais peut perturber la mise en page pour des avertissements bénins. |
| error_reporting 0 | error_reporting(0); | N'affiche aucun message sur le site relatif à son exécution |
| max_execution_time = 300 | set_time_limit(300); | Définit le "timeout", c'est-à-dire le temps maximum en secondes autorisé pour exécuter un script PHP. |
| post_max_size = 80M | ini_set('post_max_size', '80M'); | Définit la taille maximum d'un fichier que l'on peut envoyer au serveur en HTTP. |

#### MySQL

Télécharger et installer le .msi sur http://dev.mysql.com/downloads/gui-tools/5.0.html.
Pour arrêter, démarrer, démarrer automatiquement le serveur MySQL vous devez aller dans la gestion des services (Démarrer/Exécuter/services.msc).

### Apache CGI ou module ?

On peut configurer Apache pour utiliser PHP comme binaire CGI, ou comme module.
L'installation en module offre de meilleures garanties en matière de sécurité, de meilleures performances, et certaines fonctionnalités absentes de l'installation en CGI. Cette installation est cependant un peu plus difficile (mais rassurez-vous, pas tellement plus que l'installation CGI), aussi nous intéresserons nous à celle-ci.
* Dans le répertoire de PHP, trouvez la DLL php5ts.dll, et copiez-la dans le répertoire d'Apache.
* Ouvrez ensuite le fichier httpd.conf. On en a déjà parlé plus tôt, vous vous souvenez où il est, n'est-ce pas ?
* Dans ce fichier, ajouter cette ligne qui permet à Apache de savoir que l'extension .php concerne l'utilisation du module PHP :
    AddType application/x-httpd-php .php
* Puis, ajoutez ces deux lignes qui charge et exécute (respectivement) le module PHP5 au démarrage du serveur :
    LoadModule php5_module c:\php\php5apache.dll
    AddModule mod_php5.c
Enregistrez le fichier httpd.conf et fermez-le.

### IIS

IIS est activé automatiquement sur Windows Server et Windows 10, et peut l'être manuellement pour les versions antérieures, dans le panneau de configuration, Activer ou désactiver des fonctionnalités de Windows. C'est également là que l'on peut le désactiver pour donner le port 80 à Apache.
Son processus est issu de C:\Windows\System32\inetsrv\w3wp.exe et est lancé en tant que "Service réseau". Ce compte local devra donc avoir le droit de lecture sur les fichiers du site web.
Sur Windows Server uniquement, lors de la première utilisation il faut ajouter le rôle Serveur Web dans le Gestionnaire de serveur, accessible dans le menu démarrer, Tous les programmes, Outils d'administration. Puis pour ce rôle il faut cocher plusieurs services de rôle :
* CGI (sous peine d'erreurs 500 à chaque commande PHP).
* ODBC pour les connexions aux bases de données.
Télécharger et installer ensuite le manager PHP pour pouvoir configurer PHP dans :
* Le Gestionnaire des services Internet (%windir%\system32\inetsrv\InetMgr.exe) sur Windows Server.
* Les Services Internet sur Windows PC.
Si ensuite IIS renvoie systématiquement des erreurs 500 par la suite (même sans appel PHP), installer Visual C++ 32 bits (PHP ne fonctionne pas en 64 bits en 2016).

## Docker

Il existe de nombreuses images de conteneur Docker pouvant fournir PHP. Exemple de Dockerfile :
* FROM php:8.2-cli
* FROM php:8.2-fpm

### PHP 7.4 FPM

Exemple avec GD :

## IDE

Pour développer efficacement en PHP il est indispensable d'utiliser un environnement de développement intégré (IDE) plutôt qu'un éditeur de texte sur le PC client. Ils seront abordés dans les chapitres suivants.

### vim

vim dispose de plugins pour programmer en PHP.

## Références

* ↑ https://www.tecmint.com/connect-nginx-to-php-fpm/
* ↑ https://technet.microsoft.com/fr-fr/library/cc753077(v=ws.10).aspx
* ↑ http://blog.bobbyallen.me/2016/05/02/installing-php7-on-windows-server-2012-r2-and-iis-8/
* ↑ https://phpmanager.codeplex.com/
* ↑ https://www.microsoft.com/fr-fr/download/details.aspx?id=48145
* ↑ https://hub.docker.com/_/php
* ↑ https://itecnote.com/tecnote/php-installing-gd-extension-in-docker/
* ↑ https://www.octopuce.fr/debugger-php-en-cli-avec-xdebug-vim/

# Composer

Composer est un logiciel de gestion des bibliothèques PHP open source. Celles-ci sont aussi accessibles sur https://packagist.org/.

## Installation

Pour l'installer il y a trois solutions :
* Avec les commandes PHP décrites sur https://getcomposer.org/download/.
* En téléchargeant le package par navigateur à la même adresse.
* En le téléchargeant avec la commande cURL, comme le montre la vidéo suivante :
À la fin il faut juste disposer du fichier composer.phar.
Pour le lancer, on peut utiliser la commande composer s'il est installé avec PHP, ou php composer.phar s'il est juste téléchargé.
Pour l'installer à partir du téléchargement :
Enfin, pour tester l'installation, lancer :

## Utilisation

Le programme Composer lit et modifie la liste des bibliothèques du projet dans le fichier composer.json.

### init

Pour créer le fichier composer.json :

### create-project

Alternative à init pour les apps initialisée par un framework.

### require

Pour installer un paquet, par exemple client client HTTP Guzzle :
Si l'installation réussit, il ajoute le nom et la version du paquet dans composer.json, ceux de ses dépendances dans composer.lock, et télécharge leurs fichiers dans un dossier "vendors". Il informe ensuite des problèmes de dépendances, par exemple si la version de PHP locale est inférieure à celle recommandée pour le paquet. En cas d'erreur il retire tout ce qu'il a fait.

#### Paramètres

On peut aussi préciser le numéro de version, par exemple MediaWiki :
On peut aussi installer plusieurs paquets à la suite :
Pour éviter de télécharger une bibliothèque destinée au développement en environnement de production, l'ajouter en mode "dev", puis lancer composer install en développement, et composer install --no-dev en production :
Pour utiliser une branche du dépôt de la dépendance, , utiliser le mot réservé ":dev-" suivi de son nom. Ex :
Pour utiliser un commit particulier du dépôt de la dépendance, utiliser le mot réservé "dev-master". Ex :

### install

Généralement quand on clone un projet git existant contenant un composer.json, il suffit ensuite pour le faire fonctionner, d'installer ses dépendances ainsi :
Si plusieurs versions de PHP sont installées, il faut préciser laquelle exécute composer ainsi :

### update

Ne jamais lancer de composer update sur un projet existant, sous peine de devoir tout retester. En effet, mieux vaut ne mettre à jour qu'une seule bibliothèque en précisant son nom :
Il faut parfois éditer le composer.json avec la règle de la nouvelle version souhaitée avant de lancer l'update.

### show

Affiche toutes les bibliothèques installées sur une ligne chacune, ce qui est plus lisible que composer.lock.

### depends

Affiche les bibliothèques qui dépendent du package donné en paramètre.

### clear-cache
## Syntaxe du composer.json

La syntaxe JSON de ce fichier contient quelques extensions :

### name

Le nom de l'application, telle qu'elle sera appelée par composer.
Il existe une syntaxe pour le nommage des bibliothèques sous peine de warnings lors des manipulations avec composer. Elles doivent être de la forme vendor name/package name, uniquement avec des caractères alphanumériques plus "-", "." ou "_".

### require

Le paragraphe "require" contient les noms des dépendances ainsi que leurs numéros de version (SemVer).
| Symbole | Rôle (placé avant un numéro de version) | Exemple |
| >= | permet d'en étendre le numéro. De même on trouve les symboles >, <, <=. | "php": ">=5.5.9" inclut PHP 7. |
| != | exclut une version. | |
| - | définit une plage de versions. | |
| ¦¦ | ajoute des versions possibles. | "symfony/symfony": "2.8 ¦¦ 3.0" regroupe uniquement ces deux versions. |
| * | étend à toutes les sous-versions. | "symfony/symfony": "3.1.*" comprend la 3.1.1. |
| ~ | étend aux versions suivantes du même niveau. | "doctrine/orm": "~2.5" concerne aussi la 2.6 mais pas la 2.4 ni la 3.0. |
| ^ | fait la même chose que tilde sous réserve qu'il y ait une compatibilité ascendante. | |

#### Stability Flag

Après la version à trois nombres, on peut suffixer un arobase puis un Stability Flag. Exemples :
* @dev
* @stable

### require-dev

On y trouve ce qui a été installé avec require --dev, donc généralement des bibliothèques de tests et d'analyse de code.

### config

Ensemble de paramètres de composer, par exemple le timeout ou les identifiants vers certains dépôts.

### autoload

Mapping des namespaces vers les classes. Cela permet de plus d'inclure tous les fichiers des dossiers automatiquement (et donc d'éviter les fonctions require et include).
Exemple :
De plus, un mapping spécifique aux environnements dev est possible avec :

### scripts

Scripts qui s’exécutent quand on lance "composer".
* Soit automatiquement si présents dans "auto-scripts".
* Soit manuellement. Exemple avec Doctrine dans Symfony :
Utilisation :

### extra

Complément de "scripts".

### conflict

Liste automatiquement les dépendances en conflit, c'est-à-dire qui ne peuvent pas être installées avec l'application courante dans une tierce.

### repositories

Pour spécifier des dépôts privés (qui ne sont pas accessibles sans communiquer leur URL).

### Exemple complet

Exemple de mediawiki/core :

## Changer de version de PHP

Composer ne permet pas de changer de version de PHP en ligne de commande. Pour ce faire, il faut éditer le composer.json en mettant la version cible souhaitée, puis lancer composer update.

## Références

* ↑ https://curl.haxx.se/download.html
* ↑ https://getcomposer.org/doc/articles/versions.md
* ↑ https://igor.io/2013/02/07/composer-stability-flags.html
* ↑ https://getcomposer.org/doc/06-config.md
* ↑ https://coopernet.fr/formation/php/autoload
* ↑ https://getcomposer.org/doc/articles/scripts.md
* ↑ https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/core/+/master/composer.json

# PhpStorm

IDE en freemium réputé le meilleur pour le langage PHP (compter 10 € par mois pour l'utiliser au-delà d'un mois), PhpStorm permet entre autres des recherches relativement rapides dans le code grâce à son indexation, de l'autocomplétion des langages Web, de nombreuses propositions d'optimisations de code et des plugins (ex : Git, Docker, frameworks PHP...).

## Installation

Le logiciel est multi-plateforme est ses prérequis figure avec les liens de téléchargement sur le site officiel : https://www.jetbrains.com/help/phpstorm/installation-guide.html.

## Configuration

Pour un projet git, il est recommandé d'ajouter le dossier .idea/ créé par PhpStorm dans le fichier .gitignore.
Pour éviter de modifier la totalité des fichiers d'un projet mal formaté, il faut désactiver le reformatage automatique lors du copier-coller sans Settings, Editor, Smart Keys, Reformat on paste : None.

### Exclure les fichiers minifiés de l'indexation

Idéalement l'indexation des fichiers par PhpStorm devrait prendre moins d'une minute, et ses recherches ne devraient renvoyer que du code source lisible par un humain (par les fichiers minifiés).
Pour ce faire, il faut exclure certains dossiers dans File\Settings\Directories.
Par exemple sur un projet Symfony on exclura :
* public/build (pour les .js optimisés)
* var (pour les .php optimisés, et les logs)

## Fonctionnalités
### Refactorisation

Par rapport à ses concurrents, il offre de nombreuses options de refactorisation. Par exemple, quand on renomme une variable en passant par le menu "Refactor", il peut le répercuter dans tout le code du projet qui l'appelle, y compris dans les getters et setters. De plus, il peut ajouter ces derniers automatiquement, ainsi que le constructeur d'une classe selon ses attributs (raccourci ALT + Ins), avec un formatage très personnalisable, par exemple pour les retours à la ligne après chaque attributs ou selon une largeur.
À ce propos, afin de respecter la PSR-1 lors de l'insertion de setters, il convient de paramétrer dans Editor\Code Style\PHP\Blank lines, Before return statement = 1.

### Autoformatage

Il fournit aussi de nombreuses options d'autoformatage et son analyse de code permet par exemple de trouver les variables non utilisées. Quand on appelle une méthode avec du type hinting, il apparait sans avoir besoin d'ouvrir le fichier de cette dernière. Depuis la version 2019.3, il affiche les méthodes mortes en couleur plus sombre (en plus des variables mortes qu'il signalait déjà).
Par ailleurs, pour le pretty-print XML ou JSON : Code\Reformat Code.

### Terminal

Par ailleurs, il possède un lien vers un terminal shell intégré dans une fenêtre du footer, et peut aussi exécuter des requêtes SQL sur des bases si on lui ajoute les sources de données. À ce propos, il permet de naviguer dans une base de données nativement avec une interface, comme le fait PhpMyAdmin, Adminer ou MySQL Workbench.
L'interpréteur de commande est modifiable dans Settings\Tools\Terminal. Par exemple pour utiliser du shell Unix depuis Windows, on peut mettre :

### Gestion de version

Son système VCS est compatible avec git et permet de voir l'historique des modifications des fichiers en couleur. Par exemple avec un clic droit dans la marge on peut afficher les annotations pour retrouver l'auteur d'un passage, puis réitérer l'opération en affichant les annotations précédentes pour remonter tout l'historique.
De plus, quand on regarde le différentiel des fichiers modifiés depuis le dernier commit (onglet "Version Control" en bas, "resolve", puis "merge..."), en cas de conflit il propose un outil de résolution à trois colonnes très ergonomique.
Enfin, son outil de rebase interactif permet des squash et fixup en masse (dans Log, sélectionner la branche, sélectionner les commits à squasher dans la liste).

### Xdebug

Xdebug peut être déclenché depuis une page Web ou une commande shell. S'il est déjà installé sur le serveur PHP, et pour les pages Web dans le navigateur, voici ce qu'il reste à faire pour le faire fonctionner dans PhpStorm :
* Cliquer sur l'icône en haut à droite Listen for debug connect.
* Lancer le script à déboguer (afficher la page Web ou entrer la commande shell).
Une fenêtre apparait alors dans PhpStorm Incoming Connection From Xdebug, demandant quel est l'index.php correspondant au signal reçu. Cocher "Import mappings from deployment" si les fichiers sont exécutés sur un serveur distant, et "Manually choose local file or project" s'il est local. Cette deuxième option dresse une liste des index.php trouvés dans le projet, mais pour conserver celui par défaut, choisir leur dossier parent (le nom du projet), et cliquer sur "Accept".
En cas de problème, un outil de diagnostic se trouve dans File, Settings, chercher "Xdebug".

#### Docker

Si le serveur PHP est dans un conteneur Docker, il faut le stipuler à PhpStorm :
* Ajouter un serveur : dans File, (Languages & Frameworks,) PHP, Servers, ajouter une URL pour le port 80, et une pour le 443. Pour chacun, cocher "Use path mappings" et y mettre le chemin de chaque projet accessible dans le conteneur PHP.
* Ajouter une configuration de lancement : en haut à droite dans Add Configuration... ou Edit Configurations..., créer une entrée PHP Remote Debug, dans laquelle il faut renseigner le serveur précédemment créé, et la clé de session envoyée par le module de son navigateur.
Le php.ini dépend de l'OS hôte :
* Linux :
* Windows :
* Mac :
Exemple de Dockerfile :

## Raccourcis clavier

Raccourcis clavier indispensables :
| Maj Maj | Rechercher un fichier |
| Ctrl + Maj + N | Ouvrir un fichier (ex : quand on le copie-colle depuis le terminal) |
| Ctrl + Maj + F | Rechercher dans les fichiers |
| Ctrl + G | Aller à la ligne n°X |
| Ctrl + D | Dupliquer la ligne courante |
| Ctrl + Maj + Alt | Sélectionner (en clic, double-clic ou glisser) plusieurs morceaux de codes pour pouvoir les copier. |
| Ctrl + Maj + Alt + T | Renommer en refactorant |
| Ctrl + B | Trouver les utilisations de l'objet courant (équivalent au clic droit, find usages) |
| Ctrl + E | Fichiers récents |
| Ctrl + K | Commiter |
| Ctrl + L | Vider le terminal (utile pour afficher uniquement les derniers logs) |
| Alt + Insert | Générer du code, par exemple le constructeur ou les getters et setters à partir des attributs. |
| Alt + clic | Décupler le curseur pour écrire la même chose à plusieurs endroits. |
| F2 | Se rendre sur l'erreur de compilation du fichier courant |

## Plugins

PhpStorm dispose de plusieurs plugins installables dans un deuxième temps, classables par thèmes. Certains sont payants, mais en voici des gratuits utiles :
* EditorConfig récupère automatiquement la configuration d'IDE par projet (par exemple les conventions de codage) à partir d'un fichier .editorconfig versionné. NB : ce format de fichier fonctionne dans la plupart des autres IDEs.
* SonarLint analyse de code statique en cours de frappe, synchronisable avec SonarQube.
* Prise en charge de plusieurs frameworks PHP :
** Symfony donne :
*** Un accès aux fichiers YAML de déclaration de services depuis les classes PHP et vice-versa en un clic
*** Un accès aux fichiers Twig entre eux ou depuis les classes PHP en un clic. Il faut toutefois ajouter au préalable chaque dossier "template" dans Settings, PHP, Symfony, Twig / Template (Namespace = __main__, Type = ADD_PATH).
** WordPress
** Drupal
** Joomla
* Des frameworks JS :
** Node.js
** Angular
** Next.js
** Vue.js
* Docker

## Critique

* Début 2019, il considère à tort un fichier accessible par deux liens symboliques Linux comme deux fichiers.
* En 2020 et 2023, quand plusieurs projets sont ouverts ensemble, il mélange leurs espaces de nom (namespaces) comme si c'était le même (notamment dans les CTRL + clic).
* Il est possible que l'application freeze le PC. Pour éviter cela aller dans le menu Help/Change Memory Settings et diminuer la valeur.

## Références

* ↑ https://gist.github.com/chadrien/c90927ec2d160ffea9c4#gistcomment-2398281
* ↑ https://plugins.jetbrains.com/plugin/7294-editorconfig
* ↑ https://github.com/editorconfig/editorconfig/wiki/Projects-Using-EditorConfig
* ↑ https://plugins.jetbrains.com/plugin/7219-symfony-support

# NetBeans
## Installation de NetBeans

NetBeans est un environnement de développement intégré (EDI), générique et extensible. Il permet nativement de développer en Java, C, C++, JavaScript, XML, Groovy, PHP et HTML.
De plus, il possède son propre wiki officiel (en anglais). La présente page est donc destinée à le synthétiser au maximum.
Pour démarrer l'installation, le télécharger la version LTS sur https://netbeans.org/downloads/, ou bien la toute dernière sur http://bits.netbeans.org/dev/nightly/latest/.

## Configuration

* Pour installer les plugins comme PHP ou Python : https://netbeans.org/downloads/index.html.
* Par défaut le chemin d'accès d'un fichier ouvert apparait en survol de son nom. Pour l'afficher en permanence sous la barre de menu : Tools, Options, Appearance, Show full file path.
* L'autoformatage est réglable dans Tools, Options, Editor, Formatting.
** Pour déplacer la barre verticale rouge qui se trouve par défaut à 80 caractères de la gauche : Tools, Options, Editor, Formatting, Right Margin. Par exemple sur GitHub, la taille des écrans est de 120 caractères, il vaut donc mieux ne pas dépasser cette largeur pour éviter lors des relectures de codes, de descendre chercher un des ascenseurs pour remonter lire une fin de ligne.
* Pour bénéficier des avantages propres à un framework (ex : autocompletion des objets du projet ou ouverture d'une déclaration de méthode avec "CTRL + clic" sur un appel), il convient, après installation dans "Tools\Plugins" de spécifier manuellement son emplacement dans "Tools\Options", puis pour PHP par exemple "Framework & Tools".

## Utilisation

NetBeans permet de comparer deux fichiers : Tools, Diff...

### Gestion de versions

Les gestions de version sont regroupées dans le menu Team. NetBeans peut donc tout à fait remplacer des clients Git purs tels que GitHub Desktop ou Smartgit.
Pour éviter de commiter fichier par fichier, ajouter le bouton Commit All - Repository en le faisant glisser depuis View, Toolbars, Customize.

## Principaux raccourcis claviers

Liste exhaustive en anglais : http://wiki.netbeans.org/KeymapProfileFor60.
* Alt + Maj + o : ouvre le fichier recherché.
* Ctrl + o : ouvre le fichier déclarant l’objet sélectionné (recherche de classe).
* Ctrl + Maj + f : cherche un texte dans les fichiers le dépôt.
* Ctrl + b : cherche la déclaration d'un élément (dans le même fichier ou pas).
* Ctrl + espace : propose une liste de complétion (mots-réservés et squelettes de fonctions).
* Ctrl + Maj + espace : affiche la documentation d'une méthode (Javadoc, PHPDoc...).
* Ctrl + p : affiche uniquement les arguments possibles d'une méthode.
* Ctrl + Maj + c : commente les lignes sélectionnées.

## Plugins

Certains plugins peuvent se révéler utiles :
* http://plugins.netbeans.org/plugin/45925/sort-line-tools : trie les lignes dans l'ordre alphabétique.
* http://plugins.netbeans.org/plugin/37077/autosave-module-for-6-9-and-later : sauvegarde automatiquement chaque fichier modifié en temps réel.

## Références

* ↑ http://wiki.netbeans.org

# Eclipse

Eclipse est un environnement de développement intégré (EDI), générique et extensible (site officiel http://www.eclipse.org). Son système de plugins permet d'ajouter des fonctionnalités diverses.
Initialement prévu pour développer en Java, grâce aux plugins il peut maintenant également gérer des projets développés avec d'autres langages de programmation tels que :
* Le C et le C++ grâce à l'ensemble de plugins CDT (C Development Toolkit) (compilateur non intégré).
* Le Python via PyDev.
* Avant l'arrivée d'Android Studio, le développement pour Android se faisait avec Eclipse grâce à l'ensemble de plugins ADT (Android Development Toolkit).
Certains IDE sont basés sur Eclipse, et permettent par exemple le développement de logiciel embarqués pour des systèmes temps réel.

## Installation de Eclipse

La page de téléchargement d'Eclipse permet de récupérer une version déjà adaptée au langage ciblé sur http://www.eclipse.org/downloads/. Mais pour installer un plugin manuellement, il faut :
* Lancer Eclipse, puis dans le menu déroulant :Help>Software Updates>Find and Install...
* Cocher Search for new features to install, bouton Next. Bouton New Remote Site..., entrer l'adresse de téléchargement :
* Bouton Finish, choisir un miroir proche puis continuer l'installation.

## Utilisation de Eclipse

L'interface de l'IDE Eclipse est basée sur différentes perspectives. Une seule perspective n'est visible à la fois, et se compose de plusieurs vues. Exemples :
* La perspective "Java" se compose par défaut de la vue "Package Explorer", de la vue éditeur de code en Java avec un onglet par fichier ouvert, de la vue "Outline" donnant la hiérarchie des éléments composant la classe du fichier ouvert.
* La perspective "Debug" est ouverte automatiquement au lancement d'une application en mode débogage et se compose par défaut de la vue "Debug" affichant la pile d'appel, de la vue des points d'arrêt nommée "Breakpoints", de la vue éditeur de code en Java avec un onglet par fichier ouvert, de la vue "Outline" donnant la hiérarchie des éléments composant la classe du fichier ouvert.
* Deux ou plusieurs perspectives peuvent être affichées conjointement.
Chaque vue est une sous-fenêtre qui a un titre et se place dans un cadre particulier de la fenêtre de l'IDE. Les vues peuvent être déplacées à la souris par drag and drop pour changer la disposition de la perspective. Plusieurs vues peuvent partager le même cadre, auquel cas, une barre d'onglets permet de basculer entre les vues. Un double clic sur le titre d'une vue provoque l'affichage du cadre qui la contient en pleine fenêtre, réduisant les autres cadres à une icône sur les côtés. Un second double clic restaure les cadres.
Le menu "Window" permet de changer de perspective, et d'ajouter des vues à la perspective courante. Une vue peut également être retirée de la perspective affichée en utilisant la croix à droite du titre de la vue.

### Édition de lignes

L'éditeur de code possède des raccourcis clavier pratiques rendant l'édition des lignes de code plus rapide :
| Touches | Touches | Effet |
| Shift | ↵ Enter | Ajouter une nouvelle ligne après la ligne courante. |
| Ctrl | ↑/↓ | Faire défiler la vue vers le haut/le bas. |
| CtrlShift | ↑/↓ | Déplacer le curseur sur le membre précédent/suivant de la classe. |
| Alt | ↑/↓ | Déplacer la ligne courante ou les lignes sélectionnées vers le haut/le bas dans le texte. |
| CtrlAlt | ↑/↓ | Dupliquer la ligne courante ou les lignes sélectionnées vers le haut/le bas. |
| CtrlShift | : | Commenter/Décommenter la ligne courante. |

### Complétion de code

L'éditeur de code peut compléter automatiquement le code là où se trouve le curseur :
| Touches | Touches | Effet |
| Ctrl | Espace | Ouvrir la liste des suggestions de complétion. Une fois la suggestion choisie, la validation se fait par l'une des touches suivantes : ↵ Enter, n'ajoute rien derrière la suggestion ; Espace ou ., ajoute également le caractère produit derrière la suggestion. Toute autre touche produit le caractère sans valider (annuler la complétion). |
| AltShift | : | Complète avec la seule possibilité, ou produit un bip s'il y a plusieurs possibilités. |

### Navigation et autres astuces

* Dans les codes sources dépassant la hauteur de fenêtre de l'éditeur, placez le pointeur de la souris sur l'accolade fermante d'un bloc pour voir apparaître un résumé du code d'ouverture du bloc en bulle d'aide. Ceci est fort utile pour vérifier quel bloc est fermé par l'accolade sans avoir à faire défiler le code.
* Placez le pointeur de la souris sur un identifiant de classe, méthode ou variable et enfoncez la touche Ctrl pour faire apparaître un lien cliquable vers la définition.
* Cliquez sur un identifiant de membre de classe pour faire apparaître toutes les occurrences d'utilisation dans le fichier : à la fois dans le texte et dans la barre de défilement. Les blocs apparaissant dans la barre de défilement sont cliquables pour faire défiler le code à la position de l’occurrence. Il y a deux couleurs distinctes pour les occurrences utilisées en lecture (accès, appel, ...) et celles utilisées en écriture (affectation).
    Il peut arriver que cela ne semble pas fonctionner car l'éditeur peut être dans un mode autre que celui par défaut. Il faut dans ce cas appuyer une ou deux fois la touche Échap pour que cela fonctionne.

## Références

* ↑ https://eclipse.org/cdt/
* ↑ (anglais) http://pydev.org/

# Visual Studio Code

Visual Studio Code (ou simplement nommé "code") est un logiciel éditeur de texte graphique, gratuit fonctionnant sous Windows. Il est capable de prendre en charge le débogage, d'effectuer la coloration syntaxique, l'auto-complétion et surtout le pliage de code (code folding), c'est à dire le masquage à volonté de différents blocs d'instructions (contenu d'une classe, d'une fonction, d'une boucle, etc.) : cette fonctionnalité se révèle extrêmement pratique lorsque vos scripts commencent à s'allonger... Il intègre également la gestion de version (notamment Git et SVN), une fenêtre de terminal ainsi qu'un raccourci pour lancement des scripts.
Cet éditeur est disponible pour Windows sur https://code.visualstudio.com .

## Langages supportés

Visual Studio Code prend immédiatement en charge presque tous les principaux langages informatiques.
Plusieurs d'entre eux sont inclus par défaut, comme HTML et CSS, et aussi JavaScript, TypeScript, Java, PHP, mais d'autres extensions de langage peuvent être trouvées et téléchargées gratuitement à partir de VS Code Marketplace.

## Utilisation
### Édition de lignes

L'éditeur de code possède des raccourcis clavier pratiques rendant l'édition des lignes de code plus rapide :
| Touches | Touches | Effet |
| Ctrl | ↵ Enter | Ajouter une nouvelle ligne après la ligne courante. |
| Ctrl | ↑/↓ | Faire défiler la vue vers le haut/le bas. |
| Alt | ↑/↓ | Déplacer la ligne courante ou les lignes sélectionnées vers le haut/le bas dans le texte. |
| AltShift | ↑/↓ | Dupliquer la ligne courante ou les lignes sélectionnées vers le haut/le bas. |
| Ctrl | : | Commenter/Décommenter la ligne courante. |

## Références

* ↑ https://code.visualstudio.com/docs/editor/versioncontrol
* ↑ https://marketplace.visualstudio.com/vscode

# Bases du langage

PHP est un langage dont les programmes s'exécutent côté serveur pour produire la réponse à une requête HTTP, ou une commande shell.
En général, il produit une réponse dans un langage de notation (ex : HTML, XML, ou JSON), et le code PHP peut s'intégrer dedans, par exemple dans les balises HTML comme montré dans ce chapitre introductif.
Il peut également produire une sortie dans un format binaire, par exemple une image PNG produite dynamiquement pour une représentation graphique des données, ou un fichier quelconque pour filtrer les accès à des fichiers téléchargeables.
Dans les premiers chapitres, seul le cas de la sortie en HTML est abordé.

## Intégration du code

Pour que PHP interprète votre code, vous devez remplir deux conditions :
* Votre code doit être placé dans un fichier d'extension .php (selon la configuration du serveur cela peut varier), ouvert via un serveur web en HTTP.
* Votre code doit être compris entre deux balises : <?php ... ?>. Tout ce qui n'est pas compris entre ces balises n'est pas interprété par PHP :
L'utilisation des balises <? ?> (sans le mot "php") peut poser des problèmes de compatibilité. Il faut en effet que pour cela, la directive short_open_tags soit activée dans la configuration de l'environnement, ce qui n'est pas le cas sur la plupart des serveurs mutualisés et hébergements gratuits. Imaginez que vous changiez de serveur avec un interpréteur qui ne reconnaisse pas les balises courtes, il vous faudra alors modifier les balises de chaque fichier, travail fastidieux. Il est donc conseillé de prendre l'habitude d'utiliser les balises de la forme <?php ?>, reconnue universellement.
Pour regarder si votre configuration prend en compte ce type de balises, entrez le code suivant :
Cela affichera le contenu du php.ini. Pour l'obtenir en CLI :
Autre exemple : trouver le .ini utilisé :
Il est possible de trouver des extensions de fichiers comme .phtml, .php3 ou autres. Il est cependant conseillé d'utiliser l'extension .php qui garantit son interprétation par PHP.

## Les directives

Il est possible de définir certains comportements de PHP lors de la compilation par des directives inscrites dans la commande declare. Par exemple :

## Références

* ↑ http://php.net/manual/fr/control-structures.declare.php

# Commentaires
## Principe

Les commentaires sont en réalité des portions de texte qui ne seront pas interprétées par PHP et ne seront visibles que dans le code source. Ils jouent un rôle très important dans la réalisation et la mise à jour d'un script : en effet, les commentaires rendent le code plus lisible et peuvent aider les éventuelles personnes qui souhaitent retravailler votre script. En effet, si les commentaires sont très utiles aux programmeurs seuls, ils le sont encore plus lors du travail en équipe.
Il existe trois façons différentes d'ajouter des commentaires à son script PHP :
* La méthode avec les symboles // pour ajouter un commentaire sur une ligne.
* La méthode avec le sigle # pour ajouter un commentaire sur une ligne également.
* La méthode avec les caractères /* */ pour désigner un bloc de commentaires.
Il est important de ne pas emboîter les commentaires. Exemple à ne pas suivre :
L'interpréteur comprendra que le commentaire s'arrête à hihi*/ et il tentera d'interpréter blalbal*/. Il en résultera donc une erreur.

## Annotations

Il existe des logiciels qui génèrent une documentation complète à partir des commentaires insérés dans le code du programme. De là est apparue une certaine forme de standardisation de ceux-ci afin de faciliter la génération de documentation, appelée PHPDoc. On peut en effet ajouter des commentaires structurés pour permettre de générer une documentation automatique via PEAR ou PhpDocumentor. En pratique, cela se traduit par des mots-clés interprétés, précédés d'un arobase, appelés "annotations".
Exemple :
Les annotations permettent de plus, aux IDE d'en déduire l'autocomplétion, et aident les analyseurs de code statique à garantir la qualité du code. Elles étaient les seules à pouvoir préciser certains types de variables avant l'apparition des type hinting et type checking en PHP7.
Exemple de commentaires indispensables avant PHP7 :
Depuis PHP7 :

## Attributs

Depuis PHP8, il existe des attributs, représentés par des mots-clés suivant un croisillon, pour préciser des informations (métadonnées) sur les classes, fonctions, constantes ou variables. Ex :
Cet attribut sert à ne pas ajouter de warning si le type retourné ne peut pas être déterminé.
Il en existe aussi d'autres comme :
* "Attribute" : pour déclarer un nouvel attribut (en précisant par exemple s'il est restreint aux fonctions).
* "Route" : pour relier une URL à une méthode.
Les attributs d'une classe peuvent être récupérés à l'exécution avec : ReflexionClass->getAttributes.

## Références

* ↑ http://pear.php.net/manual/en/standards.sample.php
* ↑ http://www.phpascal.com/programmation-web/PHP/commentaire-php.html
* ↑ https://www.php.net/manual/fr/language.attributes.overview.php
* ↑ https://php.watch/versions/8.1/ReturnTypeWillChange

# Premier programme
## Hello World

Écrivons notre premier programme PHP. Pour le moment nous nous contenterons d'afficher le fameux "Hello World".
La commande shell est :

### Dans un fichier

Soit le fichier HelloWorld.php ci-dessous, il peut être lancé par :
* les commandes shell php -q HelloWorld.php ou php -f HelloWorld.php
* un navigateur Web, ex : http://localhost/HelloWorld.php

## Étude du code

Le terme echo représente une fonction propre à PHP qui a pour rôle d'afficher du texte, mais on peut aussi utiliser la fonction print à la place.
Quant à 'Hello World', il est écrit entre apostrophes pour indiquer qu'il s'agit de texte, mais on peut aussi utiliser des guillemets à la place.
Enfin, le point-virgule (;) sert à indiquer la fin de l'instruction. On peut donc placer plusieurs commandes sur une seule ligne.

## Parse error

Il s'agit d'une erreur fréquente quand on débute en PHP. Elle est généralement due à une erreur de syntaxe. Cela peut être simplement à cause de l'omission d'un point-virgule ou bien par ce que vous avez une apostrophe qui gène.
Exemple de code erroné :
Ne s'affichera pas, pour ce faire il faut juste mettre un antislash (\) devant notre apostrophe.
Exemple de code opérationnel :
On peut aussi rendre plus lisible le code source en utilisant les caractères suivants :
* \n : saut de ligne,
* \t : tabulation,
* \r : retour de chariot.
Attention : Ces caractères ne sont interprétés par le moteur PHP que s'ils sont introduits à l'aide de double apostrophe (guillemets) :
Vous pouvez remarquer que l'exemple précédent est constitué de deux langages HTML et PHP, vous remarquerez aussi que le script est placé entre les balises <body></body> ce n'est pas une obligation ainsi le code suivant retourne la même chose :

## Particularités de PHP CLI

PHP en ligne de commande possède plusieurs différences avec PHP sur serveur Web :
* Les variables superglobales sont différentes : il n'y a pas de $_GET, $_POST et $_COOKIE.
* Les paramètres (après le nom du script) sont récupérables par la variable globale $argv, et leur nombre par $argc (ou $_SERVER['argc'] si "register_globals = off;" dans php.ini).

## Références

* ↑ http://php.net/manual/fr/features.commandline.options.php

# Variables
## Définition

En PHP, les variables sont représentées par un signe dollar "$" suivi du nom de la variable, ou d'un underscore "_" pour les constantes (un warning apparait quand ces dernières sont redéfinies).
Le nom est sensible à la casse (par exemple $MaVariable est différent de $mavariable). Dans tous les cas, les variables doivent commencer par une lettre (a-z, A-Z) :

## Exemple

Nota bene : une variable accolée à du texte est précédée d'un point. Ce dernier sert à la concaténation et dans le cas présent est surtout utile pour indiquer à l'interpréteur que l'on passe du texte, puis à une variable. On lui évite ainsi un temps de réflexion qu'il aurait si l'on avait écrit :
* Pour citer du texte contenant uniquement des apostrophes ou des guillemets, on peut encadrer les uns par les autres :
* Pour citer du texte contenant les deux symboles, on peut utiliser le caractère d'échappement "\" :

### Here document

Pour éviter de s'encombrer des caractères d'échappement, il existe aussi les syntaxes heredoc et nowdoc avec l'opérateur "<<<". Ex :
heredoc interprète similairement à une chaine entre guillemets et nowdoc entre apostrophes.
Le mot de fin ("Test" dans l'exemple) des syntaxes heredoc ne doit pas être indenté ni suivi d'autres caractères que le ";", dans les versions PHP antérieures à 7.3.
Mais si cela pose problème, utiliser les accolades pour forcer l'interpolation :

## Chaines binaires

A ne pas confondre avec les nombres binaires qui sont composés de 0 et de 1, les chaines binaires sont apparues en PHP 5.2.1 et indiquées avec le préfixe "b". Ex :
Elles se distinguent des autres chaines par leur encodage, qui ne permet pas à ses caractères non ASCII d'être affichés brutes. Par exemple, print(b'é'); donne : �.
On peut alors la convertir avec :

## Types de variables

Contrairement à de nombreux langages de programmation, en PHP il ne faut pas prédéclarer une variable mais celle-ci est typée lors de son instanciation.
En PHP il y a donc quatre types de variables scalaires :
* entiers (integer) : nombres naturels sans décimale (sans virgule) ;
* réels (float) : nombres décimaux (on parle généralement de type "double", car il s'agit de nombre décimaux à double précision). On peut y introduire des puissances de 10 avec la lettre "e" (ex : 2e1 = 20, 4e-3 = 0.004) ;
* booléens (boolean) : deux valeurs possibles : 1 ou 0. Elles sont équivalentes aux mots réservés true ou false (en français, vrai ou faux) ;
* chaînes de caractères (string) : ensembles de caractères (des phrases).
De plus, on trouve les types complexes :
* tableaux (array) : listes d'éléments ordonnés.
* objets (object) : classe instanciée.

### Pratique sur les nombres flottant

Il faut toujours arrondir les nombres flottant à l'affichage, mais aussi lors des comparaisons.
Exemple :
Lors de la division de nombres à virgules flottantes, on peut facilement avoir une imprécision à cause du mode de leur stockage en mémoire :
donne :

## Variables dynamiques

Il est pratique d'avoir parfois des noms de variables qui sont variables. C'est-à-dire un nom de variable qui est affecté et utilisé dynamiquement. La valeur MaVariable est affectée à une variable classique appelée a avec l'instruction suivante :
Une variable dynamique, ou variable variable, utilise le nom d'une autre variable. Dans l'exemple ci-dessous, la valeur bonjour est affectée à la variable dynamique $$a, c'est-à-dire à une variable dont le nom est la valeur $a de la variable a. La variable classique a contient la valeur MaVariable donc le code :
est équivalent à : $MaVariable="bonjour";
Attention : cette syntaxe est inutile pour les fonctions. Ex :
Dans le cas des tableaux variables, il faut préciser si l'index s'applique à la variable ou à la variable dynamique à l'aide d'accolades :

### Variable de classe variable

Les variables de classe seront introduites en détails dans un chapitre ultérieur. Mais il faut savoir que leurs noms peuvent aussi être variables avec ces notations :

## Autres variables

Les variables présentées dans ce paragraphe sont des tableaux indicés par le nom de la valeur accédée (une chaîne de caractère).

### Variables superglobales

    Pour plus de détails voir : Programmation PHP/Variables superglobales.

### Variables de sessions

    Pour plus de détails voir : Programmation PHP/Sessions.
Lors de la création d'une session (session_start), il est possible d'enregistrer des variables (par session_register('nom_variable') = $variable ). On peut aussi utiliser le tableau $_SESSION pour créer et modifier une variable de session (par exemple : $_SESSION['ma_variable'] = 3; )
Il est également possible de supprimer les sessions courantes dans le code PHP en utilisant la fonction session_destroy. La destruction de la session en cours peut aussi se faire par la fermeture du navigateur.
Pour supprimer une variable de session sans supprimer la session entière, il suffit d'utiliser la fonction unset($_SESSION['ma_variable']).

### Variables de cookie

    Pour plus de détails voir : Programmation PHP/Cookies.
Le tableau $_COOKIE permet de gérer les cookies (définis avec setcookie). Ces cookies sont d'une très grande importance mais sont limités à 20 dans la configuration par défaut de PHP.
Ne pas mettre d'informations privées (mots de passe du serveur...) dans ces variables car elles sont stockées dans un fichier non protégé, sur le disque dur de l'utilisateur.

### Variables de requêtes

$_REQUEST est un tableau associatif constitué du contenu des variables $_GET, $_POST, $_COOKIE.

### Variables de fichiers

    Pour plus de détails voir : Programmation PHP/Fichiers.
Lors d'un téléchargement de fichiers vers le serveur, une variable est assignée aux données de ce fichier. Il s'agit de $_FILES. Elle permet de récupérer le nom du fichier envoyé (exemple : mon_image.png), le nom du fichier temporaire où PHP a copié les données et où il est donc possible de les lire (exemple: C:\temp\T0001AF7.tmp).
Exemple :

### Variables mixtes

Le mot clé mixed permet de définir une variable mixte.

### Variables de serveurs

$_SERVER permet d'obtenir des renseignements sous forme d'un tableau sur le serveur.

#### 'PHP_SELF'

    Le nom du fichier du script en cours d'exécution, par rapport à la racine web. Par exemple, $_SERVER['PHP_SELF'] dans le script situé à l'adresse http://www.monsite.com/test.php/foo.bar sera /test.php/foo.bar. La constante __FILE__ contient le chemin complet ainsi que le nom du fichier courant.

#### 'argv'

    Tableau des arguments passées au script. Lorsque le script est appelé en ligne de commande, cela donne accès aux arguments, comme en langage C. Lorsque le script est appelé avec la méthode GET, ce tableau contiendra la chaîne de requête.

#### 'argc'

    Contient le nombre de paramètres de la ligne de commande passés au script (si le script fonctionne en ligne de commande).

#### 'GATEWAY_INTERFACE'

    Numéro de révision de l'interface CGI du serveur : i.e. ' CGI/1.1 '.

#### 'SERVER_NAME'

    Le nom du serveur hôte qui exécute le script suivant. Si le script est exécuté sur un hôte virtuel, ce sera la valeur définie pour cet hôte virtuel.

#### 'SERVER_SOFTWARE'

    Chaîne d'identification du serveur, qui est donnée dans les en-têtes lors de la réponse aux requêtes.

#### 'SERVER_PROTOCOL'

    Nom et révision du protocole de communication : i.e. ' HTTP/1.0 ';

#### 'REQUEST_METHOD'

    Méthode de requête utilisée pour accéder à la page; i.e. ' GET ', ' HEAD ', ' POST ', ' PUT '.

#### 'REQUEST_TIME'

    Le temps Unix depuis le début de la requête. Disponible depuis PHP 5.1.0.

#### 'QUERY_STRING'

    La chaîne de requête, si elle existe, qui est utilisée pour accéder à la page.

#### 'DOCUMENT_ROOT'

    La racine sous laquelle le script courant est exécuté, comme défini dans la configuration du serveur.

#### 'HTTP_ACCEPT'

    Contenu de l'en-tête Accept: de la requête courante, s'il y en a une.

#### 'HTTP_ACCEPT_CHARSET'

    Contenu de l'en-tête Accept-Charset: de la requête courante, si elle existe. Par exemple : ' iso-8859-1,*,utf-8 '.

#### 'HTTP_ACCEPT_ENCODING'

    Contenu de l'en-tête Accept-Encoding: de la requête courante, si elle existe. Par exemple : ' gzip '.

#### 'HTTP_ACCEPT_LANGUAGE'

    Contenu de l'en-tête Accept-Language: de la requête courante, si elle existe. Par exemple : ' fr '.

#### 'HTTP_CONNECTION'

    Contenu de l'en-tête Connection: de la requête courante, si elle existe. Par exemple : ' Keep-Alive '.

#### 'HTTP_HOST'

    Contenu de l'en-tête Host: de la requête courante, si elle existe.

#### 'HTTP_REFERER'

    L'adresse de la page (si elle existe) qui a conduit le client à la page courante. Cette valeur est affectée par le client, et tous les clients ne le font pas. Certains navigateur permettent même de modifier la valeur de HTTP_REFERER sous forme de fonctionnalité. En bref, ce n'est pas une valeur de confiance.

#### 'HTTP_USER_AGENT'

    Contenu de l'en-tête User_Agent: de la requête courante, si elle existe. C'est une chaîne qui décrit le client HTML utilisé pour voir la page courante. Par exemple : Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). Entre autres choses, vous pouvez utiliser cette valeur avec get_browser pour optimiser votre page en fonction des capacités du client.

#### 'HTTP_header'

    Valeur de l'en-tête HTTP correspondant envoyé dans la requête du client.

#### 'HTTPS'

    Définissez à une valeur non-vide si le script nécessite d'utiliser le protocole HTTPS.

#### 'REMOTE_ADDR'

    L'adresse IP du client qui demande la page courante.

#### 'REMOTE_HOST'

    Le nom de l'hôte qui lit le script courant. La résolution DNS inverse est basée sur la valeur de REMOTE_ADDR

#### 'REMOTE_PORT'

    Le port utilisé par la machine cliente pour communiquer avec le serveur web.

#### 'SCRIPT_FILENAME'

    Le chemin absolu vers le fichier contenant le script en cours d'exécution.

#### 'SERVER_ADMIN'

    La valeur donnée à la directive SERVER_ADMIN (pour Apache), dans le fichier de configuration. Si le script est exécuté par un hôte virtuel, ce sera la valeur définie par l'hôte virtuel.

#### 'SERVER_PORT'

    Le port de la machine serveur utilisé pour les communications. Par défaut, c'est '80'. En utilisant SSL, par exemple, il sera remplacé par le numéro de port HTTP sécurisé.

#### 'SERVER_SIGNATURE'

    Chaîne contenant le numéro de version du serveur et le nom d'hôte virtuel, qui sont ajoutés aux pages générées par le serveur, si cette option est activée.

#### 'PATH_TRANSLATED'

    Chemin dans le système de fichier (pas le document-root) jusqu'au script courant, une fois que le serveur a fait une traduction chemin virtuel -> réel.

#### 'SCRIPT_NAME'

    Contient le nom du script courant. Cela sert lorsque les pages doivent s'appeler elles-mêmes. La constante __FILE__ contient le chemin complet ainsi que le nom du fichier (i.e. inclut) courant.

#### 'REQUEST_URI'

    L'URI qui a été fourni pour accéder à cette page. Par exemple : ' /index.html '.

#### 'PHP_AUTH_DIGEST'

    Lorsque vous utilisez PHP avec Apache en tant que module faisant une identification HTTP Digest cette variable est définie dans l'en-tête 'Authorization' envoyé par le client (que vous devez donc utiliser pour réaliser la validation appropriée).

#### 'PHP_AUTH_USER'

    Lorsque vous utilisez PHP avec Apache ou IIS (ISAPI en PHP 5) en tant que module faisant une identification HTTP, cette variable est définie à l'utilisateur fourni par l'utilisateur.

#### 'PHP_AUTH_PW'

    Lorsque vous utilisez PHP avec Apache ou IIS (ISAPI en PHP 5) en tant que module faisant une identification HTTP, cette variable est définie au mot de passe fourni par l'utilisateur.

#### 'AUTH_TYPE'

    Lorsque vous utilisez PHP avec Apache en tant que module faisant une identification HTTP, cette variable est définie au type d'identification.

#### Détection du protocole

Pour déterminer si l'utilisateur se connecte en HTTP ou HTTPS à partir de la superglobale $_SERVER :
* $_SERVER['REQUEST_SCHEME'] semble la meilleure option, car renvoie "http" ou "https".
* $_SERVER['SERVER_PORT'] renvoie 80 ou 443.
* $_SERVER['HTTPS'] donne true en HTTPS ou null en HTTP (provoque un warning unset).
* $_SERVER['SERVER_PROTOCOL'] ne convient pas du tout car renvoie "HTTP/1.1" dans les deux cas.
* $_SERVER['HTTP_X_FORWARDED_PROTO'] et $_SERVER['HTTP_FRONT_END_HTTPS'] : à creuser...
Si ces variables renvoient les caractéristiques HTTP en connexion HTTPS, c'est qu'il faut activer SSL pour le site.

## Tester les types

Plusieurs fonctions permettent de déterminer les types des objets.
Soit une variable $v :
* gettype($v) donne son type simple ("object" si c'est une instance de classe).
* get_class($v) donne son type complexe si c'est une instance de classe.
* is_null($v) teste si un objet est null. Équivaut à "=== null".
* is_bool($v) est vrai si booléen.
* is_numeric($v) est vrai si numérique.
* is_int($v) est vrai si entier.
* is_float($v) est vrai si décimal.
* is_string($v) est vrai si chaine.
* is_array($v) est vrai si tableau.
* is_object($v) est vrai si objet.
* $v instanceof MaClasse est vrai si l'objet est de type "MaClasse".

## Conversions

En PHP, il n'y a pas de déclaration de variable selon un type figé. Pour le forcer, il faut donc utiliser les fonctions suivantes, ou un cast (vers un type entre parenthèses).
Soit une variable $v, et $s un séparateur :
* intval($v) ou (int) $v convertit en entier.
* floatval($v) ou (float) $v convertit en flottant.
* chr($v) convertit en caractère.
* strval($v) ou (string) $v convertit un scalaire en chaine de caractères.
* implode($s, $v) ou join($s, $v) transforme un tableau en chaine selon un séparateur donné.
* explode($s, $v) convertit une chaine en tableau avec un séparateur donné entre les valeurs.
De plus, il est possible de réaliser un transtypage en préfixant la variable avec le type entre parenthèses. Exemple :
(bool) "false" renvoie true car toute string non vide est vraie.

### URLs

Tous les caractères Unicode n'étant pas admis dans les URL, on utilisera urlencode pour convertir une chaine dans ce format.
De plus, si l'URL contient des paramètres HTTP, http_build_query permet, en plus de l'encodage, de les générer à partir d'un tableau associatif.

## Références

* ↑ http://fr2.php.net/manual/fr/language.types.string.php#language.types.string.syntax.heredoc
* ↑ https://www.php.net/manual/fr/language.types.string.php#language.types.string.syntax.heredoc
* ↑ https://github.com/microsoft/vscode/issues/137539
* ↑ https://www.php.net/manual/en/language.types.float.php
* ↑ http://php.net/manual/fr/language.variables.variable.php
* ↑ http://www.php.net/manual/fr/function.setcookie.php
* ↑ http://php.net/manual/fr/function.is-null.php

# Variables superglobales
## Les variables superglobales

Ces variables sont prédéfinies à PHP et sont destinées à stocker des informations bien spécifiques. Elles se présentent généralement sous la forme d'un tableau associatif à une ou deux dimensions. Elles sont disponibles dans tous les contextes d'exécution (fonctions ou méthodes).
Voici une liste non-exhaustive (comprenant les cas d'utilisation les plus courants) :

### Variables de serveur : $_SERVER

Elle contient des informations sur le serveur (nom, IP, logiciels installés…)
Par exemple pour extraire l'URL de la page courante :

#### Références

* « Extraire l’url de la page en cours » [html]
* (en) « $_SERVER » [html]

### Variables d'environnement : $_ENV

Elle contient des informations sur l'environnement d'exécution du script PHP (c'est-à-dire sur le serveur). Elle est donc directement liée au serveur et à son système.
Prenons comme exemple, le prénom 'Paul' :
En imaginant que l'utilisateur 'Paul' exécute ce script, on aura alors :
* Exemple
* Mon nom d'utilisateur est Paul !

### Cookies : $_COOKIE

Elle stocke les informations sur les cookies envoyés aux clients.
Un petit exemple pour illustre cela :
On suppose que le cookie "name" a été défini précédemment, (on prendra Paul encore une fois)
L'exemple ci-dessus va afficher alors :
* Exemple
* Bonjour Paul !

### GET variables : $_GET

Elle stocke les valeurs des arguments passés par URL. Ses clés sont donc par conséquent variables. Pour illustrer ces propos, imaginons que l'utilisateur ai entrée l'URL suivant : http://example.com/?name=Paul
L'exemple ci-dessus va afficher alors :
* Exemple
* Bonjour Paul !

### POST variables : $_POST

Elle stocke les valeurs des informations passées par formulaire avec la méthode="post". Ses clés sont donc par conséquent variables.
L'exemple ci dessous est un formulaire comportant un champ de saisie et un bouton de soumission.
Quand un utilisateur soumet des données en cliquant sur "Soumettre", les données du formulaire sont envoyées dans un fichier spécial dans l'attribut d'action de la balise <form>.
Puis, on peut utiliser $_POST pour recueillir la valeur du champ de saisie.
* Exemple
* <html>
* <body>
* <form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
* Nom : <input type="text" nom="fnom">
* <input type="soumettre">
* </form>
* <?php
* if ($_SERVER["REQUEST_METHOD"] == "POST") {
* // collecte la valeur du champ de saisie
* $nom = $_REQUEST['fnom'];
* if (empty($nom)) {
* echo "Le nom est vide";
* } else {
* echo $nom;
* </body>
* </html>

### Variables de requête : $_REQUEST

Un tableau associatif constitué du contenu des variables $_GET, $_POST, $_COOKIE.
L'exemple ci dessous est un formulaire comportant un champ de saisie et un bouton de soumission.
Quand un utilisateur soumet des données en cliquant sur "Soumettre", les données du formulaire sont envoyées dans un fichier spécial dans l'attribut d'action de la balise <form>.
Puis, on peut utiliser $_REQUEST pour recueillir la valeur du champ de saisie.
* Exemple
* <html>
* <body>
* <form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
* Nom : <input type="text" nom="fnom">
* <input type="soumettre">
* </form>
* <?php
* if ($_SERVER["REQUEST_METHOD"] == "POST") {
* // collecte la valeur du champ de saisie
* $nom = $_REQUEST['fnom'];
* if (empty($nom)) {
* echo "Le nom est vide";
* } else {
* echo $nom;
* </body>
* </html>

### Variable de téléchargement : $_FILES

Elle stocke les informations sur un fichier envoyé via HTTP par le client par un formulaire.

### Variables de session : $_SESSION

Elle contient les valeurs de la session en cours pour le client.

### Variables globales : $GLOBALS

Elle stocke les variables globales de la page. Ses clés sont donc variables.
Ci-dessous, un exemple d'utilisation de la variable $GLOBALS.
* Exemple
* <?php
* $x = 75;
* $y = 25;
* function addition
* $GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y'];
* addition;
* echo $z;
Lorsqu'on exécute ce code, on obtient "100" (=> résultat de la variable 'z' + 'y').

## filter_input

Une bonne pratique consiste à filtrer les contenus des variables superglobales, qui sont vulnérables aux injections de code.
Pour des raisons de sécurité, on évitera donc d'appeler directement les tableaux des variables superglobales comme dans les paragraphes précédents, pour leur préférer la syntaxe filter_input :
Ne pas confondre avec la fonction filter_var qui permet d'appliquer des validations ou nettoyages de certaines données (ex : email, URL, adresse IP, booléen...).

## Références

* ↑ https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet#Untrusted_data
* ↑ http://php.net/manual/fr/function.filter-input.php
* ↑ http://php.net/manual/fr/filter.filters.validate.php

# Constantes

Tout comme en C, PHP peut utiliser des variables dont on précise la valeur une fois pour toutes et qui ne pourra être modifiée jusqu'à la fin de l'exécution du code.

## Nom

Le nom d'une constante suit les mêmes règles que celles pour les variables, mis à part qu'il n'est pas précédé par $. Par convention on les baptise avec des lettres capitales.

## Déclaration

Pour déclarer une constante, on utilise la fonction define (depuis PHP3) qui renvoie un booléen true en cas de réussite de déclaration et false en cas d'échec.
La syntaxe de define est la suivante :
La chaîne de caractère est le nom de la constante, pouvant contenir lettre, tiret, underscore et chiffre (la première lettre de la chaîne est une lettre dans [a-zA-Z]).

## Utilisation

L'utilisation est semblable à celle des variables.
Depuis PHP 5, la déclaration de constantes à l'intérieur d'une classe peut se faire avec le mot-clé const de la façon suivante :
Ces constantes sont publiques par défaut, mais PHP 7.1 introduit la possibilité de les rendre privée avec : private const.

## Informations supplémentaires
### Type de données

Une constante, si elle peut être de type booléen, entier, nombre à virgule flottante ou chaîne de caractère, mais en aucun cas un objet
Depuis PHP 7, elle peut aussi être un tableau de scalaires.
Depuis PHP7.4, les nombres entiers peuvent être rendus plus lisibles dans le code en ajoutant des "_" comme séparateurs. Ex :

### Unicité de la déclaration

La redéclaration d'une constante portant le même nom est ignorée, et la valeur de la première déclaration reste valable.
D'où l'utilisation de defined pour déterminer si une constante est déjà définie ou pas :

### Conflit de nom

Il existe des constantes intégrées à PHP, or on ne peut créer une constante portant leurs noms, cela entraînerait une erreur. En général, évitez la syntaxe suivante pour le nom d'une variable ou d'une constante :

### Constantes prédéfinies

Il en existe de deux types :
* fixes en valeur
* dont la valeur est dynamique

#### Constantes intégrées à valeur fixe

Les constantes suivantes ont des valeurs fixes, comme celles définies avec define :
* TRUE : vrai (booléen) = 1.
* FALSE : faux (booléen) = 0.
* INF : l'infinie.
* PHP_VERSION : version de PHP du serveur exécutant le script.
* PHP_OS : nom du système d'exploitation du serveur exécutant le script.
* PHP_EOL : end of line = \n.
* DIRECTORY_SEPARATOR : '/' sur Linux et MacOS, '\' sur Windows.

#### Constantes intégrées à valeur dynamique

Les constantes magiques :
* __DIR__ : dossier courant.
* __NAMESPACE__ : namespace courant.
* __FILE__ : chemin complet du fichier qui est actuellement exécuté par le serveur (exemple : /la/ou/est/le/fichier.php).
* __CLASS__ : nom de la classe dans laquelle on se trouve.
* __TRAIT__ : trait courant.
* __FUNCTION__ : nom de la fonction dans laquelle on se trouve.
* __METHOD__ : nom de la méthode dans laquelle on se trouve.
* __LINE__ : ligne du fichier qui est actuellement exécuté par le serveur.
Exemple d'utilisation :
Qui affichera :
L'affichage de la première ligne, par exemple, dépend d'où est situé le fichier dans l'arborescence des fichiers.

## Références

* ↑ http://php.net/define
* ↑ http://php.net/manual/fr/function.defined.php
* ↑ http://php.net/manual/fr/reserved.constants.php
* ↑ https://www.php.net/manual/fr/language.constants.magic.php

# Opérateurs

Les opérateurs sont des symboles qui permettent de manipuler les variables.

## Opérateurs arithmétiques
### + Opérateur d'addition

Si les opérandes sont des tableaux, "+" est l'opérateur union.

### % Opérateur modulo

Il sert à tester si un nombre est le multiple d'un autre :

## Opérateurs logiques booléens

Les opérateurs logiques agissent sur les types booléens (true ou false).
* ! : négation. Transforme false en true et true en false.
* && : opérateur "et".
* and : opérateur "et" de moindre priorité.
* || : opérateur "ou"
* or : opérateur "ou" de moindre priorité.

## Opérateurs logiques bit à bit

Les opérateurs logiques bit à bit agissent sur chaque bit des valeurs entières.
* ~ Négation : 0 -> 1 et 1 -> 0
* & Opérateur et (and)
* | Opérateur ou (or)
* ^ Opérateur ou exclusif (xor)
* >> : décalage à droite (division par deux)
* << : décalage à gauche (multiplication par deux).

## Opérateurs d'assignation

Ils permettent de simplifier l'écriture des assignations.
* += additionne deux valeurs et stocke le résultat dans la variable ($x += 5 équivaut à $x = $x+5)
* -= soustrait deux valeurs et stocke le résultat dans la variable ($x -= 5 équivaut à $x = $x-5)
* *= multiplie deux valeurs et stocke le résultat dans la variable ($x *= 5 équivaut à $x = $x*5)
* /= divise deux valeurs et stocke le résultat dans la variable ($x /= 5 équivaut à $x = $x/5)
* %= donne le reste de la division de deux valeurs et stocke le résultat dans la variable ($x %=5 équivaut à $x = $x%5)
* |= effectue un OU logique entre deux valeurs et stocke le résultat dans la variable ($x |=5 équivaut à $x = $x|5)
* ^= effectue un OU exclusif entre deux valeurs et stocke le résultat dans la variable ($x ^= 5 équivaut à $x = $x^5)
* &= effectue un ET logique entre deux valeurs et stocke le résultat dans la variable ($x &= 5 équivaut à $x = $x&5)
* .= concatène deux chaînes et stocke le résultat dans la variable ($x .= 'test' équivaut à $x = $x.'test')

## Opérateurs d'incrémentation

* ++ : incrémente de 1 la valeur de la variable si "$x = 1 ", "$x++" vaut "++$x" qui vaut "2".
* -- : décrémente de 1 la valeur de la variable si "$x = 2", "$x--" vaut "--$x" qui vaut "1".
Ces opérateurs sont très utiles dans les boucles (notamment for).

## Opérateurs de comparaison

* == renvoie un booléen pour indiquer l'égalité (ce n'est pas =) : $x == 1 teste si la valeur $x est égale à 1.
* === renvoie un booléen pour indiquer à l'identique, c'est-à-dire l'égalité à la fois de la valeur et du type.
* != (alias <>) renvoie un booléen pour indiquer la différence : $x != 1 teste si la valeur $x est différente de 1.
* !== renvoie un booléen pour indiquer la différence ou de la valeur ou du type.
* > renvoie un booléen pour indiquer la supériorité stricte si $x > 1 teste si la valeur $x est strictement supérieure à 1.
* < renvoie un booléen pour indiquer l'infériorité stricte : $x < 1 teste si la valeur $x est strictement inférieure à 1.
* >= renvoie un booléen pour indiquer la supériorité-égalité si $x >= 1 teste si la valeur $x est supérieure ou égale à 1.
* <= renvoie un booléen pour indiquer l'infériorité-égalité si $x <= 1 teste si la valeur $x est inférieure ou égale à 1.
* <=> renvoie 1 si le premier opérande est supérieur, 0 s'il est égal, et -1 s'il est inférieur au deuxième.
Si les opérandes sont des tableaux :
* "==" est l'opérateur d'égalité (mêmes paires clés/valeurs).
* "===" vérifie aussi le type et l'ordre des paires clés/valeurs.
* "!=" (alias "<>") est l'opérateur d'inégalité.
* "!==" est l'opérateur non identique.

## Opérateurs divers
### Opérateur ?

L'opérateur ? permet de renvoyer une valeur ou une autre en fonction d'un test.
* ?? (depuis PHP 7) (Null Coalescing Operator) opérateur binaire qui renvoie l'opérande qui le précède s'il existe (isset), sinon l'opérande qui le suit.
* ?: (depuis PHP 7) opérateur ternaire qui renvoie l'opérande qui le précède s'il existe et est non vide (empty), sinon l'opérande qui le suit.
Par exemple :
qui est équivalent au bloc PHP suivant :
Toutefois il présente un autre avantage que sa concision : la stratégie d'évaluation de cet opérateur ne calcule pas le "else" si le script n'a pas besoin d'y aller. Il devient donc moins gourmand en ressources.
En l'absence de premier résultat, le ternaire renvoie l'expression comparée si non nulle ou vide. Exemple :

### -> Opérateur objet

L'opérateur objet -> permet d'accéder aux propriétés d'un objet (variables et méthodes de classe). Exemple :
Depuis PHP 8 il a une version qui renvoie null si l'objet est null :

### :: Opérateur de résolution de portée

L'opérateur ::, également appelé en PHP Paamayim Nekudotayim, permet d'accéder aux membres statiques ou constants d'une classe. Exemple :

### @ Opérateur de contrôle d'erreur

L'arobase permet d'ignorer les erreurs de l'expression qui le suit. Ex :

### & Opérateur de référence

"&" accolé avant une variable désigne sa référence, qui est en quelque sorte un pointeur en lecture seule. Elles sont utiles par exemple pour éviter copier un grand tableau en mémoire quand il est en paramètre d'une fonction. Exemple :
Son utilisation pour les fonctions sera détaillée dans le chapitre sur les fonctions, mais on peut aussi l'utiliser dans les boucles.

### ... Opérateur de fonction variadique

Depuis PHP 5.6, "..." dans la liste des arguments d'une fonction indique que ceux-ci sont d'un nombre variable.
Exemple :

## Précédence des opérateurs

Quand une opérande est entourée de deux opérateurs (ex : 1 + 2 * 3 = 7), des règles de priorités s'appliquent systématiquement pour résoudre les opérations.
Site source légèrement incomplet, ex : $$.

## Références

* ↑ https://www.php.net/manual/fr/language.operators.array.php
* ↑ https://www.php.net/manual/fr/function.fmod.php
* ↑ PHP>=7
* ↑ https://wiki.php.net/rfc/isset_ternary
* ↑ http://php.net/manual/fr/language.references.php
* ↑ https://www.php.net/manual/fr/language.operators.precedence.php

# Fonctions
## Définition de fonction

Outre les dizaines de fonctions natives, PHP permet bien entendu d'écrire ses propres fonctions. Pour en définir une, il suffit d’utiliser le mot-clef function. Comme le langage est faiblement typé, une fonction peut retourner n’importe quel type de valeur (chaîne, entier…) ou ne rien retourner du tout. Enfin, ses arguments peuvent avoir des valeurs par défaut, être nommés (depuis PHP8) et sont limités à 12 par fonction.
Notez que lorsqu'une fonction arrive à un return, elle l'effectue puis se termine, même s'il y a d'autres instructions après.
Par ailleurs, en cas de gros volume de données à retourner, on peut utiliser yield au lieu de return pour les décomposer à l'aide du générateur PHP (classe Generator).
Contrairement à d'autres langages, PHP ne permet pas d'appeler certains arguments par leurs noms : si l'on souhaite appeler un des derniers arguments, il faut donc définir tous ceux avant lui, même les optionnels. Toutefois pour éviter ce désagrément, on peut utiliser la classe ReflectionMethod. NB : il existe aussi ReflectionClass.

### Portée des variables

Le problème de portée des variables est assez réduit en PHP. Une fonction n'a accès qu’à ses arguments, ses propres variables et aux variables globales importées statiquement (mot clé global). De ce fait, il y a peu de confusion.
Toujours suivant le même principe, les variables utilisées dans une fonction sont toutes détruites à sa sortie (les variables globales non, bien entendu).
* Exemple
* $valeur1=10;
* $valeur2=20;
* function exemple($valeur)
* global $valeur1; // récupération de la valeur globale de $valeur1
* $valeur3=5;
* $calcul=$valeur1+$valeur2+$valeur3+$valeur; // 10 + 0 + 5 + le paramètre qui sera entre parenthèses.
* //$valeur2 n'ayant pas été définie comme valeur globale, la variable $valeur2 est donc vide.
* return $calcul;
* echo exemple(2); // affiche 17
On peut aussi trouver un peu plus compliqué si vous utilisez deux fichiers. L'un pour les variables, l'autre pour les traitements.

#### Espaces de noms

Depuis PHP 5.3.0, des espaces de noms peuvent être définis pour cloisonner certains objets, à l'aide du mot clé namespace utilisé en début de fichier. Exemple de définition :
Soit un fichier TestNS.php suivant :
Le fichier doit être encodé en ANSI ou Unicode sans BOM, mais pas en Unicode seul, sous peine d’avoir l'erreur Namespace declaration statement has to be the very first statement in the script, et d'être obligé de coller le mot "namespace" à "?php").
Exemple d’utilisation :

### Références de variables

Les références sont utiles lorsque l’on souhaite retourner plusieurs valeurs dans une fonction. On utilise alors le passage d'argument par référence, qui fait que quand une fonction modifie un argument, la valeur de la variable du programme principale change aussi.
Pour utiliser un argument en tant que référence, il suffit d'y mettre l'opérateur de référence, le symbole & devant, dans la déclaration de la fonction.
Un exemple concret devrait vous faire comprendre :
* Exemple
* function foo(&$arg1, &$arg2, $arg3)
* $arg1 = 4;
* $arg2 = 6;
* $arg3 = 8;
* foo($var1, $var2, $var3);
* print $var1; //affichera 4
* print $var2; //affichera 6
* print $var3; //affichera NULL car $arg3 n'est pas une référence (pas de &)

## Fonctions variables

On appelle "fonction variable" une fonction dont on ne peut prédire le nombre d'arguments. Ce genre de fonction pourra se révéler pratique pour exécuter certains codes répétitifs ou le programmeur n'a pas envie de recopier le nom de la fonction pour n valeurs.
Pour cela, il faut retenir deux fonctions importantes :
* func_num_args : permet de compter le nombre d'arguments (retourne true ou false).
* func_get_args : permet de récupérer la valeur d’un argument (retourne un tableau de valeur).
Ces deux fonctions ne peuvent s'utiliser qu’à l'intérieur d’une fonction; dans le cas contraire un message d'erreur s'affichera.
* Exemple
* function afficher_variables
* $nb_args = func_num_args;
* $list_args = func_get_args;
* for ($i = 0; $i < $nb_args; $i++) {
* echo $list_args[$i].' ';
* $var1 = 'programmeur';
* afficher_variables('Je suis', $var1, ', c\'est utile', ', c\'est intéressant.'); // Et on peut en rajouter autant que nécessaire.
Le code se comprend de lui-même. Il affichera : Je suis programmeur, c’est utile, c’est intéressant.

## Fonctions de rappel

Pour passer une fonction en argument d'une autre, il faut utiliser call_user_func. Ex :

## Fonctions anonymes

Une fonction sans nom peut être stockée dans une variable permettant de l'appeler. Le mot clé use permet d'injecter des variables globales dedans. Ex :

## Fonctions fléchées

Depuis PHP7.4, on peut définir une fonction anonyme avec l'opérateur "=>" et le mot réservé fn. Ex :

## Fonctions prédéfinies

Voici une liste des fonctions globales prédéfinies en PHP les plus usuelles.
* print (alias echo) : affiche le contenu de la variable placée en paramètre.
* printf et dérivés (ex : sprintf) : print formaté, affiche un texte dont on remplace les marqueurs, numérotables, par les variables en paramètre. Exemple :
Les types suivants sont généralement utilisés :
* d : digit
* f : float
* s : string
* Pour échapper les "%" pour sont interprétés par ces fonctions, ce n'est pas "\" mais "%".
* Ne pas utiliser les doubles quotes sous peine de Undefined variable: d.
* sleep($secondes) : attend un certain nombre de secondes (utilisation déconseillée quand un humain doit attendre un résultat).
* call_user_func_array('maFonction', 'mesArguments') : exécute une fonction à partir de son nom en chaîne de caractères.
* getenv : affiche toutes les variables d'environnement, ou celle demandée en paramètre.
* ignore_user_abort(true) : ("false" par défaut) continue l'exécution d'un script lancé par un utilisateur, même s'il change de page ou clique annule le chargement.
* header : ajoute une clé dans l'en-tête HTTP de la réponse.
* ini_get : lit le php.ini.
* ini_set : modifie le php.ini le temps de l'instance.
* set_time_limit : redéfinit la limite de temps du php.ini.
* require : importe le code PHP d'un autre fichier, avec une erreur si c'est impossible.
* require_once : idem en garantissant que chaque fichier n'est ajouté qu'une fois.
* include : importe le code PHP d'un autre fichier, sans erreur si c'est impossible.
* include_once : idem en garantissant que chaque fichier n'est ajouté qu'une fois.
* getmypid : retourne l'ID du processus courant dans l'OS.

### Sur les chaînes

* trim($string) : supprimer les espaces et retours chariots en début et fin de chaîne par défaut. Son second paramètre permet de remplacer les symboles à retirer.
* strip_tags : supprime les balises HTML de la chaîne mentionnée en paramètre 1, en conservant ceux en paramètre 2 (sous la forme d'une chaine comme '<p><br>').
* ucfirst : met une majuscule en début de chaîne.
* lcfirst : met une minuscule en début de chaîne.
* strtoupper : met en lettres capitales toute la chaîne.
* strtolower : met en bas de casse toute la chaîne.
* strlen : compte la taille d'une chaîne en octets. Pour avoir le nombre de caractères, utiliser mb_strlen (pour multibyte).
* str_contains($chaine, $cle) : cherche si une chaîne contient une sous-chaîne.
* <codestr_starts_with($chaine, $cle) : vérifie si une chaîne commence par une sous-chaîne.
* str_replace($ancien, $nouveau, $texte) : remplace des caractères par d'autres dans un texte ou un tableau.
* str_ireplace($ancien, $nouveau, $texte) : fait la même chose en ignorant la casse.
* strtr($texte, $ancien, $nouveau) (string translate) : réputée plus rapide que str_replace.
* strpos($meubleDeFoin, $aiguille) : première position d'une sous-chaine. Attention : ne jamais utiliser comme si elle renvoyait un booléen (if (strpos)) car si la recherche est en première position (0) elle sera considérée comme fausse avec le typage faible. Il faut tester l'existence avec if (false !== strpos).
* stripos($meubleDeFoin, $aiguille) : fait la même chose en ignorant la casse.
* strrpos($meubleDeFoin, $aiguille) : dernière position d'une sous-chaine.
* substr($texte, $debut , $fin) : tronque un texte en sous-chaine. Utiliser mb_substr en Unicode.
    Pour accéder à un seul caractère d'une chaine, PHP peut la considérer comme un tableau (ex : $chaine[0]).
    Ex :
* substr_count($chaine, $sous-chaine) : compte le nombre de sous-chaine dans une chaine.
* str_pad : complète une chaine avec un caractère pour qu'elle atteigne la taille demandée si ce n'était pas le cas. Ex :
* eval($chaine) : exécute une chaine comme un script PHP.
* count_chars($chaine) : renvoie un tableau avec en clés chaque caractère de la chaine, et en valeur son nombre d'occurrences. Pratique pour détecter les anagrammes.

#### Encodage

    Pour plus de détails voir : Coder avec Unicode/Conversion#PHP.
* utf8_encode($chaine) et utf8_decode($chaine) sont dépréciée en PHP 8.2, il faut utiliser à la place mb_convert_encoding($chaine, 'UTF-8') et mb_convert_encoding($chaine, 'ISO-8859-1').

#### URLs

* parse_url : découpe une chaîne en partie d'une adresse URL (protocole, domaine et chemin d'accès).
* http_build_query : crée une URL à partir d'un tableau d'arguments GET. Par défaut le séparateur est "&" (3e argument). Cette fonction échappe les séparateurs. Ex :

### Sur les nombres

* pow($nombre, $exposant) (power) : élève un nombre à la puissance de l'exposant donné.
* sqrt($nombre) (square root) : racine carrée.
* max($nombre1, $nombre2, ...) : affiche le plus grand nombre parmi ceux en paramètres.
* min($nombre1, $nombre2, ...) : affiche le plus petit nombre d'une liste.
* round($nombre) : arrondit un nombre à l'entier le plus proche, ou selon une précision en deuxième paramètre s'il est renseigné. Exemple :
* number_format($nombre, 2, ',', ' ') : formate un nombre donné, où "2" représente le nombre de chiffres après la virgule, "," le séparateur décimal et " " le séparateur de milliers.
Ne jamais comparer des nombres issus du number_format car les séparateurs faussent les calculs. Exemple :

### Bufferisation de sortie

La bufferisation de sortie bloque l'envoie de données au client HTTP pour les mettre dans une mémoire tampon à la place.
* ob_start : démarre l'utilisation du tampon.
* ob_get_contents : affiche le contenu du tampon.
* ob_clean : efface le tampon sans l'envoyer.
* ob_flush : envoie le tampon au client.

## Références

* ↑ http://php.net/manual/fr/indexes.functions.php
* ↑ http://php.net/manual/fr/language.generators.syntax.php
* ↑ http://php.net/manual/fr/reflectionclass.getdoccomment.php
* ↑ http://php.net/manual/fr/language.namespaces.rationale.php
* ↑ http://php.net/manual/fr/ref.funchand.php
* ↑ http://php.net/manual/fr/function.sprintf.php
* ↑ https://www.alsacreations.com/article/lire/254-le-point-sur-la-fonction-include-php.html
* ↑ http://php.net/manual/fr/function.str-replace.php
* ↑ https://www.keycdn.com/blog/php-performance#10-use-the-strongest-str-functions
* ↑ http://php.net/manual/fr/function.strpos.php
* ↑ http://php.net/manual/fr/function.max.php
* ↑ http://php.net/manual/fr/function.round.php
* ↑ https://www.php.net/manual/fr/ref.outcontrol.php

# Tableaux
## Création de tableau

Un tableau (en anglais array) est une collection d'objet. En PHP, ces objets n'ont pas forcément le même type (cohabitation entre des entiers, des chaines…). Chaque objet est identifié par une clé appelée indice, que l'on met entre crochets (ex : $tableau[indice]).
Il existe trois manières de déclarer un tableau vide :
Pour créer un tableau non vide :
print ne fonctionne pas pour les tableaux, il faut utiliser var_dump ou print_r. Par ailleurs, pour récupérer la chaine affichée par ces fonctions, utiliser print_r(MonTableau1, true).
Autres exemples :
Il en est de même pour les tableaux à deux dimensions.
On distingue deux types de tableau :
* Le tableau standard, dont la clé est son indice (le numéro de ligne en partant de zéro). Pratique pour être parcouru par une variable compteur, ou pour être rempli dans un certain ordre.
* Le tableau associatif, auquel on accède par le nom d'une clé en chaine de caractères.

## Tableau itératifs

Les clés du tableaux sont des nombres. Ils ont l'avantage de pouvoir être parcourus par un compteur.
* Exemple
* $tab = ['val1', 'val2', 'val3']; // $tab[0] vaut val1 /-/ $tab[1] vaut val2 /-/ etc.
* for($i = 0; $i<2; $i++)
* echo $tab[$i];
Ce code affichera : val1val2.
En PHP, on peut aussi directement affecter des indices du tableau, comme suit :
Notez que les indices ne sont pas typés (on pourra indifféremment utiliser $tab[1] et $tab['1']).

## Tableaux associatifs

Ils fonctionnent de la même manière que les tableaux itératifs, sauf que l'utilisateur en choisit la clé. À chaque clé correspond une valeur (injection).
Voici un exemple de déclaration :
* Exemple
* $tab = ['cle1' => 'val1', 'cle2' => 'val2', 'cle3' => 'val3'];
* print $tab['cle2']; //affichera : val2
* //parcours du tableau en boucle
* foreach ($tab as $key => $value)
* print $key." : ".$value.". ";
Résultat : cle1 : val1. cle2 : val2. cle3 : val3.
Pour ne garder que les valeurs on peut utiliser implode, qui convertit un tableau en chaine avec séparateur :
Résultat : val1. val2. val3.

## Fonctions de lecture

* count : cette fonction renvoie le nombre d'éléments présent dans le tableau.
* key : clé de l'élément courant du tableau, celui vers lequel le pointeur fait référence.
* current : valeur de l'élément courant.
* reset : valeur du premier élément.
* end : valeur du dernier élément.
* each : valeur de l'élément courant, et avance le pointeur au suivant.
* prev : valeur de l'élément précédent.
* next : valeur de l'élément suivant.
* array_values($tab) : renvoie un tableau contenant toutes les valeurs du tableau en paramètre. S'utilise pour reconstruire des clés consécutives sans changer les valeurs.
* array_keys($botteDeFoin, $aiguille) : renvoie un tableau contenant toutes les clés du tableau en paramètre. De plus, si une valeur est définie en paramètre deux, le résultat ne contient que les clés associées à celle-ci.
* array_key_exists($cle, $tab) : renvoie "vrai" si la clé est dans le tableau.
* array_key_first($tab) : renvoie la première clé d'un tableau.
* array_key_last($tab) : renvoie la dernière clé d'un tableau.
* array_diff($t1, $t2) : renvoie le tableau des différences entre ceux en paramètres (peut servir pour supprimer par valeur).
* array_sum($tab) : renvoie la somme des valeurs du tableau.
* array_intersect($t1, $t2) : intersection entre plusieurs tableaux.

### Exemple

Affiche 0 : mixte valeur1
Les fonctions key et current peuvent accéder aux autres éléments du tableau après each ou next.
Il existe aussi différentes méthodes liées aux tableaux, des méthodes de tri, de recherche, de concaténation de tableaux, des méthodes d'ajouts et de suppressions d'éléments, etc.

### Recherches

* in_array($aiguille, $botteDeFoin) : recherche de présence par valeur. Renvoie un booléen si l'élément est trouvé.
* array_search($aiguille, $botteDeFoin) : recherche de position par valeur. Renvoie la clé de l'élément trouvé, ou false sinon.
* array_keys($botteDeFoin, $aiguille) : recherche par clé (déjà décrit au paragraphe précédent).
php -r "var_dump(in_array(0, ['test']));" = true

### Comparaison

Pour comparer deux tableaux :

### Condition

Un tableau vide dans une condition vaudra "faux", alors qu'un non vide vaudra "true".

## Fonctions d'écriture

Pour manipuler des tableaux il est indispensable de connaitre les fonctions suivantes :
* str_split($string) : convertit une chaine de caractères en tableau itératif, chaque ligne étant composée d'un caractère.
* mb_str_split($string) : idem mais en caractères multi-octets.
* explode($separateur, $tableau) : convertit une chaine de caractères en tableau itératif, donc le contenu correspond aux sous-chaines situées autour d'un séparateur donné.
* implode($separateur, $tableau) : convertit un tableau en chaine de caractères. Le séparateur à placer dans la chaine est facultatif.
* sizeof($tableau) : renvoie la taille du tableau (le nombre d'objets qu'il contient). Attention : avant PHP 7.2 cette fonction pouvait aussi remplacer strlen.
* array_push($monTableau, $valeur) : ajoute une ligne à la fin du tableau, équivaut à $monTableau (empile).
* array_unshift($monTableau, $valeur) : ajoute une ligne au début du tableau.
* array_pop($monTableau) : retire la dernière ligne du tableau, en la renvoyant (dépile).
* array_shift($monTableau) : retire la première ligne du tableau, en la renvoyant.
* array_merge($monTableau1, $monTableau2, $monTableau3...) : fusionne plusieurs tableaux.
* array_merge_recursive : idem en multidimensionnel.
* array_replace($monTableau1, $monTableau2, $monTableau3...) : fusionne plusieurs tableaux en replaçant les clés existantes du premier par celles des autres. Cela permet par exemple de fusionner deux tableaux en préservant leurs clés.
* array_replace_recursive : idem en multidimensionnel.
* array_unique($tableau) : filtre les valeurs en doublon (quelles que soient leurs clés).
* array_filter($tableau, fonction) : filtre les lignes selon une fonction exécutée sur chaque élément. Pour injecter des variables dans la fonction, utiliser "use" (ex : array_filter($tableau, function($ligne) use($variable1){...).
* array_column($tableau, colonne) : filtre par colonne. Renvoie uniquement les valeurs d'un champ donné pour chaque élément.
* array_reduce($tableau, fonction) : transforme le tableau selon une fonction exécutée sur chaque élément.
* array_map(fonction, $tableau) exécute une fonction sur chaque valeur du tableau. Exemples :
** Pour trimer chaque ligne d'un tableau : array_map('trim', $tableau)
** Pour créer un tableau de tableau : array_map(function($ligne) { return explode('=', $ligne); } , $tableau)
* array_walk($tableau, fonction) : exécute une fonction sur chaque élément (clé ou valeur).
* array_chunk($tableau, $taille) : découpe le tableau fourni en tableaux de la taille fournie.
* array_slice($tableau, $début, $taille) : renvoie la partie du tableau à partir de l'élément dont le numéro est le premier paramètre, de la taille en paramètre deux.
* array_flip($tableau) : inverse les clés et valeurs. Attention : un tableau ne peut avoir que des types primitifs en clé, pas des objets (sinon c'est l'erreur Illegal offset type).
* unset($tableau[$index]) : supprimer la ligne.
* Exemple
* $chaine = 'MonFichier.2016.txt';
* $tab = explode('.', $chaine); // au niveau des points, on explose la chaine (en trois)
* var_dump($tab); /* affiche :
* array(3) {
* [0]=> string(10) "MonFichier"
* [1]=> string(4) "2016"
* [2]=> string(3) "txt"
* echo $tab[0]; // affiche : MonFichier
* echo 'L\'extension du fichier est : '.$tab[sizeof($tab)-1]; // affiche : L'extension du fichier est : txt
Comme le premier indice du tableau est zéro, le dernier est égal à sa taille moins un.
* Joindre les éléments "id" d'un tableau de tableaux
* echo implode(', ', array_map(function ($ligne) {
* return $ligne['id'];
* }, $tableau));

### Tris

* array_multisort($tableau, SORT_ASC) permet de trier un tableau dans l'ordre croissant de ses valeurs.
* sort($tableau) : trie le tableau par valeurs croissantes, en recréant des clés numériques.
* asort($tableau) : trie le tableau par valeurs croissantes, en conservant les clés associées.
* arsort, fonction) : trie le tableau par valeurs décroissantes, en conservant les clés associées.
* ksort($tableau) : trie par clés croissantes par défaut.
* krsort($tableau) : trie par clés décroissantes par défaut.
* usort($tableau, fonction) : trie selon une fonction donnée.
* Exemple
* $array = array("name"=>"Toyota", "type"=>"Celica", "colour"=>"black", "manufactured"=>"1991");
* array_multisort($array, SORT_ASC);
* var_dump($array);
* // array(4) { ["manufactured"]=> string(4) "1991" ["type"]=> string(6) "Celica" ["name"]=> string(6) "Toyota" ["colour"]=> string(5) "black" }
* // On remarque que les majuscules sont avant les minuscules.
* arsort($array);
* var_dump($array);
* // array(4) { ["colour"]=> string(5) "black" ["name"]=> string(6) "Toyota" ["type"]=> string(6) "Celica" ["manufactured"]=> string(4) "1991" }
* asort($array);
* var_dump($array);
* // array(4) { ["manufactured"]=> string(4) "1991" ["type"]=> string(6) "Celica" ["name"]=> string(6) "Toyota" ["colour"]=> string(5) "black" }
* sort($array);
* var_dump($array);
* // array(4) { [0]=> string(4) "1991" [1]=> string(6) "Celica" [2]=> string(6) "Toyota" [3]=> string(5) "black" }
* ksort($array);
* var_dump($array);
* // array(4) { ["colour"]=> string(5) "black" ["manufactured"]=> string(4) "1991" ["name"]=> string(6) "Toyota" ["type"]=> string(6) "Celica" }
Pour trier de l'Unicode il faut utiliser le flag "SORT_LOCALE_STRING".
Exemple :
donne :

## Tableaux multi-dimensionnels

La clé d’un tableau peut pointer sur un second tableau créant ainsi un tableau multi-dimensionnel.
Résultat :
    0-Hubert Gérant : hubert@example.com
    1-Jean Réceptionniste : reception@example.com
    NB : Dans cet exemple, une base de données serait sûrement plus adéquate.

## ArrayAccess

Cette classe native permet de redéfinir l'opérateur d'index () dans les objets qui en héritent. Par exemple, pour lui faire accepter un autre tableau ou NULL comme index, ou déclencher un évènement quand on le modifie.

## Destructuration

PHP ne gère pas la destructuration avec l'opérateur égal comme le fait JavaScript ou Python (ex : x, y = getXY). À la place, il propose plusieurs fonctions :
* list($x, $y) : traite les variables en paramètre comme un tableau. Ex : list($x, $y) = getArrayWithTwoLines;
* compact($x, $y) : crée un tableau avec les noms des variables en paramètre comme clés, et leurs valeurs comme valeurs.
* extract($tableau) : déclare et assigne une variable pour chaque ligne du tableau en paramètre, de nom la clé de la ligne, et de valeur la valeur de la ligne (contraire de compact).

## Références

* ↑ http://php.net/manual/fr/function.array-push.php
* ↑ http://php.net/manual/fr/function.array-unshift.php
* ↑ http://php.net/manual/fr/function.array-pop.php
* ↑ http://php.net/manual/fr/function.array-shift.php
* ↑ http://php.net/manual/fr/function.array-merge.php
* ↑ http://php.net/manual/fr/function.array-map.php
* ↑ http://php.net/manual/fr/function.usort.php
* ↑ http://php.net/manual/fr/class.arrayaccess.php
* ↑ http://php.net/manual/fr/function.list.php
* ↑ http://php.net/manual/fr/function.compact.php
* ↑ http://php.net/manual/fr/function.extract.php

# Structures de contrôle

Une structure conditionnelle fonctionne de manière à ce que si la valeur de la condition est true alors tel schéma est appliqué, et si la valeur est false, un autre schéma est réalisé.

## if - else

La structure la plus simple se présente sous la forme d'un if et d'un else. Le if teste une condition :
* Si elle est réalisée le code entre les accolades après le if sera exécuté, puis le serveur passera au code après le else ;
* Si elle n'est pas réalisée c'est ce qui est entre les accolades suivant le else qui sera exécuté.

### Emploi de if seul

Un if peut être employé seul, en fait le else étant l'alternative, le code à exécuter par défaut, on peut s'en passer pour n'exécuter un code seulement si une condition est réalisée.

### Emploi de elseif

Lorsqu'une condition n'est pas réalisée, plutôt que de passer directement à l'exécution du code par défaut (déclaré par else), il peut être plus judicieux de tester une autre condition (déclarée par elseif). En clair la structure est semblable à un ordre de préférence :
Emploi de elseif :
| Symboliquement | Traduction en code |
| Soit une condition 1 La condition 1 est elle réalisée ? OUI code 1 (puis sortie de la structure hypothétique) NON la condition 2 est elle réalisée ? OUI code 2 (puis sortie de la structure hypothétique) NON la condition 3 est elle réalisée ? OUI code 3 (puis sortie de la structure hypothétique) NON ... (aucune des conditions annexes n'ont été vérifiées) Par défaut exécutons le code défaut | <?php if (condition 1) { code 1; } elseif(condition 2) { code 2; } elseif(condition 3) { code 3; } else { code par défaut; } |

### Imbrication

On peut imbriquer les if les uns dans les autres. Simplement lorsqu'un if imbriqué aura fini d'être exécuté, il retournera à l'étape logique suivante du rang hiérarchique supérieur.
Notons que dans ce cas mieux vaut imaginer tous les cas de figure pour ne pas se retrouver avec une structure hypothétique vacillante en ce que la situation n'aura pas été prévue.

## switch

Lorsque l'on teste des conditions en nombre important sur une même valeur, l'utilisation de if est fastidieuse. Il existe bien heureusement une structure créée à cet usage : le switch. On déclare la variable à tester avec switch : switch($surlasellette). Dans ce switch on utilise case pour déclarer la valeur de la variable pour laquelle une action est envisagée : case "valeur": (ici ne pas oublier les deux points !) une suite d'instructions s'ensuit et est généralement clôturée par break; pour que les autres cas ne soient pas traités à la suite. La valeur par défaut, corollaire du else pour if, est introduite par default:.
Intérêt et emploi de switch :
| Avec if | Traduction en switch |
| <?php $valeur = "testable"; if ($valeur == "ce n'est pas cela") { echo "ok"; } elseif ($valeur == "ce n'est pas non plus cela") { echo "ok"; } elseif($valeur == "c'est encore moins cela" or $valeur == "ou cela") { echo "ok"; } else { echo "pas d'accord"; } | <?php switch (variable) { case valeur_1: instruction(s); break; case valeur_2: instruction(s); break; case valeur_3: case valeur_4: instruction(s); break; default: instruction(s); } |
switch s'imbrique aussi comme if. Le plus important étant de ne pas oublier de mettre l'instruction break avant un nouveau case.
Le switch compare avec "==" et pas "===".

## match

Depuis PHP8, cette structure retourne une valeur selon plusieurs conditions. Ex :

## Syntaxe alternative

PHP propose une syntaxe alternative aux accolades pour ses structures de contrôle, qui sont le ":" puis "end_nom_de_la_structure;". Ex :
C'est notamment pratique si vous utilisez php comme moteur de templating

## Références

* ↑ https://www.php.net/manual/fr/control-structures.match.php
* ↑ https://www.php.net/manual/fr/control-structures.alternative-syntax.php

# Boucles
## Concept

Une boucle est une instruction qui exécute un code tant qu'une condition établie est vérifiée. Si la condition est toujours vérifiée, on se trouve dans une boucle infinie. Les boucles permettent le parcours des tableaux et d'utiliser des données rendues sous la forme de tableau par une fonction de php dialoguant par exemple avec un autre langage.
Il en existe de deux types (avec des variantes) :
* while : le programme se répète tant qu'une condition est vraie (ex : tant que x est inférieur à 10).
* for : le programme se répète un certain nombre de fois (ex : pour x allant de 1 à 10 avec un pas de +1 à chaque itération).

## while

while est un mot anglais signifiant "tant que" en français. Le programme exécute une routine tant que la condition est vraie.
Deuxième syntaxe (moins courante) :
Troisième syntaxe (assez rare), quand la condition contient une méthode qui change à chaque itération, jusqu'à renvoyer faux :

### do while

Idem avec premier passage obligatoire : la condition est vérifié en fin de bloc.

## for

for est un mot anglais signifiant "pour" en français. Le programme exécute une routine pour des valeurs d'une variable qui vérifient une certaine condition. Généralement cette condition est de type "intervalle", c'est-à-dire pour des valeurs plus petites qu'une borne.
* Le premier élément est exécuté au début de la boucle dans tous les cas.
* Le second élément (la condition) est testé avant chaque exécution de l'instruction ou itération, s'il renvoie TRUE l'instruction sera exécutée, si FALSE est renvoyé on sort de la boucle.
* La dernière expression est exécutée après chaque itération.
Attention la structure dans la parenthèse est for( ; ; )

### foreach

Les boucles foreach apparues avec PHP 4, constituent une manière simple de parcourir des tableaux. Il existe deux syntaxes :
* La plus simple s'intéresse aux clés dans les tableaux. Le type de ces clés dépend des valeurs contenues dans le tableau. foreach simplifie une tache qui aurait certes été possible avec for, mais fastidieuse :
Intérêt de foreach :
| Avec for | Avec foreach |
| $array = array('valeur1', 'valeur2', 'valeur3'); for($i = 0; $i < count($array); $i++) { echo $array[$i]; //renvoie "valeur1valeur2valeur3" } | $array = array('valeur1', 'valeur2', 'valeur3'); foreach($array as $value) { echo $value; // renvoie "valeur1valeur2valeur3" } |
as signifiant "comme", on récupère une variable contenant la valeur dans la cellule correspondante.
* La seconde se penche davantage sur les tableaux associatifs du type
Ainsi on récupère le nom de la clé et la valeur du champ. En fait la structure $cle => $valeur est celle de la déclaration du tableau.
Par ailleurs, il est possible d'itérer des objets depuis PHP 5.

## break et continue

Les mots clés :
* break : sort de la boucle avant la fin.
* continue : passe immédiatement à l'itération suivante.
Pour sortir ou continuer la boucle mère :
* break 2;
* continue 2;