Programmation PHP/Version imprimable

Un livre de Wikilivres.
Aller à : navigation, rechercher
Webysther 20160423 - Elephpant.svg
link={{{link}}}

Ceci est la version imprimable de Programmation PHP.

  • Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
  • Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
  • Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.


Programmation PHP

Une version à jour et éditable de ce livre est disponible sur Wikilivres,
une bibliothèque de livres pédagogiques, à l'URL :
http://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 ».

Sections

Introduction

Historique[modifier | modifier le wikicode]

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, 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 J2EE 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, et en 2016 il est utilisé dans plus de 80 % des sites Internet !

Sites Web statiques ou dynamiques[modifier | modifier le wikicode]

À l'origine du Web, les sites Web étaient des sites statiques : constitués d'un ensemble de pages écrites dans le langage HTML. L'information présente sur ces pages était toujours identique et leur mise à jour était particulièrement fastidieuse. Le serveur Web se contentait de diffuser les pages telles quelles à l'utilisateur. L'interaction entre le site et l'utilisateur était très sommaire : l'utilisateur demandait une page web et le serveur la lui fournissait.

Aujourd'hui la plupart des sites sont dynamiques : à l'intérieur des pages HTML, le concepteur du site a inséré des programmes. Ces programmes permettent une plus grande souplesse dans la gestion du site, sa mise à jour et ses fonctionnalités. La possibilité d'insérer des programmes a permis de décupler les fonctionnalités des sites Web.

Pour vous en convaincre prenons quelques exemples :

  • Vous voulez écrire un site qui présente une centaine de produits. Vous n'allez pas écrire 100 pages différentes, une pour chacun des produits ! Mais plutôt une seule page (page type) permettant de présenter n'importe quel produit. Cette page va contenir un programme qui interagira avec une base de données. Dans la base de données, seront stockées les informations utiles pour chaque produit : le nom du produit, sa présentation, sa référence, son prix, etc. Le programme aura donc pour rôle d'aller chercher l'information utile dans la base de données et de l'afficher en HTML. De plus, pour ajouter un produit, il suffira d'ajouter un élément dans la base de données. Il est même possible d'avoir des programmes permettant de passer une commande pour vos différents produits !
  • Vous voulez diffuser rapidement des informations sur Internet : vous voulez avoir un outil convivial qui vous permet d'ajouter un article, de le modifier, de le supprimer... Vous allez donc écrire un programme permettant de modifier à volonté les différents articles. Un exemple bien connu de ce type de programme est le blog : il s'agit d'un programme permettant à n'importe quel utilisateur non informaticien de gérer ses différents articles.
  • L'encyclopédie Wikipédia est réalisée avec un programme (en PHP d'ailleurs) qui permet à chaque utilisateur de créer et de modifier les articles tout en gardant un historique complet des différentes versions des articles.
  • les forums de discussion sont des lieux d'échange permettant une interaction étroite entre le serveur et l'utilisateur. Grâce aux programmes qu'ils utilisent, il est possible de se connecter, de consulter les messages des différents forums, d'y répondre. Les modérateurs de ces forums peuvent modifier les messages, les supprimer, interdire un utilisateur indélicat.

Dans chacun des exemples précédents il a été nécessaire d'incorporer un programme à l'intérieur des pages du site afin de réaliser des fonctionnalités de haut niveau. Aujourd'hui la quasi-totalité des sites professionnels sont dynamiques et il est quasi inconcevable de réaliser un site statique. Le langage PHP est un des langages utilisables pour réaliser facilement les sites Web dynamiques, ne serait-ce que parce qu'il est disponible sur la plupart des serveurs hébergeant des sites.

Possibilités[modifier | modifier le wikicode]

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.


Installer PHP

Principe[modifier | modifier le wikicode]

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), mais le réel intérêt est d'installer PHP comme extension d'un serveur HTTP, pour y publier des sites web.

Unix / Linux[modifier | modifier le wikicode]

LAMP[modifier | modifier le wikicode]

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

Installation manuelle[modifier | modifier le wikicode]

Apache sur Debian / Ubuntu[modifier | modifier le wikicode]

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 :

commande

$ lynx http://localhost/

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
PHP[modifier | modifier le wikicode]

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 php7.0 && apt-get install libapache2-mod-php7.0

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/apache 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 :

commande

$ lynx http://localhost/test.php

Pour débugger :

commande

$ tail /var/log/apache2/error.log

Apache sur Gentoo[modifier | modifier le wikicode]

Premièrement il faut installer Apache si ce n'est pas déjà fait :

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 seul[modifier | modifier le wikicode]

MySQL est disponible sur http://dev.mysql.com/downloads/gui-tools/5.0.html au format :

  1. .msi (Windows)
  2. .dmg (Mac)
  3. .rpm (Linux)
  4. .tar

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 &

APT[modifier | modifier le wikicode]

# apt-get install mysql-server mysql_secure_installation

Puis, modifier PHP pour qu'il supporte MySQL :

# apt-get install php4-mysql
Variante[modifier | modifier le wikicode]

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.


**NB :** 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.

Sur Gentoo[modifier | modifier le wikicode]

 emerge mysql

Installer PhpMyAdmin[modifier | modifier le wikicode]

Depuis un tout-en-un :

sudo ln -s /usr/share/phpmyadmin /var/www/phpmyadmin

Sinon :

sudo apt-get install phpmyadmin php5

Installer Apache et PHP avec PhpMyAdmin[modifier | modifier le wikicode]

Grâce aux dépendances des paquets, cette opération peut se faire en une seule fois : Remarque : Vérifiez que la case "Traiter les paquets recommandés comme des dépendances" soit cochée dans Synaptic, configuration, préférences.

$ sudo apt-get install phpmyadmin

Cela installera automatiquement apache2 + php + modules d'apache pour PHP et MySQL + PhpMyAdmin. Pour accéder à PhpMyAdmin, il faut se rendre à la page http://localhost/PhpMyAdmin.

Note : En cas de problème d'authentification (erreur 2002 notamment) installer le paquet mysql-server peut résoudre ce dernier.

Après l'installation, il vaut mieux modifier les droits d'accès de root, et ajouter un mot de passe pour un peu plus de sécurité. Pour cela, il faut se rendre à la page privilèges de PhpMyAdmin.

Remarque pour Ubuntu 5.04 (Hoary Hedgehog) : Afin que cette commande fonctionne il est nécessaire d'avoir effectué les modifications suivantes : dans /etc/apt/ éditer le fichier sources.list supprimer les # des lignes suivantes :

# deb http://fr.archive.ubuntu.com/ubuntu hoary universe

(cette ligne est dans certain cas '# deb http://archive.ubuntu.com/ubuntu/ hoary universe main restricted multiverse')

# deb-src http://fr.archive.ubuntu.com/ubuntu hoary universe

Pour la version d'Ubuntu 5.10 (Breezy), vous pouvez effectuer ces changements avec le gestionnaire de paquets synaptic (apt) : Système ---> Administration ---> Gestionnaire de paquets Synaptic

            Catégories ---> Dépôts ----> Ajouter et ensuite, sélectionner : maintenu par la communauté universe...

Lancer le chargement des nouvelles sources :

$ sudo apt-get update

Puis lancer l'installation de PhpMyAdmin comme décrit ci-dessus.

Extensions[modifier | modifier le wikicode]

Pour activer des modules complémentaires :

a2enmod Nom_du_module # passe dans /etc/apache2/mods-enabled/

Pour les désactiver :

a2dismod Nom_du_module # passe dans /etc/apache2/mods-available/

Pour activer des sites :

a2ensite Nom_du_site # passe dans /etc/apache2/sites-enabled/

Pour les désactiver :

a2dissite Nom_du_site # passe dans /etc/apache2/sites-available/


Problème d'encodage d'Apache2[modifier | modifier le wikicode]

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

Encodage par défaut en Latin1 (ISO-8859-1)[modifier | modifier le wikicode]

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

Aucun encodage par défaut[modifier | modifier le wikicode]

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 !


Créer son site[modifier | modifier le wikicode]

Placez vos fichiers .php et .html dans /var/www pour qu'ils deviennent le site de votre machine (celui disponible à l'adresse http://nom_ou_ip_de_votre_machine/).

Créer sa page utilisateur[modifier | modifier le wikicode]

Placez vos fichiers php et html dans un sous-répertoire "public_html" de votre répertoire utilisateur pour qu'ils deviennent votre site utilisateur (celui disponible à l'adresse http://nom_ou_ip_de_votre_machine/~votre_login/)

Permettre l'utilisation de fichiers dans le "~/public_html"[modifier | modifier le wikicode]

Il faut activer le module userdir :

 sudo a2enmod userdir
 sudo /etc/init.d/apache2 reload


Windows[modifier | modifier le wikicode]

Tout-en-un[modifier | modifier le wikicode]

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 :

  1. EasyPHPtéléchargement : n'a pas vocation à être installé pour de la production, mais pour le développement. Il stocke les bases de données dans C:\Program Files (x86)\EasyPHP\binaries\mysql\data.
  2. WAMPtéléchargement : est du même type qu'EasyPHP : ce logiciel installe facilement un serveur Web Apache, une base de données MySQL et PHP 4 et 5. Il a l'avantage de permettre de passer facilement de PHP 4 à PHP 5, sans avoir à refaire une installation ou une compilation. Tout comme EasyPHP, c'est un environnement de développement, et non un environnement de production. Attention : la résolution des noms d'hôtes se réalise séparément. Les installations WAMP servent à tester en local sur votre PC. Dans la plupart des cas, il suffit d'utiliser le fichier Hosts local, comme on le ferait sur une machine Linux, afin de lier des noms aux adresses IP. Dans Windows XP, Vista et 7, ce fichier se trouve dans le répertoire systemroot\System32\Drivers\Etc. Il peut se faire que le service ait déjà été configuré. Lorsque vous vous en doutez, contactez votre administrateur réseau. Remarque : vous trouverez une liste des possibilités de résolution de noms avec MS Windows sur Microsoft.com.
  3. XAMPPtéléchargement : est du même type qu'EasyPHP ou WAMP, le deuxième P étant pour Perl. Son usage est recommandé avec PHPEclipse, et il fournit aussi un serveur Apache Tomcat par défaut.
  4. The Uniform Servertéléchargement : en anglais seulement avec Apache2, Perl5, PHP5, MySQL5, phpMyAdmin.
link={{{link}}}Attention !

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.

link={{{link}}}Attention !

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-dbserver
Logo EasyPHP.

Message d'erreur relatif à SSL[modifier | modifier le wikicode]

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

;extensions=php_openssl.dll

Si tout se passe bien, vous pouvez ouvrir la page de test dans votre navigateur.

Installation manuelle[modifier | modifier le wikicode]

Installer Apache[modifier | modifier le wikicode]

Pour installer Apache, double-cliquez sur le fichier exécutable, et suivez les instructions d'installation automatique.

Si vous installez Apache sur un ordinateur de développement, renseignez le champ "nom de domaine" avec la valeur localhost.

Si vous installez un serveur de production et que vous disposez d'un nom de domaine, vous devriez disposer des informations nécessaires concernant votre nom de domaine, fournies par le registrar.

Une fois l'installation terminée, il faut encore indiquer à Apache qu'il doit fonctionner conjointement avec PHP, car il ne sait pas les traiter par défaut. Pour cela, il faut modifier les informations de configuration d'Apache, contenues dans le fichier httpd.conf, qui se trouve dans le dossier d'installation d'Apache, dans le sous-dossier conf.

Installer PHP[modifier | modifier le wikicode]

Une fois l'archive téléchargée, décompressez-la à la racine de votre disque dur et renommez le dossier en 'PHP'. Dans le dossier PHP, vous trouverez deux fichiers: php.ini-dist et php.ini-recommended. Copiez php.ini-recommended dans votre dossier C:\Windows ou C:\winnt (le nom du dossier dépend de la version de votre système.
renommez-le en php.ini.

Ce fichier est le fichier de configuration qui contrôle les options dont vous disposerez. Par exemple :

PHP.ini PHP Rôle
error_reporting E_ALL error_reporting(E_ALL); Affiche tous les avertissements et erreurs directement sur le site. C'est utile pour la préproduction car cela évite de rechercher d'éventuels messages dans les logs, mais peut perturber la mise en page pour des avertissements bénins.
error_reporting 0 error_reporting(0); N'affiche aucun message sur le site relatif à son exécution
max_execution_time = 300 Définit le "timeout", c'est-à-dire le temps maximum en secondes autorisé pour exécuter un script PHP.
post_max_size = 80M Définit la taille maximum d'un fichier que l'on peut envoyer au serveur en HTTP.

MySQL[modifier | modifier le wikicode]

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).


IIS[modifier | modifier le wikicode]

