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
Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la Licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans Texte de dernière page de couverture. Une copie de cette licence est incluse dans l'annexe nommée « Licence de documentation libre GNU ».
Introduction Répartition des langages de programmation côté serveur, des sites Internet le 28 avril 2016.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[1].
Les nouvelles fonctionnalités du PHP 5 (paru en 2004) concernent surtout la programmation orientée objet[2] :
Les principales fonctionnalités apportées par PHP 7 (depuis 2015) sont[3] :
Nouvelles fonctionnalités du PHP 8.0 en 2020[4][5] :
match
str_contains()
str_starts_with()
et str_ends_with()
get_debug_type()
: il s'agit d'un gettype()
plus précis, car il renvoie le nom de la classe au lieu de "object
"Pour PHP 8.1, sorti en novembre 2021 :
never
PHP 8.2 est sorti le 8 décembre 2022[7] :
readonly class
signifie que tous les arguments de son constructeur son implicitement en readonly
.null
, true
et false
.PHP 8.3 sort le 23 novembre 2023[8] :
PHP 8.4 date du 21 novembre 2024 :
#[\Deprecated]
(pour remplacer l'annotation)[10].À 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 :
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.
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 :
declare(strict_types = 1);Installer PHP
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.
Logiciel tout-en-un pour Linux (Apache + MySQL + PHP), comme WAMP pour Windows.
commande nécessitant les privilèges root
# apt-get install tasksel
# tasksel install lamp-server
commande nécessitant les privilèges root
# apt-get install apache2
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 :
commande nécessitant les privilèges root
# /etc/init.d/apache2 start
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 :
# vi /etc/default/apache2 ... NO_START=0
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 :
telnet localhost 9000 CTRL + ALT + ] quit
FPM signifie FastCGI Process Manager, puisque le processus PHP-fpm écoute les requêtes CGI[1]. 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 :
deb http://ftp.fr.debian.org/debian/ stable main non-free contrib deb-src http://ftp.fr.debian.org/debian/ stable main non-free contrib
Ce qui suit suppose que le serveur Web a bien été installé ; exécuter les commandes suivantes :
sudo apt-get update && apt-get install php8.2 && apt-get install libapache2-mod-php8.2
Une fois ces commandes exécutées, redémarrer le serveur Web. Dans le cas d'Apache cela s'effectue avec la commande suivante :
/etc/init.d/apache2 restart
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 :
commande
$ tail /var/log/apache2/error.log
Pour PHP 7 ou 8 sur Ubuntu :
sudo add-apt-repository ppa:ondrej/php
Sur Debian :
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
Puis :
sudo apt update sudo apt install php8.2 php8.2-common php8.2-cli php8.2-fpm sudo a2enmod php8.2
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 :
sudo update-rc.d apache2 disable sudo update-rc.d mysql disable
Voici une liste de bibliothèques fréquemment utilisées dans les applications :
# apt-get install -y \ php8.2-mysql \ php8.2-cli \ php8.2-gd \ php8.2-curl \ php8.2-mbstring \ php8.2-xml
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
.
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" :
sudo apt-get install ppa-purge sudo ppa-purge ppa:ondrej/php-7.0
Premièrement il faut installer Apache :
emerge apache
Ensuite, il faut installer PHP :
emerge dev-lang/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 est disponible sur http://dev.mysql.com/downloads/gui-tools/5.0.html au format :
En l'absence de gestionnaire de paquets, utiliser le .tar ainsi :
shell> groupadd mysql shell> useradd -r -g mysql mysql shell> cd /usr/local shell> tar zxvf /path/to/mysql-VERSION-OS.tar.gz shell> ln -s full-path-to-mysql-VERSION-OS mysql shell> cd mysql shell> chown -R mysql . shell> chgrp -R mysql . shell> scripts/mysql_install_db --user=mysql shell> chown -R root . shell> chown -R mysql data shell> bin/mysqld_safe --user=mysql &
$ sudo apt-get install mysql-server mysql_secure_installation
La dénomination des paquets mentionnés peut varier légèrement selon la version. Dans un terminal, entrez :
$ sudo apt-get install mysql-server
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 : [1])
Lancez ensuite la commande :
cd && sudo mysql_secure_installation
Appuyez sur Entrée lorsqu'il vous demande le mot de passe root MySQL : pour le moment il n'y en a pas.
MySQL a ses propres utilisateurs, avec leurs propres privilèges. Le root MySQL n'est donc pas le root système. Il est conseillé de ne pas mettre les mêmes mots de passes pour les utilisateurs MySQL et les utilisateur du système.
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 :
$ sudo dpkg-reconfigure mysql-server
et de répondre "Non" à la question du démarrage systématique de MySQL.
emerge mysql
De nombreux modules complémentaires peuvent être installés sur Apache.
Pour les lister, on utilise apachectl
(parfois apache2ctl
) :
apachectl -t -D DUMP_MODULES
ou
apache2ctl -M
Pour activer un module :
a2enmod Nom_du_module
Un fichier est alors créé dans /etc/apache2/mods-enabled/.
Exemple pour la réécriture d'URL :
a2enmod rewrite
Pour le désactiver :
a2dismod Nom_du_module
La configuration du module reste toutefois disponible dans /etc/apache2/mods-available/.
Les extensions PHP nécessitent une autre commande. Ex :
phpenmod mbstring
Pour lister les sites du serveur :
apachectl -S
Pour activer un site :
a2ensite Nom_du_site
Le fichier du site est alors visible dans /etc/apache2/sites-enabled/.
Pour le désactiver :
a2dissite Nom_du_site
Le site est dans /etc/apache2/sites-available/.
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) :
Content-Type: text/html; charset=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 :
$ sudo gedit /etc/apache2/apache2.conf
Cherchez la ligne suivante :
#AddDefaultCharset ISO-8859-1
Décommentez-la en enlevant le # :
AddDefaultCharset ISO-8859-1
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 :
AddDefaultCharset ISO-8859-15
ainsi que la ligne suivante dans le paragraphe en-dessous :
AddCharset ISO-8859-15 .iso8859-15 .latin15 .fr
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 :
$ sudo /etc/init.d/apache2 reload
Il est également possible de s'affranchir de tout encodage par défaut, de la manière suivante :
Cherchez la directive AddDefaultCharset :
AddDefaultCharset ISO-8859-1
Remplacez l'attribut par la valeur Off :
AddDefaultCharset Off
Là encore, on demandera à Apache de relire sa configuration :
$ sudo /etc/init.d/apache2 reload
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 !
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 :
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 :
net start ews-dbserver net start ews-httpserver net start ews-dashboard pause net stop ews-dashboard net stop ews-httpserver net stop ews-dbserverLogo EasyPHP.
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.
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
.
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ôleerror_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.
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).
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.
php5ts.dll
, et copiez-la dans le répertoire d'Apache.httpd.conf
. On en a déjà parlé plus tôt, vous vous souvenez où il est, n'est-ce pas ?.php
concerne l'utilisation du module PHP :
AddType application/x-httpd-php .php
LoadModule php5_module c:\php\php5apache.dll
AddModule mod_php5.c
Enregistrez le fichier httpd.conf
et fermez-le.
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[2]. Puis pour ce rôle il faut cocher plusieurs services de rôle :
Télécharger et installer ensuite le manager PHP[4] pour pouvoir configurer PHP dans :
Si ensuite IIS renvoie systématiquement des erreurs 500 par la suite (même sans appel PHP), installer Visual C++ 32 bits[5] (PHP ne fonctionne pas en 64 bits en 2016).
Il existe de nombreuses images de conteneur Docker pouvant fournir PHP. Exemple de Dockerfile[6] :
FROM php:8.2-cli
FROM php:8.2-fpm
Exemple avec GD[7] :
FROM php:7.4-fpm RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd
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 dispose de plugins pour programmer en PHP[8].
ComposerComposer est un logiciel de gestion des bibliothèques PHP open source. Celles-ci sont aussi accessibles sur https://packagist.org/.
Pour l'installer il y a trois solutions :
À 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 :
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
Enfin, pour tester l'installation, lancer :
Le programme Composer lit et modifie la liste des bibliothèques du projet dans le fichier composer.json.
Pour créer le fichier composer.json :
composer init
Alternative à init pour les apps initialisée par un framework.
composer create-project "symfony/skeleton:^5" mon_projet
Pour installer un paquet, par exemple client client HTTP Guzzle :
composer guzzlehttp/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.
On peut aussi préciser le numéro de version, par exemple MediaWiki :
composer require mediawiki/semantic-media-wiki "1.9.*,>=1.9.0.1"
On peut aussi installer plusieurs paquets à la suite :
composer require symfony/framework-bundle symfony/console
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 :
composer require --dev phpunit/phpunit ^8
Pour utiliser une branche du dépôt de la dépendance, , utiliser le mot réservé ":dev-" suivi de son nom. Ex :
composer require mediawiki/semantic-media-wiki:dev-123_ma_branche
Pour utiliser un commit particulier du dépôt de la dépendance, utiliser le mot réservé "dev-master". Ex :
composer require mediawiki/semantic-media-wiki dev-master#hash_du_commit
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 :
/usr/bin/php8.2 /usr/local/bin/composer install
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 :
php composer.phar update mediawiki/semantic-media-wiki --with-dependencies
Il faut parfois éditer le composer.json avec la règle de la nouvelle version souhaitée avant de lancer l'update.
Affiche toutes les bibliothèques installées sur une ligne chacune, ce qui est plus lisible que composer.lock.
Affiche les bibliothèques qui dépendent du package donné en paramètre.
La syntaxe JSON de ce fichier contient quelques extensions[2] :
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 "_".
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.
Après la version à trois nombres, on peut suffixer un arobase puis un Stability Flag[3]. Exemples :
@dev
@stable
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.
Ensemble de paramètres de composer[4], par exemple le timeout ou les identifiants vers certains dépôts.
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()
)[5].
Exemple :
"autoload": { "psr-4": { "App\\": "src/" } },
De plus, un mapping spécifique aux environnements dev est possible avec :
"autoload-dev": { "psr-4": { "App\\Tests\\": "tests/" } },
Scripts qui s’exécutent quand on lance "composer"[6].
... "scripts": { "doctrine-cc": "php bin/console doctrine:cache:clear-metadata && php bin/console doctrine:cache:clear-query && php bin/console doctrine:cache:clear-result" }, ...
Utilisation :
composer doctrine-cc
Complément de "scripts".
Liste automatiquement les dépendances en conflit, c'est-à-dire qui ne peuvent pas être installées avec l'application courante dans une tierce.
Pour spécifier des dépôts privés (qui ne sont pas accessibles sans communiquer leur URL).
Exemple de mediawiki/core[7] :
{ "name": "mediawiki/core", "description": "Free software wiki application developed by the Wikimedia Foundation and others", "type": "mediawiki-core", "keywords": [ "mediawiki", "wiki" ], "homepage": "https://www.mediawiki.org/", "authors": [ { "name": "MediaWiki Community", "homepage": "https://www.mediawiki.org/wiki/Special:Version/Credits" } ], "license": "GPL-2.0-or-later", "support": { "issues": "https://bugs.mediawiki.org/", "irc": "irc://irc.libera.chat/mediawiki", "wiki": "https://www.mediawiki.org/" }, "prefer-stable": true, "require": { "composer/semver": "3.2.4", "cssjanus/cssjanus": "2.0.0", "ext-ctype": "*", "ext-dom": "*", "ext-fileinfo": "*", "ext-iconv": "*", "ext-intl": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlreader": "*", "guzzlehttp/guzzle": "7.2.0", "liuggio/statsd-php-client": "1.0.18", "monolog/monolog": "2.2.0", "oojs/oojs-ui": "0.42.0", "pear/mail": "1.4.1", "pear/mail_mime": "1.10.9", "pear/net_smtp": "1.9.2", "php": ">=7.2.22", "psr/container": "1.1.1", "psr/log": "1.1.3", "ralouphie/getallheaders": "3.0.3", "wikimedia/assert": "0.5.0", "wikimedia/at-ease": "2.1.0", "wikimedia/base-convert": "2.0.1", "wikimedia/cdb": "1.4.1", "wikimedia/cldr-plural-rule-parser": "2.0.0", "wikimedia/common-passwords": "0.3.0", "wikimedia/composer-merge-plugin": "2.0.1", "wikimedia/html-formatter": "3.0.1", "wikimedia/ip-set": "3.0.0", "wikimedia/ip-utils": "3.0.2", "wikimedia/less.php": "3.1.0", "wikimedia/minify": "2.2.4", "wikimedia/normalized-exception": "1.0.1", "wikimedia/object-factory": "3.0.2", "wikimedia/parsoid": "^0.14.0-a14@alpha", "wikimedia/php-session-serializer": "2.0.0", "wikimedia/purtle": "1.0.7", "wikimedia/relpath": "3.0.0", "wikimedia/remex-html": "2.3.2", "wikimedia/request-timeout": "1.1.0", "wikimedia/running-stat": "1.2.1", "wikimedia/scoped-callback": "3.0.0", "wikimedia/services": "2.0.1", "wikimedia/shellbox": "2.0.0", "wikimedia/utfnormal": "3.0.2", "wikimedia/timestamp": "3.0.0", "wikimedia/wait-condition-loop": "2.0.2", "wikimedia/wrappedstring": "3.2.0", "wikimedia/xmp-reader": "0.8.1", "zordius/lightncandy": "1.2.5" }, "require-dev": { "composer/spdx-licenses": "1.5.4", "doctrine/dbal": "2.10.4||3.0.0", "doctrine/sql-formatter": "1.1.1", "giorgiosironi/eris": "^0.10.0", "hamcrest/hamcrest-php": "^2.0", "johnkary/phpunit-speedtrap": "^3.1", "justinrainbow/json-schema": "~5.2", "mediawiki/mediawiki-codesniffer": "37.0.0", "mediawiki/mediawiki-phan-config": "0.10.6", "nikic/php-parser": "4.10.2", "nmred/kafka-php": "0.1.5", "php-parallel-lint/php-console-highlighter": "0.5", "php-parallel-lint/php-parallel-lint": "1.3.0", "phpunit/phpunit": "^8.5", "psy/psysh": "0.10.5", "seld/jsonlint": "1.8.3", "symfony/yaml": "~3.4|~5.1", "wikimedia/testing-access-wrapper": "~2.0", "wmde/hamcrest-html-matchers": "^1.0.0" }, "replace": { "symfony/polyfill-ctype": "1.99", "symfony/polyfill-mbstring": "1.99" }, "suggest": { "ext-apcu": "Local data cache for greatly improved performance", "ext-curl": "Improved http communication abilities", "ext-openssl": "Cryptographical functions", "ext-wikidiff2": "Diff accelerator", "monolog/monolog": "Flexible debug logging system", "nmred/kafka-php": "Send debug log events to kafka" }, "autoload": { "psr-0": { "ComposerHookHandler": "includes/composer", "ComposerVendorHtaccessCreator": "includes/composer", "ComposerPhpunitXmlCoverageEdit": "includes/composer" } }, "autoload-dev": { "files": [ "vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest.php", "vendor/wmde/hamcrest-html-matchers/src/functions.php" ] }, "scripts": { "mw-install:sqlite": "php maintenance/install.php --server=http://localhost:4000 --dbtype sqlite --dbpath cache/ --scriptpath '' --pass adminpassword MediaWiki Admin", "serve": "php -S localhost:4000", "lint": "parallel-lint --exclude vendor", "phan": "phan -d . --long-progress-bar", "phpcs": "phpcs -p -s --cache", "fix": [ "phpcbf" ], "pre-install-cmd": "ComposerHookHandler::onPreInstall", "pre-update-cmd": "ComposerHookHandler::onPreUpdate", "post-install-cmd": "ComposerVendorHtaccessCreator::onEvent", "post-update-cmd": "ComposerVendorHtaccessCreator::onEvent", "test": [ "composer lint .", "composer phpcs ." ], "test-some": [ "composer lint", "composer phpcs" ], "phpunit": "phpunit", "phpunit:unit": "phpunit --colors=always --testsuite=core:unit,extensions:unit,skins:unit", "phpunit:integration": "phpunit --colors=always --testsuite=core:integration,extensions:integration,skins:integration", "phpunit:coverage": "phpunit --testsuite=core:unit --exclude-group Dump,Broken", "phpunit:coverage-edit": "ComposerPhpunitXmlCoverageEdit::onEvent", "phpunit:entrypoint": "php tests/phpunit/phpunit.php" }, "config": { "optimize-autoloader": true, "prepend-autoloader": false }, "extra": { "merge-plugin": { "include": [ "composer.local.json" ], "merge-dev": false } } }
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
.
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...).
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.
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.
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 :
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.
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.
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 :
C:\Program Files\Git\bin\sh.exe
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 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 :
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".
Si le serveur PHP est dans un conteneur Docker, il faut le stipuler à PhpStorm :
Le php.ini dépend de l'OS hôte[1] :
xdebug.remote_host = 172.170.0.1
xdebug.remote_host = "docker.for.win.host.internal"
xdebug.remote_host = "docker.for.mac.host.internal"
Exemple de Dockerfile :
RUN pecl install -f xdebug \ && docker-php-ext-enable xdebug COPY xdebug.ini $PHP_INI_DIR/conf.d # ou s'il y a peu de lignes à ajouter dans le .ini : RUN echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.iniRaccourcis 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
PhpStorm dispose de plusieurs plugins installables dans un deuxième temps, classables par thèmes. Certains sont payants, mais en voici des gratuits utiles :
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[1] (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/.
NetBeans permet de comparer deux fichiers : Tools, Diff...
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.
Liste exhaustive en anglais : http://wiki.netbeans.org/KeymapProfileFor60.
Certains plugins peuvent se révéler utiles :
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 :
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 EclipseLa 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 :
Help>Software Updates>Find and Install...
Name: Nom du plugin URL: adresse du plugin, ex : http://www.eclipse.org/cdt/downloads.php
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 :
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.
Eclipse Édition de lignesL'éditeur de code possède des raccourcis clavier pratiques rendant l'édition des lignes de code plus rapide :
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 codeL'éditeur de code peut compléter automatiquement le code là où se trouve le curseur :
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 :
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 astucesL'IDE Eclipse montre beaucoup de choses à ne pas faire quand on conçoit une interface graphique ; notamment concernant les raccourcis clavier :
L'historique de navigation entre les fichiers est également mal géré : après une action de navigation avant (CTRL+clic sur une méthode, par exemple) changeant le fichier courant, plusieurs retours en arrière sont généralement nécessaires pour revenir à la position précédente.
Visual Studio CodeVisual 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)[1], 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ésVisual 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[2].
Utilisation Édition de lignesL'éditeur de code possède des raccourcis clavier pratiques rendant l'édition des lignes de code plus rapide :
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 Bases du langagePHP 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é.
Pour que PHP interprète votre code, vous devez remplir deux conditions :
<?php ... ?>
. Tout ce qui n'est pas compris entre ces balises n'est pas interprété par PHP :<!DOCTYPE html> <html> <head> <title>Le titre de l'onglet</title> <meta charset="utf8" /> </head> <body> <p>Du texte en html</p> <? echo 'un exemple de texte en php'; ?> <p>Encore du texte en html</p> //Écriture recommandée et universelle <?php echo "Encore du texte en php"; ?> <body> </html>
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é :
php7.3 -r "echo php_ini_loaded_file().PHP_EOL;"
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.
Dans le cas des fichiers .php qui commencent par <?php
et finissent par ?>
, la balise fermante est optionnelle voire déconseillée.
Il est possible de définir certains comportements de PHP lors de la compilation par des directives inscrites dans la commande declare()
[1]. Par exemple :
declare(encoding = 'UTF-8');
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 :
//
pour ajouter un commentaire sur une ligne.#
pour ajouter un commentaire sur une ligne également./* */
pour désigner un bloc de commentaires.<?php # un commentaire PHP // encore un commentaire PHP /* et encore un autre, mais sur plusieurs lignes cette fois-ci ! */
Il est important de ne pas emboîter les commentaires. Exemple à ne pas suivre :
<?php /*blabla /* hihi*/ blalbal*/
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.
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[1] 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[2] :
/** * Commentaires sur le rôle du fichier courant * * date modifier : 13 mars 2013 * @since 13 mars 2013 * @author Prénom Nom (courriel) * @copyright PHPascal.com * @version 1.2 * */
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 :
class MyEntity { /** @var int|null */ private $id; /** * @return int|null */ public function getId() { return $this->id; } }
Depuis PHP7 :
class MyEntity { private int $id; public function getId(): ?int { return $this->id; } }
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[3]. Ex :
<?php #[\ReturnTypeWillChange] public function getMixedData() { return $this->mixedData; }
Cet attribut sert à ne pas ajouter de warning si le type retourné ne peut pas être déterminé[4].
Il en existe aussi d'autres comme :
Les attributs d'une classe peuvent être récupérés à l'exécution avec : ReflexionClass()->getAttributes().
Premier programmeÉcrivons notre premier programme PHP. Pour le moment nous nous contenterons d'afficher le fameux "Hello World".
La commande shell est[1] :
php -r "print 'Hello World!';"
Soit le fichier HelloWorld.php
ci-dessous, il peut être lancé par :
php -q HelloWorld.php
ou php -f HelloWorld.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Mon premier script PHP !</title> </head> <body> <p><?php echo 'Hello World!'; ?></p> </body> </html>
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.
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é :
<?php // Parse error assurée echo 'J'irais bien boire un coup.';
Ne s'affichera pas, pour ce faire il faut juste mettre un antislash (\
) devant notre apostrophe.
Exemple de code opérationnel :
<?php // Antislash et c'est bon echo 'J\'irais bien boire un coup.';
On peut aussi rendre plus lisible le code source en utilisant les caractères suivants :
Attention : Ces caractères ne sont interprétés par le moteur PHP que s'ils sont introduits à l'aide de double apostrophe (guillemets) :
echo "Retourne à la ligne\n";
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 :
<?php $texte= 'Hello World'; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Mon premier script PHP !</title> </head> <body> <?php echo ($texte); ?> </body> </html>
PHP en ligne de commande possède plusieurs différences avec PHP sur serveur Web :
$_GET
, $_POST
et $_COOKIE
.$argv
, et leur nombre par $argc
(ou $_SERVER['argc']
si "register_globals = off;" dans php.ini).global $argv; global $argc;Variables
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) :
$1MaVariable // incorrect $MaVariable // correct $_MaVariable // correct $àéè // correct MA_CONSTANTE // correct _MA_CONSTANTE // correct
<?php // Initialisation des variables $Prenom = 'Romuald'; $Age = '23 ans'; $Profession = 'informaticien'; // Affichage echo 'Bonjour ' . $Prenom . ', tu as ' . $Age . ' et ta profession est ' . $Profession . '.'; // Ce qui affichera sur votre navigateur : Bonjour Romuald, tu as 23 ans et ta profession est informaticien. // Une autre manière de faire echo "Bonjour $Prenom, tu as $Age et ta profession est $Profession"; // Ce qui affichera sur votre navigateur : Bonjour Romuald, tu as 23 ans et ta profession est informaticien. // Subtilité des " et des ' echo 'Bonjour $Prenom, tu as $Age et ta profession est $Profession'; // Ce qui affichera sur votre navigateur : Bonjour $Prenom, tu as $Age et ta profession est $Profession // Le contenu d'une chaîne construite avec des " sera interprété par PHP et les variables // éventuellement utilisées seront remplacées par leurs valeurs.
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 :
echo "Bonjour $Prenom, tu as $Age et ta profession est $Profession";
echo 'Hello \'the\' "World" !';
Pour éviter de s'encombrer des caractères d'échappement, il existe aussi les syntaxes heredoc et nowdoc avec l'opérateur "<<<"[1]. Ex :
$v = 1; echo <<<Test 'Hello' "World" \\ $v heredoc Test; // 'Hello' "World" \ 1 heredoc echo <<<'Test' 'Hello' "World" \\ $v nowdoc Test; // 'Hello' "World" \\ $v nowdoc
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[2].
Le délimiteur heredoc ou nowdoc permet de forcer une coloration syntaxique dans certains IDE comme PhpStorm ou vscode
[3]. Par exemple,
echo <<<HTML
a un rendu différent de echo
<<<SQL
.
Par défaut, on peut accéder aux propriétés et méthodes d'objets en heredoc. Ex :
$v1 = new stdClass(); $v1->name = "World"; $v2 = ['one', 'two']; echo <<<Test Hello $v1->name $v2[1] Test;
Mais si cela pose problème, utiliser les accolades pour forcer l'interpolation :
$v1 = new stdClass(); $v1->name = ['one', 'two']; echo <<<Test Hello $v1->name[1] // Hello Array[1] Hello {$v1->name[1]} // Hello two Test;
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 :
b'ma_chaine'
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 :
print(iconv('ISO-8859-1', 'UTF-8', b'é'));
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.
$x = 1; // indique implicitement que $x est un entier $mot = 'test'; // indique que $mot est une chaîne de caractères
En PHP il y a donc quatre types de variables scalaires :
De plus, on trouve les types complexes :
Il faut toujours arrondir les nombres flottant à l'affichage, mais aussi lors des comparaisons[4].
Exemple :
$ php -r "var_dump(8 - 6.4 == 1.6);" bool(false) $ php -r "var_dump(round(8 - 6.4, 1) == 1.6);" bool(true)
Lors de la division de nombres à virgules flottantes, on peut facilement avoir une imprécision à cause du mode de leur stockage en mémoire :
echo PHP_VERSION.PHP_EOL; var_dump(fmod(9999.00000, 9998.00001));
donne :
7.3.14 float(0.99999000000025)
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 :
$a = "MaVariable";
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 :
$$a = "bonjour";
est équivalent à : $MaVariable="bonjour";
, ou encore ${$a} = "bonjour";
.
Attention : cette syntaxe est inutile pour les fonctions. Ex :
<?php function direBonjour() { echo "Bonjour !"; } $a = 'direBonjour'; $a();
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[5] :
<?php $a = ['Hello', 'World']; echo ${$a[0]}; // Undefined variable: Hello echo ${$a}[0]; // Array to string conversion
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 :
echo $this->$myVariableName; echo $this->{'variable'.$i}; echo self::$myStaticVariableName; echo constant(self::class.'::'.strtoupper($myConstantName));
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).
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'])
.
Le tableau $_COOKIE
permet de gérer les cookies (définis avec setcookie()
[6]). 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.
$_REQUEST est un tableau associatif constitué du contenu des variables $_GET, $_POST, $_COOKIE.
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 :
Le mot clé mixed
permet de définir une variable mixte.
$_SERVER permet d'obtenir des renseignements sous forme d'un tableau sur le serveur.
'PHP_SELF'
$_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'
'argc'
'GATEWAY_INTERFACE'
'SERVER_NAME'
'SERVER_SOFTWARE'
'SERVER_PROTOCOL'
'REQUEST_METHOD'
'REQUEST_TIME'
'QUERY_STRING'
'DOCUMENT_ROOT'
'HTTP_ACCEPT'
'HTTP_ACCEPT_CHARSET'
'HTTP_ACCEPT_ENCODING'
'HTTP_ACCEPT_LANGUAGE'
'HTTP_CONNECTION'
'HTTP_HOST'
'HTTP_REFERER'
'HTTP_USER_AGENT'
'HTTP_header'
'HTTPS'
'REMOTE_ADDR'
'REMOTE_HOST'
'REMOTE_PORT'
'SCRIPT_FILENAME'
'SERVER_ADMIN'
'SERVER_PORT'
'SERVER_SIGNATURE'
'PATH_TRANSLATED'
'SCRIPT_NAME'
'REQUEST_URI'
'PHP_AUTH_DIGEST'
'PHP_AUTH_USER'
'PHP_AUTH_PW'
'AUTH_TYPE'
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.
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"[7].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".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 :
$a = 1; $b = (bool) $a; print gettype($a); // integer print gettype($b); // boolean
(bool) "false"
renvoie true
car toute string non vide est vraie.
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.
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) :
Elle contient des informations sur le serveur (nom, IP, logiciels installés…)
Par exemple pour extraire l'URL de la page courante :
echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
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' :
<?php echo 'Mon nom d\'utilisateur est ' .$_ENV["USER"] . '!';
En imaginant que l'utilisateur 'Paul' exécute ce script, on aura alors :
Exemple
Mon nom d'utilisateur est Paul !Elle stocke les informations sur les cookies envoyés aux clients.
Un petit exemple pour illustre cela :
<?php echo 'Bonjour ' . htmlspecialchars($_COOKIE["name"]) . '!';
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 :
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
<?php echo 'Bonjour ' . htmlspecialchars($_GET["name"]) . '!';
L'exemple ci-dessus va afficher alors :
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>
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>
Elle stocke les informations sur un fichier envoyé via HTTP par le client par un formulaire.
Elle contient les valeurs de la session en cours pour le client.
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').
Une bonne pratique consiste à filtrer les contenus des variables superglobales, qui sont vulnérables aux injections de code[1].
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()
[2] :
<?php echo filter_input(INPUT_GET, 'password'); // bien echo $_GET['password']; // pas bien
Ne pas confondre avec la fonction filter_var() qui permet d'appliquer des validations ou nettoyages de certaines données[3] (ex : email, URL, adresse IP, booléen...).
ConstantesTout 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.
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.
// Noms valides CONSTANTE1 CONSTANTE_2 // Noms invalides 0CONSTANTE
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[1].
La syntaxe de define
est la suivante :
define(chaine_de_caractere, valeur);
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]).
L'utilisation est semblable à celle des variables.
<?php define("CONSTANTE", "Texte ici"); echo CONSTANTE; // affiche "Texte ici"
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 :
<?php class MaClasse { const CONSTANTE = "Texte ici"; function afficher() { echo self::CONSTANTE; } } $instance = new MaClasse; $instance->afficher();
Ces constantes sont publiques par défaut, mais PHP 7.1 introduit la possibilité de les rendre privée avec : private const
.
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.
<?php // Le code suivant va générer une erreur en PHP 5 (mais pas en PHP 7) define ("CONSTANTE", ["a", "b", "c"]); print_r(CONSTANTE);
Depuis PHP7.4, les nombres entiers peuvent être rendus plus lisibles dans le code en ajoutant des "_" comme séparateurs. Ex :
echo 10_00_000; // affiche 10000000
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.
<?php define ("CONSTANTE", "première définition"); define ("CONSTANTE", "deuxième définition"); // ignoré echo CONSTANTE; // retournera toujours "première définition"
D'où l'utilisation de defined()
pour déterminer si une constante est déjà définie ou pas[2] :
define("CONSTANTE", "première définition"); if (!defined("CONSTANTE")) { //...
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 :
__NOM__
Il en existe de deux types[3] :
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.Les constantes magiques[4] :
__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 :
<?php echo 'Fichier: ' . __FILE__ . "\n"; echo 'Ligne: ' . __LINE__ . "\n"; class test { function foo() { echo 'Fonction: ' . __FUNCTION__ . "\n"; echo 'Classe: ' . __CLASS__ . "\n"; } } test::foo(); // ou alors $test = new test(); $test->foo();
Qui affichera :
Fichier: /home/ze/toto.php Ligne: 3 Fonction: foo Classe: test Fonction: foo Classe: test
L'affichage de la première ligne, par exemple, dépend d'où est situé le fichier dans l'arborescence des fichiers.
OpérateursLes opérateurs sont des symboles qui permettent de manipuler les variables.
<?php $un_chiffre = 4; //affectation de l'entier 4 à la variable un_chiffre $un_mot = 'je suis fan des pâtes'; //affectation de la chaîne de caractères à la variable "un_mot"
<?php $mon_premier_chiffre = 3; //affectation du premier chiffre $mon_deuxieme_chiffre = 4; //affectation du deuxième chiffre $resultat = $mon_premier_chiffre + $mon_deuxieme_chiffre; //affectation de l'addition des deux chiffres echo $resultat; //affiche 3+4 soit 7
Si les opérandes sont des tableaux, "+" est l'opérateur union[1].
<?php $mon_premier_chiffre = 3; $mon_deuxieme_chiffre = 4; $resultat = $mon_premier_chiffre - $mon_deuxieme_chiffre; echo $resultat; //affiche 3-4 soit -1
<?php $mon_premier_chiffre = 3; $mon_deuxieme_chiffre = 4; $resultat = $mon_premier_chiffre * $mon_deuxieme_chiffre; echo $resultat; //affiche 3*4 soit 12
<?php $mon_premier_chiffre = 2; $mon_deuxieme_chiffre = 3; $resultat = $mon_premier_chiffre ** $mon_deuxieme_chiffre; echo $resultat; //affiche 2^3 soit 8
<?php $mon_premier_chiffre = 3; $mon_deuxieme_chiffre = 4; $resultat = $mon_premier_chiffre / $mon_deuxieme_chiffre; echo $resultat; //affiche 3/4 soit 0,75
<?php $mon_premier_chiffre = 3; $mon_deuxieme_chiffre = 4; $resultat = $mon_premier_chiffre % $mon_deuxieme_chiffre; echo $resultat; //affiche 3 modulo 4 soit 3 (le modulo est le reste entier de la division euclidienne)
Il sert à tester si un nombre est le multiple d'un autre :
<?php if ($nb % 3 == 0) { // $nb est un multiple de trois }
Le reste de la division peut être obtenu avec la fonction
fmod()
[2]
.
Les opérateurs logiques agissent sur les types booléens (true
ou false
).
false
en true
et true
en false
.Les opérateurs logiques bit à bit agissent sur chaque bit des valeurs entières.
0
-> 1
et 1
-> 0
Ils permettent de simplifier l'écriture des assignations.
Ces opérateurs sont très utiles dans les boucles (notamment for).
Si les opérandes sont des tableaux :
L'opérateur ?
permet de renvoyer une valeur ou une autre en fonction d'un test.
??
(depuis PHP 7) [5] (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 :
$appreciation = ($note>10) ? "bon" : "mauvais";
qui est équivalent au bloc PHP suivant :
if ($note > 10) { $appreciation = "bon"; } else { $appreciation = "mauvais"; }
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 :
print 1 ?: 2; // 1 print 0 ?: 2; // 2 print null ?: 2; // 2
Il est généralement plus lisible de placer un retour chariot avant les ternaires. Ex :
print 'Un est plus ' . (1 > 2 ? ' grand' : ' petit' ). ' que deux.';
L'opérateur objet -> permet d'accéder aux propriétés d'un objet (variables et méthodes de classe). Exemple :
print $voiture->couleur; $voiture->repeindre('bleu');
Depuis PHP 8 il a une version qui renvoie null si l'objet est null :
$voiture = null; print $voiture?->couleur;
L'opérateur ::, également appelé en PHP Paamayim Nekudotayim, permet d'accéder aux membres statiques ou constants d'une classe. Exemple :
L'arobase permet d'ignorer les erreurs de l'expression qui le suit. Ex :
print 1/0; //Warning: Division by zero, puis INF print @(1/0); // INF
"&" accolé avant une variable désigne sa référence[6], 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 :
public function archive(&$db) { var_dump($db); }
Son utilisation pour les fonctions sera détaillée dans le chapitre sur les fonctions, mais on peut aussi l'utiliser dans les boucles.
Depuis PHP 5.6, "..." dans la liste des arguments d'une fonction indique que ceux-ci sont d'un nombre variable.
Exemple :
public function somme(...$nombres) { $somme = 0; foreach ($nombres as $n) { $somme += $n; } return $somme; } echo somme(1, 2, 3); echo somme(1, 2, 3, 4);
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[7].
À faire...
Site source légèrement incomplet, ex : $$.
FonctionsOutre les dizaines de fonctions natives[1], 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.
Début d’un principe
Principe
// foo retourne le résultat de la somme du deuxième paramètre et de 4. // Si aucun second paramètre n'est donné, la fonction utilisera la valeur 0 par défaut. function foo($arg1, $arg2 = 0) { print 'Fonction foo(' . $arg1 . ',' . $arg2 . ') donne : '; return $arg2+4; // tout ce qui suit ne sera jamais exécuté } //appel à la fonction print foo(1,3); //affichera: Fonction foo(1,3) donne 7 print foo(5); //affichera: Fonction foo(5,0) donne 4
Fin du principe
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.
Contrairement à PHP 8, PHP 7 et antérieur 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
[2].
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[3] (classe Generator).
Ne jamais faire de condition "yield" sinon "return" car PHP renverra toujours un Generator mais si elle est fausse (si besoin il faut les séparer dans deux fonctions).
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.
Début d’un principe
Principe
<?php //-- fichier 1 : les variables globales (mot clef '''global''') global $var1 = "Salut";
Fin du principe
Début d’un principe
Principe
<?php //-- fichier 2 : les traitements echo "J'utilise ma variable globale : ".$GLOBALS['var1']; //-- Récupération via $GLOBALS
Fin du principe
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[4]. Exemple de définition :
<?php namespace Projet1; ...
Soit un fichier TestNS.php suivant :
<?php namespace Projet1\SousProjet2; function Fonction1() { echo "Fonction exécutée.\n"; echo __NAMESPACE__; }
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 :
<?php require 'TestNS.php'; Projet1\SousProjet2\Fonction1();
Par convention, l'arborescence du système de fichiers correspond à celle des espaces de noms. Dans l'exemple ci-dessus, il faudrait donc placer le fichier dans Projet1\SousProjet2\TestNS.php et faire plutôt require 'Projet1\SousProjet2\TestNS.php';
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 &)
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 :
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.
Pour passer une fonction en argument d'une autre, il faut utiliser call_user_func()
. Ex :
function fonctionAppelante(string $nomDeFonctionAppelee) { return call_user_func($nomDeFonctionAppelee); }
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 :
$variableGlobale = 'Hello'; $fonctionAnonyme = function ($argument) use ($variableGlobale) { return $variableGlobale.' '.$argument.PHP_EOL; }; echo $fonctionAnonyme('World'); // Hello World echo $fonctionAnonyme('You'); // Hello You
Depuis PHP7.4, on peut définir une fonction anonyme avec l'opérateur "=>" et le mot réservé fn
. Ex :
$fonctionFlechee = fn($argument) => $variableGlobale.' '.$argument.PHP_EOL; echo $fonctionFlechee('World'); // Hello World echo $fonctionFlechee('You'); // Hello You
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[6]. Exemple :printf('Compteur : %s. ', 1); // Compteur : 1. printf('Compteur : %s. ', 2); // Compteur : 2. printf('Compteur : %s, taille : %s. ', 3, 1); // Compteur : 3, taille : 1. printf('Compteur : %2$s, taille : %1$d. ', 1, 4); // Compteur : 4, taille : 1. printf('Compteur : %1$d, taille : %1$d. ', 5); // Compteur : 5, taille : 5. echo vsprintf('Tailles : %d, %d, %d, %d', [1, 2, 3, 4]); // Tailles : 1, 2, 3, 4
Les types suivants sont généralement utilisés :
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[7].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.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.str_replace($ancien, $nouveau, $texte)
: remplace des caractères par d'autres dans un texte ou un tableau[8].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
[9].strpos($meubleDeFoin, $aiguille)
[10] : 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]
).
echo substr('Hello World', 0, 2); // "He" : les deux premiers caractères echo substr('Hello World', -2); // "ld" : les deux derniers caractères echo substr('Hello World', 0, -1); // "Hello Worl" : tout sauf le dernier caractère
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 :echo str_pad(10, 2, '0'); // 10 echo str_pad(9, 2, '0'); // 90 echo str_pad(9, 2, '0', STR_PAD_LEFT); // 09
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.strcspn($chaine, $caracteres)
: (complementary span) renvoie la taille de la sous-chaine située avant les caractères mentionnés[11].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')
.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 :php -r "var_dump(http_build_query(['x' => 1, 'y' => 2]));" string(7) "x=1&y=2" php -r "var_dump(http_build_query(['x' => '1/', 'y' => '2&'], '/', '/'));" string(13) "x=1%2F/y=2%26"
pow($nombre, $exposant)
(power) : élève un nombre à la puissance de l'exposant donné.sqrt($nombre)
(square root) : racine carrée.max($nombre1, $nombre2, ...)
[12] : 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é[13]. Exemple :echo round(5.49); // 5 echo round(5.50); // 6 echo round(5.555, 2); // 5.56
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 : -1000.00 < -1000.02 // false -1,000.00 < -1,000.02 // -1
La bufferisation de sortie bloque l'envoie de données au client HTTP pour les mettre dans une mémoire tampon à la place[14].
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.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 :
$tab = []; // depuis PHP 5.4 $tab = {}; // moins permissif aux concaténations $tab = array(); // déconseillé depuis PHP 7
Pour créer un tableau non vide :
$t1 = array('champ1', 'champ2'); $t2 = ['champ1', 'champ2']; $t3[0] = 'champ1'; $t3[1] = 'champ2'; // Affiche les trois mêmes tableaux : Array ( [0] => champ1 [1] => champ2 ) var_dump($t1); var_dump($t2); var_dump($t3);
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 :
$tab[0] = 1; // entier $tab[1] = 2.0; // flottant array_push($tab,'Ligne 3'); $tab[] = 'Ligne 4'; var_dump($tab);
Il en est de même pour les tableaux à deux dimensions.
$tab = []; $tab[0][0] = '0-0'; $tab[0][1] = '0-1'; $tab[1][0] = '1-0'; $tab[1][1] = '1-1'; var_dump($tab);
On distingue deux types de tableau :
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 :
Début d’un principe
Principe
$tab[0] = 1; $tab[99] = 3;
Fin du principe
Notez que les indices ne sont pas typés (on pourra indifféremment utiliser $tab[1] et $tab['1']).
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 :
print implode(". ", $tab).". ";
Résultat : val1. val2. val3.
count
: cette fonction renvoie le nombre d'éléments présent dans le tableau.Début d’un principe
Principe
$tab = [1, 2, 3, 4]; print count($tab); //affiche 4
Fin du principe
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.$tab = ["mixte valeur<sub>1</sub>","mixte valeur<sub>2</sub>","...","mixte valeur<sub>n</sub>"]; echo key($tab); echo ' : '; echo current($tab);
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.
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
Pour comparer deux tableaux :
$a1 == $a2; // compare le contenu et la taille $a1 === $a2; // compare le contenu, la taille et l'index
Un tableau vide dans une condition vaudra "faux", alors qu'un non vide vaudra "true".
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[]
[1] (empile).array_unshift($monTableau, $valeur)
: ajoute une ligne au début du tableau[2].array_pop($monTableau)
: retire la dernière ligne du tableau, en la renvoyant[3] (dépile).array_shift($monTableau)
: retire la première ligne du tableau, en la renvoyant[4].array_merge($monTableau1, $monTableau2, $monTableau3...)
: fusionne plusieurs tableaux[5].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[6]. Exemples :
array_map('trim', $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));
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[7].Les tris croissants définis par défaut sont modifiables par des flags en deuxième paramètre.
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 :
$array = ['à', 'i', 'o', 'u', 'é']; sort($array); print_r($array); setlocale(LC_COLLATE, 'fr'); // parfois 'fr_FR.UTF-8' sort($array, SORT_LOCALE_STRING); print_r($array);
donne :
Array ( [0] => i [1] => o [2] => u [3] => à [4] => é )
Array ( [0] => à [1] => é [2] => i [3] => o [4] => u )
La clé d’un tableau peut pointer sur un second tableau créant ainsi un tableau multi-dimensionnel.
Début d’un principe
Principe
$indiv[] = [ 'nom' => 'Hubert', 'poste' => 'Gérant', 'Email' => 'hubert@example.com', 'idBureau' => 1 ]; $indiv[] = [ 'nom' => 'Jean', 'poste' => 'Réceptionniste', 'Email' => 'reception@example.com', 'idBureau' => 1 ]; $indiv[] = [ 'nom' => 'Amélie', 'poste' => 'Président', 'Email' => 'contact@example2.com', 'idBureau' => 2 ]; $affBureau = 1; foreach ($indiv as $no => $data) { if ($data['idBureau'] == $affBureau) { echo $no .'-'. $data['nom'] .' <i>'. $data['poste'] .'</i> : '. $data['Email'] .'<br />'; } }
Fin du principe
Résultat :
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[8].
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[9]. 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[10].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[11] (contraire de compact()
).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é.
La structure la plus simple se présente sous la forme d'un if() {}
et d'un else {}
. Le if
teste une condition :
else {}
;else
qui sera exécuté.<?php if (condition) { instruction au cas où la condition serait réalisée; } else { instruction au cas où la condition ne serait pas réalisée; }
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.
<?php if (condition) { instruction au cas où la condition est réalisée; } //si la condition n'est pas réalisée, il ne se passe rien
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 :
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; }
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.
<?php if() { if() { } elseif() { } else { } } elseif() {} else {}
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.
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:
.
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 "===".
Depuis PHP8, cette structure retourne une valeur selon plusieurs conditions[1]. Ex :
echo match ($variable) { 'clé_1' => 'valeur 1', 'clé_2' => 'valeur 2', default => 'unknown value', };
PHP propose une syntaxe alternative aux accolades pour ses structures de contrôle, qui sont le ":" puis "end_nom_de_la_structure;"[2]. Ex :
if ($a == $b): echo "Test"; endif;
C'est notamment pratique si vous utilisez php comme moteur de templating
<?php if ($a == $b): ?> <p>Ici un paragraphe</p> <?php else if ($a > $b): ?> <p>Paragraphe alternatif</p> <?php else: ?> <p>Paragraphe si rien ne correspond</p> <?php endif; ?>Boucles
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
est un mot anglais signifiant "tant que" en français. Le programme exécute une routine tant que la condition est vraie.
while (condition) { instructions(s); }
Deuxième syntaxe (moins courante) :
while (condition): instructions(s); endwhile;
Troisième syntaxe (assez rare), quand la condition contient une méthode qui change à chaque itération, jusqu'à renvoyer faux :
Idem avec premier passage obligatoire : la condition est vérifié en fin de bloc.
do { instructions(s); } while (condition);
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.
for (première expression ; condition d'arrêt ; itération) { instruction; }
TRUE
l'instruction sera exécutée, si FALSE
est renvoyé on sort de la boucle.Attention la structure dans la parenthèse est for( ; ; )
Les boucles foreach
apparues avec PHP 4, constituent une manière simple de parcourir des tableaux. Il existe deux syntaxes :
foreach
simplifie une tache qui aurait certes été possible avec for
, mais fastidieuse :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.
$array = array( "ville" => "Montargis", "température" => "15 degrés" );
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.
foreach($array as $cle => $valeur) { commandes; }
Par ailleurs, il est possible d'itérer des objets depuis PHP 5.
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;
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.3