:tocdepth: 2 ============================ PHP : Les bases ============================ Le PHP, c'est quoi ? ==================== PHP Hypertext Preprocessor +++++++++++++++++++++++++++ .. figure:: _static/php/logo_php.png :height: 6ex :align: right :alt: php Source image `Wikimedia commons`__ __ http://commons.wikimedia.org/wiki/File:PHP-logo.svg * Un acronyme récursif * Un **langage de script interprété côté serveur** * Qui permet d'écrire des pages web **dynamiques** * Indiqué par l'extension de fichier **.php** * Un outil pour interagir avec une `base de données `:doc: (MySQL) Documentation: http://php.net/ Comment ça marche ? ++++++++++++++++++++ - Reprenons l'architecture client serveur ; pour une page statique (HTML) : .. figure:: _static/php/client-serveur_HTML.png :alt: client-serveur-html - pour une page dynamique (PHP) : .. figure:: _static/php/client-serveur_PHP.png :alt: client-serveur-php Quel lien avec HTML/CSS ? ++++++++++++++++++++++++++ - Le client (navigateur) est incapable de lire du code PHP, mais il sait afficher du code HTML et/ou CSS. - PHP est interprété côté serveur : .. figure:: _static/php/client-serveur_PHP2.png :alt: client-serveur-php2 - On va donc demander à PHP de générer du HTML. - On peut aussi utiliser PHP pour générer autre chose : du CSS, du JSON... ! Quel lien avec JavaScript ? ++++++++++++++++++++++++++++ JavaScript : - est un langage de script, tout comme PHP ; - permet de modifier dynamiquement le contenu HTML/CSS ; - **mais** s'éxécute **généralement** côté client et non côté serveur. .. figure:: _static/php/client-serveur_JS.png :alt: client-serveur-JS Pourquoi utiliser PHP alors ? +++++++++++++++++++++++++++++ Pour des raisons : * Fonctionnelles : les données sont centralisées sur le serveur (ex. forum) * De sécurité : Certaines données doivent rester inaccessibles au client (mot de passe) * De personnalisation : chaque utilisateur peut avoir une page différente (horloge) Autres concurrents : * `ASP.NET`_ * `Ruby on Rails`_ * `JSP (Java EE)`_ .. _ASP.NET: http://www.asp.net/ .. _Ruby on Rails: http://rubyonrails.org/ .. _JSP (Java EE): http://www.oracle.com/technetwork/java/javaee/jsp/index.html Ma première page ================ Les fichiers PHP ++++++++++++++++ * Extension ".php" * Instructions entre les balises ```` - Syntaxe courte pour l'affichage : ```` * Commentaires: - Multilignes ``/*`` ... ``*/`` - Monoligne ``//`` ou ``#`` * Instructions terminées par ``;`` * Insensible à la casse pour les noms de fonction MAIS pas pour les noms de variables. Exemple : générer du HTML +++++++++++++++++++++++++ .. code-block:: html+php Ma première page en PHP ! Ce texte est écrit par du script PHP !'; ?> L'instruction ``echo`` est un mot-clé PHP. Il permet d'écrire la chaîne de caractères qui suit dans la sortie (comparable à ``printf()`` en C). .. nextslide:: L'équivalent avec la syntaxe courte : .. code-block:: html+php Ma première page en PHP ! Ce texte est écrit par du script PHP !' ?> Autres types de sortie ++++++++++++++++++++++ Cet exemple est aussi un script PHP valide : .. code-block:: php Mais la sortie n'est plus du HTML (pas de DOCTYPE, aucune balise). C'est du texte brut (type MIME : ``text/plain``). Enfin, voyons comment générer du CSS (type MIME : ``text/css``) : .. code-block:: php body { background-color: ; } .. nextslide:: Un tel exemple ne représente que peu d'intérêt, mais lorsque nous verrons comment dynamiser nos scripts cela deviendra intéressant ! .. tip:: Nous verrons par la suite qu'il est possible d'inclure un fichier PHP dans un autre, ce qui donne tout son intérêt à concevoir des fichiers PHP réduits, mais génériques. .. _exo_premierepagephp: Exercice (10 minutes) +++++++++++++++++++++ #. Téléchargez le modèle minimal de `page HTML <_static/php/html5_minimal.html>`__. #. Sauvegardez le fichier sous l'extension ".php" #. Ajoutez du code PHP entre balises ```` pour afficher du texte dans la page - Essayez également la syntaxe courte ```` #. Testez l'éxécution de votre script depuis un serveur (local ou en ligne) #. Comparez votre fichier avec la source reçue au niveau du client Voir le `résultat <_static/php/corrections/premierepagephp/>`__ attendu. Un point sur l'UTF-8 ====================== Apache et UTF-8 ++++++++++++++++ Il existe différente normes pour coder les accents dans les chaînes de caractère, **utf-8** est la plus récente mais les navigateurs utilisent par défaut latin1 qui est la norme historique pour les langues occidentales. .. tip:: Si votre éditeur de texte sauvegarde vos fichiers en utf-8 mais que le navigateur de votre visiteur interprète cela comme du latin1, les accents seront mal affichés (é à la place de é...). Plusieurs solutions pour spécifier l'encodage au navigateur, dans l'ordre de préférence : .. nextslide:: * Configurer le serveur Web pour ajouter un en-tête HTTP. Pour apache, c'est dans /etc/apache2/apache2.conf - Configuration globale : c'est dans /etc/apache2/apache2.conf * On n'y a pas toujours accès (il faut être root) - Configuration locale (juste votre site) : fichiers .htaccess (voir chapitre suivant) * Utiliser la fonction PHP ``header('Content-Type: text/html; charset=utf-8)`` - Cette fonction doit être appelée avant d'avoir fait la moindre sortie, sinon c'est trop tard (on ne peut pas ajouter un en-tête HTTP lorsque le transfert du contenu a déjà commencé). .. nextslide:: * Utiliser la balise HTML ```` dans la section ```` - pour en `savoir plus`__ .. __: https://www.alsacreations.com/article/lire/628-balises-meta.html#httpequiv Les fichiers .htaccess ++++++++++++++++++++++ Fichier ``.htaccess`` : * fichiers de configuration apache * portée limitée au dossier * pas de reboot apache necessaire Permettent: * Sécurité (Public/Privé, ...) * Réécriture d'URL * Redirection * Gestion erreurs (404, 403, ...) - afficher une page personnalisée Structure .htaccess +++++++++++++++++++ Ensemble de directives, similaire au fichier de config apache .. code-block:: apache RewriteEngine on ErrorDocument 404 /erreur.html Dans notre cas, pour modifier l'encodage dans les en-tetes HTTP .. code-block:: apache AddDefaultCharset UTF-8 .. tip:: Pour créer un fichier .htaccess sous windows, il faut (entre autre) que les extensions de fichier soient visibles dans le navigateur Les variables ============== Syntaxe +++++++ Utilisation de la mémoire du serveur afin de stocker des informations durant l'éxécution du script PHP, dans des **variables** qui : * s'écrivent avec un identifiant précédé d'un ``$``, par exemple ``$ma_variable``, * ne se déclarent pas, c'est l'affectation qui détermine leur type : .. slide:: - booléen (``true``/``false``) - nombre entier - flottants (nombre à virgule) - chaîne de caractères (entre quotes, ``'``) - tableau - ressource (handler de fichier, comme en C avec ``fopen()``) - ou même un objet (programmation orientée objet) Exemple ------- .. code-block:: php `Résultat <_static/php/test.php#affvariable>`__ HTML : .. code-block:: html Vous avez 21 ans ! Les chaînes de caractères +++++++++++++++++++++++++ Les chaînes de caractères : * écrites entre ``'`` ou entre ``"`` * concaténation avec ``.`` (attention ``+`` fait la somme) * peuvent interpréter la valeur d'une variable (si ``"`` est utilisé) NB: Beaucoup de fonctions existent pour la manipulation des strings (`PHP Manual for Strings`_) .. _PHP Manual for Strings: http://www.php.net/manual/fr/ref.strings.php Affichage de chaines -------------------- La syntaxe de PHP permet de simplifier l'affichage de chaînes de caractères entre elles ou avec des variables. La syntaxe est différente suivant les délimiteurs utilisés : .. code-block:: php .. nextslide:: .. code-block:: html Voici une phrase composée de 8 mots. Voici une $mot1 composée de $mot2 mots. Voici une phrase composée de 8 mots. NB : Le caractère ``\n`` correspond à un retour à la ligne en texte brut. A ne pas confondre avec la balise ``
`` qui est un retour à la ligne HTML ! Les tableaux +++++++++++++ Les tableaux sont un type spécial de variable capable de stocker plus d'une valeur. Il existe deux types de tableaux en PHP : * Les tableaux **numérotés** (tableaux simples) * Les tableaux **associatifs** (tableaux clé-valeur) Les tableaux numérotés ---------------------- Ils contiennent des éléments accessibles via leur indice. Les indices démarrent à 0 en PHP. Par exemple, votre tableau pourrait contenir : ====== =========== Clé Valeur ====== =========== 0 François 1 Michel 2 Nicole 3 Véronique 4 Benoît ... ... ====== =========== Affectation ``````````` * Avec la fonction ``array`` : .. code-block:: php * Depuis les indices : .. code-block:: php .. nextslide:: * Avec des indices implicites (ajouter à la fin) : .. code-block:: php Ce code est équivalent au précédent, mais sera moins lisible pour l'accès futur aux éléments du tableau. Accès aux éléments `````````````````` .. code-block:: php Voir le `résultat <_static/php/test.php#accestableau>`__ . Les tableaux associatifs ------------------------ Ils permettent de donner des noms aux clés Par exemple, votre tableau pourrait contenir : ========== ========================== Clé Valeur ========== ========================== prenom François nom Dupont adresse 3 rue du Paradis ville Marseille ========== ========================== Cette fois, les notion de "clé" et de "valeur" prennent tout leur sens. Affectation ``````````` * Avec la fonction ``array`` : .. code-block:: php 'François', 'nom' => 'Dupont' ); ?> .. nextslide:: * En définissant les indices : .. code-block:: php Accès aux éléments `````````````````` .. code-block:: php Voir le `résultat <_static/php/test.php#accestableauassoc>`__ . Conversion de type ++++++++++++++++++ Le "cast" existe en PHP : il est possible de convertir une variable d'un type à un autre type. Il suffit de préciser le type après conversion entre parenthèses. Par exemple : .. code-block:: php Voir le `résultat <_static/php/test.php#cast>`__ . .. tip:: Il est recommandé de privilégier aux casts les fonctions spécialisées comme `intval`__. .. __: http://php.net/manual/fr/function.intval.php Les structures de contrôle ========================== Les conditions +++++++++++++++++ Elles permettent de définir des **conditions** lors de l'éxécution de votre script PHP : ======= ========================================= Symbole Signification ======= ========================================= == Est équivalent à === Est strictement égal (type et valeur) à != N'est pas équivalent à !== N'est pas strictement égal à > Est supérieur à < Est inférieur à >= Est supérieur ou égal à <= Est inférieur ou égal à ======= ========================================= .. nextslide:: .. warning:: ``0 == false`` est vrai mais ``0 === false`` est faux. Privilégier **===** et **!==**, sauf cas particuliers. Voir la fonction `strpos`__ pour comprendre... __ http://php.net/manual/fr/function.strpos.php Exemple : ``if ... else`` ------------------------- .. code-block:: php :linenos: = 8) // SI $save_mdp = true; elseif ($longueur_mdp >= 6) // SINON SI { $save_mdp = true; echo "Ce mot de passe n'est pas très sûr !\n"; } else // SINON { echo "Ce mot de passe est trop court !\n"; $save_mdp = false; } if ($save_mdp) echo "Mot de passe sauvegardé !"; ?> Voir le `résultat <_static/php/test.php#mdp>`__ . .. nextslide:: PHP tolère aussi l'écriture condensée (nommée opérateur ternaire) : .. code-block:: php Comparée au ``if``, cette écriture permet de réduire le nombre de lignes de code, au détriment de sa lisibilité. Elle est cependant pratique pour lutilisation des balises courtes : .. code-block:: php = 18) ? 'Accès autorisé' : 'Accès refusé' ?> Exemple : ``switch`` -------------------- .. code-block:: php :linenos: Voir le `résultat <_static/php/test.php#switch>`__ . Les conditions multiples ++++++++++++++++++++++++ Il est possible de combiner les conditions dans une même instruction : ======= ============ ========================== Symbole Mot-clé Signification ======= ============ ========================== ``&&`` AND Et ``||`` OR Ou ``!`` NOT Négation de la condition ======= ============ ========================== Exemple : .. code-block:: php Les boucles et opérateurs ========================= Les boucles +++++++++++ Il existe trois boucles en PHP : * la boucle ``while`` ; * la boucle ``for`` ; * la boucle ``foreach``. La boucle ``while`` ------------------- Elle permet d'éxécuter la même série d'instructions tant que la **condition d'arrêt** n'est pas vérifiée. Exemple : .. code-block:: php Voir le `résultat <_static/php/test.php#while>`__ . .. nextslide:: .. tip:: La bouche ``do-while`` existe aussi. Pratique pour s'assurer qu'on rentre au moins une fois dans la boucle. La boucle ``for`` ------------------- Elle est très semblable à la boucle ``while`` mais permet cette fois de regrouper les conditions initiales, d'arrêt et l'incrémentation. Exemple : .. code-block:: php Voir le `résultat <_static/php/test.php#for>`__ . .. _boucle_foreach: La boucle ``foreach`` --------------------- Les tableaux ne **DOIVENT PAS** être parcourus à l'aide d'une boucle for indicée comme en C, pour la bonne raison que les éléments intermédiaires peuvent être supprimés et donc la contiguité des éléments n'est pas assurée. La bonne pratique est d'utiliser foreach. Pour les tableaux simples ````````````````````````` .. code-block:: php Voir le `résultat <_static/php/test.php#foreach>`__ . Pour les tableaux clé-valeur ```````````````````````````` .. code-block:: php 'François', 'nom' => 'Dupont', 'adresse' => '3 Rue du Paradis', 'ville' => 'Marseille'); foreach($coordonnees as $champ => $element){ echo $champ . ' : ' .$element . "\n"; } ?> Voir le `résultat <_static/php/test.php#foreach2>`__ . .. _exo_tableau: Exercice ```````` #. Créez un nouveau fichier PHP vide. #. Créez et initialisez un tableau clé-valeur dont les clés seront "prix_unitaire" et "quantite". #. Réalisez un affichage basique en parcourant votre tableau. Voir le `résultat <_static/php/corrections/tableau/>`__ attendu. Les opérateurs ++++++++++++++ L'utilisation de variables implique la présence d'opérateurs pour pouvoir les manipuler. PHP comprend une multitude d'opérateurs pour manipuler les variables numériques, booléennes, ou les chaînes de caractères. Opérateurs arithmétiques ------------------------ PHP reconnait tous les `opérateurs arithmétiques`__ classiques : =========== =============== ======================================================================= Exemple Nom Résultat =========== =============== ======================================================================= -$a Négation Opposé de $a. $a + $b Addition Somme de $a et $b. $a - $b Soustraction Différence de $a et $b. $a \* $b Multiplication Produit de $a et $b. $a / $b Division Quotient de $a et $b. $a % $b Modulo Reste de $a divisé par $b. $a \*\* $b Exponentielle Résultat de l'élévation de $a à la puissance $b. Introduit en PHP 5.6. =========== =============== ======================================================================= __ http://php.net/manual/fr/language.operators.arithmetic.php Opérateurs d'affectation ------------------------ On peut modifier une variable "à la volée" : =============== =============== ======================= Exemple Nom Résultat =============== =============== ======================= $a = 3 Affectation $a vaut 3. $a += 3 Addition $a vaut $a + 3. $a -= 3 Soustraction $a vaut $a - 3. $a \*= 3 Multiplication $a vaut $a \* 3. $a /= 3 Division $a vaut $a /3. $a %= 3 Modulo $a vaut $a % 3. $a++ Incrémentation Equivalent à $a += 1. ``$a--`` Décrémentation Equivalent à $a -= 1. $b .= 'chaine' Concaténation $b vaut $b.'chaine'. =============== =============== ======================= Opérateurs de `comparaison`__ ----------------------------- ============== ================== ======================================================= Exemple Nom Résultat ============== ================== ======================================================= $a == $b Équivalent TRUE si $a est égal à $b $a===$b Identique TRUE si $a == $b, + même type. $a != $b Non-équiv. TRUE si $a est différent de $b $a <> $b Non-équiv. TRUE si $a est différent de $b $a !== $b Différent TRUE si $a != $b ou types différents. $a < $b Inférieur TRUE si $a est inférieur strict à $b. $a > $b Supérieur TRUE si $a est supérieur strict à $b. $a <= $b Inférieur ou égal TRUE si $a est inférieur ou égal à $b. $a >= $b Supérieur ou égal TRUE si $a est supérieur ou égal à $b. ============== ================== ======================================================= __ http://php.net/manual/fr/language.operators.comparison.php Les fonctions ============= Définir une fonction ++++++++++++++++++++ La syntaxe PHP impose l'utilisation du mot-clé ``function`` : .. code-block:: php Les fonctions peuvent ne rien retourner (pas d'instruction ``return``, ou instruction explicite ``return;``). En fait, c'est la valeur ``NULL`` qui est retournée. Appeler une fonction ++++++++++++++++++++ .. code-block:: php .. note:: Comme le langage PHP n'est pas typé, il est possible d'injecter des types de variables incompatibles dans les fonctions. Il faut donc penser à cette éventualité lors de l'écriture de vos fonctions. .. tip:: Une bonne pratique consiste à définir vos fonctions dans des fichiers séparés, puis de les inclure dans vos pages grâce à la fonction ``require_once``. Voir le `résultat`__ attendu. __ _static/php/corrections/fonction/ Les fonctions de PHP ++++++++++++++++++++ PHP propose une multitude de fonctions "toutes prêtes", qui permettent entre autre : * de manipuler les chaînes de caractères, * de déplacer/envoyer des fichiers, * de manipuler des images, * d'envoyer des e-mail, * de crypter les mots de passe, * de manipuler les dates, * ... Le site web de PHP référence `toutes les fonctions`__ par catégorie. __ http://fr.php.net/manual/fr/funcref.php Intégrer des fichiers externes ------------------------------ * PHP a été pensé pour la conception d'applications Web * PHP permet de définir des "briques de base" réutilisables * Il existe plusieurs fonctions d'intégration : - ``include('page.php');`` qui permet d'intégrer le contenu de 'page.php'. Un message warning s'affiche si la ressource est manquante. - ``require('page.php');`` qui fait la même chose mais une erreur fatale est retournée si la ressource est manquante (arrêt du script). - ``include_once('page.php');`` et ``require_once('page.php');`` intègrent en plus un test pour empêcher une intégration multiple. Transmettre des données ======================= Via un formulaire : Les méthodes d'envoi ++++++++++++++++++++++++++++++++++++++++ En HTML, la balise ``
`` spécifie la méthode HTTP utilisée par le formulaire : * **GET** : * Dans le cas d'une lecture d'information (accès à un article, recherche) * Les données seront passées via l’URL (défaut) * **POST** : * Dans le cas d'une modification (Paramètres utilisateurs) * Les données seront passées dans le corps de la requête HTTP GET : Envoi par l'URL +++++++++++++++++++++ La méthode d'envoi GET est celle utilisée par défaut lorqu'on utilise les formulaires sans préciser la méthode : .. code-block:: html ...
Cette écriture est exactement équivalente à : .. code-block:: html
...
GET : Envoi par l'URL +++++++++++++++++++++ Les données du formulaire qui sont passées dans l'URL s'écrivent sous la forme : .. raw:: html