Gestionnaire de serveur Windows 2008.

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[1]. Puis pour ce rôle il faut cocher plusieurs services de rôle :

  • CGI[2] (sous peine d'erreurs 500 à chaque commande PHP).
  • ODBC pour les connexions aux bases de données.
  • ...

Télécharger et installer ensuite le manager PHP[3] pour pouvoir configurer PHP dans :

  • Le Gestionnaire des services Internet (%windir%\system32\inetsrv\InetMgr.exe) sur Windows Server.
  • Les Services Internet sur Windows PC.

Si ensuite IIS renvoie systématiquement des erreurs 500 par la suite (même sans appel PHP), installer Visual C++ 32 bits[4] (PHP ne fonctionne pas en 64 bits en 2016).

CGI ou module ?[modifier | modifier le wikicode]

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.

  1. Dans le répertoire de PHP, trouvez la DLL php5ts.dll, et copiez-la dans le répertoire d'Apache.
  2. Ouvrez ensuite le fichier httpd.conf. On en a déjà parlé plus tôt, vous vous souvenez où il est, n'est-ce pas ?
  3. Dans ce fichier, ajouter cette ligne qui permet à Apache de savoir que l'extension .php concerne l'utilisation du module PHP :
    AddType application/x-httpd-php .php
    
  4. Puis, ajoutez ces deux lignes qui charge et exécute (respectivement) le module PHP5 au démarrage du serveur :
    LoadModule php5_module c:\php\php5apache.dll
    
    AddModule mod_php5.c
    

Enregistrez le fichier httpd.conf et fermez-le.

Composer[modifier | modifier le wikicode]

Composer est un logiciel de gestion des bibliothèques PHP open source.

Installation[modifier | modifier le wikicode]

Pour l'installer il y a trois solutions :

  • Avec les commandes PHP décrites sur https://getcomposer.org/download/.
  • En téléchargeant le package par navigateur à la même adresse.
  • En le téléchargeant avec la commande cURL[5], comme le montre la vidéo suivante :

A la fin il faut juste disposer du fichier composer.phar.

Utilisation[modifier | modifier le wikicode]

Pour le mettre à jour :

php composer.phar update

Pour installer un paquet, par exemple MediaWiki :

php composer.phar require mediawiki/semantic-media-wiki "1.9.*,>=1.9.0.1"

Composer vous 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.

Si l'installation réussit, il ajoute le paquet dans composer.json. La syntaxe JSON de ce fichier contient quelques extensions[6] :

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.

Références[modifier | modifier le wikicode]


Bases du langage

Intégration du code[modifier | modifier le wikicode]

Pour que PHP interprète votre code, vous devez remplir deux conditions :

  1. Votre code doit être placé dans un fichier d'extension .php (selon la configuration du serveur cela peut varier), ouvert via un serveur web en HTTP.
  2. Votre code doit être compris entre deux balises : <?php ... ?>. Tout ce qui n'est pas compris entre ces balises n'est pas interprété par PHP :
<!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>
link={{{link}}}
Attention !

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 :

    <?php
        phpinfo();
    ?>


Il est possible de trouver des extensions de fichiers comme .phtml, .php3 ou autres. Il est cependant conseillé d'utiliser l'extension .php qui garantit son interprétation par PHP.

Les commentaires[modifier | modifier le wikicode]

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. Il existe trois façons différentes d'ajouter des commentaires à son script PHP :

  1. La méthode avec les symboles // pour ajouter un commentaire sur une ligne.
  2. La méthode avec le sigle # pour ajouter un commentaire sur une ligne également.
  3. La méthode avec les caractères /* */ 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 ! */
?>
link={{{link}}}
Attention !

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.

Standardisation des commentaires[modifier | modifier le wikicode]

Les commentaires sont très utiles aux programmeurs, mais se révèlent surtout indispensables lors de travail en équipe. Il existe en outre 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. On peux en effet ajouter des commentaires structurés pour permettre de générer une documentation automatique via PEAR[1] ou phpDocumentor[2]. Exemple[3] :

/*
* 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 commentaires ainsi interprétés (ex : variables après arobase) sont appelés des annotations.

Les directives[modifier | modifier le wikicode]

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

 declare(encoding = "UTF-8");

Références[modifier | modifier le wikicode]


Premier programme

Hello World[modifier | modifier le wikicode]

É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!';"

Dans un fichier[modifier | modifier le wikicode]

Soit le fichier HelloWorld.php ci-dessous, il peut être lancé par :

<!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>

Analyse du code[modifier | modifier le wikicode]

Le terme echo représente une fonction propre à PHP qui a pour rôle d'afficher du texte, mais on peut aussi utiliser la fonction print à la place.

Quant à 'Hello World', il est écrit entre apostrophes pour indiquer qu'il s'agit de texte, mais on peut aussi utiliser des guillemets à la place.

Enfin, le point-virgule (;) sert à indiquer la fin de l'instruction. On peut donc placer plusieurs commandes sur une seule ligne.

Parse error[modifier | modifier le wikicode]

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 :

  • \n : saut de ligne,
  • \t : tabulation,
  • \r : retour de chariot.

Attention : Ces caractères ne sont interprétés par le moteur PHP que s'ils sont introduits à l'aide de double apostrophe (guillemets) :

  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>

Particularités de PHP CLI[modifier | modifier le wikicode]

PHP en ligne de commande possède plusieurs différences avec PHP sur serveur Web :

  • Les variables superglobales sont différentes : il n'y a pas de $_GET, $_POST et $_COOKIE.
  • Les paramètres (après le nom du script) sont récupérables avec $argv, et leur nombre par $argc (ou $_SERVER['argc'] si "register_globals = off;" dans PHP.ini).

Références[modifier | modifier le wikicode]



Variables

Définition[modifier | modifier le wikicode]

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
     _MaVariable  // correct

Exemple[modifier | modifier le wikicode]

  <?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";
  • Pour citer du texte contenant uniquement des apostrophes ou des guillemets, on peut encadrer les uns par les autres :
echo 'Hello "World"!';
  • Pour citer du texte contenant les deux symboles, on peut utiliser le caractère d'échappement "\" :
echo 'Hello \'the\' "World" !';
  • Sinon il existe aussi la syntaxe Heredoc avec l'opérateur "<<<"[1] :
echo <<<Test
 'Hello' "World"!
Test;

Rappel : le caractère ";" indique qu'il s'agit d'une fin de commande, sans celui-ci l'interpréteur PHP ne comprend pas quand se trouve la fin d'une instruction. Le "<?php" et "?>" indique respectivement qu'il s'agit d'un début de code en PHP et de sa fin.

Types de variables[modifier | modifier le wikicode]

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 que $x est un entier
$mot='test' indique que $mot est une chaîne

En PHP il y a donc 4 types de variables scalaires

  • entiers (integer) : nombres naturels sans décimale (sans virgule)
  • réels (float) : nombres décimaux (on parle généralement de type double, car il s'agit de nombre décimaux à double précision)
  • chaînes de caractères (string) : ensembles de caractères
  • booléens (boolean) : true ou false où true = vrai et false = faux en français
  • tableaux (array) : listes d'éléments ordonnés.

Fonctions usuelles sur les chaines[modifier | modifier le wikicode]

  • 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[2]. 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.
  • trim() : supprimer les espaces et retours chariots en début et fin de chaine.
  • strip_tags() : supprime les balises HTML mentionnées en paramètre.
  • ucfirst() : met une majuscule en début de chaine.
  • lcfirst() : met une minuscule en début de chaine.
  • strtoupper() : met en lettres capitales toute la chaine.
  • strtolower() : met en bas de casse toute la 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.

Variables dynamiques[modifier | modifier le wikicode]

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 :

 <?php
   $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 :

 <?php
   $$a="bonjour";
 ?>

est équivalent à : $MaVariable="bonjour";

Autres variables[modifier | modifier le wikicode]

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

Variables d'environnement[modifier | modifier le wikicode]

Accessibles par $_ENV, cette variable est une 'superglobale', ou globale automatique. Cela signifie qu'elle est simplement disponible dans tous les contextes d'exécution (fonctions ou méthodes).

Variables globales[modifier | modifier le wikicode]

$_GLOBAL est une superglobale, l'enregistrement dans cette variable permet de récupérer la valeur n'importe quand.

Variables de sessions[modifier | modifier le wikicode]

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

Lors de la création d'une session (session_start()), il est possible d'enregistrer des variables (par session_register('nom_variable') = $variable ). On peut aussi utiliser le tableau $_SESSION pour créer et modifier une variable de session (par exemple : $_SESSION['ma_variable'] = 3; )

Il est également possible de supprimer les sessions courantes dans le code PHP en utilisant la fonction session_destroy(). La destruction de la session en cours peut aussi se faire par la fermeture du navigateur.

Pour supprimer une variable de session sans supprimer la session entière, il suffit d'utiliser la fonction unset($_SESSION['ma_variable']).

Variables de cookie[modifier | modifier le wikicode]

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

Le tableau $_COOKIE permet de gérer les cookies (définis avec setcookie()[3]). Ces cookies sont d'une très grande importance mais sont limités à 20 dans la configuration par défaut de PHP.

link={{{link}}}Attention !

Ne pas mettre d'informations privées (mots de passe du serveur...) dans ces variables car elles sont stockées dans un fichier non protégé, sur le disque dur de l'utilisateur.

Variables de requêtes[modifier | modifier le wikicode]

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

Variables de fichiers[modifier | modifier le wikicode]

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

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

Exemple :

 $_FILES['nom_fichier']

Variables mixtes[modifier | modifier le wikicode]

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

Variables de serveurs[modifier | modifier le wikicode]

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

'PHP_SELF'
Le nom du fichier du script en cours d'exécution, par rapport à la racine web. Par exemple, $_SERVER['PHP_SELF'] dans le script situé à l'adresse http://www.monsite.com/test.php/foo.bar sera /test.php/foo.bar. La constante __FILE__ contient le chemin complet ainsi que le nom du fichier courant.
'argv'
Tableau des arguments passées au script. Lorsque le script est appelé en ligne de commande, cela donne accès aux arguments, comme en langage C. Lorsque le script est appelé avec la méthode GET, ce tableau contiendra la chaîne de requête.
'argc'
Contient le nombre de paramètres de la ligne de commande passés au script (si le script fonctionne en ligne de commande).
'GATEWAY_INTERFACE'
Numéro de révision de l'interface CGI du serveur : i.e. ' CGI/1.1 '.
'SERVER_NAME'
Le nom du serveur hôte qui exécute le script suivant. Si le script est exécuté sur un hôte virtuel, ce sera la valeur définie pour cet hôte virtuel.
'SERVER_SOFTWARE'
Chaîne d'identification du serveur, qui est donnée dans les en-têtes lors de la réponse aux requêtes.
'SERVER_PROTOCOL'
Nom et révision du protocole de communication : i.e. ' HTTP/1.0 ';
'REQUEST_METHOD'
Méthode de requête utilisée pour accéder à la page; i.e. ' GET ', ' HEAD ', ' POST ', ' PUT '.
'REQUEST_TIME'
Le temps Unix depuis le début de la requête. Disponible depuis PHP 5.1.0.
'QUERY_STRING'
La chaîne de requête, si elle existe, qui est utilisée pour accéder à la page.
'DOCUMENT_ROOT'
La racine sous laquelle le script courant est exécuté, comme défini dans la configuration du serveur.
'HTTP_ACCEPT'
Contenu de l'en-tête Accept: de la requête courante, s'il y en a une.
'HTTP_ACCEPT_CHARSET'
Contenu de l'en-tête Accept-Charset: de la requête courante, si elle existe. Par exemple : ' iso-8859-1,*,utf-8 '.
'HTTP_ACCEPT_ENCODING'
Contenu de l'en-tête Accept-Encoding: de la requête courante, si elle existe. Par exemple : ' gzip '.
'HTTP_ACCEPT_LANGUAGE'
Contenu de l'en-tête Accept-Language: de la requête courante, si elle existe. Par exemple : ' fr '.
'HTTP_CONNECTION'
Contenu de l'en-tête Connection: de la requête courante, si elle existe. Par exemple : ' Keep-Alive '.
'HTTP_HOST'
Contenu de l'en-tête Host: de la requête courante, si elle existe.
'HTTP_REFERER'
L'adresse de la page (si elle existe) qui a conduit le client à la page courante. Cette valeur est affectée par le client, et tous les clients ne le font pas. Certains navigateur permettent même de modifier la valeur de HTTP_REFERER sous forme de fonctionnalité. En bref, ce n'est pas une valeur de confiance.
'HTTP_USER_AGENT'
Contenu de l'en-tête User_Agent: de la requête courante, si elle existe. C'est une chaîne qui décrit le client HTML utilisé pour voir la page courante. Par exemple : Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). Entre autres choses, vous pouvez utiliser cette valeur avec get_browser pour optimiser votre page en fonction des capacités du client.
'HTTP_header'
Valeur de l'en-tête HTTP correspondant envoyé dans la requête du client.
'HTTPS'
Définissez à une valeur non-vide si le script nécessite d'utiliser le protocole HTTPS.
'REMOTE_ADDR'
L'adresse IP du client qui demande la page courante.
'REMOTE_HOST'
Le nom de l'hôte qui lit le script courant. La résolution DNS inverse est basée sur la valeur de REMOTE_ADDR
'REMOTE_PORT'
Le port utilisé par la machine cliente pour communiquer avec le serveur web.
'SCRIPT_FILENAME'
Le chemin absolu vers le fichier contenant le script en cours d'exécution.
'SERVER_ADMIN'
La valeur donnée à la directive SERVER_ADMIN (pour Apache), dans le fichier de configuration. Si le script est exécuté par un hôte virtuel, ce sera la valeur définie par l'hôte virtuel.
'SERVER_PORT'
Le port de la machine serveur utilisé pour les communications. Par défaut, c'est '80'. En utilisant SSL, par exemple, il sera remplacé par le numéro de port HTTP sécurisé.
'SERVER_SIGNATURE'
Chaîne contenant le numéro de version du serveur et le nom d'hôte virtuel, qui sont ajoutés aux pages générées par le serveur, si cette option est activée.
'PATH_TRANSLATED'
Chemin dans le système de fichier (pas le document-root) jusqu'au script courant, une fois que le serveur a fait une traduction chemin virtuel -> réel.
'SCRIPT_NAME'
Contient le nom du script courant. Cela sert lorsque les pages doivent s'appeler elles-mêmes. La constante __FILE__ contient le chemin complet ainsi que le nom du fichier (i.e. inclut) courant.
'REQUEST_URI'
L'URI qui a été fourni pour accéder à cette page. Par exemple : ' /index.html '.
'PHP_AUTH_DIGEST'
Lorsque vous utilisez PHP avec Apache en tant que module faisant une identification HTTP Digest cette variable est définie dans l'en-tête 'Authorization' envoyé par le client (que vous devez donc utiliser pour réaliser la validation appropriée).
'PHP_AUTH_USER'
Lorsque vous utilisez PHP avec Apache ou IIS (ISAPI en PHP 5) en tant que module faisant une identification HTTP, cette variable est définie à l'utilisateur fourni par l'utilisateur.
'PHP_AUTH_PW'
Lorsque vous utilisez PHP avec Apache ou IIS (ISAPI en PHP 5) en tant que module faisant une identification HTTP, cette variable est définie au mot de passe fourni par l'utilisateur.
'AUTH_TYPE'
Lorsque vous utilisez PHP avec Apache en tant que module faisant une identification HTTP, cette variable est définie au type d'identification.

Détection du protocole[modifier | modifier le wikicode]

Pour déterminer si l'utilisateur se connecte en HTTP ou HTTPS à partir des superglobales :

  • $_SERVER['REQUEST_SCHEME'] semble la meilleure option, car renvoie "http" ou "https".
  • $_SERVER['SERVER_PORT'] renvoie 80 ou 443.
  • $_SERVER['HTTPS'] donne true en HTTPS ou null en HTTP (provoque un warning unset).
  • $_SERVER['SERVER_PROTOCOL'] ne convient pas du tout car renvoie "HTTP/1.1" dans les deux cas.
  • $_SERVER['HTTP_X_FORWARDED_PROTO'] et $_SERVER['HTTP_FRONT_END_HTTPS'] : à creuser...

Si ces variables renvoient les caractéristiques HTTP en connexion HTTPS, c'est qu'il faut activer SSL pour le site.

Tester les types[modifier | modifier le wikicode]

Plusieurs fonctions permettent de déterminer les types des objets.

Soit une variable $v :

  • gettype($v) donne son type.
  • is_null($v) teste si un objet est null. Équivaut à "=== null"[4].
  • 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.

Conversions[modifier | modifier le wikicode]

En PHP, il n'y a pas de déclaration de variable selon un type figé. Pour le forcer, il faut donc utiliser les méthodes suivantes.

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

Références[modifier | modifier le wikicode]

  1. http://fr2.php.net/manual/fr/language.types.string.php#language.types.string.syntax.heredoc
  2. http://php.net/manual/fr/function.sprintf.php
  3. http://www.php.net/manual/fr/function.setcookie.php
  4. http://php.net/manual/fr/function.is-null.php



Variables superglobales

Les variables superglobales[modifier | modifier le wikicode]

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.

Voici une liste non-exhaustive (comprenant les cas d'utilisation les plus courants) :

Variables de serveur : $_SERVER[modifier | modifier le wikicode]

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'];

Références[modifier | modifier le wikicode]

  • (fr) Erreur de paramétrage de {{Lien web}} : les paramètres url et titre sont obligatoires.
  • (en) Erreur de paramétrage de {{Lien web}} : les paramètres url et titre sont obligatoires.

Variables d'environnement : $_ENV[modifier | modifier le wikicode]

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 !

Cookies : $_COOKIE[modifier | modifier le wikicode]

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éfinit précédemment, (on prendra Paul encore une fois)

L'exemple ci-dessus va afficher alors :

Exemple

Bonjour Paul !

GET variables : $_GET[modifier | modifier le wikicode]

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 :

Exemple

Bonjour Paul !

POST variables : $_POST[modifier | modifier le wikicode]

Elle stocke les valeurs des informations passées par formulaire avec la méthode="post". Ses clés sont donc par conséquent variables. Voir le cours sur les formulaires.

L'exemple ci dessous est un formulaire comportant un champ de saisie et un bouton de soumission.

Quand un utilisateur soumet des données en cliquant sur "Soumettre", les données du formulaire sont envoyées dans un fichier spécial dans l'attribut d'action de la balise <form>.

Puis, on peut utiliser $_POST pour recueillir la valeur du champ de saisie.


Exemple

<html>
<body>

<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Nom : <input type="text" nom="fnom">
  <input type="soumettre">
</form>

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // collecte la valeur du champ de saisie
    $nom = $_REQUEST['fnom'];
    if (empty($nom)) {
        echo "Le nom est vide";
    } else {
        echo $nom;
    }
}
?>

</body>
</html>

Variables de requête : $_REQUEST[modifier | modifier le wikicode]

Un tableau associatif constitué du contenu des variables $_GET, $_POST, $_COOKIE.

L'exemple ci dessous est un formulaire comportant un champ de saisie et un bouton de soumission.

Quand un utilisateur soumet des données en cliquant sur "Soumettre", les données du formulaire sont envoyées dans un fichier spécial dans l'attribut d'action de la balise <form>.

Puis, on peut utiliser $_REQUEST pour recueillir la valeur du champ de saisie.


Exemple

<html>
<body>

<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Nom : <input type="text" nom="fnom">
  <input type="soumettre">
</form>

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // collecte la valeur du champ de saisie
    $nom = $_REQUEST['fnom'];
    if (empty($nom)) {
        echo "Le nom est vide";
    } else {
        echo $nom;
    }
}
?>

</body>
</html>

Variable de téléchargement : $_FILES[modifier | modifier le wikicode]

Elle stocke les informations sur un fichier envoyé via HTTP par le client. Voir le cours sur les formulaires.

Variables de session : $_SESSION[modifier | modifier le wikicode]

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

Variables globales : $GLOBALS[modifier | modifier le wikicode]

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').


Constantes

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

Nom[modifier | modifier le wikicode]

Le nom d'une constante suit les mêmes règles que celles pour les variables, mis à part que le nom d'une constante n'est pas précédé par $.

<?php
// Noms valides
CONSTANTE1
CONSTANTE2
CONSTANTE_plus

// Noms invalides
0CONSTANTE

?>

Déclaration[modifier | modifier le wikicode]

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]).

Utilisation[modifier | modifier le wikicode]

L'utilisation est similaire à celle des variables.

<?php
  define("CONSTANTE", "Texte ici");
  echo CONSTANTE; // affiche "Texte ici"
?>

En PHP5, 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();
?>

Informations supplémentaires[modifier | modifier le wikicode]

Type de données[modifier | modifier le wikicode]

Une constante, si elle peut être de type booléen, entier, nombre à virgule flottante ou chaîne de caractère, ne peut en aucun cas être un tableau ou un objet. Elle est donc forcément scalaire.

 <?php
 // Le code suivant va générer une erreur
 define ("CONSTANTE", array("a", "b", "c"));
 echo CONSTANTE;
 ?>

Unicité de la déclaration[modifier | modifier le wikicode]

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 not defined("CONSTANTE") {
     //...

Conflit de nom[modifier | modifier le wikicode]

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__

Constantes prédéfinies[modifier | modifier le wikicode]

Il en existe de deux types[3] :

  • fixes en valeur
  • dont la valeur est dynamique

Constantes intégrées à valeur fixe[modifier | modifier le wikicode]

Les constantes suivantes ont des valeurs fixes, comme celles définies avec define :

  • TRUE : vrai (booléen) = 1.
  • FALSE : faux (booléen) = 0.
  • 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.
  • INF : l'infinie.

Constantes intégrées à valeur dynamique[modifier | modifier le wikicode]

Les constantes parfois dites "magiques":

  • __FILE__ : retourne le chemin complet (exemple: /la/ou/est/le/fichier.php) du fichier qui est actuellement exécuté par le serveur.
  • __LINE__ : retourne la ligne du fichier qui est actuellement exécuté par le serveur.
  • __FUNCTION__ : retourne le nom de la fonction dans laquelle on se trouve.
  • __CLASS__ : retourne le nom de la classe dans laquelle on se trouve.

Exemple:

<?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.

Références[modifier | modifier le wikicode]


Opérateurs

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

Opérateurs arithmétiques[modifier | modifier le wikicode]

  • = Opérateur d'affectation
<?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"
?>
  • + : Opérateur d'addition
<?php
$mon_premier_chiffre = 3; //affectation du premier chiffre
$mon_deuxieme_chiffre = 4; //affectation du deuxieme chiffre
$resultat = $mon_premier_chiffre + $mon_deuxieme_chiffre; //affectation de l'addition des deux chiffres
echo $resultat; //affiche 3+4 soit 7
?>
  • - Opérateur de soustraction
<?php
$mon_premier_chiffre = 3; //affectation du premier chiffre
$mon_deuxieme_chiffre = 4; //affectation du deuxieme chiffre
$resultat = $mon_premier_chiffre - $mon_deuxieme_chiffre; //affectation de la soustraction des deux chiffres
echo $resultat; //affiche 3-4 soit -1
?>
  • * Opérateur de multiplication
<?php
$mon_premier_chiffre = 3; //affectation du premier chiffre
$mon_deuxieme_chiffre = 4; //affectation du deuxieme chiffre
$resultat = $mon_premier_chiffre * $mon_deuxieme_chiffre; //affectation de la multiplication des deux chiffres
echo $resultat; //affiche 3*4 soit 12
?>
  • / Opérateur de division
<?php
$mon_premier_chiffre = 3; //affectation du premier chiffre
$mon_deuxieme_chiffre = 4; //affectation du deuxieme chiffre
$resultat = $mon_premier_chiffre / $mon_deuxieme_chiffre; //affectation de la division des deux chiffres
echo $resultat; //affiche 3/4 soit 0,75
?>
  • % Opérateur modulo
<?php
$mon_premier_chiffre = 3; //affectation du premier chiffre
$mon_deuxieme_chiffre = 4; //affectation du deuxieme chiffre
$resultat = $mon_premier_chiffre % $mon_deuxieme_chiffre; //affectation du modulo  des deux chiffres
echo $resultat; //affiche 3 modulo 4 soit 3 (le modulo est le reste de la division euclidienne (sans virgule) )
?>

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

<?php
if ($nb % 3 == 0) { 
 // $nb est un multiple de trois
}
?>

Opérateurs logiques booléens[modifier | modifier le wikicode]

Les opérateurs logiques agissent sur les types booléens (true ou false).

  •  ! : négation. Transforme false en true et true en false.
  • && : opérateur "et".
  • and : opérateur "et" de moindre priorité.
  • || : opérateur "ou"
  • or : opérateur "ou" de moindre priorité.

Opérateurs logiques bit à bit[modifier | modifier le wikicode]

Les opérateurs logiques bit à bit agissent sur chaque bit des valeurs entières.

  • ~ Négation : 0 -> 1 et 1 -> 0
  • & Opérateur et (and)
  • | Opérateur ou (or)
  • ^ Opérateur ou exclusif (xor)

Opérateur d'assignation[modifier | modifier le wikicode]

Ils permettent de simplifier l'écriture des assignations.

  • += additionne deux valeurs et stocke le résultat dans la variable ($x+=5 équivaut à $x=$x+5)
  • -= soustrait deux valeurs et stocke le résultat dans la variable ($x-=5 équivaut à $x=$x-5)
  • *= multiplie deux valeurs et stocke le résultat dans la variable ($x*=5 équivaut à $x=$x*5)
  • /= divise deux valeurs et stocke le résultat dans la variable ($x/=5 équivaut à $x=$x/5)
  •  %= donne le reste de la division de deux valeurs et stocke le résultat dans la variable ($x%=5 équivaut à $x=$x%5)
  • |= effectue un OU logique entre deux valeurs et stocke le résultat dans la variable ($x|=5 équivaut à $x=$x|5)
  • ^= effectue un OU exclusif entre deux valeurs et stocke le résultat dans la variable ($x^=5 équivaut à $x=$x^5)
  • &= effectue un ET logique entre deux valeurs et stocke le résultat dans la variable ($x&=5 équivaut à $x=$x&5)
  • .= concatène deux chaînes et stocke le résultat dans la variable ($x.='test' équivaut à $x=$x.'test')
  •  ??[1] renvoie l'opérande qui le précède s'il existe, sinon l'opérande qui le suit.

Opérateur d'incrémentation[modifier | modifier le wikicode]

  • ++ : incrémente de 1 la valeur de la variable si "$x=1", "$x++" vaut "++$x" qui vaut "2".
  • -- : décrémente de 1 la valeur de la variable si "$x=2", "$x--" vaut "--$x" qui vaut "1".

Ces opérateurs sont très utiles dans les boucles (notamment for).

Opérateur de comparaison[modifier | modifier le wikicode]

  • == renvoie un booléen pour indiquer l'égalité (ce n'est pas =) : $x == 1 teste si la valeur $x est égale à 1.
  • >= renvoie un booléen pour indiquer la supériorité-égalité si $x >= 1 teste si la valeur $x est supérieure ou égale à 1.
  • <= renvoie un booléen pour indiquer l'infériorité-égalité si $x <= 1 teste si la valeur $x est inférieure ou égale à 1.
  • > renvoie un booléen pour indiquer la supériorité stricte si $x > 1 teste si la valeur $x est strictement supérieure à 1.
  • < renvoie un booléen pour indiquer l'infériorité stricte : $x < 1 teste si la valeur $x est strictement inférieure à 1.
  •  != renvoie un booléen pour indiquer la différence : $x != 1 teste si la valeur $x est différente de 1.
  • === renvoie un booléen pour indiquer l'égalité à la fois de la valeur et du type.
  •  !== renvoie un booléen pour indiquer la différence ou de la valeur ou du type.
  • <=>[2] renvoie 1 si le premier opérande est supérieur, 0 s'il est égal, et -1 s'il est inférieur au deuxième.

Opérateur divers[modifier | modifier le wikicode]

Opérateur ternaire[modifier | modifier le wikicode]

L'opérateur ? permet de renvoyer une valeur ou une autre en fonction d'un test. Par exemple :

$appreciation = ($note>10) ? "bon" : "mauvais";

qui est équivalent au bloc PHP suivant :

if ($note>10)
$appreciation="bon";
else
$appreciation="mauvais";

ou

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 à la place. Exemple :

print 1 ?: 0;
// 1

Opérateur objet[modifier | modifier le wikicode]

L'opérateur objet -> permet d'accéder aux propriétés d'un objet. Exemple :

print $voiture->couleur;
$voiture->repeindre('bleu');

Opérateur de résolution de portée[modifier | modifier le wikicode]

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

print $voiture::couleur;

Opérateur de contrôle d'erreur[modifier | modifier le wikicode]

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

Opérateur de référence[modifier | modifier le wikicode]

"&" accolé avant une variable désigne sa référence[3], 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);
}

Précédence des opérateurs[modifier | modifier le wikicode]

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[4].

Références[modifier | modifier le wikicode]


Tableaux

Création de tableau[modifier | modifier le wikicode]

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);
link={{{link}}}
Attention !

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 = array();
 $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 :

  • Le tableau standard, dont la clé est son indice (le numéro de ligne en partant de zéro). Pratique pour être parcouru par une variable compteur, ou pour être rempli dans un certain ordre.
  • Le tableau associatif, auquel on accède par le nom d'une clé en chaine de caractères.


Tableau itératifs[modifier | modifier le wikicode]

Les clés du tableaux sont des nombres. Ils ont l'avantage de pouvoir être parcourus par un compteur.

Exemple

$tab = array('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
Fin du principe


Notez que les indices ne sont pas typés (on pourra indifféremment utiliser $tab[1] et $tab['1']).


Tableaux associatifs[modifier | modifier le wikicode]

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 = array('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 impode(), qui convertit un tableau en chaine avec séparateur :

 print implode(". ", $tab).". ";

Résultat : val1. val2. val3.


Fonctions de lecture[modifier | modifier le wikicode]

  • count : cette fonction renvoie le nombre d'éléments présent dans le tableau.
Début d’un principe
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.
  • array_keys($tab) : 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.

Exemple :

 $tab = array ("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.


Fonctions d'écriture[modifier | modifier le wikicode]

Pour manipuler des tableaux il est indispensable de connaitre les fonctions suivantes :

  • explode($separateur, $tableau) : convertit une chaine de caractères en tableau itératif.
  • implode($separateur, $tableau) : convertit un tableau en chaine de caractères.
  • sizeof($tableau) : renvoie la taille du tableau (le nombre d'objets qu'il contient).
  • 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 une la dernière ligne du tableau, en la renvoyant[3] (dépile).
  • array_shift($monTableau) retire une la première ligne du tableau, en la renvoyant[4].
  • array_merge($monTableau1, $monTableau2, $monTableau3) : fusionne plusieurs tableaux[5].
  • in_array($aiguille, $botteDeFoin) renvoie un booléen si l'élément est trouvé.
  • array_search($aiguille, $botteDeFoin) renvoie la clé de l'élément trouvé, ou NULL sinon.
  • array_unique($tableau) filtre les valeurs en doublon (quelles que soient leurs clés).
  • array_filter($tableau, fonction) filtre les lignes selon fonction exécutée sur chaque élément.
  • array_map(fonction, $tableau) exécute une fonction sur chaque valeur du tableau[6]. Ex : array_map('trim', $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.


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
link={{{link}}}
Attention !

Comme le premier indice du tableau est zéro, le dernier est égal à sa taille moins un.


Joindre les éléments "id" d'un tableau de tableaux

echo implode(', ', array_map(function ($ligne) {
  return $ligne['id'];
}, $tableau));

Tris[modifier | modifier le wikicode]

  • 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.
  • usort($tableau, fonction) : trie selon une fonction donnée[7].
  • ksort($tableau) : trie par clés croissantes.

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" }

Tableaux multi-dimensionnels[modifier | modifier le wikicode]

La clé d’un tableau peut pointer sur un second tableau créant ainsi un tableau multi-dimensionnel.

Début d’un principe
Fin du principe


Résultat :

0-Hubert Gérant : hubert@example.com
1-Jean Réceptionniste : reception@example.com
NB : Dans cet exemple, une base de données serait sûrement plus adéquate.

Références[modifier | modifier le wikicode]


Structures de contrôle

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

if - else[modifier | modifier le wikicode]

La structure la plus simple se présente sous la forme d'un if() {} et d'un else {}. Le if teste une condition :

  • Si elle est réalisée le code entre les accolades après le if sera exécuté, puis le serveur passera au code après le else {} ;
  • Si elle n'est pas réalisée c'est ce qui est entre les accolades suivant le else qui sera exécuté.
<?php
if (condition) { 
 instruction au cas  la condition serait réalisée;
} else {
 instruction au cas  la condition ne serait pas réalisée;
}
?>

Emploi de if seul[modifier | modifier le wikicode]

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  la condition est réalisée;
}
//si la condition n'est pas réalisée, il ne se passe rien
?>

Emploi de elseif[modifier | modifier le wikicode]

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 similaire à un ordre de préférence :

Emploi de elseif
Symboliquement Traduction en code
Soit une condition 1

La condition 1 est elle réalisée ?
OUI 
 code 1 (puis sortie de la structure hypothétique)
NON
 la condition 2 est elle réalisée ?
OUI
 code 2 (puis sortie de la structure hypothétique)
NON
 la condition 3 est elle réalisée ?
OUI
 code 3 (puis sortie de la structure hypothétique)
NON

...

(aucune des conditions annexes n'ont été vérifiées)
Par défaut exécutons le code défaut

<?php
condition 1

if(condition 1)
{ code 1; }
elseif(condition 2)
{ code 2; }
elseif(condition 3)
{ code 3; }

...

else
{ code par défaut; }
?>

Imbrication[modifier | modifier le wikicode]

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.

switch[modifier | modifier le wikicode]

Lorsque l'on teste des conditions en nombre important sur une même valeur, l'utilisation de if est fastidieuse. Il existe bien heureusement une structure créée à cet usage : le switch. On déclare la variable à tester avec switch : switch($surlasellette) {}. Dans ce switch on utilise case pour déclarer la valeur de la variable pour laquelle une action est envisagée : case "valeur" : (ici ne pas oublier les deux points !) une suite d'instructions s'ensuit et est généralement clôturée par break; pour que les autres cas ne soient pas traités à la suite. La valeur par défaut, corollaire du else pour if, est introduite par default :.

Intérêt et emploi de switch
Avec if Traduction en switch
<?php 

$valeur = "testable";
if($valeur == "ce n'est pas cela") 
{echo "ok";}
elseif($valeur == "ce n'est pas non plus cela") 
{echo "ok";}
elseif($valeur == "c'est encore moins cela" or $valeur == "ou cela") 
{echo "ok";}
else
{echo "pas d'accord";}
?>
<?php

switch (variable)
{
case valeur_1 :
instruction(s);
break;
 
case valeur_2 :
instruction(s);
break;

case valeur_3 :
case valeur_4 :
instruction(s);
break;

default : 
instruction(s);
}

switch s'imbrique aussi comme if. Le plus important étant de ne pas oublier de mettre l'instruction break avant un nouveau case.

Opérateur ternaire[modifier | modifier le wikicode]

Une condition à deux opérandes peut aussi être écrite sous la forme abrégée suivante :

$foo = $bar ? $SiVrai : $SiFaux;

Exemple :

print 'Un est plus ' . (1 > 2 ? ' grand' : ' petit') . ' que deux.';



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 trois types :

  1. while() { }
  2. for() {}
  3. foreach() {}

while[modifier | modifier le wikicode]

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);
}

for[modifier | modifier le wikicode]

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;
  }
  • Le premier élément est exécuté au début de la boucle dans tous les cas.
  • Le second élément (la condition) est testé avant chaque exécution de l'instruction ou itération, s'il renvoie TRUE l'instruction sera exécutée, si FALSE est renvoyé on sort de la boucle.
  • La dernière expression est exécutée après chaque itération.

Attention la structure dans la parenthèse est for( ; ; )

foreach[modifier | modifier le wikicode]

Les boucles foreach apparues avec PHP 4, constituent une manière simple de parcourir des tableaux. Il existe deux syntaxes :

  • La plus simple s'intéresse aux clés dans les tableaux. Le type de ces clés dépend des valeurs contenues dans le tableau. foreach simplifie une tache qui aurait certes été possible avec for, mais fastidieuse :
Intérêt de foreach
Avec for Avec foreach
  $array = array('valeur1', 'valeur2', 'valeur3');
  for($i = 0; $i < count($array); $i++) { 
    echo $array[$i]; //renvoie "valeur1valeur2valeur3"
  }
  $array = array('valeur1', 'valeur2', 'valeur3');
  foreach($array as $value) { 
    echo $value; // renvoie "valeur1valeur2valeur3"
  }

as signifiant "comme", on récupère une variable contenant la valeur dans la cellule correspondante.

  • La seconde se penche d'avantage sur les tableaux associatifs du type
  $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.

break et continue[modifier | modifier le wikicode]

Les mots clés :

  • break : sort de la boucle avant la fin.
  • continue : passe immédiatement à l'itération suivante.


Fonctions

Déclaration de fonction[modifier | modifier le wikicode]

PHP permet bien entendu d'écrire ses propres fonctions. Pour déclarer une fonction en PHP, il suffit d’utiliser le mot-clef function. Comme le langage n'est pas 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.

Début d’un principe
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.

Portée des variables[modifier | modifier le wikicode]

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
Fin du principe


Début d’un principe
Fin du principe


Espaces de noms[modifier | modifier le wikicode]

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[1]. 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__;
}
?>
link={{{link}}}Attention !

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';

Références de variables[modifier | modifier le wikicode]

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 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 &)

Les fonctions variables[modifier | modifier le wikicode]

On appelle "fonction variable" une fonction dont on ne peut prédire le nombre d'arguments. Ce genre de fonction pourra se révéler pratique pour exécuter certains codes répétitifs ou le programmeur n'a pas envie de recopier le nom de la fonction pour n valeurs.

Pour cela, il faut retenir deux fonctions importantes :

  • func_num_args : permet de compter le nombre d'arguments (retourne true ou false).
  • func_get_args : permet de récupérer la valeur d’un argument (retourne un tableau de valeur)[2].

Ces deux fonctions ne peuvent s'utiliser qu’à l'intérieur d’une fonction; dans le cas contraire un message d'erreur s'affichera.

Exemple

function afficher_variables ()
{
    $nb_args = func_num_args();
    $list_args = func_get_args();

    for ($i = 0; $i < $nb_args; $i++) {
        echo $list_args[$i].' ';
    }
}
$var1 = 'programmeur';
afficher_variables('Je suis', $var1, ', c\'est utile', ', c\'est intéressant.'); // Et on peut en rajouter autant que nécessaire.

Le code se comprend de lui-même. Il affichera : Je suis programmeur, c’est utile, c’est intéressant.

Fonctions usuelles[modifier | modifier le wikicode]

  • str_replace($ancien, $nouveau, $texte) : remplace des caractères par d'autres dans un un texte[3].
  • str_ireplace($ancien, $nouveau, $texte) : fait la même chose en ignorant la casse.
  • strpos($meubleDeFoin, $aiguille)[4] : position d'une sous-chaine.
  • stripos($meubleDeFoin, $aiguille) : fait la même chose en ignorant la casse.
  • substr($texte, $debut , $fin) : tronque un texte en sous-chaine.
  • max($nombre1, $nombre2, ...)[5] : affiche le plus grand nombre parmi les paramètres.
  • min($nombre1, $nombre2, ...) : fait la même chose avec le minimum.
  • round($nombre) : arrondit un nombre à l'entier le plus proche, ou selon une précision en deuxième paramètre s'il est renseigné[6]. Exemple :
echo round(5.49);  // 5
echo round(5.50);  // 6
  • call_user_func_array('maFonction', 'mesArguments) : exécute une fonction à partir de son nom en chaine de caractères.

Références[modifier | modifier le wikicode]


Dates

date()[modifier | modifier le wikicode]

La fonction date() créer une chaine de caractère contenant la date du jour au format défini par son paramètre, selon la syntaxe suivante[1] :

  • Y (year) : année.
  • m (month) : mois.
  • d (day) : jour.
  • w (week) : jour de la semaine sous forme d'un numéro.
    1. dimanche
    2. lundi
    3. mardi
    4. mercredi
    5. jeudi
    6. vendredi
    7. samedi

Exemple :

echo date('Y-m-d'); // affiche 2016-07-10

A cela on peut rajouter les options d'horodatage les plus courantes :

  • a (ante meridiem ou post meridiem) : renvoie "am" le matin et "pm" l'après-midi.
  • h (hour) : heure de 0 à 12. A utiliser avec "a".
  • H (Hour) : heure de 0 à 24.
  • i (minute) : minute.
  • s (second) : seconde.

Exemple :

echo date('Y-m-d H:i:s'); // affiche 2016-07-10 20:06:34

strtotime()[modifier | modifier le wikicode]

Cette fonction transforme un texte (en anglais) en date[2].

Par exemple, pour afficher la plage des dates de la semaine précédente[3] :

$previous_week = strtotime('-1 week +1 day');

$start_week = strtotime('last monday midnight', $previous_week);
$end_week = strtotime('next sunday', $start_week);

$start_week = date('Y-m-d', $start_week);
$end_week = date('Y-m-d', $end_week);

echo 'La semaine dernière était du '.$start_week.' au '.$end_week;
// Le vendredi 2016-07-29 cela affiche : La semaine dernière était du 2016-07-18 au 2016-07-24

checkdate()[modifier | modifier le wikicode]

Il est impératif dans un formulaire de vérifier si une date est au bon format. Pour ce faire il existe checkdate()[4] qui demande de séparer le mois, le jour puis l'année. Exemple :

var_dump(checkdate(0, 0, 2000)); // false
var_dump(checkdate(1, 1, 2000)); // true

DateTime[modifier | modifier le wikicode]

Cette classe peut être instanciée en style POO ou en style procédural[5]. Exemple :

$date = new DateTime('2018-01-01');
echo $date->format('Y-m-d H:i:s');
// ou
$date = date_create('2018-01-01');
echo date_format($date, 'Y-m-d H:i:s');

Résultat : 2018-01-01 00:00:00.

DateInterval[modifier | modifier le wikicode]

Cette classe gère les intervalles entre deux dates et est instanciée avec les paramètres suivants, dont les majuscules représentent les valeurs sur deux chiffres (ex : "01" au lieu de "1")[6] :

  • p : period (période).
  • y : year (année).
  • m : month (mois).
  • d : day (jour).
  • h : hour (heure).
  • i : minute.
  • s : second (seconde).
  • a : nombre de jours au total.

Exemple :

$dateInterval = new DateInterval('P1Y2M3D');
echo $dateInterval->format('%y an %m mois %d jours');

Résultat : 1 an 2 mois 3 jours.

Les objets de cette classe peuvent aussi être obtenus en calculant la différence entre deux DateTime :

$date1 = new DateTime('2017-01-01');
$date2 = new DateTime('2017-11-01');
$dateInterval = $date2->diff($date1);
echo $dateInterval->format('%a jours');

Résultat : 304 jours.

Timestamps[modifier | modifier le wikicode]

time()[modifier | modifier le wikicode]

Cette fonction affiche la date courante au format horodatage Unix, c'est-à-dire en nombre de seconde depuis le premier janvier 1970.

Ce format permet d'additionner ou soustraire deux dates très facilement, est peut être reconverti en date en étant placé en second paramètre de la fonction date().

mktime()[modifier | modifier le wikicode]

Cette fonction (make time) crée une chaine de caractères contenant un horodatage Unix, c'est-à-dire un nombre de seconde représentant une date comprise en 1970 et 2038.

Exemple de calcul avec strtotime(), qui accepte les timestamps en second paramètre :

$christmasTimeStamp = mktime(0, 0, 0, 12, 25, 2017); // 1514178000
$FirstDayOfNextMonthTimeStamp = strtotime('first day of next month', $christmasTimeStamp); // 1514782800
echo 'Le premier du mois après Noël 2017 est : '.date('Y-m-d', $FirstDayOfNextMonthTimeStamp); // 2018-01-01

Références[modifier | modifier le wikicode]


Sessions

Comme vous le savez, à la fin d'un script PHP, toutes les variables crées sont détruites et il est impossible d'y accéder depuis un autre script. Alors comment faire pour passer des données entres les pages ?

La réponse : les sessions.

C'est en effet la solution la plus simple pour un webmaster afin de garder des informations sur son visiteur.

Un cookie et une session, quelles différences[modifier | modifier le wikicode]

Une session est plus ou moins similaire aux cookies HTTP. Les données d'une session sont cependant stockées sur le serveur et non chez le client, ce qui l'empêche de pouvoir les modifier manuellement, comme il peut le faire pour un cookie.

La durée de vie d'une session[modifier | modifier le wikicode]

Une session est, comme son nom l'indique, une session de navigation. Elle commence donc lors de l'accès à une page les utilisant et se termine à la fermeture du navigateur du client.

Une fois la session terminée, elle est détruite ainsi que toutes les données qu'elle contient. Elle doit donc ne contenir que des données temporaires.

Cependant, la session possède aussi un délai d'expiration. Celui-ci peut être modifié dans la configuration du serveur (directive session.gc_maxlifetime de php.ini), mais vaut généralement une trentaine de minutes. Une fois ce délai dépassé, la session est supprimée.

Comment ça marche ?[modifier | modifier le wikicode]

Lors de l'accès à une page nécessitant une session, PHP va vérifier si une a déjà été ouverte et la réutiliser ou en créer une nouvelle. Il va donc lui attribuer un identifiant unique et se débrouiller pour que la prochaine page consultée puisse le connaître.

Pour cela, il exploite deux fonctionnalités. Premièrement, si l'utilisation de cookie est possible (le client ne les a pas désactivés), PHP crée un cookie contenant l'identifiant de session. Deuxièmement, si les cookies ne sont pas disponibles, il va réécrire les URL de la page pour inclure cet identifiant dans le lien.

Dans les deux cas, le script ayant besoin d'accéder aux données de la session recevra l'identifiant et sera capable de charger les données qu'elle contient.

Est-ce que c’est sécurisé[modifier | modifier le wikicode]

Une session est toujours plus sécurisée qu'un cookie puisque le client ne peut pas la modifier manuellement. Un risque subsiste tout de même si l'identifiant de session peut être découvert.

Par exemple, les cookies transitent sur le réseau en clair. Si quelqu’un est capable d'intercepter les communications entre le client et le serveur, il est capable de voir le cookie et de découvrir l'identifiant de session. Il n'aura alors plus qu’à créer un faux cookie et PHP le prendra pour le pauvre internaute s'étant fait voler son cookie. Pour éviter cela, on peut utiliser une connexion cryptée ou configurer le serveur de façon à ce qu’il rende la lecture de ce cookie impossible par JavaScript (Http Only).

Utiliser les sessions[modifier | modifier le wikicode]

Initialiser une session[modifier | modifier le wikicode]

Pour pouvoir utiliser la fonctionnalité de session de PHP, il faut lancer le moteur de session en utilisant la fonction session_start().

Cette fonction doit être en mesure d'envoyer des headers HTTP, aucune donnée ne doit donc avoir été transmise au navigateur. Vous pouvez soit placer ce code au tout début de votre script, soit utiliser les fonctions de bufférisation de sortie.

Une session portant un nom personnalisé[modifier | modifier le wikicode]

Une session porte par défaut le nom "PHPSESSID", c’est lui qui sera utilisé comme nom de cookie ou comme paramètre GET dans les liens... pas très esthétique. Il peut donc vous venir l'envie de changer ce nom.

Pour cela, la fonction session_name() entre en scène.

Début d’un principe
Fin du principe


Ce code va donc charger une session avec l'identifiant provenant du cookie ou du paramètre GET portant le nom nom_de_session.

Noter la position de l'instruction 'session_start()'. Elle doit se trouver AVANT n’importe quel traitement de votre page '.php' .

Changer manuellement l'identifiant de la session[modifier | modifier le wikicode]

PHP détecte automatiquement l'identifiant à utiliser, cependant, vous pourrez avoir besoin de le changer manuellement, si vous voulez développer un système alternatif pour passer l'identifiant de session entre les pages. Vous pouvez par exemple vous baser sur le hachage (md5() ou sha1()) de l'adresse IP du client pour déterminer l'identifiant de la session. Attention aux proxys et aux internautes dont l'IP change à chaque requête.

Pour définir manuellement l'identifiant de session, la fonction session_id(). Elle prend un paramètre optionnel, qui est le nouvel identifiant de session. Dans tous les cas, la fonction retourne l'identifiant courant de la session.

Exemple

<?php

$identifiant = sha1($_SERVER['REMOTE_ADDR']);
/* Premièrement, nous récupérons l'adresse IP du client,
   puis nous utilisons une fonction de hachage pour
   générer un code valide. En effet, l'identifiant d'une
   session ne peut contenir que des lettres (majuscules
   ou minuscules) et des chiffres. */

$ancien_identifiant = session_id($identifiant);
/* Ensuite, nous modifions manuellement l'identifiant de 
   session en utilisant session_id() et en lui donnant 
   l'identifiant généré plus haut. Comme toujours, la
   fonction retourne l'ancien identifiant, on le place
   dans une variable, au cas où on aurait besoin de le
   réutiliser. */

session_start();
/* On démarre la session, PHP va utiliser le nouvel
   identifiant qu'on lui aura fournis. */

?>
link={{{link}}}Attention !

Dans l'exemple ci-dessus, deux ordinateurs accédant au site par la même adresse IP publique, auront accès à la dernière session ouverte (donc pas forcément la leur).

Lire et écrire des données dans la session[modifier | modifier le wikicode]

Les données de la session sont très facilement accessibles au travers d'un simple tableau PHP. Depuis PHP 4.1.0, vous pouvez utiliser le tableau super-global $_SESSION. Dans les versions plus anciennes, il s'appelait $HTTP_SESSION_VARS et nécessitait le mot clé global pour y accéder depuis une fonction.

Ces tableaux n'existent qu'une fois la session chargée. Tout ce qui est stocké à l'intérieur est sauvegardé et accessible depuis toutes les pages PHP utilisant les sessions.

Exercice : Une zone d'administration protégée par mot de passe[modifier | modifier le wikicode]

Dans cet exercice, nous allons fabriquer pas-à-pas une zone d'administration pour votre site web, protégée par un mot de passe. Nous nous occuperons de la partie identification uniquement.

Dans le chapitre précédent, vous avez également créé le même type de script, mais en utilisant un cookie. Nous allons donc adapter le code en utilisant des sessions à la place.

Le formulaire[modifier | modifier le wikicode]

Voici le code du formulaire en HTML, il va afficher une boîte de texte et un bouton "Connexion".

Début d’un principe
Fin du principe


La page de vérification[modifier | modifier le wikicode]

Le formulaire ci-dessus pointe vers une page nommée verfication.php. Cette page va vérifier que le mot de passe est juste et, si c’est le cas, placer un élément dans le tableau de la session pour que la page suivante puisse vérifier que vous êtes bien autorisé à voir la page.

Premièrement, nous devons initialiser la session. Nous laissons PHP choisir le nom.

Début d’un principe
Fin du principe


L'appel à la fonction session_start() a fabriqué le tableau $_SESSION. Pour l'instant celui-ci est vide.

Il faut maintenant vérifier que le mot de passe fourni est le bon. Nous créons ensuite une entrée dans le tableau de la session contenant true (vrai) si le code est le bon. Nous pouvons alors rediriger le navigateur de l'internaute ou afficher un message d'erreur.

Début d’un principe
Fin du principe


Si vous ne comprenez pas la ligne if($mdp == $_POST['mdp']) {, vous devriez lire (ou relire) le chapitre sur les formulaires.

Pour résumé, le code suivant suffit à l'identification du visiteur :

Début d’un principe
Fin du principe


La page d'administration[modifier | modifier le wikicode]

Cette page doit se nommer admin.php. Si vous décidez d’utiliser un autre nom, il faudra modifier le script d'identification pour qu’il pointe sur la bonne page.

Comme dans l'autre page, nous devons commencer par initier une session.

Début d’un principe
Fin du principe


Nous avons alors accès au tableau $_SESSION.

Si le visiteur a fourni le bon mot de passe, il existe un élément dans le tableau nommé 'admin' et valant true. Dans le cas contraire, cet élément n'existe pas. Il suffit donc de vérifier sa présence pour savoir si le visiteur est réellement l'administrateur du site. Pour cela, nous utilisons la fonction isset() qui vérifie si la variable (ou l'élément du tableau) existe.

Début d’un principe
Fin du principe


La suite du script n'est plus le sujet de cet exercice, le but est en effet atteint. Vérifier l'identité du visiteur pour lui permettre d'accéder à un espace privé.

Fermer une session[modifier | modifier le wikicode]

De la même façon que d'autre fonctionnalités de PHP, comme les connexions aux bases de données ou un pointeur de fichier, les sessions n'ont pas besoin d’être fermée.

Une fois le script PHP terminé, les données de la session sont automatiquement sauvegardée pour le prochaine script.

Cependant, durant toute l'exécution du script, le fichier de la session est verrouillé et aucun autre script ne peut y toucher. Ils doivent donc attendre que le premier arrive à la fin.

Vous pouvez fermer plus rapidement une session en utilisant la fonction session_write_close().

Si vous voulez également détruire la session, vous pouvez utiliser la fonction session_destroy() couplée à la fonction session_unset().


Cookies

Introduction[modifier | modifier le wikicode]

Base de données des cookies Firefox, lue avec SQLite.
Cookie ajouté à Firefox après commande PHP setcookie('wiki', 'user');.

Les cookies sont téléchargés du serveur HTTP sur le PC client, stockés dans le répertoire du navigateur de l'utilisateur courant. Par exemple dans Windows 7[1] :

  1. Firefox : C:\Users\%USERNAME%\AppData\Roaming\Mozilla\Firefox\Profiles\xxxxxxxx.default\cookies.sqlite (lisible par exemple avec https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/).
  2. Chrome C:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Safe Browsing Cookies.
  3. Internet Explorer : C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Cookies.

Ces cookies sont limités à 20 par domaine dans la configuration par défaut de PHP.

link={{{link}}}
Attention !

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.

D'une manière générale, les cookies prennent la forme suivante :

Set-Cookie: nom=nouvelle_valeur; expires=date; path=/; domain=.exemple.org
  • Le chemin (path) permet de ne les rendre opérants que dans certaines parties d'un site.
  • Le domaine fonctionne même avec d'autres serveurs (voir pixel espion).

Syntaxe[modifier | modifier le wikicode]

<?php
  setcookie('cookie1', 'valeur1');
  echo $_COOKIE["cookie1"];
?>

Exemples[modifier | modifier le wikicode]

<?php
  if (isset($_COOKIE["cookie1"])) {
    echo 'Authentifié';
  } else {
    echo 'Non authentifié';
  }
?>

Références[modifier | modifier le wikicode]


Formulaire

Le PHP est un langage de traitement. Une page en php pourra analyser et effectuer des opérations suite à un formulaire. Ce formulaire devra être écrit en HTML, dans une page .html (.htm) ou .php. Pour notre exemple, nous allons créer une page avec laquelle un utilisateur pourra se connecter à une zone administrateur.

Présentation[modifier | modifier le wikicode]

Notre formulaire (form.html) comprendra deux éléments :

  • le champ du mot de passe ("password")
  • un bouton pour soumettre le formulaire

La page de traitement, en PHP (traitement.php) :

  • vérification si le mot de passe est correct
  • envoi d'un cookie. ceci sera la preuve que l'ordinateur distant est autorisé à accéder aux pages

Une page de la zone administration (admin.php) :

  • vérification si l'utilisateur est autorisé à consulter les pages

Le formulaire[modifier | modifier le wikicode]

Le code source présenté ici est uniquement le formulaire. Pour un affichage agréable de la page il est nécessaire de l'"habiller". Voir comment créer une page en HTML. Ce script ne sera pas expliqué. Pour le comprendre vous devez avoir les bases du formulaire en HTML.

Début d’un principe
Fin du principe


En gros, ce formulaire enverra sur la page traitement.php la valeur de l'entrée "mdp".

Le traitement[modifier | modifier le wikicode]

Pour comprendre la suite, vous devez avoir en tête la chose suivante sur les variables. Le champ dont le nom est "mdp" (name=mdp) envoie sur la page de traitement la variable $mdp avec pour valeur l'entrée renseignée.

Pour récupérer les valeurs d'un formulaire on utilise $valeur=$_POST["nomvariable"];

Si vous désirez récupérer les valeurs passée via une URL, par exemple http://www.example.com/index.php?mdp=valeur, on utilise $valeur=$_GET["mdp"];

Il est possible de récupérer directement la valeur d'un formulaire via le nom du champ (dans notre exemple $mdp contiendrait la valeur saisie du formulaire) mais il est fortement conseillé d’utiliser $_POST pour des raisons de sécurité et de compatibilité.

Début d’un principe
Fin du principe


La zone administration[modifier | modifier le wikicode]

La zone administration va vérifier si l'utilisateur est autorisé à consulter ces pages. Il va comparer le mot de passe entré dans le cookie avec le mot de passe réel.

Début d’un principe
Fin du principe


Fichiers

L'utilisation de fichier peut être utile pour exporter des données à archiver ou accélérer un traitement par un système de cache. Cette page explique comment interagir avec un fichier.

Dossiers[modifier | modifier le wikicode]

  • Pour afficher le répertoire courant : dirname(__dir__).
  • Pour changer de dossier : chdir().
  • Pour créer un dossier : mkdir().

Sachant que les systèmes d'exploitation n'ont pas les mêmes séparateurs de dossiers (sous Windows on utilise "\" et en unixerie c'est "/"), on peut utiliser la constante prédéfinie : DIRECTORY_SEPARATOR[1].

Droits des fichiers[modifier | modifier le wikicode]

Windows[modifier | modifier le wikicode]

Sous Windows il suffit de se rendre dans l'onglet sécurité des propriétés d'un fichier, pour cocher les cases autorisant le programme à le lire et/ou le modifier.

Unix[modifier | modifier le wikicode]

chmod est le système de droit d'accès a un fichier Unix. Il s'agit d'un nombre à trois chiffres que l’on attribut à un fichier (ex. : 755). Il détermine le droit d'accès au fichier en question, qui peut le modifier.

Selon sa valeur le système d'exploitation autorise ou non la modification du fichier. Sous GNU/Linux, l'utilisateur 'root', (superutilisateur), a tous les droits, c'est-à-dire qu’il peut modifier tous les fichiers.

Lorsque qu'un fichier est créé manuellement, le chmod du fichier en question est 755, avec un tel chmod nous ne pouvons pas modifier le fichier avec un script PHP. Pour pouvoir le modifier, il suffit juste de changer le chmod du fichier, en lui donnant la valeur 766. Sous Windows, cette notion est masquée et il suffit d’être administrateur de la machine (utilisateur par défaut) pour pouvoir modifier un fichier.

  • Pour récupérer les permissions : fileperms($localFilePath) & 0777
  • Le propriétaire : fileowner($localFilePath))

Ouvrir un fichier[modifier | modifier le wikicode]

Pour déclencher l'ouverture d'un fichier chez celui qui exécute le script, on précise son type puis son emplacement :

header("Content-Type: application/pdf");
header("Content-Disposition: inline; filename='".$fichier."'");

Télécharger un fichier[modifier | modifier le wikicode]

header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename='".$fichier."'");
link={{{link}}}
Attention !

Le téléchargement ne doit pas être précédé d'affichages (ex : echo ou logs de warning) sinon ils apparaitront dans l'en-tête du fichier, le rendant illisible.

Zipper un fichier[modifier | modifier le wikicode]

Cette fonctionnalité est fournie nativement depuis PHP 5.2.0. Pour compresser des fichiers, il faut d'abord créer l'archive vide, puis les y ajouter un par un avec la méthode addFile(Fichier source, Nom du fichier dans l'archive)[2] :

$zip = new ZipArchive();
$f = '../Temp/'.$nomFichier.'.zip';
if ($zip->open($f, ZipArchive::CREATE)!==TRUE) { exit("Impossible de créer le .zip"); }
$zip->addFile('../Temp/'.$nomFichier.'.xls',$nomFichier.'.xls');
$zip->close();

Éditer et fermer un fichier[modifier | modifier le wikicode]

Créer un fichier avec un attribut chmod de 766. Ensuite il faut ouvrir le fichier en question avant de lire/écrire. Pour cela la fonction fopen est là :

Début d’un principe
Fin du principe


Explication : La fonction fopen à besoin de deux paramètres pour pouvoir s'exécuter :

  • $nomFichier, il s'agit du chemin du fichier
  • $mode, il s'agit du mode de l'ouverture

La fonction fopen utilise le premier paramètre, pour déterminer le chemin du fichier a ouvrir/créer.

Voici les différents modes d'ouvertures pour la fonction fopen :

Mode Description
r Ouvre en lecture seule, et place le pointeur de fichier au début du fichier.
r+ Ouvre en lecture et écriture, et place le pointeur de fichier au début du fichier.
w Ouvre en écriture seule, et place le pointeur de fichier au début du fichier et réduit la taille du fichier à 0. Si le fichier n'existe pas, on tente de le créer.
w+ Ouvre en lecture et écriture, et place le pointeur de fichier au début du fichier et réduit la taille du fichier à 0. Si le fichier n'existe pas, on tente de le créer.
a Ouvre en écriture seule, et place le pointeur de fichier à la fin du fichier. Si le fichier n'existe pas, on tente de le créer.
a+ Ouvre en lecture et écriture, et place le pointeur de fichier à la fin du fichier. Si le fichier n'existe pas, on tente de le créer.
x Créé et ouvre le fichier en lecture seule ; place le pointeur de fichier au début du fichier.

Si le fichier existe déjà, fopen() va échouer, en retournant FALSE et en générant une erreur de niveau E_WARNING. Si le fichier n'existe pas, fopen() tente de le créer. Ce mode est l'équivalent des options O_EXCL|O_CREAT pour l'appel système open(2) sous-jacente. Cette option est supportée à partir de PHP 4.3.2 et fonctionne uniquement avec des fichiers locaux.

x+ Crée et ouvre le fichier en lecture et écriture ; place le pointeur de fichier au début du fichier.

Si le fichier existe déjà, fopen() va échouer, en retournant FALSE et en |générant une erreur de niveau E_WARNING. Si le fichier n'existe pas, fopen() tente de le créer.

Pour le fermer maintenant, il y a la fonction fclose.

Début d’un principe
Fin du principe


Copier un fichier[modifier | modifier le wikicode]

if (!copy($ancienFichier, $nouveauFichier)) {
    echo 'La copie a échoué.';
}

Pour les images il existe aussi imagecopyresampled[3].

Supprimer un fichier[modifier | modifier le wikicode]

if (!unlink($fichier)) {
    echo 'La suppression a échoué.';
}

Interagir avec le fichier[modifier | modifier le wikicode]

Lecture[modifier | modifier le wikicode]

Une fois ouvert, il existe plusieurs manière de lire le contenu d'un fichier : caractère par caractère, ligne par ligne, jusqu'à une certaine taille, ou tout entier.

file[modifier | modifier le wikicode]

Pour lire le fichier en entier, utiliser file() :

Début d’un principe
Fin du principe

Ainsi, $fichier[0] correspond à la première ligne, $fichier[1] à la seconde, etc.

fgets[modifier | modifier le wikicode]

La méthode générale pour lire ligne par ligne avec la fonction fgets, dont la définition est la suivante :

Début d’un principe
Fin du principe


La variable $objetFichier doit être le résultat de l'ouverture d'un fichier avec fopen. Pour lire un fichier en entier, il suffit d’utiliser fgets en boucle ; la condition de sortie de la boucle serait alors l'arrivée à la fin de fichier, évènement notifié par la fonction feof.

Exemple de parcours d'un fichier ligne par ligne

<?php
$nomFichier = "chemin_ou_nom_de_fichier";
$objetFichier = fopen($nomFichier, "r"); //ouverture en lecture

if ($objetFichier) {
    //on lit le fichier tant que la fin n'est pas atteinte
    while (!feof($objetFichier)) {
        $ligne = fgets($objetFichier);
        echo $ligne;
    }
    fclose($objetFichier);
}
else
    echo "Erreur : impossible d'ouvrir le fichier.";
?>

fgetc[modifier | modifier le wikicode]

La fonction équivalente pour lire caractère par caractère se nomme fgetc :

Début d’un principe
Fin du principe


Notez que cette fonction retourne FALSE arrivée à la fin du fichier. Lors d'un parcours, il faut donc tester impérativement la valeur avant de l’utiliser, avec un test logique de la forme « $caractere !== FALSE ».

fgetcsv[modifier | modifier le wikicode]

Cette fonction fonctionne comme "fgets" sauf qu'en plus elle utilise le séparateur "," (qui peut être changé par le paramètre "delimiter"[4]) pour créer un sous-tableau de champs par ligne.

Écriture[modifier | modifier le wikicode]

Une fois le fichier ouvert, l'écriture se fait via la fonction fwrite.

Début d’un principe
Fin du principe


Explication :

  • $objetFichier : variable pointant vers un fichier ouvert avec fopen
  • $chaine : la chaîne à écrire dans le fichier
  • retour : le nombre de caractère écrits, ou FALSE si erreur

L'utilisation est alors la même que pour la lecture : ouvrir le fichier, écrire et fermer.

Exemple d'écriture

<?php
$nomFichier = "chemin_ou_nom_de_fichier";
$chaine = "Je suis une chaine écrite par PHP !\n"
$objetFichier = fopen($nomFichier, "w"); //ouverture en lecture

if ($objetFichier) {
    if(fwrite($objetFichier, $chaine) === FALSE) {
       echo "Erreur : impossible d'écrire dans le fichier.";
    }
    fclose($objetFichier);
}
else {
    echo "Erreur : impossible d'ouvrir le fichier.";
}
?>

Attention : Si vous ouvrez le fichier avec l'option w ou w+, le contenu du fichier sera effacé s'il existait. Pour écrire à la fin, il faut ouvrir avec les options a ou a+ (voir ci-dessus). Enfin, si vous pouvez avec l'option r+, le contenu sera écrasé, puisque le pointeur de fichier sera placé au début.


Par ailleurs, la fonction file_put_contents() effectue un fopen(), fwrite() et fclose() successivement[5].

Se déplacer[modifier | modifier le wikicode]

Parfois, il peut être nécessaire de se déplacer dans le fichier, par exemple pour revenir au début. Pour cela, il faut utiliser la fonction fseek comme suit :

Début d’un principe
Fin du principe

Explication :

  • $objetFichier : variable pointant vers un fichier ouvert avec fopen
  • $position : la position à laquelle on veut se déplacer. Pour revenir au début, $position doit valoir zéro.

Pour aller à la fin :

Début d’un principe
Fin du principe


Fichiers uploadés[modifier | modifier le wikicode]

Copier-coller ces lignes dans un fichier vierge upload.php pour qu’il affiche le nom des fichiers qu'on upload avec :

<?php
echo '
<form method="POST" action="upload.php" enctype="multipart/form-data">
     <input type="file" name="fichier">
     <input type="submit" name="envoyer" value="Uploader">
</form>';
if (isset($_FILES['fichier']))
{
  echo $_FILES['fichier']['name'];
}
?>

Pour tester si un fichier ou un dossier local existe, utiliser file_exists()[6].

Fichiers temporaires[modifier | modifier le wikicode]

Pour créer des fichiers qui seront automatiquement détruits en fin de connexion, le dossier temporaire est accessible avec : sys_get_temp_dir().

La fonction tempnam() quant-à elle nomme automatiquement un nouveau fichier temporaire avec un nom unique :

$fileName = tempnam(sys_get_temp_dir(), 'MonFichier1');

Fichiers distants[modifier | modifier le wikicode]

HTTP[modifier | modifier le wikicode]

Pour lire un fichier en HTTP (par exemple cette page web) :

<?php
$page = file_get_contents("http://fr.wikibooks.org/wiki/PHP/Fichiers");
echo $page;
?>

ou[7]

<?php
$url = 'http://fr.wikibooks.org/wiki/PHP/Fichiers';
echo htmlspecialchars(implode('', file($url)));
?>

Pour tester si un fichier distant existe, utiliser get_headers()[8].

 fonctionne aussi bien avec HTTPS.

FTP[modifier | modifier le wikicode]

Déposer un fichier (sans vérifier s'il en écrase un)[9] :

<?php
copy('fichier_local.txt', 'ftp://login:password@server/repertoire/fichier_distant.txt');
?>

Souvent le répertoire porte le nom de l'utilisateur, et on écrase le fichier s'il existe :

<?php
$serveur = 'serveur1';
$login = 'utilisateur1';
$password = 'mdp1';
$fichier = 'fichier1';
copy($fichier, 'ftp://'.$login.':'.$password.'@'.$serveur.'/'.$login.'/'.$fichier, stream_context_create(array('ftp' => array('overwrite'=>True))));
?>

Fonctions propres au FTP, pour lire un serveur distant, y télécharger et déposer des fichiers[10] :

$cnx = ftp_connect($serveur);
$loginResult = ftp_login($cnx, $login, $password);

// Liste des noms des dossiers et fichiers du dossier distant (dans le désordre)
$dossierDistant = ftp_nlist($cnx, ".");
var_dump($dossierDistant);

// Liste des éléments du dossier distant avec leurs inodes
$dossierDistant2 = ftp_rawlist($cnx, ".");
var_dump($dossierDistant2);

// Change de répertoire :
var_dump(ftp_pwd($cnx));
ftp_chdir($cnx, 'tmp');
var_dump(ftp_pwd($cnx));

// Téléchargement du dernier fichier distant
sort($dossierDistant);
$distant = $dossierDistant[sizeof($dossierDistant)-1];
$local = 'FichierLocal.txt';
if (!ftp_get($cnx, $local, $distant, FTP_BINARY)) {
    echo "Erreur ftp_get\n";
} else {
    ftp_delete($cnx, $distant);
}

// Téléversement d'un fichier local
$local = 'FichierLocal2.txt';
if (!ftp_put($cnx, $distant, $local, FTP_ASCII)) {
    echo "Erreur ftp_put\n";
}

Pour définir le timeout, voir ftp_set_option()[11].

SFTP[modifier | modifier le wikicode]

On utiliser les trois fonctions suivantes pour construire l'URL ouverte par fopen[12] :

$connexion = ssh2_connect('tools-login.wmflabs.org', 22);
ssh2_auth_password($connexion, 'monLogin', 'MonMotDePasse');
$sftp = ssh2_sftp($connexion);
$stream = fopen("ssh2.sftp://$sftp/monFichier", 'r');

Extraction regex[modifier | modifier le wikicode]

Pour filtrer le contenu d'un fichier, par exemple récupérer tout ce qui se trouve entre parenthèses dans un tableau, en expressions rationnelles :

$regex = "/\(([^)]*)\)/";
preg_match_all($regex, file_get_contents($nomFichier), $matches);
print_r($matches);

Fichiers binaires[modifier | modifier le wikicode]

Certains fichiers binaires comme les .docx et les .xlsx seront abordés dans les chapitres suivants sur les bibliothèques et frameworks.

Références[modifier | modifier le wikicode]

  1. http://php.net/manual/fr/dir.constants.php
  2. http://php.net/manual/fr/ziparchive.addfile.php
  3. http://php.net//manual/fr/function.imagecopyresampled.php
  4. http://php.net/manual/fr/function.fgetcsv.php
  5. http://php.net/manual/fr/function.file-put-contents.php
  6. http://php.net/manual/fr/function.file-exists.php
  7. developpez.net
  8. http://php.net/manual/fr/function.get-headers.php
  9. http://php.net/manual/fr/book.ftp.php
  10. http://php.net/manual/fr/function.ftp-nlist.php
  11. http://php.net/manual/fr/function.ftp-set-option.php
  12. http://php.net/manual/fr/function.ssh2-sftp.php



Objets COM

Installation[modifier | modifier le wikicode]

Le système d'exploitation Windows fournit des objets COM (Component Object Model) pour manipuler des fichiers dans divers langages de programmation dont PHP.

Le serveur Web IIS charge déjà ce composant par défaut, pour Apache par contre il faut l'ajouter au php.ini : extension=php_com_dotnet.dll.

Pour être sûr qu'il soit activé ensuite, on peut utiliser[1] :

 ini_set('com.allow_dcom','1');

Exemple[modifier | modifier le wikicode]

Création d'un .xls :

$Excel = new COM('excel.application');
$Classeur = $Excel->Workbooks->Add();
$Feuille = $Classeur->Worksheets(1);
$Cellule = $Feuille->Cells(1,1);

$Cellule->Value = 'Hello World!';

$Classeur->SaveAs('Monclasseur.xls');
$Classeur->Close();
$Excel->Quit();

On peut aussi créer des .doc.

Références[modifier | modifier le wikicode]


Images

Introduction[modifier | modifier le wikicode]

PHP peut créer et modifier dynamiquement des images, par exemple avec la bibliothèque GD, inclue depuis PHP 3.0.

La création d'une nouvelle image se déroule généralement ainsi :

  1. Chargement en mémoire d'une image, nouvelle ou existante.
  2. Chargement éventuel des couleurs à y apporter.
  3. Modifications éventuelles de ses composants (création de lignes, points, remplissages, ajout de textes...).
  4. Restitution de l'image après avoir posté son type dans l'en-tête.
  5. Libération mémoire.

Créer une nouvelle image[modifier | modifier le wikicode]

Pour créer une image ex-nihilo, on utilise la fonction :

imagecreatetruecolor($hauteur, $largeur)

qui crée en mémoire une nouvelle image de hauteur et largeur définies en pixel, et restitue une référence à l'image crée.

Il existe aussi une autre fonction pour cela, mais elle n'est pas recommandée car son amplitude de couleurs est moindre[1] :

imagecreate($largeur, $hauteur)

Pour charger en mémoire une image sauvegardée sur le disque :

imagecreatefrom<type>($chemin)

Exemple :

$img = imagecreatefrompng('image.png');

Autre fonction :

imagecreatefromstring($texte)

qui crée une image à partir de son format texte, spécifié en paramètre.

S'il survient une erreur, ces fonctions renvoient false.

Travailler avec les couleurs[modifier | modifier le wikicode]

Pour allouer une couleur il faut en définir les paramètres RVB :

$couleur = imagecolorallocate($image, $r, $v, $b)

Pour définir une transparence dans un PNG :

imagecolortransparent($image, $couleur)

$couleur est le résultat de imagecolorallocate.

Il est également possible de déterminer la transparence, comprise entre 0 et 127 (qui représente la transparence totale) à l'aide de la fonction :

imagecolorallocatealpha($image, $r, $v, $b, $transparence)
 la première couleur allouée définit le fond de toute l'image.

Sinon, un fond transparent peut également être assuré par les deux fonctions ci-dessous :

    imageAlphaBlending($image, false);
    imageSaveAlpha($image, true);

Une fois l'image créée et colorisée, on peut y appliquer les opérations :

  • Dessiner des pixels (ex : créer des lignes).
  • Travailler sur les pixels existants en désignant des zones.

Dessiner des formes[modifier | modifier le wikicode]

Pour dessiner un pixel, on utilise ses coordonnées (x, y ci-dessous) :

imagesetpixel(image, x, y, couleur)

Pour tracer une ligne entre deux points :

imageline(image, x1, y1, x2, y2, couleur)

Pour créer un rectangle par sa diagonale :

imagerectangle(image, x1, y1, x2, y2, couleur)

Pour représenter une ellipse par son centre, sa hauteur et sa largeur :

imageellipse(image, x, y, h, l, couleur)

ou en précisant son arc par ses angles en gradient (numérotés dans le sens horaire) :

imagearc(image, x, y, h, l, angle1, angle2, couleur)

Retravailler les pixels existants[modifier | modifier le wikicode]

Une des fonctions les plus utilisées pour retravailler des images comme des photos, est certainement imagecopyresized, qui permet de copier une zone rectangulaire pour la coller dans une autre image[2]. Exemple :

imagecopyresized(dst_image, src_image, dst_x, dst_y, src_x, src_y, dst_w, dst_h, src_w, src_h);

où :

  • src_image est l'image source ;
  • dst_image est l'image de destination ;
  • dst_x, dst_y sont les coordonnées de dst_image ;
  • src_x, src_y sont les coordonnées de src_image en partant d'en haut à gauche ;
  • dst_w, dst_h, src_w, src_h sont les largeurs et hauteurs des rectangles de source et destination.

On peut ensuite comprendre que si dst_w est égal à src_w, et dst_h à src_h, la portion rectangulaire de l'image restera de la même taille. Dans le cas contraire on allonge ou on élargit.

La fonction imagecopyresampled reçoit les mêmes paramètres que imagecopyresized, mais avec la différence que, en cas de redimensionnement, la qualité est améliorée.

Puis il existe la fonction imagefilter, qui permet de nombreux effets tels que les niveaux de gris, le relief, ou la recoloration[3].

Imprimer l'output[modifier | modifier le wikicode]

Le format de l'image obtenue ("png", "jpeg" ou "gif") peut être spécifié par la fonction header, via le content-type (par défaut text/html) ainsi :

header("Content-type: image/<type>");

Pour visualiser l'image ensuite, la placer en paramètre dans une fonction dépendant de son type : imagepng, imagejpeg ou imagegif.

Puis, libérer la mémoire avec imagedestroy($image). Cette étape facultative est particulièrement recommandée pour les images volumineuses.

Exemple[modifier | modifier le wikicode]

Le code suivant affiche dans le navigateur, un carré rouge de 50 pixels dans un noir de 100.

$image = imagecreatetruecolor(100, 100);
$couleur = imagecolorallocate($image, 255, 0, 0);
imagefilledrectangle($image,0,0,50,50,$couleur);
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);

Références[modifier | modifier le wikicode]


Mails

Mail()[modifier | modifier le wikicode]

Le code suivant se connecte à localhost:25 pour envoyer un mail[1] :

<?php
     $to      = 'Destinataire@gmail.com';
     $subject = 'Sujet du mail';
     $message = 'Contenu du message';
     $headers = 'From: Expediteur@gmail.com' . "\r\n" .
       'Reply-To: Expediteur@gmail.com' . "\r\n" .
       'X-Mailer: PHP/' . phpversion();
     mail($to, $subject, $message, $headers);
?>

Si la machine hébergeant le script n'est pas pourvue d'un serveur SMTP, le freeware portable Simple Mail Server[2] peut jouer ce rôle rapidement sans installation.

Utilisation de Mail() plus complexe...[modifier | modifier le wikicode]

Exemple

<?php
$mail = 'test@test.fr'; // Déclaration de l'adresse de destination.
if (!preg_match("#^[a-z0-9._-]+@(hotmail|live|msn).[a-z]{2,4}$#", $mail)) // On filtre les serveurs qui rencontrent des bogues.
{
	$passage_ligne = "\r\n";
}
else
{
	$passage_ligne = "\n";
}
//=====Déclaration des messages au format texte et au format HTML.
$message_txt = "Bonjour, voici un e-mail envoyé par un script PHP.";
$message_html = "<html><head></head><body><b>Bonjour</b>, voici un e-mail envoyé par un <i>script PHP</i>.</body></html>";
//==========
 
//=====Création de la boundary
$boundary = "-----=".md5(rand());
//==========
 
//=====Définition du sujet.
$sujet = "Hey mon ami !";
//=========
 
//=====Création du header de l'e-mail.
$header = "From: \"WeaponsB\"<test@test.fr>".$passage_ligne;
$header.= "Reply-to: \"WeaponsB\" <test@test.fr>".$passage_ligne;
$header.= "MIME-Version: 1.0".$passage_ligne;
$header.= "Content-Type: multipart/alternative;".$passage_ligne." boundary=\"$boundary\"".$passage_ligne;
//==========
 
//=====Création du message.
$message = $passage_ligne."--".$boundary.$passage_ligne;
//=====Ajout du message au format texte.
$message.= "Content-Type: text/plain; charset=\"ISO-8859-1\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: 8bit".$passage_ligne;
$message.= $passage_ligne.$message_txt.$passage_ligne;
//==========
$message.= $passage_ligne."--".$boundary.$passage_ligne;
//=====Ajout du message au format HTML
$message.= "Content-Type: text/html; charset=\"ISO-8859-1\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: 8bit".$passage_ligne;
$message.= $passage_ligne.$message_html.$passage_ligne;
//==========
$message.= $passage_ligne."--".$boundary."--".$passage_ligne;
$message.= $passage_ligne."--".$boundary."--".$passage_ligne;
//==========
 
//=====Envoi de l'e-mail.
mail($mail,$sujet,$message,$header);
//==========
?>

Explication:

  • Ouverture boundary.(sert à séparer les différentes parties de notre e-mail)
  • Déclaration de type (exemple texte, par défaut les clients mail tentent de convertir l'HTML en texte).
  • Texte.
  • Ouverture boundary.
  • Déclaration de type (exemple HTML,par défaut les clients mail tentent de convertir l'HTML en texte)).
  • HTML.
  • Fermeture boundary.
  • Fermeture boundary.


Avec la mise en place de pièce jointe[modifier | modifier le wikicode]

Exemple

<?php
$mail = 'test@test.fr'; // Déclaration de l'adresse de destination.
if (!preg_match("#^[a-z0-9._-]+@(hotmail|live|msn).[a-z]{2,4}$#", $mail)) // On filtre les serveurs qui présentent des bogues.
{
	$passage_ligne = "\r\n";
}
else
{
	$passage_ligne = "\n";
}
//=====Déclaration des messages au format texte et au format HTML.
$message_txt = "Bonjour, voici un e-mail envoyé par un script PHP.";
$message_html = "<html><head></head><body><b>Bonjour</b>, voici un e-mail envoyé par un <i>script PHP</i>.</body></html>";
//==========
 
//=====Lecture et mise en forme de la pièce jointe.
$fichier   = fopen("background.jpg", "r");
$attachement = fread($fichier, filesize("background.jpg"));
$attachement = chunk_split(base64_encode($attachement));
fclose($fichier);
//==========
 
//=====Création de la boundary.
$boundary = "-----=".md5(rand());
$boundary_alt = "-----=".md5(rand());
//==========
 
//=====Définition du sujet.
$sujet = "Fichier important";
//=========
 
//=====Création du header de l'e-mail.
$header = "From: \"WeaponsB\"<test@test.fr>".$passage_ligne;
$header.= "Reply-to: \"WeaponsB\" <weaponsb@mail.fr>".$passage_ligne;
$header.= "MIME-Version: 1.0".$passage_ligne;
$header.= "Content-Type: multipart/mixed;".$passage_ligne." boundary=\"$boundary\"".$passage_ligne;
//==========
 
//=====Création du message.
$message = $passage_ligne."--".$boundary.$passage_ligne;
$message.= "Content-Type: multipart/alternative;".$passage_ligne." boundary=\"$boundary_alt\"".$passage_ligne;
$message.= $passage_ligne."--".$boundary_alt.$passage_ligne;
//=====Ajout du message au format texte.
$message.= "Content-Type: text/plain; charset=\"ISO-8859-1\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: 8bit".$passage_ligne;
$message.= $passage_ligne.$message_txt.$passage_ligne;
//==========
 
$message.= $passage_ligne."--".$boundary_alt.$passage_ligne;
 
//=====Ajout du message au format HTML.
$message.= "Content-Type: text/html; charset=\"ISO-8859-1\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: 8bit".$passage_ligne;
$message.= $passage_ligne.$message_html.$passage_ligne;
//==========
 
//=====On ferme la boundary alternative.
$message.= $passage_ligne."--".$boundary_alt."--".$passage_ligne;
//==========
 
 
 
$message.= $passage_ligne."--".$boundary.$passage_ligne;
 
//=====Ajout de la pièce jointe.
$message.= "Content-Type: image/jpeg; name=\"background.jpg\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: base64".$passage_ligne;
$message.= "Content-Disposition: attachment; filename=\"background.jpg\"".$passage_ligne;
$message.= $passage_ligne.$attachement.$passage_ligne.$passage_ligne;
$message.= $passage_ligne."--".$boundary."--".$passage_ligne; 
//========== 
//=====Envoi de l'e-mail.
mail($mail,$sujet,$message,$header);
 
//==========
?>

Explication:

  • Ouverture boundary.
  • Déclaration du nouveau content-type et de la seconde boundary.
  • Ouverture boundary_2.
  • Déclaration de type (exemple texte).

Texte.

  • Ouverture boundary_2.
  • Déclaration de type (exemple HTML).

HTML.

  • Fermeture boundary_2.
  • Ouverture boundary.
  • Déclaration de la pièce jointe 1.
  • Ouverture boundary.
  • Déclaration de la pièce jointe 2.
  • Ouverture boundary.
  • Déclaration de la pièce jointe [...].
  • Ouverture boundary.
  • Déclaration de la pièce jointe n.
  • Fermeture boundary.

Bibliothèques[modifier | modifier le wikicode]

Ce livre abordera dans un chapitre ultérieur, des bibliothèques contenant des fonctions d'envoi d'email permettant plus d'options dans une syntaxe nettement plus concise :

Références[modifier | modifier le wikicode]



Programmation orientée objet

Introduction[modifier | modifier le wikicode]

Une classe est un format de variable non scalaire, comprenant trois types de composants :

  1. des constantes, accessibles par réflexion avec $maClasse::getConstants().
  2. des variables appelées "propriétés", accessibles avec $maClasse::getProperties().
  3. des fonctions appelées "méthodes", accessibles avec $maClasse::getMethods().

La programmation orientée objet s’effectue en deux étapes : la définition des classes, puis leur utilisation. Une fois la classe définie, il est en effet possible de créer des objets, appelés "instances", au format de la classe définie. Toutefois, les composants déclaré avec le mot "static" sont persistants, et accessibles sans instanciation préalable.

Par ailleurs, le mot-clé static peut aussi être utilisé avant l'opérateur de résolution de portée ::, pour accéder aux propriétés statiques d'une méthode. Au passage, cet opérateur peut également être précédés de noms de classes ou des mots réservés this, parent, et self[1]

Définition des classes[modifier | modifier le wikicode]

A l'instar d'une bibliothèque de fonctions, une classe est généralement stockée dans un fichier dédié, qui peut porter son nom.

Elle s'inclut donc dans un programme de la même manière qu'une bibliothèque :

include('ma_classe.php');
//ou
require('ma_classe.php');
//ou
require_once('ma_classe.php');

Toutefois, son code n'est pas pour autant utilisable car il faut d'abord l'instancier.

link={{{link}}}
Attention !

En PHP, l'inclusion doit précéder les appels du code qui y figure.

Par défaut, PHP fournit déjà la classe suivante pour créer des objets anonymes :

$c = new stdClass();
var_dump($c);

Définir une nouvelle classe adopte la syntaxe suivante :

class nomObjet
{
  var $variable1;
  var $variable2;
  ...


  function maFonction1()
  {
    ...code
  }

  function maFonction2()
  {

  }

}

Il est possible d’attribuer une valeur par défaut. Le code dans la classe est alors var $variable1 = valeur;.

La définition de méthodes de classe est identique à celle de n’importe quelle fonction à la différence que lorsqu’elle fait référence à une variable de sa classe, $variable doit être :

  • $this->variable pour cibler l'objet instancié (et $this::constante, $this->méthode()).
  • self::variable pour cibler la classe statique.


De même pour exécuter une autre méthode de sa classe. ex :

class client
{
  var $aDitBonjour = false;

  function direBonjour()
  {
    $this->message("Bonjour");
  }

  function message($message)
  {
    echo $message;
    $this->aDitBonjour = true;
  }

}

Pour utiliser une variable qui n'est pas dans la classe ou exécuter les méthodes d'une autre classe, il faut les redéclarer avec global :

class client
{
  function message($message)
  {
    global $InstanceAutreClasse
    $InstanceAutreClasse->aDitBonjour = true;
  }

}

Utilisation d’un objet[modifier | modifier le wikicode]

Attention : la classe est la définition d’un format de variable personnalisable. Le code n’est pas exécuté et il est impensable d’introduire le code suivant qui n’aurait aucun sens :

class client
{

   for ($i=0; $i<5; $i++)
   echo "$i\n";

}

Une fois la classe définie, il va falloir créer des variables objet du format de la classe définie. On crée un objet par le code suivant :

$objet = new client();

Il faut bien entendu avoir préalablement défini la classe client. La variable $objet contient donc un objet. Pour accéder à une variable pour lui faire subir des modifications, il suffit d’entrer le code suivant :

$objet->variable1 = "Hello world";

Il est possible de lui faire subir les mêmes opérations qu’à une variable normale. De même pour exécuter une fonction :

$objet->maFonction();

Autant les méthodes une fois définies ne peuvent pas être modifiées, autant il est possible d’ajouter ou de supprimer des variables dans l’objet :

$objet->variable = "valeur"; // définition de variable

unset($objet->variable); // suppressions

L’objet est unique, de sorte que s’il est enregistré dans une autre variable et qu’une modification lui est faite, elle sera visible pour les deux variables :

//Le code reprend l'ancien script

$objet = new client();
$objet2 = $objet;
$objet2->direBonjour();
echo $objet->aDitBonjour;

//affiche true

Pour dupliquer une variable, il faut donc entrer le code suivant :

$objet2 = clone $objet;

La nouvelle variable sera différente de l’ancienne mais aura les mêmes valeurs.


Il est également possible d'exécuter la méthode d'un objet sans avoir créé de variable auparavant :

class Message
{
   function direBonjour()
   {
     echo "salut";
   }
}


/* Exécute la méthode */
Message::direBonjour();

Héritage[modifier | modifier le wikicode]

PHP était initialement un langage à héritage simple[2], c'est-à-dire qu'une classe ne peut hériter que d'au plus une seule autre classe.

L'héritage consiste à transmettre les propriétés et méthodes d’une classe mère à une classe fille, en déclarant cette dernière avec extends. Ex :

class parent {
  var $varParent;

  function fonctionParent() {
    print 'Je connais fonctionParent';
  }
}

class enfant extends parent {
  var $varEnfant;

  function fonctionEnfant() {
    print 'Je connais fonctionEnfant';
  }
}

$Enfant1 = new enfant();
$Enfant1->fonctionParent();

L'héritage permet le polymorphisme, qui consiste à utiliser des variables ou méthodes dans des classes de plusieurs types, grâce à l'héritage.

Les classes filles bénéficieront automatiquement de toutes les propriétés et des méthodes de leur classe mère (qui n'a pas de limite dans le nombre de ses filles[3]).

link={{{link}}}Attention !

Les interfaces peuvent par contre bénéficier d'un héritage multiple.

Traits[modifier | modifier le wikicode]

Depuis PHP 5.4.0, une structure de données appelée "trait" permet l'héritage multiple. Exemple d'utilisation :

<?php
trait MonTrait1
{
	function Hello() {
		print 'Hello';
	}
}

trait MonTrait2
{
	function World() {
		print 'World';
	}
}

class MaClasse1
{
	use MonTrait1;
	use MonTrait2;
	
	function __construct() {
		$this->Hello();
		$this->World();
	}
}

$Test = new MaClasse1;
?>

Classes abstraites[modifier | modifier le wikicode]

Voici un exemple de classe abstraite :

class abstract MaClasseAbstraite {
  public $var="Bonjour";
  abstract public function MaMethode($var1, $var2);
}
link={{{link}}}Attention !
  • Les méthodes d'une classe abstraite peuvent contenir du code, mais les méthodes abstraites non (elles ne définissent que les arguments[4]).

Closures[modifier | modifier le wikicode]

Apparues avec PHP 5.3[5], les closures sont des classes avec des méthodes gérant les fonctions anonymes.

Classes anonymes[modifier | modifier le wikicode]

Apparues avec PHP 7[6], les classes anonymes sont des classes sans nom, déclarées lors de l'exécution.

Interfaces[modifier | modifier le wikicode]

Voici un exemple d'interface :

interface MonInterface
{
   public function setName($name);
   public function getName();
}

Et son utilisation : la classe doit reprendre les méthodes de l'interface sous peine d'erreur.

class MaClasse implements MonInterface
{
   private $NOM;

   public function setName($name){
     print 'Définition de '.$name;
     $NOM = $name;
   }

   public function getName(){
     print 'Récupération de '.$NOM;
   }
}
link={{{link}}}Attention !
  • Les méthodes d'une interface ne peuvent pas contenir de code.
  • Une classe ou une interface ne peut implémenter qu'une ou plusieurs interfaces (donc pas d'implémentation de classe).
  • Une interface ne peut hériter que d'une autre interface[7].
  • Toutes les méthodes d'une interface doivent être publiques.
  • Si un objet hérite et implémente, toujours le déclarer en plaçant le extends avant le implements.

Namespaces[modifier | modifier le wikicode]

Exemple d'espace de noms :

namespace MonEspace\Nom;

class MaClasse {}
function MaMethode() {}
const MYCONST = 1;

$a = new MaClasse;
$c = new \MonEspace\Nom\MaClasse;
$d = new \ClasseGlobale;

Pour utiliser un namespace, "use" conserve son nom mais on peut le changer avec "as" :

use MonEspace\Nom;
use SonEspace\Nom as NomExterne;

Portée des variables[modifier | modifier le wikicode]

Il est possible depuis PHP5 de préciser l'accès à certaines variables ou méthodes, en les déclarant à la place de var avec :

  • public : visible dans tout le programme.
  • protected : visible uniquement dans les instances de la classe et de ses sous-classes.
  • private : visible uniquement dans les instances de la classe.

Exemple :

class CompteEnBanque
{

  private $argent = 0;

  private function ajouterArgent($valeur)
  {
    $this->argent += $valeur;
  }

  function gagnerArgent($valeur)
  {
    $this->ajouterArgent($valeur);
  }
}


$compte = new CompteEnBanque()

//les actions suivantes sont impossibles :

$compte->argent = 3000;
$compte->ajouterArgent(3000);

//l'action suivante est possible

$compte->gagnerArgent(3000);

En effet, il faut gagner de l’argent avant d’en ajouter à la banque (quoique...).

link={{{link}}}Attention !

Ce code retournera un message d’erreur s'il est exécuté sous PHP5 ou une version ultérieure.

Les méthodes prédéfinies[modifier | modifier le wikicode]

Il existe quelques méthodes prédéfinies qui s’exécutent automatiquement à des périodes de la vie de l’objet. Elles sont appelées méthodes magiques[8], et leurs noms commencent toujours par deux underscores :

  1. __call()
  2. __callStatic()
  3. __clone()
  4. __construct()
  5. __debugInfo()
  6. __destruct()
  7. __get()
  8. __invoke()
  9. __isset()
  10. __set()
  11. __set_state()
  12. __sleep()
  13. __toString()
  14. __unset()
  15. __wakeup()

Constructeur et destructeur[modifier | modifier le wikicode]

__construct() 
Cette méthode s’exécute lors de la création de l’objet. On entre alors les attributs potentiels de la fonction lors de sa création. Cette méthode est appelée "le constructeur"
__destruct() 
Cette méthode s’exécute au contraire au moment de la destruction de la variable. Elle est appelée "le destructeur".

Voici un exemple utilisant les méthodes :

//Définition de la classe

class Humain
{
  public $homme = false;
  public $femme = false;

  function __construct($type)
  {
    if ($type=="homme")
      $this->homme=true;
    if ($type=="femme")
      $this->femme=true;
  }

  function extremeOnction()
  {
     echo 'Amen';
  }
 

  function __destruct()
  {
    $this->extremeOnction();
  }

}


//C'est un garçon !
$homme = new Humain("homme");

if ($homme->homme)
{
  echo "C'est un homme";
}
elseif ($homme->femme)
{
  echo "C'est une femme";
}

//mort de l'homme
unset($homme);


/*
La sortie sera

C'est un homme
Amen
*/

Sous php4, le constructeur avait pour nom celui de la classe. Sous php5, si la fonction __construct() n’est pas trouvée, l’interpréteur cherchera une méthode du même nom que la classe.

Copie en profondeur[modifier | modifier le wikicode]

Il existe une méthode qui s’exécute lors d’une duplication de l’objet. Son nom est __clone().

En effet, elle est utile car par défaut si $x = $y, $x n'est qu'une référence à $y et changer $x changera $y.

__get, __set, __call[modifier | modifier le wikicode]

Ces méthodes permettent de rendre dynamique l'utilisation de la classe, et permettent la surcharge magique[9].

__call()[modifier | modifier le wikicode]

La méthode __call() s'exécute quand une méthode appelée est inaccessible ou inexistante. Exemple :

	function __call($method,$arguments) {
		 echo "On a appelé $method sans succès avec les paramètres :<br/>";
		 var_dump($arguments);
	}

_get()[modifier | modifier le wikicode]

Cette méthode s'exécute quand une variable appelée est inaccessible ou inexistante. L'exemple ci-dessous lui permet de retourner une donnée dépendant du contenu de la variable $nom. Important : le contenu de la variable $nom ne sera pas prioritaire sur le nom d'une variable interne à la classe.

class test {
	public $a;
	private $b;

	function __construct($a,$b) {
	  $this->a=$a;
	  $this->b=$b;
	}

	function __get($nom) {
	  echo "On a appelé __get(\$$nom)";
	}
}

// Utilisation
$var=new test(5,10);

echo $var->a; // affiche : "5"
echo '<br/>';
echo $var->b; // affiche : "On a appelé __get($b)". En effet, b est privée et ne peut donc pas être accédée.
echo '<br/>';
echo $var->__get('a'); // affiche : "On a appelé __get($a)"
echo '<br/>';
echo $var->c; // affiche : "On a appelé __get($c)"

On voit ici que PHP va chercher en priorité à retourner une variable interne, mais si elle est privée ou inexistante, il prendra le résultat du __get.

link={{{link}}}Attention !

Ne jamais accéder à une variable de classe privée dans son __get() sous peine de boucle infinie.

Exemple de réécriture de la méthode __get ci-dessus pour accéder à la variable privée :

function __get($nom) {
  if ($nom == 'b') { echo $this->b; }
}

__set()[modifier | modifier le wikicode]

Cette méthode s'exécute quand on modifie une variable inaccessible ou inexistante. Exemple :

class test2 {
  public $a;
  private $b;
  function __construct($a,$b) {
    $this->a=$a;
    $this->b=$b;
  }
  function __get($nom) {
	echo 'get '.$nom;echo '<br/>';
  }
  function __set($nom,$value) {
	echo 'set '.$nom.' '.$value;echo '<br/>';
  }
}

$var=new test2(5,10);
$var->a=6;
echo $var->a;	// affiche 6
echo '<br/>';
$var->b=11;		// appelle __set('b',11)
echo $var->b;	// appelle __get('b')

__autoload()[modifier | modifier le wikicode]

Cette méthode se déclenche lors de l'autochargement, c'est-à-dire quand le programme charge une autre classe (lors de son instanciation ou invocation statique). Elle permet donc de lever les exceptions si par exemple la classe demandée n'existe pas.

Le code ci-dessous affiche :

  • Avant PHP 5.3.0, Fatal error: Class 'ClasseDistante' not found in C:\Program Files (x86)\EasyPHP\data\localweb\WL.php on line 7.
  • Après, ClasseDistante est introuvable !
<?php
function __autoload($ClasseDistante) {
	throw new Exception($ClasseDistante . ' est introuvable !');
}

try {
  $ClasseDistante1 = new ClasseDistante();
} catch (Exception $ex) {
  echo $ex->getMessage(), "<br/>";
}

try {
  $ClasseDistante2 = ClasseDistante::MethodeStatique();
} catch (Exception $ex) {
  echo $ex->getMessage(), "<br/>";
}
?>

__sleep() et __wakeup()[modifier | modifier le wikicode]

Ces méthodes permettent respectivement de sauvegarder et restaurer l'état d'un objet, pour qu'il soit fonctionnel après une sérialisation / désérialisation. C'est utile par exemple pour se reconnecter à une base de données.

Quelques fonctions intégrées[modifier | modifier le wikicode]

Voici quelques fonctions en relation avec la programmation orientée objet qui peuvent vous être utiles.

class_exists()[modifier | modifier le wikicode]

Vérifie qu’une classe existe. Renvoie une valeur booléenne. ex :

if( class_exists('maClasse'))
$var = new maClasse();

get_class_methods()[modifier | modifier le wikicode]

Retourne toutes les méthodes d’une classe sous forme de tableau. Ex :

$maClasse = new Classe();
$methodes = get_class_methods($maClasse);
print_r($methodes);

get_class_vars()[modifier | modifier le wikicode]

Retourne tous les attributs d'une classe, ainsi que leurs valeurs par défaut sous forme de tableau. Ex :

$maClasse = new Classe();
$attributs = get_class_vars($maClasse);
print_r($attributs);

Peut donc servir pour un "foreach" propriétés de la classe.

get_object_vars()[modifier | modifier le wikicode]

Idem avec les valeurs courantes de l'objet instance de classe.

method_exists($classe, $méthode)[modifier | modifier le wikicode]

Teste sur une méthode existe dans une classe.

serialize() et unserialize()[modifier | modifier le wikicode]

Assurent la transformation du flux de données, en précisant les types des variables et index des tableaux. Exemple :

 $Hello = 'Hello World';
 var_dump($Hello); // string(11) "Hello World" 
 $Hello = serialize($Hello);
 print $Hello;	   // s:11:"Hello World";

 $Hello = array('Hello', 'World');
 var_dump($Hello);      // array(2) { [0]=> string(5) "Hello" [1]=> string(5) "World" }
 $Hello = serialize($Hello);
 print $Hello;	        // a:2:{i:0;s:5:"Hello";i:1;s:5:"World";}

Références[modifier | modifier le wikicode]



Bonnes pratiques

La programmation objet en PHP est régie par des recommandations nommées PSR (pour PHP Standards Recommendations) publiées sur http://www.php-fig.org/psr/.

PSR1[modifier | modifier le wikicode]

Les voici résumées ici[1] :

  • Un fichier .php doit être encodé en UTF8 sans BOM.
  • Les noms de classe doivent être rédigés en StudlyCaps (commencer par une majuscule).
  • Les noms des variables et méthodes de classe doivent être écris en camelCase (en commençant par une minuscule).
  • Les noms des constantes doivent être en lettres capitales et snake_case (en séparant les mots par des underscores). Comme par exemple la native DIRECTORY_SEPARATOR.

PSR2[modifier | modifier le wikicode]

Cette norme inclut la première, plus :

  • Les alinéas doivent faire quatre espaces. Presser la touche "tabulation" peut le faire automatiquement en réglant les IDE comme Netbeans ou Eclipse.
  • Les lignes ne doivent pas dépasser 120 caractères (les IDE peuvent dessiner une ligne verticale à ce niveau).

Une fonction ne doit faire qu'une seule chose[modifier | modifier le wikicode]

Afin de comprendre tout ce que fait une fonction par son nom sans avoir à la relire, et de réaliser facilement ses tests unitaires, il convient de lui confier un seul rôle, et de ne pas lui injecter plus de deux arguments (en les remplaçant par une classe de configuration à plusieurs attributs[2], ou un tableau).

Références[modifier | modifier le wikicode]



Bases de données

Introduction[modifier | modifier le wikicode]

Soit la base de données BDDNAME contenant la table NOMTABLE. Voici la table :

  • ID : id
  • NOM : chaine de caractères
  • PRENOM : chaine de caractères
  • ADRESSE1 : chaine de caractères
  • ADRESSE2 : chaine de caractères
  • TEL1 : entier long
  • TEL2 : entier long

Cette base de données contient les deux enregistrements suivants :


0 "DUPOND" "LOUIS" "1,Petite rue" "2,Petite rue" 0543454654 0543454352
1 "DUSS" "Jean-Claude" "1,Grande rue" "2, Grande rue" null null

Constantes propres à la base utilisées par la suite :

Nom de la BDD : "BDDNAME"
Adresse de la BDD : "BDDADRESSE"
Login d'accès à la BDD : "BDDUSER"
Mot de passe pour accéder à la BDD : "BDDPASS"

Oracle[modifier | modifier le wikicode]

Voir http://php.net/manual/fr/book.oci8.php.

PostgreSQL[modifier | modifier le wikicode]

Voir http://php.net/manual/fr/book.pgsql.php.

Voir aussi[modifier | modifier le wikicode]



Microsoft SQL Server

Installation[modifier | modifier le wikicode]

On distingue plusieurs pilotes PHP pour MS-SQL Server :

  • mssql (désuet en PHP7).
  • sqlsrv
  • PDO

Windows[modifier | modifier le wikicode]

Pour se connecter au serveur MS-SQL à partir d'un tout-en-un comme EasyPHP, il suffit de télécharger les pilotes .dll[1] correspondant à sa version de PHP, puis d'indiquer leurs chemins dans le PHP.ini :

  • Sous PHP 4, copier le fichier php_mssql.dll dans les extensions.
  • Pour PHP 5.4 :
    1. Télécharger les .dll SQL30
    2. Les copier dans C:\PROGRA~2\EasyPHP\binaries\php\php_runningversion\ext
    3. Les ajouter dans C:\PROGRA~2\EasyPHP\binaries\php\php_runningversion\php.ini via les lignes suivantes[2] :
      extension=php_sqlsrv_54_ts.dll
      extension=php_pdo_sqlsrv_54_ts.dll
  • Dans PHP 5.5 on obtient toujours Fatal error: Call to undefined function sqlsrv_connect(), donc upgrader ou downgrader PHP.
  • Dans PHP 7 : cela fonctionne.

Pour vérifier l'installation, redémarrer le serveur Web, puis vérifier que la ligne pdo_sqlsrv s’est bien ajoutée dans la configuration (ex : http://127.0.0.1/home/index.php?page=php-page&display=extensions).

Linux[modifier | modifier le wikicode]

Pour se connecter au serveur MS-SQL, il suffit de télécharger les pilotes .so[3] correspondant à sa version de PHP, puis d'indiquer leurs chemins dans le PHP.ini[4] :

extension=php_pdo_sqlsrv_7_nts.so
extension=php_sqlsrv_7_nts.so

Pour vérifier l'installation, redémarrer le serveur Web, puis vérifier que la ligne pdo_sqlsrv s’est bien ajoutée dans la configuration (ex : php -r "phpinfo();" |grep sql).


Connexion[modifier | modifier le wikicode]

Pilote 1.1 SQL Server pour PHP[modifier | modifier le wikicode]

Ce pilote fournit des fonctions d’interaction avec Microsoft SQL Server. Il peut s'utiliser avec les version de SQL Server postérieure à 2005[5].

Début d’un principe
Fin du principe


Alternative désuète[modifier | modifier le wikicode]

Les fonctions suivantes sont supprimées depuis PHP 7.0[6] :

Début d’un principe
Fin du principe


Alternative Doctrine[modifier | modifier le wikicode]

Les bibliothèques Doctrine utilisent cette syntaxe[8] :

Début d’un principe
Fin du principe


Requête SQL[modifier | modifier le wikicode]

// ... connexion

$sql = "DELETE FROM ma_table WHERE colonne = '1' LIMIT 0,30";
if (!sqlsrv_query($connect, $sql))
{
  die (sqlsrv_errors());
}

// ... déconnexion

Récupération des données[modifier | modifier le wikicode]

// ... connexion

$sql = "SELECT ville, pays, code_postal FROM table_clients WHERE code_postal = '78000' AND client_id = '44' LIMIT 1";
if (!$result = sqlsrv_query($connect, $sql))
{
  die (sqlsrv_errors());
}
$client_data = sqlsrv_fetch_array($result);
extract($client_data);

echo $ville;
echo $pays;
echo $code_postal;

// ... déconnexion
link={{{link}}}
Attention !

Par défaut, sqlsrv_fetch_array() renvoie deux tableaux imbriqués : le tableau itératif et l'associatif. Pour n'en sélectionner qu'un, il faut remplir son deuxième paramètre avec[9] :

  • SQLSRV_FETCH_ASSOC : pour le tableau associatif.
  • SQLSRV_FETCH_NUMERIC : pour le tableau itératif.
  • SQLSRV_FETCH_BOTH : pour les deux (déjà par défaut).

Références[modifier | modifier le wikicode]



MySQL

PHP offre plusieurs fonctions d’interaction avec MySQL.

mysql_connect()[modifier | modifier le wikicode]

link={{{link}}}
Attention !

La fonction mysql_connect() est obsolète en PHP7, et remplacée par la classe mysqli.

Connexion[modifier | modifier le wikicode]

Exemple d'accès à une base de données MySQL
$user="BDDUSER";
$pass="BDDPASS";
$db="BDDNAME";
$table="demande_intervention";
$link=mysql_connect("localhost",$user,$pass); // Préproduction locale de BDDADRESSE
if (!$link)
die("Impossible de se connecter à mysql");
mysql_select_db($db,$link)
or die ("Impossible d'ouvrir $db :".mysql_error());
$query="insert into $table values($znom,$ztel,$znomach,zlieu,zdate)";
mysql_query($query,$link)
or die("Impossible d'ajouter des nouvelles données".mysql_error());
mysql_close($link);

Exécution d'une requête[modifier | modifier le wikicode]

Maintenant que nous sommes connectés à notre base de données, il est possible d’exécuter des requêtes dessus. En voici un exemple

Exploiter une requête de type SELECT (avec mysql_fetch_assoc)
    $requete = "SELECT * FROM NOMTABLE";
    $res = mysql_query($requete);
    //On obtient alors tous les enregistrements présents dans la table nom table, et pour exploiter les enregistrements, on peut boucler de la manière        suivante :
    while ($enregistrement = mysql_fetch_assoc ($res) ) {
        $nom = $enregistrement['NOM'];
        $prenom = $enregistrement['PRENOM'];
        $adresse1 = $enregistrement['ADRESSE1'];
        $adresse2= $enregistrement['ADRESSE2'];
        $tel1 = $enregistrement['TEL1'];
        $tel2 = $enregistrement['TEL2'];
    }

De cette manière on récupère un tableau associatif sous la forme Clé->Valeur pour chacun des enregistrements retournés par la requête.

Il existe d'autres fonctions pour cela :

  • mysql_num_rows() : retourne le nombre de lignes données par la requête.
  • mysql_fetch_row() : identique à mysql_fetch_assoc mais retourne un tableau simple indice->valeur.
  • mysql_fetch_object() : identique à mysql_fetch_assoc mais retourne un objet.
  • mysql_fetch_array() : retourne les tableaux mysql_fetch_assoc() et mysql_fetch_row().

Exemple :

Exploiter une requête de type SELECT (avec mysql_fetch_object)
    $requete = "SELECT * FROM NOMTABLE";
    $res = mysql_query($requete);

    while ($enregistrement = mysql_fetch_object ($res) ) {
       $nom = $enregistrement->NOM;
       $prenom = $enregistrement->PRENOM;
       $adresse1 = $enregistrement->ADRESSE1;
       $adresse2= $enregistrement->ADRESSE2;
       $tel1 = $enregistrement->TEL1;
       $tel2 = $enregistrement->TEL2;
    }

link={{{link}}}
Attention !

Par défaut, mysql_fetch_array() renvoie deux tableaux imbriqués : le tableau itératif et l'associatif. Pour n'en sélectionner qu'un, il faut remplir son deuxième paramètre avec[1] :

  • MYSQL_ASSOC : pour le tableau associatif.
  • MYSQL_NUM : pour le tableau itératif.
  • MYSQL_BOTH : pour les deux (déjà par défaut).

Fermeture d'une connexion[modifier | modifier le wikicode]

 //Ferme la connexion MySQL
 mysql_close ($ressource);

mysqli_connect()[modifier | modifier le wikicode]

Cette fonction fonctionne un peu comme mysql_connect()[2] :

$link = mysqli_connect("BDDADRESSE","BDDUSER","BDDPASS","BDDNAME");
if (!$link) { die(mysqli_connect_errno()); }
mysqli_query($link, $query);
mysqli_close($link);

Les fonctions de manipulation de données ont pour préfixe "mysqli" avec les mêmes suffixes que celles du paragraphe précédent :

  • mysql_num_rows()
  • mysql_fetch_assoc()
  • mysql_fetch_row()
  • mysql_fetch_object()

Classe mysqli[modifier | modifier le wikicode]

La classe mysqli permet les mêmes opérations que les fonctions précédentes, avec l'avantage de la programmation objet en plus (ex : héritage, introspection...) :

$query = 'SELECT * FROM NOMTABLE';
$link = new mysqli("BDDADRESSE","BDDUSER","BDDPASS","BDDNAME");
if ($link->connect_error) { die(mysqli_connect_errno()); }
$result = $link->query($query);
while($row = $result->fetch_assoc()){
    var_dump($row);
}
$result->close();
$link->close();

Références[modifier | modifier le wikicode]



PDO

Introduction[modifier | modifier le wikicode]

PDO (PHP Data Objects) est une extension définissant l'interface pour accéder à plusieurs types de base de données, fournie automatiquement depuis PHP 5.1. Avec ce système, pour utiliser plusieurs SGBD il n'est pas nécessaire de changer les fonctions de communication dans tout le code, mais seulement les arguments envoyés au constructeur.

Les pilotes suivants sont disponibles[1] :

  1. 4D
  2. CUBRID
  3. Firebird
  4. IBM DB2
  5. Informix
  6. Microsoft SQL Server
  7. MySQL
  8. Oracle Database
  9. PostgreSQL
  10. SQLite

Et aussi via ODBC.

Installation[modifier | modifier le wikicode]

 pour PHP 5.0, l'extension est disponible en tant qu'extension PECL, et doit être activée[2] en ajoutant ou décommentant la ligne de "php_pdo.dll" dans php.ini.

Pour activer les différents SGBD qui doivent communiquer avec PDO, il faut ajouter ou décommenter les lignes extension=php_pdo_[SGBD utilisé].dll dans php.ini, que ce soit sur Apache ou IIS. Exemple :

extension=php_pdo_firebird.dll
extension=php_pdo_mysql.dll
extension=php_pdo_oci.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll
extension=php_pdo_sqlsrv_54_ts.dll

Les .dll de Microsoft SQL Server sont téléchargeables sur le site officiel[3].

Les classes de l'extension PDO[modifier | modifier le wikicode]

L'extension PDO comporte trois classes[4] :

  • La classe PDO correspond à une connexion à la base de données.
  • La classe PDOStatement représente d'une part une requête préparée et d'autre part le jeu de résultats de la requête une fois qu'elle est exécutée.

Cette classe offre des méthodes de parcours, de comptage, d'informations.

  • La classe PDOException représente une erreur émise par PDO.

Accès à la base de données avec PDO[modifier | modifier le wikicode]

L'accès à la base de données se fait en instanciant un objet PDO. Les paramètres à indiquer au constructeur sont :

  • la source de la base de données ;
  • optionnellement, le nom d'utilisateur et le mot de passe.

Par exemple, pour accéder à une base de données de nom ma_bd accessible sur le port mon_port du serveur mon_serveur avec l'utilisateur mon_id associé au mot de passe mon_mot_de_passe, le code sera le suivant :

  • Pour MySQL[5] :
$connexion = new PDO('mysql:host=mon_serveur;dbname=ma_bd;port=mon_port','mon_id','mon_mot_de_passe');
  • Pour MS-SQL[6] les noms des paramètres diffèrent :
$connexion = new PDO('sqlsrv:server=mon_serveur:mon_port;Database=ma_bd','mon_id','mon_mot_de_passe');
  • MS-SQL via une source de données ODBC (à créer dans C:\Windows\SysWOW64\odbcad32.exe) :
$connexion = new PDO('odbc:nom_de_la_source','mon_id','mon_mot_de_passe');
link={{{link}}}
Attention !

Par rapport à mysqli, PDO indique le nom réseau de la machine qui l'utilise en suffixe du compte MySQL, ce qui change le nom du compte et donc les permissions sur les bases. Par exemple si 'mon_id@%' est autorisé, ce n'est pas forcément le cas de 'mon_id@192.168.1.10', ce qui provoque l'erreur Access denied for user.

Passer des requêtes en PDO[modifier | modifier le wikicode]

Des méthodes permettent de passer des requêtes à l'objet récupéré lors de la connexion.

  • PDO::exec(string $statement)

La méthode exec() permet de passer et exécuter une requête SQL de type INSERT, UPDATE, DELETE.
Elle retourne le nombre de lignes affectées par la requête.

$requete="DELETE * FROM matable WHERE champ1='mavaleur'";
$resultat=$connexion->exec($requete);
echo $resultat.' suppressions effectuées';
  • PDO::query(string $statement)

La méthode query() permet de passer et exécuter une requête SQL de type SELECT.
Elle retourne le jeu de résultats (s'il y en a) sous forme d'objet PDOStatement.

$requete="SELECT champ1, champ2 FROM matable";
$resultat=$connexion->query($requete);

Quelques méthodes de PDOStatement[modifier | modifier le wikicode]

  • PDOStatement::fetch() récupère la ligne suivante d'un jeu de résultats PDO.
  • PDOStatement::fetchAll() retourne un tableau contenant toutes les lignes du jeu d'enregistrements PDO.
  • PDOStatement::fetchObject() récupère la ligne suivante et la retourne en tant qu'objet.
  • PDOStatement::fetchColumn() retourne une colonne depuis la ligne suivante d'un jeu de résultats PDO.
  • PDOStatement::rowCount() retourne le nombre de lignes affectées par le dernier appel à la fonction.
  • PDOStatement::closeCursor() libère la connexion au serveur, permettant ainsi à d'autres requêtes SQL d'être exécutées. La requête reste dans un état lui permettant d'être de nouveau exécutée. Cette fonction retourne TRUE en cas de succès ou FALSE si une erreur survient.
  • PDOStatement::execute() exécute une requête préparée.

Les paramètres de la méthode fetch[modifier | modifier le wikicode]

La méthode fetch() peut avoir en paramètre le type de retour du résultat. Par défaut, sans paramètre, le paramètre implicite est PDO::FETCH_BOTH.

  • PDO::FETCH_ASSOC retourne le jeu de résultats sous forme d'un tableau associatif, dont la clé est le nom de colonnes.

Exemple d'utilisation :

while ($ligne = $resultat ->fetch(PDO::FETCH_ASSOC)) {    
 echo $ligne['champ3'].' '.$ligne['champ1'].'<br/>';   
}
  • PDO::FETCH_NUM retourne le jeu de résultats sous forme d'un tableau indexé par numéro commençant à 0.

Exemple d'utilisation :

while ($ligne = $resultat ->fetch(PDO::FETCH_NUM)) {    
 echo $ligne[2].' '.$ligne[0].'<br/>';   
}
  • PDO::FETCH_BOTH retourne un tableau indexé et un tableau associatif.
  • PDO::FETCH_OBJ retourne le jeu de résultats sous forme d'un objet dont les noms de propriétés correspondent aux noms des colonnes.

Faire une requête préparée avec PDO[modifier | modifier le wikicode]

PDO::prepare() permet de préparer une requête que l'on exécutera ensuite avec la méthode PDOStatement::execute().

Les variables (parties de la requête spécifiques au moment de l'exécution) seront passées à la requête préparée grâce à cette méthode execute(). Ce dispositif protège l'application d'attaque de type injection SQL.

Jongler avec plusieurs SGBD en même temps[modifier | modifier le wikicode]

Pour exécuter alternativement des requêtes sur plusieurs SGBD, par exemple pour comparer leurs bases :


Notes et références[modifier | modifier le wikicode]


SQLite

SQLite est le moteur de base de données intégré à PHP5.

Connexion[modifier | modifier le wikicode]

// On se connecte à la base
// CHEMIN_BDD constitue de chemin physique de la base de données
$db = new SQLiteDatabase(CHEMIN_BDD);

Exécution d'une requête[modifier | modifier le wikicode]

Maintenant que nous sommes connectés à notre base de données, il est possible d’exécuter des requêtes dessus. En voici un exemple

$requete = "SELECT * FROM NOMTABLE";
$res = $db->arrayQuery ($requete, SQLITE_ASSOC);

On obtient alors tous les enregistrements présents dans la table nom table, et pour exploiter les enregistrements, on peut boucler de la manière suivante :

foreach($res as $enregistrement) {
    $nom = $enregistrement['NOM'];
    $prenom = $enregistrement['PRENOM'];
    $adresse1 = $enregistrement['ADRESSE1'];
    $adresse2= $enregistrement['ADRESSE2'];
    $tel1 = $enregistrement['TEL1'];
    $tel2 = $enregistrement['TEL2'];
}

De cette manière on récupère un tableau associatif sous la forme Clé->Valeur pour chacun des enregistrements retournés par la requête. C'est la constante SQLITE_ASSOC qui permet cela. La constante SQLITE_NUM permet de retourner un tableau indexé numériquement. Il existe d'autres méthodes...

  • numRows () : retourne le nombre de lignes données par la requête.

Fermeture d'une connexion[modifier | modifier le wikicode]

 $db->close();


Expressions rationnelles

Syntaxe[modifier | modifier le wikicode]

Expressions rationnelles courantes
Caractère Type Explication
. Point n'importe quel caractère
[...] classe de caractères tous les caractères énumérés dans la classe
[^...] classe complémentée Tous les caractères sauf ceux énumérés
^ circonflexe marque le début de la chaine, la ligne...
$ dollar marque la fin d'une chaine, ligne...
| barre verticale alternative - ou reconnaît l'un ou l'autre
(...) parenthèse utilisée pour limiter la portée d'un masque ou de l'alternative
* astérisque 0, 1 ou plusieurs occurrences
+ le plus 1 ou plusieurs occurrence
 ? interrogation 0 ou 1 occurrence
  • ?! : négation (ex : '#^((?!sous-chaine_exclue).)#').
  • $1 : résultat du premier groupe de capture.
  • ?: : ignorer le groupe de capture lors de leur numérotation.
Classe Prédéfinie
Classe Signification
[[:alpha:]] n'importe quelle lettre
[[:digit:]] n'importe quel chiffre
[[:xdigit:]] caractères héxadécimaux
[[:alnum:]] n'importe quelle lettre ou chiffre
[[:space:]] n'importe quel espace blanc
[[:punct:]] n'importe quel signe de ponctuation
[[:lower:]] n'importe quelle lettre en minuscule
[[:upper:]] n'importe quelle lettre capitale
[[:blank:]] espace ou tabulation
[[:graph:]] caractères affichables et imprimables
[[:cntrl:]] caractères d'échappement
[[:print:]] caractères imprimables exceptés ceux de contrôle

En plus de ces classes prédéfinies, les propriétés Unicode sont aussi prédéfinies.

Recherche[modifier | modifier le wikicode]

La fonction preg_match demande deux paramètres : l'expression rationnelle et la chaine à scanner.

<?php
$chaine="Test regex PHP pour Wikibooks francophone.";

if(preg_match('`.*Wikibooks.*`',$chaine)) {
	print("Le texte parle de Wikibooks");
} else {
	print("Le texte ne parle pas de Wikibooks"); 
}
?>

Pour obtenir tous les résultats dans un tableau, remplacer preg_match par preg_match_all[1], et print par print_r.

link={{{link}}}
Attention !

Le regex PHP doit toujours être entouré d'un symbole délimiteur, dans notre exemple c'est ` mais on utilise aussi souvent / et #.

link={{{link}}}
Attention !

Pour chercher un dollar, "\$" ne fonctionne pas car c'est le format de certaines variables, utiliser donc des apostrophes au lieu des guillemets : '\$'.

Remplacement[modifier | modifier le wikicode]

La fonction preg_replace comprend trois paramètres : remplacé, remplaçant, chaine à traiter.

<?php
// Remplace tous les espaces par des underscores
$chaine="Test regex PHP pour Wikibooks francophone.";
$chaineTriee=preg_replace('`( )`','_',$chaine);
echo $chaineTriee;
?>

Références[modifier | modifier le wikicode]


Concevoir du code de haute qualité

Introduction[modifier | modifier le wikicode]

La programmation est accessible à tout le monde. En revanche, créer du code de qualité demande une rigueur et une organisation qui n'est pas toujours au rendez-vous. Voici donc un tutoriel pour apprendre à programmer du code de haute qualité. Les exemples seront pris au PHP mais leur application est toujours valable quel que soit le langage de programmation.

Pourquoi bien programmer ?[modifier | modifier le wikicode]

Il est important d'aborder cette question dès le début pour légitimer ce cours, la motivation étant un facteur non négligeable de l'apprentissage.

Le bien-programmer est tout d'abord indispensable pour travailler en équipe. Lorsque vous travaillez dans un projet avec d'autres développeurs, il est important de coordonner votre action, d'éditer du code lisible... ce qui augmentera considérablement votre rendement de travail.

Vous vous apercevrez rapidement qu'un code bien programmé simplifie la vie : Lorsque vous avez créé un script une année auparavant et que vous devez vous replonger dessus, vous serez heureux de gagner du temps en retrouvant plus facilement le sens du code grâce à sa lisibilité. De plus, du bon code est plus compatible et générera moins d'erreurs ...

La quantité toujours grandissante de développeurs risque d'entraîner une saturation du marché. Vous serez jugés sur votre qualité de programmation. Un code aux normes est un sceau garantissant votre compétence de développeur.

Les critères de qualité[modifier | modifier le wikicode]

La programmation doit posséder des qualités qui ne sont pas arbitraires. Chaque critère sera accompagné d'une rapide description de son utilité.

La portabilité[modifier | modifier le wikicode]

La portabilité du code est son degré d'indépendance à son environnement.

Cette qualité est surtout requise pour des scripts destinés à être utilisés par le grand public. Par exemple, lorsqu'en PHP, vous utilisez des balises <?, vous réduisez la portabilité du code. En effet, l'usage des balises de ce type nécessite l'activation de la fonction SHORT_TAGS, donc dépend de l'environnement du script. Par définition, cela réduit la portabilité du code. Il vaut mieux utiliser la balise <?php qui marche quel que soit l'environnement.

La lisibilité[modifier | modifier le wikicode]

Il n'est pas besoin de chercher loin pour trouver les avantages que confèrent un code lisible : il permet aux autres développeurs de modifier plus facilement votre script, mais également à vous-même de comprendre plus rapidement un de vos anciens programmes. La lisibilité du code permet également d'éviter les erreurs de logique qui apparaissent plus distinctement.

La lisibilité est très liée à la définition de normes.

La lisibilité du code inclut un bon usage de la commentarisation. Les commentaires sont faits pour augmenter la rapidité de compréhension du script par le développeur, mais il ne doit pas en être fait un usage excessif, lequel serait néfaste pour la lisibilité. Voici un exemple de mauvaise utilisation des commentaires :

/* Code qui va afficher "salut" par un echo. Ce programme est fait en PHP compatible php3*/
echo "salut"; //affiche "salut"
#fin du programme

Il devient difficile de distinguer le code parmi les commentaires. Cet exemple était volontairement exagéré, mais n'est pas si loin de quelques scripts que l'on peut trouver sur le Net.

La définition de normes[modifier | modifier le wikicode]

Les normes sont des décisions le plus souvent arbitraires sur des méthodes de programmation. L'important n'est pas ce que définissent les normes, mais que des normes soient définies.

La définition de normes confère une continuité logique au code. Par exemple, en PHP, il est possible de nommer des variables de deux manières différentes :

$maSuperVariable   // Écriture en "CamelCase"
$ma_super_variable // Écriture avec des underscores

Vous serez rapidement désorienté si tantôt vous utilisez une méthode, tantôt une autre, et il se peut que vous perdiez des heures à chercher la cause d'une erreur d'écriture de variable.

De plus, lorsque vous travaillez en commun avec d'autres développeurs, si vous n'avez pas défini le nom du fichier de connexion à la base de données, lors de la fusion des scripts, vous devrez tout remodifier et perdre ainsi un temps précieux.

L'unicité du code (DRY)[modifier | modifier le wikicode]

L'unicité du code (ou DRY pour "Don't repeat yourself", Ne vous répétez pas) est le principe selon lequel aucun code ne doit être double dans le script. Ce critère a un enjeu pratique et vise à augmenter la rapidité des modifications d'un script. Prenons un exemple :

Vous faites un programme de comptabilité d'entreprise et vous vous connectez à une base de données. Si dans chaque page où vous vous connectez, vous entrez le code suivant :

<?php
$connect = mysql_connect('host','account','password');

//actions sur la BDD

?>

Le jour où vous voudrez changer le mot de passe de la base de données, vous devrez modifier chaque script, tâche qui s'avère laborieuse. Si en revanche lorsque vous vous connectez à la base de données vous entrez le code suivant :

include 'connect.php';

Et que dans le fichier connect.php vous entrez les informations de votre base de données, vous n'aurez qu'à modifier ce seul fichier lors d'un changement de mot de passe.

La duplication de code est donc considérée comme un anti-patron de programmation.

Exemple concret[modifier | modifier le wikicode]

Créez un fichier conf/config.php dans lequel vous mettez vos informations de connexion à la base de données :

define('HOST', 'localhost');
define('USER', 'moi');
define('PASS', 'mon_mdp');
define('DB', 'mon_site');
define('PREFIX', 'mon_site_'); // Préfixe des tables SQL

Lorsque vous ferez une requête, vous la ferez de la manière suivante :

mysql_connect(HOST, USER, PASS);
mysql_select_db(DB);

$temp = mysql_query('SELECT * FROM '. PREFIX .'ma_table');

La gestion des erreurs[modifier | modifier le wikicode]

Votre programme ne doit pas afficher au client de message d'erreur. Cela ne signifie pas non plus qu'il faille les étouffer. Il faut, par du code de qualité, réduire au maximum les erreurs possibles, puis traiter les autres en les enregistrant par exemple dans un fichier.

Voici une manière de n'afficher les erreurs que lors du débogage :

if ($debogage) {
  error_reporting(E_ALL);
} else {
  error_reporting(0);
}

Pour créer une bonne gestion des erreurs, partez du principe que l'utilisateur est imprévisible, et qu'il va justement faire ce qu'il ne faut pas (Loi de Murphy). Envisagez toutes les possibilités et trouvez-y une solution, en testant les exceptions (ex : caractères d'échappements ou symboles non ASCII comme des sinogrammes pour voir s'ils s'affichent bien).

Les conflits de critères[modifier | modifier le wikicode]

Réaliser un programme rassemblant toutes les qualités présentées précédemment est extrêmement difficile. La plupart du temps, certains critères entrent en conflit, par exemple entre la compatibilité et la lisibilité. Il va alors falloir établir une hiérarchie.

Il n'existe pas de hiérarchie absolue. Elle dépend du type de projet que vous menez. Voici quelques exemples de hiérarchisation de critères en fonction du projet :


Projet destiné au grand public[modifier | modifier le wikicode]

Par exemple, vous décidez un jour de concevoir un CMS. Les qualités requises seront :

  • La portabilité du code (car le CMS doit fonctionner sous le plus grand nombre de serveurs, donc doit dépendre le moins possible de sa configuration)
  • La gestion des erreurs (sachant que les personnes qui vont utiliser le script ne l'ont pas fait, il ne doit pas retourner de message d'erreur car ils ne pourraient pas l'arranger)
  • La définition de normes (vous le programmerez certainement en équipe, donc il faut coordonner votre action)
  • La lisibilité du code (toujours pour des raisons de coordination)

Script pour un particulier[modifier | modifier le wikicode]

Si on vous demande de programmer un système de restriction d'accès pour un site particulier, il va falloir que le code possède les critères suivants :

  • La lisibilité du code (un autre développeur doit pouvoir facilement modifier votre script si le client le lui demande)

Erreurs à éviter[modifier | modifier le wikicode]

Attention à ne pas vous laisser avoir par des idées fausses d'autant plus dangereuses qu'elles sembleraient logiques. En voici quelques exemples :

Le code optimisé[modifier | modifier le wikicode]

Parfois le code le plus court n'est pas le plus rapide d'exécution[1]. En voici un exemple :

//Code le plus court
for ($i=0; $i<count($array); $i++)
{
  echo $array[$i];
}

//Code le plus rapide
$count = count($array);
for ($i=0; $i<$count; $i++)
{
  echo $array[$i];
}

En effet, avec le premier code, à chaque itération, la taille du tableau est recalculée, ce qui ralentit le script. Le code le plus court n'est donc pas le plus rapide d'exécution.

Guillemets simples pourquoi ?[modifier | modifier le wikicode]

Toutes les chaînes peuvent être écrites autant avec des guillemets simples ('foo') qu'avec des guillemets doubles ("bar"). Cependant, on conseille généralement d'employer les guillemets simples parce qu'ils sont plus rapides. En voici la raison : à l'intérieur des guillemets doubles, les variables sont interprétées et substituées correctement.

Exemple :

echo "Votre nom est $nom et vous êtes $etatUser. Il vous reste $pointAction point(s) d'action.";
//Fait ce qu'on s'attend qu'il fasse. Alors que :
echo 'Votre nom est $nom et vous êtes $etatUser. Il vous reste $pointAction point(s) d\'action.';
//écrira bêtement la chaine avec les nom des variables. Il faudra additionner les chaines ensembles :
echo 'Votre nom est '. $nom .' et vous êtes '. $etatUser .'. Il vous reste '. $pointAction .' point(s) d\'action.';

Si à première vue ça semble être un avantage pour les guillemets doubles et qu'il est vrai que dans certaines conditions particulières, ça puisse augmenter la lisibilité du code, ça a aussi son désavantage : chacune des chaînes écrites avec des guillemets doubles doit d'abord être traversée par PHP pour y chercher de telles variables. En y regardant bien, le plus souvent c'est à des endroits où il n'y a aucune chance que se retrouvent de telles variables. Cette opération est en soi extrêmement rapide, presque qu'imperceptible, mais les chaînes se retrouvent souvent dans des endroits clés : des boucles, des fonctions exécutées des milliers des fois. Par ailleurs, même si on doit ajouter des variables dans une chaîne, ce sont les guillemets simples qui seront les plus rapides (Sauf cas extrême : echo "$a - $b,$c + $d $e $sigma $epsilon";). C'est pourquoi on conseille de s'habituer et d'employer les guillemets simples le plus souvent possible.

Par ailleurs, lorsqu'on avance dans le niveau de programmation avec les objets et les tableaux (qui ne sont pas interprétés correctement dans les guillemets doubles), les occasions de se servir de ceux-ci vont en s'amenuisant considérablement.

link={{{link}}}Attention !

En cas de migration des guillemets vers les apostrophes, il faut remplacer tous les retours à la ligne \n qui ne sont plus interprétés, par des <br/>.

Outils[modifier | modifier le wikicode]

  • PHPCS, un sniffeur de code[2].

Références[modifier | modifier le wikicode]

  1. http://www.phpbench.com/
  2. http://pear.php.net/package/PHP_CodeSniffer/redirected



Exceptions

Tester l'existence[modifier | modifier le wikicode]

Pour éviter les warnings de variables inexistantes il vaut mieux les initialiser au début. Si toutefois cela s'avère impossible, on recourt à des tests sur les fonctions suivantes pour le faire :

if (!isset($maVariable)) { $maVariable = ''; }
if (!defined('MA_CONSTANTE')) { define('MA_CONSTANTE', ''); }
if (!function_exists('maFonction')) { function maFonction() {} }

empty()[modifier | modifier le wikicode]

Permet de savoir si une variable est définie et si contient une valeur. Cela équivaut à :

  • isset($v) and $v == "".

ou

  • isset($v) and $v == false.

try ... catch[modifier | modifier le wikicode]

Tout comme en Java, la levée d'exception est assurée un bloc try ... catch. Cela permet à un script de poursuivre son exécution malgré les erreurs (ex : panne réseau), et ainsi de ne pas bloquer l'utilisateur sur une page blanche ou en anglais destinée au développeur.

Exemple :

try {
  echo '1 / 2 = ' 1/2;
  echo '3 / 0 = ' 3/0; // instruction qui déclenchera l'exception
  echo '2 / 1 = ' 2/1; // cette instruction ne sera pas exécutée à cause de la précédente
}
catch (Exception $e) {
  echo $e->getMessage(); // afficher le message lié à l'exception
}

Il n'est donc pas nécessaire de prévoir ce qui peut interrompre le programme pour s'en prémunir et poursuivre l'exécution en fonction.

La classe de gestion des erreurs nommée Exception est gracieusement mise à votre disposition par l’interpréteur dans les versions ultérieures à PHP 5.0.

Autre exemple d’utilisation :

class Humain
{
  var $age;

  function __construct($combien)
  {
    $this->age = $combien;
   
    try
    {
      if ($this->age<0)
      throw new Exception('Un peu jeune');
      if ($this->age>200)
      throw new Exception('Un peu vieux');
    }
    catch (Exception $e)
    {
      echo $e->getMessage();
      exit();
    }
  }

}

//Retournera un message d'erreur
$humain = new Humain(700);
$humain = new Humain(-3);

//Sans erreur
$humain = new Humain(16);

Par ailleurs, il est possible de modifier les exceptions PHP avec set_exception_handler()[1].

Affichage d'une trace lisible[modifier | modifier le wikicode]

Afin de clarifier la trace de l'exécution des scripts, il peut être utile de formater celle-ci avec la balise <pre> :

if ($debogage) {
  print '<pre>';
  var_dump(scandir('.'));
  print '</pre>';
}

NB : on rappelle que les commandes ini_set('display_errors', 1); et error_reporting(E_ALL); permet d'afficher à l'écran toutes les erreurs et avertissements.

debug_print_backtrace[modifier | modifier le wikicode]

Cette fonction affiche automatiquement la trace de l'exécution menant à elle.

Erreurs connues[modifier | modifier le wikicode]

Connect Error, 2002: Aucune connexion n'a pu être établie car l'ordinateur cible l'a expressément refusée.[modifier | modifier le wikicode]

Relancer le serveur de base de données.

Connect Error, 2002: Une tentative de connexion a échoué car le parti connecté n'a pas répondu convenablement au-delà d'une certaine durée ou une connexion établie a échoué car l'hôte de connexion n'a pas répondu.[modifier | modifier le wikicode]

Ouvrir les pare-feux.

This extension requires the Microsoft ODBC Driver 11 for SQL Server[modifier | modifier le wikicode]

Installer le pilote depuis https://www.microsoft.com/en-us/download/details.aspx?id=36434.

Unable to initialize module. Module compiled with module API=x. PHP compiled with module API=y. These options need to match[modifier | modifier le wikicode]

Se procurer une autre DLL à renseigner dans PHP.ini.


Fatal error[modifier | modifier le wikicode]

[] operator not supported for strings[modifier | modifier le wikicode]

// On récupère une variable dont on ne connait pas le type pour en faire un tableau
if (!isset($tableau1)) {
  $tableau1 = array();
} elseif (is_string($tableau1)) {
  $tableau1 = array($tableau1);
}
$tableau1[] = 'paramètre suivant';


Allowed memory size of x bytes exhausted[modifier | modifier le wikicode]

Modifier le PHP.ini ou bien ajouter une autre limite dans le programme :

 ini_set("memory_limit","100M");


Call to a member function ... on a non-object[modifier | modifier le wikicode]

La méthode est invoquée sur une variable qui n'est pas une classe.


Call to undefined function[modifier | modifier le wikicode]

Si une fonction est définie mais qu'on ne peut pas l'invoquer dans une méthode de classe, il faut préalablement l'importer en tenant compte du polymorphisme.


Call to undefined function sqlsrv_connect()[modifier | modifier le wikicode]

Installer le pilote correspondant à la version de PHP du serveur Web :

  1. Télécharger sur https://www.microsoft.com/en-us/download/details.aspx?id=20098.
  2. Copier dans le dossier PHP (ex : C:\Program Files (x86)\EasyPHP\binaries\php\php_runningversion\ext).
  3. Ajouter à PHP.ini.
  4. Redémarrer le serveur Web.

Call to undefined method[modifier | modifier le wikicode]

La méthode est invoquée sur une classe qui ne l'a pas.


Cannot access empty property[modifier | modifier le wikicode]

Une variable non définie ne peut pas fournir de propriété. Si elle était définie ailleurs c'est qu'elle est inaccessible, et donc qu'il faut la récupérer (ex : avec global).


Error connecting to the ODBC database: [Microsoft][SQL Server Native Client 10.0][SQL Server]échec de l'ouverture de session de l'utilisateur[modifier | modifier le wikicode]

La précédente connexion n'a pas dû être fermée proprement avant une tentative de reconnexion. Essayer au choix :

mysql_close($conn); // MySQL
sqlsrv_close($conn); // MS-SQL
odbc_close($conn); // ODBC


Out of memory[modifier | modifier le wikicode]

Éditer le PHP.ini pour augmenter la ligne :

memory_limit = 256M

pdo_sqlsrv_db_handle_factory: Unknown exception caught[modifier | modifier le wikicode]

Installer et configurer le paquet suivant :

apt-get install -y locales
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen

Uncaught exception 'com_exception' with message 'Failed to create COM object `xxx.application': Accès refusé.[modifier | modifier le wikicode]

Sur le serveur Web Windows, dans démarrer, exécuter dcomcnfg (sinon y aller dans Outils d'administration, Service de composants), puis Ordinateurs, Poste de travail, Configuration DCOM, aller dans les propriétés de l'application mentionnée, puis dans l'onglet Sécurité, définir la première permission (Autorisations d'exécution et d'activation à Personnaliser et ajouter le compte du serveur ou site qui exécute le script (ex pour ISS : IIS_IUSRS ou IUSR).

Par exemple pour Word l'application se prénomme "Document Microsoft Office Word", et Excel "Microsoft Excel Application".


Uncaught exception 'com_exception' with message 'Source: Microsoft Office Excel Description: Mémoire insuffisante.[modifier | modifier le wikicode]

Il faut certainement rerégler la Configuration DCOM voire le serveur Web.


Uncaught exception 'PDOException' with message[modifier | modifier le wikicode]

could not find driver[modifier | modifier le wikicode]

Se référer à la liste des pilotes connus dans Programmation PHP/PDO#Installation.

SQLSTATE[28000] [1045] Access denied for user[modifier | modifier le wikicode]

Si l'utilisateur existe avec les privilèges nécessaires, y compris depuis toute localisation (@%), il faut quand-même créer un deuxième compte homonyme pour l'emplacement distant (ex : 'username'@'example.com'). Par exemple dans phpMyAdmin, remplir la provenance mentionnée en erreur ('example.com') dans le champ "Client".

SQLSTATE[28000] SQLConnect: 18456 [Microsoft][ODBC SQL Server Driver][SQL Server] Échec de l'ouverture de session de l'utilisateur[modifier | modifier le wikicode]

Se référer à Programmation PHP/PDO#Accès à la base de données avec PDO : la source de données ODBC doit être suivie du compte pour y accéder.

SQLSTATE[IM002] SQLConnect: 0 [Microsoft][Gestionnaire de pilotes ODBC] Source de données introuvable et nom de pilote non spécifié[modifier | modifier le wikicode]

Se référer à Programmation PHP/PDO#Accès à la base de données avec PDO : la source de données ODBC doit être crée dans C:\Windows\SysWOW64\odbcad32.exe.

SQLSTATE[IMSSP]: An invalid keyword 'host' was specified in the DSN string[modifier | modifier le wikicode]

Se référer à Programmation PHP/PDO#Accès à la base de données avec PDO : le paramètre 'host' est valide pour MySQL mais pas pour MS-SQL.

SQLSTATE[IMSSP]: The DSN string ended unexpectedly[modifier | modifier le wikicode]

Se référer à Programmation PHP/PDO#Accès à la base de données avec PDO : les virgules et points-virgules changent d'un pilote à l'autre.

SQLSTATE[IMSSP]: This extension requires the Microsoft SQL Server 2012 Native Client ODBC Driver to communicate with SQL Server[modifier | modifier le wikicode]

Se référer à Programmation PHP/PDO#Accès à la base de données avec PDO : utiliser la syntaxe ODBC.

Notice[modifier | modifier le wikicode]

Undefined property[modifier | modifier le wikicode]

La propriété de la variable n'est pas déclarée.


Undefined index: SERVER_NAME in ...php[modifier | modifier le wikicode]

Certaines versions de PHP utilisent $_SERVER['HTTP_HOST'] au lieu de $_SERVER['SERVER_NAME'].

Undefined variable[modifier | modifier le wikicode]

La variable n'est pas déclarée.

Use of undefined constant[modifier | modifier le wikicode]

La constante n'est pas déclarée.

Parse error[modifier | modifier le wikicode]

syntax error, unexpected '(', expecting variable (T_VARIABLE) or '$' in...[modifier | modifier le wikicode]

Séparer le $ dans la chaine (ex : {$ -> { $).


syntax error, unexpected (T_ENCAPSED_AND_WHITESPACE), expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING)[modifier | modifier le wikicode]

Remplacer les variables incluses dans des chaines. Ex :

$query="select $contact['member']"; // pas bien
$query="select ".$contact['member']; // bien

syntax error, unexpected '$Variable' (T_VARIABLE), expecting function (T_FUNCTION)[modifier | modifier le wikicode]

Dans une classe en dehors des méthodes, il faut déclarer les variables avec leur portée :

private $Variable;

Strict Standards[modifier | modifier le wikicode]

Declaration of extFunctions::logs() should be compatible with functions::logs($chaine)[modifier | modifier le wikicode]

La fonction (logs() dans l'exemple) existe déjà, peut-être avec des majuscules (peu importe les arguments).

Only variables should be passed by reference[modifier | modifier le wikicode]

Il faut appliquer la fonction end() sur une variable au lieu du résultat d'une opération[2]. Ex :

// $extension = end(explode('.', $fichier));
$ext = explode('.', $fichier);
$extension = end($ext);

Warning[modifier | modifier le wikicode]

Cannot use a scalar value as an array[modifier | modifier le wikicode]

Un tableau de valeurs ne peut pas être redéfini en tableau de tableaux si elles existent. Remplacer les cas ainsi :

$tab['1'] = 1;
//$tab['1']['un'] = 'un';
$tab['un']['un'] = 'un';


date_diff() expects parameter 1 to be DateTimeInterface[modifier | modifier le wikicode]

La classe native DateTime() est plus pratique que la fonction date_diff() :

$Avant = new DateTime('20140101');
$Apres = new DateTime();
print $Avant->diff($Apres)->format("%d");


Illegal string offset[modifier | modifier le wikicode]

On invoque une entrée inexistante dans un tableau associatif. Lever l'exception avec Try ou if (!isset(.

Erreurs SMTP[modifier | modifier le wikicode]

La connexion a échoué[modifier | modifier le wikicode]

Vérifier le serveur HTTP qui interprète le .php.

SMTP Error: Could not connect to SMTP host[modifier | modifier le wikicode]

Changer de SMTP, ex : http://www.commentcamarche.net/faq/893-parametres-de-serveurs-pop-imap-et-smtp-des-principaux-fai

SMTP server error: ERR Email ID not found[modifier | modifier le wikicode]

Si les mails partent sans arriver[modifier | modifier le wikicode]

  • Vérifier que l'IP de l'expéditeur n'est pas blacklistée : http://whatismyipaddress.com/blacklist-check
  • Définir un reverse DNS si absent
  • Veiller à ce que le mail ne soit pas présumé spam, en évitant les sujets vides par exemple, ou les pièces jointes exécutables non compressées (.exe, .cmd, .vbs...).

Autres[modifier | modifier le wikicode]

IIS tourne dans le vide après la mise à jour de PHP[modifier | modifier le wikicode]

Vérifier que les dépendances sont bien installées (ex : Visual C++)[3].

La connexion a été réinitialisée[modifier | modifier le wikicode]

Erreur sous Firefox provenant d'un mysql_close() ou d'une directive Apache.

La page n'est pas redirigée correctement[modifier | modifier le wikicode]

Un header revient en boucle après une suite de conditions. S'il est local, le remplacer par chdir().

Les dernières lignes d'un INSERT sont ignorées[modifier | modifier le wikicode]

Il faut fragmenter en plusieurs insertions, par exemple tous les 300 enregistrements.

Références[modifier | modifier le wikicode]



Mots réservés

Mots du langage[modifier | modifier le wikicode]

Les mots qui suivent ont un sens spécial en PHP. Si vous les utilisez hors de leur contexte, des problèmes de confusions peuvent arriver.

Liste des mots spécifiques en PHP
Uniquement sous PHP 5
and or xor __FILE__ exception
__LINE__ array as break final
case class const continue php_user_filter
declare default die do public
echo else elseif empty private
enddeclare endfor endforeach endif catch
endswitch endwhile eval exit try
extends for foreach function clone
global if include include_once implements
isset list new print interface
require require_once return static throw
switch unset use var protected
while __FUNCTION__ __CLASS__ __METHOD__ abstract
extends cfunction* old_function*
* : depuis PHP4 seulement

Liste des 72 mots réservés par ordre alphabétique[1] :

__CLASS__ 
__DIR__
__FILE__ 
__FUNCTION__ 
__LINE__ 
__METHOD__ 
__NAMESPACE__
abstract
and 
array() 
as 
break 
case 
catch
cfunction ''(PHP 4)''
class 
clone
const 
continue 
declare 
default 
die() 
do 
echo() 
else 
elseif 
empty() 
enddeclare 
endfor 
endforeach 
endif 
endswitch 
endwhile 
eval() 
exit()
explode()
extends 
final
for 
foreach 
function 
global 
goto
if 
implements
include_once() 
include() 
instanceof
interface
isset() 
list() 
namespace
new 
old_function ''(PHP 4)''
or 
print() 
private
protected
public
require_once() 
require() 
return() 
split() ''(PHP < 5.3)''
static 
switch 
throw
try
unset() 
use 
var 
while 
xor

Nouveautés PHP7[modifier | modifier le wikicode]

Plusieurs opérateurs composés permettent de réduire la syntaxe d'opérations courantes :

De plus, on peut maintenant utiliser :

  • plusieurs classes dans le même use.
  • define() pour définir un tableau de constantes.

Extensions[modifier | modifier le wikicode]

Liste des 48 bibliothèques natives PHP 5.5.0 avec EasyPHP :

Core
PDO
Phar
Reflection
SPL
SimpleXML
apache2handler
bcmath
bz2
calendar
ctype
curl
date
dom
ereg
filter
ftp
gd
hash
iconv
json
libxml
mbstring
mcrypt
mhash
mysql
mysqli
mysqlnd
odbc
openssl
pcre
pdo_mysql
pdo_sqlite
pdo_sqlsrv
session
sockets
sqlite3
sqlsrv
standard
tokenizer
wddx
xdebug
xml
xmlreader
xmlwriter
xsl
zip
zlib

Références[modifier | modifier le wikicode]



Exemples/Variables

Utilisation de variables[modifier | modifier le wikicode]

Un exemple de programme[modifier | modifier le wikicode]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Variables en PHP !</title>
  </head>
  <body>

<?php

  for($i = 1; $i <= 10; $i++)
    echo ' <p>Ligne numéro '.$i.'</p>'."\n";
?>

  </body>
</html>

Explications[modifier | modifier le wikicode]

  • Une variable en php commence par le symbole $. Ici nous utilisons une variable d'identificateur $i.
  • Il n'y a pas de déclaration ni de typage fixe : une variable peut changer dynamiquement de type, ce qui est parfois vu comme un atout, parfois comme une faiblesse !
  • Ce programme comporte une boucle for qui a sa sémantique habituelle. La variable $i va donc prendre successivement les valeurs 1,2,... jusqu'à 10.
  • Dans cet exemple les chaînes de caractères sont entre apostrophes.
  • La concaténation des chaînes de caractères s'effectue grâce à l'opérateur ..
  • Remarque : si on veut qu'une chaîne de caractères contienne une apostrophe droite il faut écrire \' à l'intérieur de la chaîne.

Exécution du programme[modifier | modifier le wikicode]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Variables en php</title>
  </head>
  <body>

<p>Ligne numéro 1</p>
<p>Ligne numéro 2</p>
<p>Ligne numéro 3</p>
<p>Ligne numéro 4</p>
<p>Ligne numéro 5</p>
<p>Ligne numéro 6</p>
<p>Ligne numéro 7</p>
<p>Ligne numéro 8</p>
<p>Ligne numéro 9</p>
<p>Ligne numéro 10</p>


  </body>
</html>

Les guillemets[modifier | modifier le wikicode]

Une chaîne de caractère entre guillemet est assez particulière : si elle contient $a alors $a est remplacé par la valeur de la variable $a. Il y a automatiquement substitution. Si on écrit \$ alors il n'y a plus substitution. De la même manière, pour afficher le caractère guillemet on écrit \".

Exemple 2 : guillemets et variables[modifier | modifier le wikicode]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Variables en PHP !</title>
  </head>
  <body>

    <?php
      $a=67+33;
      echo "la variable \$a vaut $a";
    ?>

  </body>
</html>

Explications[modifier | modifier le wikicode]

Dans ce programme la variable $a vaut 67+33 donc vaut 100. Dans la chaîne de caractères \$a affichera $a et le deuxième $a sera remplacé par la valeur 100. Il s'affichera donc :
la variable $a vaut 100


Exemples/Sommaire

Un sommaire simple[modifier | modifier le wikicode]

Imaginons un site Web composé de 4 pages entre lesquelles on peut naviguer grâce à un sommaire. Notre sommaire est par exemple à gauche de l'écran et contient 4 liens hypertextes : page 1, page 2, page 3 et page 4. A droite de l'écran, le contenu principal de la page change en fonction de la page affichée. Par contre notre sommaire apparaît lui sur chacune des pages.

Le programme en php[modifier | modifier le wikicode]

Fichier index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Sommaire en PHP !</title>
  <style type="text/css">
  #sommaire
  {
  position:absolute;
  background-color:cyan;
  left:10px;
  width:100px;
  }

  #page
  {
  position:absolute;
  background-color:#AAAAAA;
  left : 200px;
  width:500px;
  height:500px;
  }
  </style>
  </head>
  <body>

    <div id="sommaire">
	<h3>Sommaire</h3>
	    <?php for($i = 1; $i <= 4; $i++) :?>
        <a href="index.php?page=<?php echo $i ?>">Page <?php echo $i ?></a><br/>
    	<?php endfor ?>
    </div>

    <div id="page">
        <?php
        if (isset($_GET['page'])) $numero=$_GET['page']; else $numero='1';
        require 'page'.$numero.'.html';
        ?>
    </div>

  </body>
</html>

fichier page1.html

<h1>Page 1</h1>
bla bla bla

fichier page2.html

<h1>Page 2</h1>
ble ble ble

fichier page3.html

<h1>Page 3</h1>
bli bli bli

fichier page4.html

<h1>Page 4</h1>
blo blo blo

Explications[modifier | modifier le wikicode]

  • Dans ce programme, la page est découpée en 2 parties : à gauche une partie ayant comme id sommaire et à droite une page ayant comme id page.
  • La partie « sommaire » utilise le style #sommaire de la feuille de style et la partie « page », le style #page.
  • Le sommaire est constitué de 4 liens hypertextes appelant respectivement index.php?page=1, index.php?page=2, index.php?page=3 et index.php?page=4. Lorsqu'on met un point d'interrogation après l'URL d'une page, cela signifie qu'on donne une valeur à un paramètre et qu'on envoie cette information au serveur par la méthode GET. Lorsqu'on clique sur l'un des 4 liens hypertextes, on appelle à chaque fois la même page index.php mais à chaque fois la valeur du paramètre nommé page change : il vaut 1, 2, 3 ou 4 selon le lien cliqué.
  • Dans la partie « page » de index.php, la valeur du paramètre page est récupérée de l'url cliquée en écrivant $_GET['page']. Ce paramètre peut très bien ne pas exister : ceci a lieu notamment la première fois qu'on appelle notre page index.php. Dans ce cas, la fonction isset() permet de savoir si une variable existe. La ligne
if (isset($_GET['page']))$numero=$_GET['page']; else $numero='1';
récupère la valeur du paramètre page et la place dans la variable $numero. Si ce paramètre n'existe pas $numero vaut 1.
  • La fonction require'nom_du_fichier'; permet d'insérer un fichier à cet endroit dans le code. Le server insère donc page1.html ou page2.html ou page3.html ou page4.html en fonction de la valeur du paramètre page (et de la variable numero).
  • Notre sommaire est terminé.


Exemples/Formulaire

Interaction avec un formulaire[modifier | modifier le wikicode]

Les principaux concepts[modifier | modifier le wikicode]

L'interaction entre une application en PHP et un utilisateur peut s'effectuer par des liens hypertextes ou par l'envoi d'un formulaire. C'est ce cas dernier que nous allons étudier ici.

Le formulaire comporte une balise form qui précise que la méthode utilisée pour envoyer le contenu du formulaire au programme en PHP est la méthode POST. Elle précise également l'action du formulaire, c'est-à-dire à quelle adresse envoyer le contenu du formulaire pour son traitement. Dans notre exemple, après un clic sur le bouton d'envoi, le formulaire déclenchera l'exécution du programme go.php. Le formulaire est composé de 3 éléments graphiques : 2 champs de type texte nommés respectivement nom et prénom et un bouton sur lequel il est écrit envoyer le formulaire. Le formulaire invite donc l'utilisateur à entrer un nom et un prénom et à cliquer sur le bouton « envoyer le formulaire ».

Le programme go.php doit récupérer les valeurs contenues dans le formulaire : pour récupérer la valeur du champ nom, il faut écrire $_POST['nom']. De la même manière, pour récupérer la valeur du champ prénom, il faut écrire $_POST['prenom']. Après un clic sur le bouton « envoyer le formulaire », une autre page s'affiche. Elle contient un message contenant "Bienvenue à" suivi du prénom et du nom définis dans le formulaire rempli. Le programme a bien récupéré la valeur des différents champs du formulaire.

Le programme en php[modifier | modifier le wikicode]

Le fichier index.html :

<!DOCTYPE html PUBLIC "-//DTD XHTML 2.0 Transitional//EN"
        "http://www.org/TR/xhtml/xhtml-transitional.dtd">

<form action="go.php" method="post">
<p>Votre nom : <input type="text" name="nom" /></p>
<p>Votre prénom : <input type="text" name="prenom" /></p>
<p><input type="submit" value="envoyer le formulaire" /></p>
</form>

Le fichier go.php :

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 1.0 Transitional//EN"
        "http://www.org/xhtml/html-transitional.dtd">
<?php 
$nom = $_POST['nom'];
$prenom = $_POST['prenom'];
echo "<h3>Bienvenue à ".$prenom.' '.$nom,"</h3>";
 
echo "<p><a href='index.html'>Retour au formulaire</a></p>";
?>

Captures d'écran[modifier | modifier le wikicode]

Le formulaire initial


Exemples/BD 1

Afficher le résultat d'une requête[modifier | modifier le wikicode]

Présentation[modifier | modifier le wikicode]

Dans cet exemple, on va créer une application qui extrait des données à partir d'une base de données et qui affiche le résultat à l'écran. Notre programme va afficher une liste d'employés d'une entreprise imaginaire : chaque employé est défini par un nom, un prénom et un salaire. La base de données utilisée sera une base mysql. Les données seront dans une table nommée employe. La table employé possède des champs NOM, PRENOM et SALAIRE. La table employé possède de plus un identifiant nommé ID qui est un entier (BIGINT) autoincrémenté et qui est une clé primaire de la table.


Nous étudierons une première version du programme et dans un second temps nous améliorerons le programme en utilisant la méthode GET lors d'une deuxième version.

Descriptif du site[modifier | modifier le wikicode]

  • La première page affiche 3 liens hypertextes :
    • un lien pour afficher la liste complète des employés,
    • un lien pour afficher la liste dans l'ordre alphabétique,
    • un lien pour afficher par salaire décroissant.
  • Sur chacune des pages, on affiche la liste et il y a un lien pour revenir à la première page.

Création de la base[modifier | modifier le wikicode]

Les requêtes suivantes permettent la création et l'initialisation des données dans notre table :

Fichier BD.sql :

CREATE TABLE `employe` (
	`ID` BIGINT NOT NULL AUTO_INCREMENT ,
	`NOM` VARCHAR( 20 ) ,
	`PRENOM` VARCHAR( 20 ) ,
	`SALAIRE` DOUBLE DEFAULT '0',
	PRIMARY KEY ( `ID` ) 
); 
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Dupond', 'Marcel', '8000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Martin', 'Xavier', '4000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Gogol', 'Henri', '3000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Hugo', 'Victor', '2000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Gali', 'Daniel', '6000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Martin', 'Georges', '9000'
	);

La table créée par ces requêtes est la suivante :


ID NOM PRENOM SALAIRE
1 Dupond Marcel 8000
2 Martin Xavier 4000
3 Gogol Henri 3000
4 Hugo Victor 2000
5 Gali Daniel 6000
6 Martin Georges 9000

Configuration de la base de données[modifier | modifier le wikicode]

La table employe appartient à la base de données toto. L'administrateur de cette base est root. Il n'a pas de mot de passe. Attention ceci est une configuration type utilisée par défaut pour la plateforme de développement EasyPHP : il est vivement recommandé de mettre un vrai mot de passe pour une plateforme en exploitation.

Les requêtes utilisées[modifier | modifier le wikicode]

  • Pour afficher la liste des employés, on utilisera la requête :

SELECT * FROM employe

  • Pour afficher la liste des employés par ordre alphabétique, on utilisera la requête :

SELECT * FROM employe ORDER BY NOM, PRENOM

  • Pour afficher la liste des employés par salaire décroissant, on utilisera la requête :

SELECT * FROM employe ORDER BY SALAIRE DESC

Comment accéder en php à une base mysql[modifier | modifier le wikicode]

Les différentes étapes à respecter seront les suivantes :

  1. récupérer les informations suivantes :
    1. le nom de la machine qui héberge le serveur de la base de données (ici localhost)
    2. le nom de la base de données (ici toto)
    3. le nom de l'utilisateur de la base de données (ici root)
    4. le mot de passe de cet utilisateur (ici le mot de passe est vide).
  2. se connecter au serveur de base de données
  3. sélectionner la base de données (ici toto) sur ce serveur.
  4. créer la requête dans une chaîne de caractères
  5. envoyer la requête à la base de données et récupérer le résultat
  6. fermer la connexion avec le serveur de base de données
  7. transformer le résultat de la requête en HTML.

Etape 1 : les paramètres spécifiques au site[modifier | modifier le wikicode]

Pour réaliser la première étape nous allons créer un fichier params.php qui contient 4 variables $host (le nom de la machine qui héberge la base de données, $user (le nom de l'utilisateur de la base de données), $password (le mot de passe de cet utilisateur) et $base le nom de la base de données. Ces paramètres changent en fonction de la plateforme que vous utilisez. Il est intéressant d'isoler ces paramètres dans un fichier séparé, que ce soit au niveau de la sécurité ou pour porter l'application sur une autre plateforme. Il faut se renseigner au niveau de l'hébergeur sur les caractéristiques de la plateforme utilisée. Les paramètres suivants sont ceux par défaut si on utilise EasyPHP. On a juste créé une base de données appelée toto.

<?php
$host='localhost';
$user='root';
$password='';
$base='toto';
?>

Pour récupérer, ces paramètres il suffit d'inclure ce fichier en utilisant le mot clé require. On écrira require'params.php' . Le fichier sera alors inclus dans le programme en php et le programmeur utilisera les 4 variables.

Etape 2 : connexion à la base de données[modifier | modifier le wikicode]

La fonction mysql_connect($host,$user,$password) permet de se connecter au serveur de base de données mysql situé sur la machine nommée $host en utilisant le nom d'utilisateur $user ayant comme mot de passe $password. Cette fonction renvoie le booléen true si la connexion est établie et false sinon.

Etape 3 : selectionner la base de données[modifier | modifier le wikicode]

Un serveur de base de données peut héberger plusieurs bases de données (une base de données est un ensemble de tables). La fonction mysql_select_db($base) permet de sélectionner la base de données à laquelle on va envoyer les requêtes. Cette fonction renvoie true si tout s'est bien passé et false sinon.

Etape 4 : création de la requête[modifier | modifier le wikicode]

Il faut ensuite créer la requête dans une chaîne de caractères. Ici la requête va être simple, par exemple $query='SELECT * FROM employe'; : on met la requête dans la variable $query. Parfois, il faudra concaténer des chaînes de caractères pour construire la requête--.

Etape 5 : envoyer la requête et récupérer le résultat[modifier | modifier le wikicode]

Pour envoyer la requête au serveur, il faut utiliser la fonction $r=mysql_query($query); qui envoie la requête $query et récupère le résultat dans $r.

Etape 6 : fermer la connexion avec le serveur de base de données[modifier | modifier le wikicode]

Pour fermer la connexion avec le serveur de base de données, il suffit d'appeler la fonction mysql_close();.

Etape 7 : générer du HTML à partir du résultat de la requête[modifier | modifier le wikicode]

Supposons que le résultat d'une requête soit contenu dans la variable $r. Il est souvent intéressant de parcourir un à un tous les enregistrements contenus dans $r. L'appel de fonction $a=mysql_fetch_object($r) permet de récupérer un à un tous les enregistrements dans la variable $a. Lors du premier appel, on récupère le premier enregistrement dans $a, lors du second appel, on récupère le second enregistrement et ainsi de suite jusqu'au dernier enregistrement. Si on appelle alors une nouvelle fois cette fonction, elle va renvoyer le booléen false. Ceci permet donc de traiter un à un tous les enregistrements en écrivant

while($a=mysql_fetch_object($r))
{
...
}

Lors de l'exécution de ce while $a va prendre toutes les valeurs des différents enregistrements contenus dans $r, du premier au dernier. À partir de l'objet $a, on pourra récupérer le champs NOM de cet enregistrement en écrivant $a->NOM. On peut ainsi récupérer la valeur de chaque champ d'un enregistrement. Il suffit donc maintennant de parcourir chaque enregistrement et d'afficher du HTML en utilisant la commande echo à partir des différents champs des enregistrements.

Les pages du site (version 1)[modifier | modifier le wikicode]

Fichier index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Afficher le résultat d'une requête</title>
  </head>
  <body>

<h1> Choisissez dans le menu ci-dessous</h1>

<a href="liste1.php">Afficher la liste des employés</a><br/>
<a href="liste2.php">Afficher la liste des employés par ordre alphabétique</a><br/>
<a href="liste3.php">Afficher la liste des employés par salaire décroissant</a><br/>
    
  </body>
</html>


Fichier params.php

<?php
$host='localhost';
$user='root';
$password='';
$base='toto';
?>


Fichier liste1.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Afficher la liste des employés</title>
  </head>
  <body>
<h1>Afficher la liste des employés</h1>
  <?php
  require 'params.php';
  mysql_connect($host,$user,$password) or die('Erreur de connexion au SGBD.');
  mysql_select_db($base) or die('La base de données n\'existe pas');
  $query='SELECT * FROM employe';
  $r=mysql_query($query);
  mysql_close();
  echo'<table><tr><td>NOM</td><td>PRENOM</td><td>SALAIRE</td></tr>';
  while($a=mysql_fetch_object($r))
    {
    $nom=$a->NOM;
    $prenom=$a->PRENOM;
    $salaire=$a->SALAIRE;
    echo"<tr><td>$nom</td><td>$prenom</td><td>$salaire</td></tr>";
    }
  echo '</table>';
  ?>
<br/>
<br/>
<a href="index.html">Retour à la page d'accueil</a>
    
  </body>
</html>


Fichier liste2.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Afficher la liste des employés par ordre alphabétique</title>
  </head>
  <body>
<h1>Afficher la liste des employés par ordre alphabétique</h1>
  <?php
  require 'params.php';
  mysql_connect($host,$user,$password) or die('Erreur le connexion au SGBD.');
  mysql_select_db($base) or die('La base de données n\'existe pas');
  $query='SELECT * FROM employe ORDER BY NOM, PRENOM';
  $r=mysql_query($query);
  mysql_close();
  echo'<table><tr><td>NOM</td><td>PRENOM</td><td>SALAIRE</td></tr>';
  while($a=mysql_fetch_object($r))
    {
    $nom=$a->NOM;
    $prenom=$a->PRENOM;
    $salaire=$a->SALAIRE;
    echo"<tr><td>$nom</td><td>$prenom</td><td>$salaire</td></tr>";
    }
  echo '</table>';
  ?>
<br/>
<br/>
<a href="index.html">Retour à la page d'accueil</a>
    
  </body>
</html>


Fichier liste3.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Afficher la liste des employés par salaire décroissant</title>
  </head>
  <body>
<h1>Afficher la liste des employés par ordre alphabétique</h1>
  <?php
  require 'params.php';
  mysql_connect($host,$user,$password) or die('Erreur le connexion au SGBD.');
  mysql_select_db($base) or die('La base de données n\'existe pas');
  $query='SELECT * FROM employe ORDER BY SALAIRE DESC';
  $r=mysql_query($query);
  mysql_close();
  echo'<table><tr><td>NOM</td><td>PRENOM</td><td>SALAIRE</td></tr>';
  while($a=mysql_fetch_object($r))
    {
    $nom=$a->NOM;
    $prenom=$a->PRENOM;
    $salaire=$a->SALAIRE;
    echo"<tr><td>$nom</td><td>$prenom</td><td>$salaire</td></tr>";
    }
  echo '</table>';
  ?>
<br/>
<br/>
<a href="index.html">Retour à la page d'accueil</a>
    
  </body>
</html>

Les pages du site (version 2)[modifier | modifier le wikicode]

Lorsqu'on étudie les fichiers liste1.php, liste2.php et liste3.php, on s'aperçoit qu'ils sont extrêmement proches : on va donc réécrire l'application en écrivant un seul fichier liste.php et en le paramétrant grâce à la méthode GET.

Le nouveau fichier index.html devient donc :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Afficher le résultat d'un requête</title>
  </head>
  <body>

<h1> Choisissez dans le menu ci-dessous</h1>

<a href="liste.php?l=1">Afficher la liste des employés</a><br/>
<a href="liste.php?l=2">Afficher la liste des employés par ordre alphabétique</a><br/>
<a href="liste.php?l=3">Afficher la liste des employés par salaire décroissant</a><br/>
    
  </body>
</html>

On constate donc que les liens hypertextes, par exemple liste.php?l=1 appelle le même fichier liste.php en lui donnant un paramètre par la méthode GET, ici l=1, ce qui permet de paramétrer le fichier.

Remarque importante : lorsqu'on utilise ce genre de liens hypertextes, il faut toujours se poser la question : que se passe-t-il si l'utilisateur accède à la page liste.php sans passer de paramètres ou alors en écrivant liste.php?l=4 ? Le programmeur doit garantir que dans un tel cas, le site reste cohérent et que ceci n'engendre pas de failles de sécurité.


Le fichier liste.php devient :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Afficher la liste des employés</title>
  </head>
  <body>
<h1>Afficher la liste des employés</h1>
  <?php
  require 'params.php';
  mysql_connect($host,$user,$password) or die('Erreur le connexion au SGBD.');
  mysql_select_db($base) or die('La base de données n\'existe pas');

  if(isset($_GET['l']))
	 $l=$_GET['l'];
	else $l=1;

         if($l==1)$query='SELECT * FROM employe';
    else if($l==2)$query='SELECT * FROM employe ORDER BY NOM, PRENOM';
    else $query='SELECT * FROM employe ORDER BY SALAIRE DESC';

  $r=mysql_query($query);
  mysql_close();
  echo'<table><tr><td>NOM</td><td>PRENOM</td><td>SALAIRE</td></tr>';
  while($a=mysql_fetch_object($r))
    {
    $nom=$a->NOM;
    $prenom=$a->PRENOM;
    $salaire=$a->SALAIRE;
    echo"<tr><td>$nom</td><td>$prenom</td><td>$salaire</td></tr>";
    }
  echo '</table>';
  ?>
<br/>
<br/>
<a href="index.html">Retour à la page d'accueil</a>
    
  </body>
</html>

Le programmeur teste en utilisant isset($_GET['l']) pour savoir si la variable l a été passée par la méthode GET et il récupère sa valeur dans la variable $l. Si ce paramètre n'existe pas, $l est fixé à la valeur 1. On construit ensuite la requête $query en fonction de la valeur de $l. Cette version du programme est plus simple mais îil faut toutefois faire très attention à la sécurité dans un tel cas.


Exemples/BD 2

Modifier une table[modifier | modifier le wikicode]

Les fichiers de l'application[modifier | modifier le wikicode]

Le fichier BD.sql[modifier | modifier le wikicode]

CREATE TABLE `employe` (
	`ID` BIGINT NOT NULL AUTO_INCREMENT ,
	`NOM` VARCHAR( 20 ) ,
	`PRENOM` VARCHAR( 20 ) ,
	`SALAIRE` DOUBLE DEFAULT '0',
	PRIMARY KEY ( `ID` ) 
); 
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Dupond', 'Marcel', '8000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Martin', 'Xavier', '4000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Gogol', 'Henri', '3000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Hugo', 'Victor', '2000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Gali', 'Daniel', '6000'
	);
INSERT INTO `employe` ( `ID` , `NOM` , `PRENOM` , `SALAIRE` ) 
	VALUES (
	'', 'Martin', 'Georges', '9000'
	);

Le fichier index.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';
?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Afficher le résultat d'un requête</title>
  </head>
  <body>
<h1> Choisissez dans le menu ci-dessous</h1>
<a href="liste.php?l=1">Afficher la liste des employés</a><br/>
<a href="liste.php?l=2">Afficher la liste des employés par ordre alphabétique</a><br/>
<a href="liste.php?l=3">Afficher la liste des employés par salaire décroissant</a><br/>
<a href="add.php">Ajouter un employé</a><br/>
<a href="delete.php">Supprimer un employé</a><br/>
<?php

if(is_admin())echo '<a href="disconnect.php">Se déconnecter</a><br/>';
?>
  </body>
</html>

Le fichier liste.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Afficher la liste des employés</title>
  </head>
  <body>
<h1>Afficher la liste des employés</h1>
  <?php

  if(isset($_GET['l']))
	{
	$l=$_GET['l'];
	}else $l=1;
  liste($l,false);
  ?>
<br/>
<br/>
<a href="index.php">Retour à la page d'accueil</a>
    
  </body>
</html>

Le fichier add.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';

$_SESSION['add_NOM']='';
$_SESSION['add_PRENOM']='';
$_SESSION['add_SALAIRE']='';
$_SESSION['add_ERROR']=0;


if(is_admin()) require 'Appli/addForm.php';
 else {
      $_SESSION['connect_target']='Appli/addForm.php';
      $_SESSION['connect_error']=0;
      $_SESSION['connect_login']='';
      require 'Appli/connectForm.php';
      }

?>

Le fichier addAction.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';
if(is_admin()) 
      {
      if(isset($_POST['add']))
      {
      $nom=$_POST['nom'];
      $prenom=$_POST['prenom'];
      $salaire=$_POST['salaire'];
      $r=add_liste($nom,$prenom,$salaire);
      if($r==0)echo '<meta http-equiv="Refresh" content="0;URL=index.php">';
	else {
	 $_SESSION['add_NOM']=$nom;
	 $_SESSION['add_PRENOM']=$prenom;
	 $_SESSION['add_SALAIRE']=$salaire;
             $_SESSION['add_ERROR']=$r;
	 require 'Appli/addForm.php';
	 }
      }else echo '<meta http-equiv="Refresh" content="0;URL=index.php">';
      }
?>

Le fichier connect.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';

if(isset($_POST['connect']))
{
if(isset($_POST['login'])) $login=$_POST['login']; else $login='';
if(isset($_POST['password'])) $password=$_POST['password']; else $password='';

if(connect($login,$password))$target=$_SESSION['connect_target'];
  else {
	$target='Appli/connectForm.php';
	$_SESSION['connect_login']=$login;
	$_SESSION['connect_error']=1;
	}
} else $target='index.php';

require $target;
?>

Le fichier disconnect.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';
disconnect();
?>
<meta http-equiv="Refresh" content="0;URL=index.php">

Le fichier delete.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';


if(is_admin()) require 'Appli/deleteForm.php';
 else {
      $_SESSION['connect_target']='Appli/deleteForm.php';
      $_SESSION['connect_error']=0;
      $_SESSION['connect_login']='';
      require 'Appli/connectForm.php';
      }

?>

Le fichier deleteAction.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';
if(is_admin()) 
      {
      
      $ID=$_GET['ID'];
      delete($ID);
      require 'Appli/deleteForm.php';
      }else echo '<meta http-equiv="Refresh" content="0;URL=index.php">';
?>

Le fichier Appli/.htaccess[modifier | modifier le wikicode]

deny from all

Le fichier Appli/params.php[modifier | modifier le wikicode]

<?php
$host='localhost';
$user='root';
$password='';
$base='toto';

$admin_login='admin';
$admin_password='aligator';
?>

Le fichier Appli/appli.php[modifier | modifier le wikicode]

<?php
function is_admin()
{
return isset($_SESSION['admin']) and ($_SESSION['admin']==true);
}

function connect($login,$user_password)
{
$r=false;
require 'params.php';
if($login==$admin_login and $user_password==$admin_password)
   {$r=true;$_SESSION['admin']=true;}
return $r;
}

function disconnect()
{
$_SESSION['admin']=false;
}

function liste($l,$editable)
{
require 'params.php';
mysql_connect($host,$user,$password) or die('Erreur le connexion au SGBD.');
mysql_select_db($base) or die('La base de données n\'existe pas');
         if($l==1)$query='SELECT * FROM employe';
    else if($l==2)$query='SELECT * FROM employe ORDER BY NOM, PRENOM';
    else $query='SELECT * FROM employe ORDER BY SALAIRE DESC';

$r=mysql_query($query);
mysql_close();
if(editable==false)echo'<table><tr><td>NOM</td><td>PRENOM</td><td>SALAIRE</td></tr>';
  else echo'<table><tr><td>NOM</td><td>PRENOM</td><td>SALAIRE</td><td>&nbsp;</td></tr>';
while($a=mysql_fetch_object($r))
    {
    $nom=$a->NOM;
    $prenom=$a->PRENOM;
    $salaire=$a->SALAIRE;
    $ID=$a->ID;
if ($editable==false)echo"<tr><td>$nom</td><td>$prenom</td><td>$salaire</td></tr>";
    else echo"<tr><td>$nom</td><td>$prenom</td><td>$salaire</td><td><a href=\"deleteAction.php?ID=$ID\">SUPPRIMER</a></td></tr>";
    }
echo '</table>';
}

function add_liste($nom,$prenom,$salaire)
{
$r=0;
if($nom=='')$r=1;
else if($prenom=='')$r=2;
else if ($salaire=='')$r=3;
else
{
require 'params.php';
mysql_connect($host,$user,$password) or die('Erreur le connexion au SGBD.');
mysql_select_db($base) or die('La base de données n\'existe pas');
$query="INSERT INTO employe (NOM,PRENOM,SALAIRE) VALUES ('$nom','$prenom','$salaire')";
mysql_query($query);
mysql_close();
}
return $r;
}

function delete($ID)
{
require 'params.php';
mysql_connect($host,$user,$password) or die('Erreur le connexion au SGBD.');
mysql_select_db($base) or die('La base de données n\'existe pas');
$query="DELETE FROM employe WHERE ID=$ID";
mysql_query($query);
mysql_close();

}
?>

Le fichier Appli/connectForm.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Connexion</title>
  </head>
  <body>
<h1> Connexion</h1>
<form method="post" action="connect.php">
<table>
<?php
$value=$_SESSION['connect_login'];
echo "<tr><td><b>LOGIN</b></td> <td><input type=\"text\" name=\"login\" value=\"$value\"/></td></tr>";
?>
<tr><td><b>MOT DE PASSE</b></td> <td><input type="password" name="password"/></td></tr>
<tr><td colspan="2"><input type="submit" value="Se connecter" name="connect"><input type="submit" value="Annuler" name="cancel"></td></tr>
</table>
</form>
<br/>
<?php
$error= $_SESSION['connect_error'];
if($error==1)echo'Erreur de connexion';
$_SESSION['connect_error']=0;
?>
   <p/>
<a href="index.php">Retour</a>
  </body>
</html>

Le fichier Appli/addForm.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Ajouter</title>
  </head>
  <body>
<h1>Ajouter un employé</h1>
<form method="post" action="addAction.php">
<table>
<?php
$nom=$_SESSION['add_NOM'];
$prenom=$_SESSION['add_PRENOM'];
$salaire=$_SESSION['add_SALAIRE'];
echo '<tr><td><b>NOM</b></td> <td><input type="text" name="nom" value="'.$nom.'"/></td></tr>';
echo '<tr><td><b>PRENOM</b></td> <td><input type="text" name="prenom" value="'.$prenom.'"/></td></tr>';
echo '<tr><td><b>SALAIRE</b></td> <td><input type="text" name="salaire" value="'.$salaire.'"/></td></tr>';
?>
<tr><td colspan="2"><input type="submit" value="Ajouter" name="add"><input type="submit" value="Annuler" name="cancel"></td></tr>
</table>
</form>
<br/>
<?php
$error=$_SESSION['add_ERROR'];
if($error==1)echo'ERREUR : le nom est vide';
if($error==2)echo'ERREUR : le prénom est vide';
if($error==3)echo'ERREUR : le salaire est vide';
?>
   <p/>
<a href="index.php">Retour</a>
  </body>
</html>

Le fichier Appli/deleteForm.php[modifier | modifier le wikicode]

<?php
session_start();
require_once'Appli/appli.php';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Suppression</title>
  </head>
  <body>
<h1> Suppression</h1>
<?php
liste(2,true);
?>
   <p/>
<a href="index.php">Retour</a>
  </body>
</html>


Exemples/Livre

Créer le livre[modifier | modifier le wikicode]

Tout d'abord, il faut créer le livre d'or, c'est-à-dire une table où seront stockés les messages.

Voici un exemple de table, avec un identifiant auto-incrémenté qui sera la clé (pour pouvoir identifier de manière unique chaque message), puis un champ pour le nom, courriel, date, ... et bien sûr le message.

CREATE TABLE `livre` (
	`id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
	`nom` VARCHAR( 128 ),
	`email` VARCHAR( 128 ),
	`date` DATE,
	`message` TEXT NOT NULL,
	PRIMARY KEY( `id` )
);

Ajouter un message[modifier | modifier le wikicode]

Voici la requête SQL qui permet d'insérer les données dans la table:

INSERT INTO `livre` ( `nom` , `email` , `date` , `message` )
 VALUES ( `UnNom` , `Une@` ,  `xx/xx/xxxx` , `blalblablabla...` );

Saisie des données[modifier | modifier le wikicode]

Voici un exemple de formulaire servant à récupérer les données saisies par l'utilisateur pour les faire suivre vers 'ajout_message.php' qui les traitera. La méthode utilisée est POST, bien que GET marche aussi, mais POST possède l'avantage de ne pas rendre visible dans l'URL les paramètres passés, ce qui rend cette méthode plus « propre » et plus claire.

fichier formulaire.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Formulaire</title>
</head>

<body>
<form name="formulaire" method="post" action="ajout_message.php">
<label for="nom">Nom :</label><input type="text" id="nom" name="nom" /><br />
<label for="email">Courriel :</label><input type="text" id="email" name="email" /><br />
<label for="message">Votre message :</label><br />
<textarea id="message" name="message" cols="50" rows="10">Message par défaut</textarea><br />
<input type="submit" />
</form>
</body>
</html>

Traitement des données[modifier | modifier le wikicode]

Le fichier « ajout_message.php » va récupérer et traiter les données saisies par l'utilisateur puis effectuer une insertion dans la base (c'est-à-dire ajouter le message dans le livre d'or). Ces données portent le nom qui leur à été donné dans le formulaire, précédé d'un '$' (représente une variable en PHP). Il est fortement conseillé d'effectuer des tests de saisie à ce niveau, pour vérifier que l'utilisateur a remplit correctement les champs (champs non vides, adressse email correcte,...).

fichier params.php

<?php
$host='localhost';
$user='root';
$password='';
$base='toto';
?>

fichier ajout_message.php

<?php
isset($_POST['nom']) or die('Pas de paramètres en entrée');

//récupération des données entrées par l'utilisateur
$nom = $_POST['nom'];
$message = $_POST['message'];
$email= $_POST['email'];

//vérification des données entrées par l'utilisateur
if (($nom == "")||($message == ""))
        die("Paramètres incorrects.
        <a href='formulaire.html'>Cliquez ici pour revenir au formulaire</a>".mysql_error());
        
//connexion à la base
require 'params.php';
$link=mysql_connect($host,$user,$password) or die('Erreur de connexion au SGBD.');
mysql_select_db($base,$link) or die('La base de données n\'existe pas');

//insertion du message

$date=date("Y-m-d"); // on récupère la date
$message = htmlspecialchars($message,ENT_QUOTES); //convertit les caractères spéciaux
$sql="INSERT INTO `livre` ( `id` , `nom` , `email` , `date` , `message` ) VALUES ( NULL , '$nom', '$email', '$date', '$message' );";
$res=mysql_query($sql,$link);
mysql_close($link);
if ($res==NULL) die('Erreur lors de l\'écriture du message'.mysql_error());

print "Message correctement ajouté.<br />Merci d'avoir pris le temps de remplir ce livre d'or";
?>

La fonction htmlspecialchar() permet de convertir les caractères spéciaux qui pourrait être interprétés comme du code HTML par un navigateur. Il existe d'autres fonctions, comme htmlentities(), qui permet en plus de spécifier les caractères de remplacment, ou n12br() qui permet de remplacer les retours chariots par le caractère HTML de retour à la ligne (br).

Récupérer les messages et les faire afficher[modifier | modifier le wikicode]

Cette partie est beaucoup plus simple à réaliser que la partie précédente.


Voici la requête SQL qui permet de récupérer toutes les informations de la table dans la base de donées:

SELECT * FROM `livre` ORDER BY `id`

Les messages seront alors triés en fonction du champ `id`, et, par defaut, par ordre croissant, donc plus du plus ancien au plus récent. Pour les classer dans l'ordre décroissant, il faut rajouter l'instruction DESC, ce qui donne la requête suivante :

SELECT * FROM `livre` ORDER BY `id` DESC

Après, il suffit d'afficher les informations obtenues grâce à la requête.

fichier affiche_message.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Livre d'or</title>
</head>

<body>
<?php
//connexion à la base
require 'params.php';
$link=mysql_connect($host,$user,$password) or die('Erreur de connexion au SGBD.');
mysql_select_db($base,$link) or die('La base de données n\'existe pas');

//récupération des messages
$sql="SELECT * FROM `livre` ORDER BY `id` DESC";
$rep=mysql_query($sql,$link);
mysql_close($link);
while ( $ligne = mysql_fetch_array($rep))
{
	//on récupère les valeurs des diffèrent champs pour chaque message
	$nom=$ligne['nom'];
	$email=$ligne['email'];
	$date=$ligne['date'];
	$message=$ligne['message'];
	/* on remplace les retours chariots '\n'
	 par le symbole de retour à la ligne en HTML : <br /> */
	$message=nl2br($message);
	
	//on affiche ses valeurs dans un tableau
	print "<table>
	<tr><th>Par :<a href=mailto:$email>$nom</a>/th>
	<th>Le : $date</th></tr>
	<tr><td colspan='2'>$message</td></tr>
	</table>";

}

?>
</body>
</html>

Ceci n'est que le strict minimum pour faire un livre d'or. D'autres fonctionnalités, comme le nombre d'affichage par page, peuvent être ajoutées.


Exemples/MiniForum

Faire un mini forum de discussion[modifier | modifier le wikicode]

Bon nombre de forums sur internet ont repris des opensources et les ont customisé. Dans cet article, nous verrons comment simplement opposer de meilleures solutions, plus souples et personnelles. Cet article traitera du programme à fournir pour cette solution sans proposer de sécurisation.

Introduction[modifier | modifier le wikicode]

Voici un forum modulaire, universel, illimité, fonctionnel et très réactif mais à sécuriser avec Mysql en backend et xhtml en frontend.


Analyse[modifier | modifier le wikicode]

TODO :

  • une vue
  • un frameset variable
  • des topics illimités
  • des catégories illimités
  • un systeme de classement
  • un systeme d'administration
  • un systeme d'authentification
  • un espace myAccount


NICE TO HAVE :

  • tout automatiser (censure / délation / ..)
  • mailer
  • BO admin

Architecture[modifier | modifier le wikicode]

À bâtir en MVC, le forum est segmenté comme :

./index.php
./config.inc.php

// STATICAL MODULES

./Objects/
./Objects/frameset.inc.php // main frameset
./Objects/mainPage.inc.php // main pages content

// FUNCTIONNAL MODULES

./Libraries/

Déploiement[modifier | modifier le wikicode]

La méthodologie RUP fonctionne par itérations successives et augmentation, amélioration du code. On obtient donc pour chaque module différentes itérations représentatives de l'état d'avancement de l'application. L'état 0 ou incrément 0 étant le draft et incrément 1, la première itération de l'applicatif.

 Fichier : config.inc.php
<?php
/*  */

define('OBJ', './Objects/');
define('LIB', './Libraries/');

$cnx = array('host'=>'localhost','user'=>'root','db'=>'miniForum','pass'=>'');

?>

increment 0 : index.php

 Fichier : index.php
<?php
/* Mini Forum - main entry 
	
	This is a mini forum 
	
	version : 	1.0
	date : 		2009 07 28
	author : 	zulul
	
*/

require_once "./config.inc.php";
require_once OBJ . "frameset.inc.php";

echo $_mainSet;

?>

increment 1 : index.php

 Fichier : index.php
<?php
/* Mini Forum - main entry 
	
	This is a mini forum 
	
	version : 	1.0
	date : 		2009 07 28
	author : 	zulul
	
*/

@session_start();

require_once "./config.inc.php";
require_once OBJ . "frameset.inc.php";

// lib
require_once LIB . "Connectivity.cla.php";
require_once LIB . "Request.cla.php";
require_once LIB . "utils.fnc.php";

// autho
if(chk_usr($cnx))
	$_SESSION['autho'] = 1;
	
echo $_mainSet;

?>


increment 2 : index.php

 Fichier : index.php
<?php
/* Mini Forum - main entry 
	
	This is a mini forum 
	
	version : 	1.0
	date : 		2009 07 28
	author : 	zulul
	
*/

@session_start();

require_once "./config.inc.php";

// lib
require_once LIB . "Connectivity.cla.php";
require_once LIB . "Request.cla.php";
require_once LIB . "utils.fnc.php";

// page listener
require_once OBJ . "listener.inc.php";

// autho
if(chk_usr($cnx))
{
	$_SESSION['autho'] = 1;
}

// controling application
require_once OBJ . "controler.inc.php";
// variing frameset call
require_once OBJ . "frameset.inc.php";


# OUTPUT
echo $_mainSet;

?>

Objects[modifier | modifier le wikicode]

 Fichier : frameset.inc.php
 
<?php
/* main page 

*/

require_once OBJ."mainPage.inc.php";

$_mainSet = <<<EOPAGE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//FR" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html lang="fr" xml:lang="fr">
 <head>
	{$_content['title']}
	{$_content['meta']}
	{$_content['style']}
 </head>
 <body>
	{$_content['main']}
 </body>
</html>
EOPAGE;
?>

increment 3 : frameset.inc.php

 Fichier : frameset.inc.php
 
 <head>
	{$_content['title']}
	{$_content['meta']}
	{$_content['script']}
	{$_content['style']}
 </head>

increment 0 : mainPage.inc.php

 Fichier : mainPage.inc.php
 
<?php
/* Main page content 

*/

$title 		= ':: TITLE ::';
$meta		= '';
$style		= '';


// head content
$_content['title']	= '<title>'.$title.'</title>';
$_content['meta']	= '<meta>'.$meta.'</meta>';
$_content['style']	= '<style>

	body
	{
		margin:0 0 0 0;
		font-family:tahoma;
		font-size:10px;
	}
	
	table td
	{
		border:1px solid;
		padding:5px;
		margin:5px;
	}

	.grey
	{
		background-color:#eee;
	}
	
	.creeper
	{
		border:1px solid;
		height:200px;
	}
	
</style>';

// content contents
$_content['authorize'] = '
	<div id="cAuthorize">
		
		<table align="center" width="100%">
			<tr><td class="grey">pseudo <input type="text" value=""/></td></tr>
			<tr><td class="grey">passwd <input type="text" value=""/></td></tr>
			<tr><td class="grey"><input type="button" value="submit()"/></td></tr>
		</table>
	</div>
	
';

// content contents
$_content['skyCreeper'] = '
	<div>
		<div class="creeper">
		<br/>this is the content
		<br/>this is thec content
		<br/>this is the content	
		</div>
	</div>';

$_content['pager'] = <<<EOPAGE
	<div id="cAuthorize">
		
		<table width="100%">
			<tr valign="top"><td width="50%" height="250" class="grey">:: 1 ::</td><td class="grey">:: 2 ::</td></tr>
			<tr valign="top"><td width="50%" height="250" class="grey">:: 3 ::</td><td class="grey">:: 4 ::</td></tr>
		</table>
		
	</div>
EOPAGE;

// body contents
$_content['main']	= <<<EOPAGE
	<table width="99%" height="600">
		
		<!-- its still better to stay with table instead of divs -->
		<tr>
			<td height="18" colspan="2" width="99%" align="center" class="grey">
				:: THIS IS TOP CONTENT ::			
			</td>
		</tr>
		<tr valign="top">
			<td width="20%">
				{$_content['authorize']}
				{$_content['skyCreeper']}
			</td>
			<td width="79%">
				{$_content['pager']}
			</td>
		</tr>
		<tr>
			<td height="18" colspan="2" width="99%" align="center" class="grey">:: THIS IS BOTTOM CONTENT ::</td>
		</tr>
	</table>
EOPAGE;

?>

increment 1 : listener.inc.php

 Fichier : listener.inc.php
 
<?php
/* application listener

*/

/* flag cases

*/
switch(true)
{
	case(@$_REQUEST['aut']=='0'):
		//action disconnect
		unset($_SESSION['autho'],$_SESSION['userMod']);
		break;
	
	/*
	case ():
		break;
	*/
}

?>


increment 1 : controler.inc.php

 Fichier : controler.inc.php
 
<?php
/* application controler

*/

# INIT

/* admin and mod status control 

*/
if(@$_REQUEST['aut']!='0')
{
	// moderating user
	mod();
}

# PREPARE

/* cases

*/
if(@$_SESSION['userMod'])
{//
	
	if(preg_match('/[0]/',$_SESSION['userMod']['adm']))
		$_mod[0] = 'superAdmin';
		
	if(preg_match('/[1]/',$_SESSION['userMod']['adm']))
		$_mod[0] = 'Admin';
		
	if(preg_match('/[0]/',$_SESSION['userMod']['mod']))
		$_mod[1] = 'superModerator';
		
	if(preg_match('/[1]/',$_SESSION['userMod']['mod']))
		$_mod[1] = 'Moderator';
}
?>

increment 1 : mainPage.inc.php

A cette itération, l'authentification du user est fonctionnelle.
Le snippet content['authorize'] change de mode.
 Fichier : mainPage.inc.php
... 
// content contents
$_content['authorize'] = (!@$_SESSION['autho'])?'
	<div id="cAuthorize">
		<form action="" method="post" name="form">
		<table align="center" width="100%">
			<tr><td colspan="2" class="grey">pseudo <input name="login" type="text" value=""/></td></tr>
			<tr><td colspan="2" class="grey">passwd <input name="pass" type="text" value=""/></td></tr>
			<tr><td class="grey" align="left"><input type="submit" value="submit" /> </td>
			<td align="right"><a href="">forgot password</a><br/><a href="">new registration</a></td></tr>
		</table>
		</form>
	</div>
':'logged';
...

increment 2 : mainPage.inc.php

A cette itération, l'attribution des privilèges du user est fonctionnelle.
Le snippet content['authorize'] affiche le statut user mode.
 Fichier : mainPage.inc.php
 
// content contents
$_content['authorize'] = (!@$_SESSION['autho'])?'
	<div id="cAuthorize">
		<form action="'.$_SERVER['PHP_SELF'].'" method="post" name="form">
		<table align="center" width="100%">
			<tr><td colspan="2" class="grey">pseudo <input name="login" type="text" value=""/></td></tr>
			<tr><td colspan="2" class="grey">passwd <input name="pass" type="text" value=""/></td></tr>
			<tr><td class="grey" align="left"><input type="submit" value="submit" /> </td>
			<td align="right"><a href="">forgot password</a><br/><a href="">new registration</a></td></tr>
		</table>
		</form>
	</div>
':'<div id="cAuthorize"><table align="center" width="100%"><tr><td>logged | 
	<a href="'.$_SERVER['PHP_SELF'].'?aut=0">disconnect</a><br/><br/>Status : '.@$_mod[0] . " " . @$_mod[1] .'</td></tr></table></div>';

// content contents
$_content['containers'] = '
	<table width="100%"><tr><td>:: PARTNER 1 ::</td></tr></table>
	<table width="100%"><tr><td>:: PARTNER 2 ::</td></tr></table>
';

increment 3 : jsScript.inc.php

intégration des javascripts
 Fichier : mainPage.inc.php
<?php

	$script = '
		/* javascript scripts
		
		*/
		
		function showHide(obj)
		{//	>(element)
			
			if(obj.style.display!="none")
				obj.style.display="none";
			else
				obj.style.display="";
		}
	
	';

?>

increment 3 : pages.inc.php

contenus des pages
 Fichier : pages.inc.php
<?php
/* pager contents

*/

// mod 1
if(@$_REQUEST['mod'] == '1' && @$_SESSION['autho']) //
{
	
	// list rubriq
	$_res=Request::SQL($cnx,'SELECT * FROM topics ORDER BY id');
	foreach($_res as $_tmp)
	{
		@$str .= '<br/><form method="post" action="' . $_SERVER['PHP_SELF'] . '?mod=1" name="f3"><input name="iDel" type="hidden" value="' . $_tmp['id'] . '" /><input type="submit" value="[-]"/> <a href="">' . $_tmp['title'] . '</a></form>';
	}
	
	$_content['pager']  = '
	<div class="title">Rubriques existantes | <span class="toAct" onclick="showHide(getElementById(\'cRubriq\'));">Ajouter une rubrique</span><br/>
		<!-- Rubriq adder -->
		<table width="100%">
			<tr valign="top">
				<td>
					<div id="cRubriq">Ajouter une nouvelle rubrique
						<form name="f2" method="post" action="' . $_SERVER['PHP_SELF'] . '?mod=1">
							<p><input name="iRubriq" type="text" size="50" /><input type="submit" value="add"/></p>
						</form>
					</div>
				</td>
			</tr>
			<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
		</table>
	</div>
	';
	
}

// rub 1
if(@$_REQUEST['rub'] == '1') //
{
	
	if(!@$_REQUEST['tId'])
	{
		// list rubriq
		$_res=Request::SQL($cnx,'SELECT * FROM topics ORDER BY id');
		foreach($_res as $_tmp)
		{
			@$str .= '<br/> <a href="'.$_SERVER['PHP_SELF'].'?rub=1&tId=' . $_tmp['id'] . '">' . $_tmp['title'] . '</a>';
		}
		
		$_content['pager']  = '
		<div class="title">Rubriques existantes
			<table width="100%">
				<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
			</table>
		</div>
		';
		
	} else {
		
		// list rubriq
		$_res=Request::SQL($cnx,'SELECT * FROM contents WHERE topicsId=' . @$_REQUEST['tId'] . ' ORDER BY id');
		foreach($_res as $_tmp)
		{
			@$str .= '<br/> <a href="' . $_SERVER['PHP_SELF'] . '?rub=1&tId=' . $_tmp['topicsId'] . '">' . $_tmp['subject'] . '</a>';
		}
		
		$_content['pager']  = '
		<div class="title">Topics existants
			<table width="100%">
			<!-- Topics adder -->
				<tr valign="top">
					<td>
						<div id="cTopics">Ajouter un nouveau topic
							<form name="f4" method="post" action="' . $_SERVER['PHP_SELF'] . '?rub=1">
								<p><input name="iTopics" type="text" size="50" /><input type="submit" value="add" /></p>
							</form>
						</div>
					</td>
				</tr>
				<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
			</table>
		</div>
		';
		
	}
}
?>


increment 4 : pages.inc.php

contenus des pages complétés
 Fichier : pages.inc.php
<?php
/* pager contents

*/

// mod 1
if(@$_REQUEST['mod'] == '1' && @$_SESSION['autho']) //
{
	
	// list rubriq
	$_res=Request::SQL($cnx,'SELECT * FROM topics ORDER BY id');
	foreach($_res as $_tmp)
	{
		@$str .= '<br/><form method="post" action="' . $_SERVER['PHP_SELF'] . '?mod=1" name="f3"><input name="iDel" type="hidden" value="' . $_tmp['id'] . '" /><input type="submit" value="[-]"/> <a href="">' . $_tmp['title'] . '</a></form>';
	}
	
	$_content['pager']  = '
	<div class="title">Rubriques existantes | <span class="toAct" onclick="showHide(getElementById(\'cRubriq\'));">Ajouter une rubrique</span><br/>
		<!-- Rubriq adder -->
		<table width="100%">
			<tr valign="top">
				<td>
					<div id="cRubriq">Ajouter une nouvelle rubrique
						<form name="f2" method="post" action="' . $_SERVER['PHP_SELF'] . '?mod=1">
							<p><input name="iRubriq" type="text" size="50" /><input type="submit" value="add"/></p>
						</form>
					</div>
				</td>
			</tr>
			<tr valign="top" height="500"><td><p>' . @$str . '</p></td></tr>
		</table>
	</div>
	';
	
}

// rub 1
if(@$_REQUEST['rub'] == '1') //
{
	if(!@$_REQUEST['tId'])
	{
		// list rubriq
		$_res=Request::SQL($cnx,'SELECT * FROM topics ORDER BY id');
		foreach($_res as $_tmp)
		{
			@$str <