http://www.site.com/page.php?param1=valeur1&param2=valeur2...


.. raw:: html

Le caractère ? sépare le nom de la page des paramètres.

Chaque couple paramètre/valeur s'écrit sous la forme : nom=valeur; ils sont séparés les uns des autres par le symbole &.

.. note:: Le nom des paramètres correspond à la valeur de l'attribut ``@name`` définit dans chaque balise ````. La valeur des paramètres correspond à la valeur de l'attribut ``@value`` s'il est définit, ou au texte saisi par l'utilisateur (dans un champ texte par exemple). Reception des données +++++++++++++++++++++ Côté serveur (en PHP, donc), les valeurs passées dans l'URL sont stockées dans un tableau associatif ``$_GET`` : Exemple (avec l'URL précédente) : .. code-block:: php .. warning:: Comme les paramètres et leurs valeurs sont intégrés dans l'URL, ils sont directement modifiables. Il est donc très important de tester si les données reçues sont celles attendues (mauvais type, données manquantes ...). Transmettre des données dans une requête ++++++++++++++++++++++++++++++++++++++++ La méthode POST doit être spécifiée dans le formulaire si l'on souhaite transmettre des données dans une requête : .. code-block:: html
...
Dans ce cas, les paramètres et leurs valeurs envoyés ne seront plus visibles dans l'URL. Traitement des données reçues en Post +++++++++++++++++++++++++++++++++++++ Les valeurs transmises par la méthode Post sont stockées dans la variable ``$_POST``. Les données sont stockées de la même manière que dans la variable ``$_GET``. .. warning:: Même si les paramètres et leurs valeurs sont transmises "en caché", il est tout de même possible d'envoyer des valeurs inattendues (par exemple, en modifiant une copie du code HTML du formulaire, ou en faisant une requête HTTP manuellement via ``curl``). Il est donc tout aussi important de contrôler les données reçues. Contrôler la valeur des paramètres ++++++++++++++++++++++++++++++++++ Lorsque des données transitent par l'URL, il faut s'assurer que les **valeurs correspondent au type attendu**. Dans le cas contraire, il faut soit essayer de les convertir soit retourner une erreur. De plus, il est possible que certains paramètres attendus dans le code PHP soient absents de l'URL, dans ce cas il est possible de **tester leur présence** avec la fonction ``isset``. .. nextslide:: Exemple : .. code-block:: php Aller plus loin dans le contrôle des paramètres +++++++++++++++++++++++++++++++++++++++++++++++ En plus de vérifier le type et la présence des paramètres, le traitement des chaînes de caractères doit comprendre une conversion pour **éviter que le texte puisse être interprété comme du code** HTML (ou JavaScript). Voir `Faille XSS`__. Il existe des fonctions PHP conçues à cet effet : ``htmlspecialchars`` (`documentation`__) et ``htmlentities`` (`documentation`__). Elles permettent de convertir les caractères spéciaux en entités HTML. Exemple : __ https://fr.wikipedia.org/wiki/Cross-site_scripting __ http://php.net/manual/fr/function.htmlspecialchars.php __ http://php.net/manual/fr/function.htmlentities.php .. nextslide:: .. code-block:: php 0) && (strlen($value) < 50)) { ... // } else echo 'Erreur...'; ?> .. _exo_impots: Exercice : Les impôts +++++++++++++++++++++ * On souhaite faire une page simple permettant à un utilisateur de calculer le montant de son impôt * On calcule le nombre de parts de l'utilisateur (nbEnfants est son nombre d'enfants) .. code:: N = nbEnfants (pas marié) N = nbEnfants+1 (marié) * On calcule le revenu par part (R est le revenu imposable) .. code:: Q = R / N Exercice : Les impôts +++++++++++++++++++++ * Les tranches du barème sont les suivantes, selon le revenu par part Q, à appliquer au revenu imposable : ======== ============ ============= ============== ============== 0 à 9963 9964 à 27518 27519 à 73778 73779 à 156243 156244 et plus ======== ============ ============= ============== ============== 0% 14% 30% 41% 45% ======== ============ ============= ============== ============== * Les déductions par part sont les suivantes, selon le revenu par part Q : ======== ============ ============= ============== ============== 0 à 9963 9964 à 27518 27519 à 73778 73779 à 156243 156244 et plus ======== ============ ============= ============== ============== 0 1394,96 5798 1391,69 20163,45 ======== ============ ============= ============== ============== Exercice : Les impôts +++++++++++++++++++++ #. Créer un formulaire permettant à l’utilisateur de rentrer ses informations #. Calculer le montant prévisionnel de son impôt #. Afficher le résultat .. figure:: _static/php/form.png