Comme nous nous dirigeons vers le futur, sur Mac OS Homebrew, PHP 5.6 n’est plus disponible. Or cette version de PHP était très utilisée, et quand vous récupérez des projets ancienc qui tournent sous cette version, ils risquent de ne pas tourner sur PHP 7 par exemple. Dans ce cas vous avez besoin de vous tourner vers la version PHP 5.6.
Seulement Homebrew officiellement ne fournit plus PHP 56. Mais il est quand même possible de l’installer avec une petite manipulation.
brew tap exolnet/homebrew-deprecated
brew install php@5.6
Ajoutez dans le fichier /etc/apache2/httpd.conf la ligne
Et décommentez la ligne qui charge le module php7, redémarrez apache avec la commande suivante (vous aurez besoin de rentrer le mot de passe :
sudo apachectl restart
Ensuite pour vérifier la version de php surtout ne faites pas en ligne de commande php -v . ! En effet il existe deux version de PHP potentiellement, une version pour la ligne de commande et une version pour le serveur web.
Changer la version de PHP utilisée en ligne de commande
Là c’est un peu plus délicat. En faisant l’installation de PHP 5.6 via Homebrew, le binaire est installé dans le répertoire : /usr/local/Cellar/php@5.6/5.6.40/bin/
Pour exécuter PHP de ce répertoire et disposer de la version 56, indiquez le chemin complet :
/usr/local/Cellar/php@5.6/5.6.40/bin/php -v
PHP 5.6.40 (cli) (built: Apr 23 2019 11:14:34)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
La veille d’écrire ce post, cela faisait à peu près deux mois que je m’était mis sur Symfony 4 (j’ai eu aussi une petite période avec Symfony 2 par le passé mais moins investi)
Pourquoi ce tweet? comme souvent mes tweets répondent à l’émotion du moment, posons la question : pourquoi ce message ?
Mon background
Ingénieur non informatique de formation, j’ai commencé ma carrière dans l’industrie puis me suis tourné vers l’informatique il y a un peu plus de dix ans, je suis entré dans le développement web. Je suis autodidacte, et ces 3 dernières années j’ai un peu boosté mon niveau en devenant salarié et travaillant dans une équipe.
Je possède des compétences en Linux, le stack LAMP, un peu vieille école, c’est-à-dire the hard way is easier (rien ne vaut une bonne requête SQL). Je n’ai pas beaucoup de théorie sur l’informatique (algo etc), j’ai fait mes armes à l’école anglo-saxonne et web, cependant je suis passé par math sup/spé.
Mon premier framework avec lequel j’ai vraiment travaillé est AngularJS, ce fut fun, puis .Net, grosse montagne, trop grosse, mais j’ai apprécié la puissance de Visual Studio, j’ai enfin compris l’intérêt du typage statique dans un IDE, puis un petit détour par Java (pouah !), puis brièvement sur Laravel 5, et là je suis sur Symfony 4.
J’avais de grandes attentes, un framework digne du nom, qu’on arrête de se moque des développeurs PHP avec les appels BDD mélangé à du HTML, c’est un level up pour moi et surtout mon CV (compétence très demandée du moins en France, donc pérennité du boulot). Symfony 4 c’est aussi et indubitablement les meilleures pratiques en code, les meilleurs patterns, pas de doute, cela fera de moi un meilleur développeur !
Ce billet n’est pas une critique de Symfony et on alter ego Laravel, et je cible tous les frameworks serverside en général.
Ce qui suit n’engage que moi, et d’autres personnes peuvent penser différemment.
Ma philosophie du code
Ce qui m’attire dans le développement c’est la résolution de problème, augmenter la productivité des gens en leur fournissant des codes qui automatisent le travail rébarbatif. Chaque fois que j’arrive à faire quelques chose en code, j’ai un shoot d’adrénaline, une satisfaction qui égaye ma journée, et en informatique c’est quelque chose de constant (ça m’arrive au moins une fois par jour). J’aime trouver des solutions, créatives, détournées, parfois même en enlevant tout le code et utiliser un software qui fait le boulot, ça me satisfait.
Le développement informatique nous procure beaucoup de libertés, moi ce qui me plait le plus c’est de créer, j’avoue que une fois que le logiciel est créé, je n’ai pas envie de faire la maintenance, ou faire une TMA trop longtemps, ce n’est pas ma tasse de thé de rester avec un logiciel des années, ce qui me plait c’est la phase travaux neuf. (j’aime aussi améliorer un logiciel pourri si le temps m’est permis, optimiser une requête SQL afin de le faire tourner dix fois plus vite me procure autant de plaisir que les travaux neufs).
Bien sûr je ne suis pas un cador, mon code n’est pas parfait, je n’y arrive pas du premier coup, je ne suis pas un ingénieur 10X (MDR). Avec l’expérience j’arrive à produire un code pas trop dégueulasse, avec toujours de meilleures pratiques. Mes applis marchent et délivrent.
Le problème avec les frameworks
J’avoue c’est Symfony le déclencheur, cela aura sans doute été moins évident avec Laravel. Donc j’ai pu regarder pas mal de vidéo de Symfony et j’ai appris beaucoup de choses, j’ai aussi fait beaucoup en code sur un projet vrai, pas sur les exercices.
Je me suis rendu compte avec les tuto sur les formulaires Symfony (qui est LE PLUS morceaux du framework à mon avis) sont un très grosse montagne, mais en même temps qu’il n’y avait pas de grosse difficultés, le framework est bien pensé. On peut tout faire, mais le problème est que l’on peut tout faire à la mode Symfony. Donc il faut savoir, pas de secret.
Un framework dirigiste
En anglais on appelle cela un opinionated framework, un framework où il faut faire à leur façon. En fait les séries de vidéos très bien faites, montrent que c’est une série de recettes qu’il faut appliquer, il ya beaucoup de choses à savoir (le côté difficile) et en même temps ce n’est pas si compliqué si on sait comment faire.
Beaucoup de paramétrages
Symfony vient avec une série de fichiers YAML, une notation très succincte, qui permet de configurer l’environnement de l’application. Donc le paramétrage est un aspect très prégnant d’une application faite avec Symfony. De même les entités sont paramétrées avec des annotations Doctrine, qui définissent les relation entre les entités (miroir des tables de la base de données), mais ça je trouve plutôt pas mal car vous gagnez beaucoup de temps, mais il faut il y a beaucoup de chose à savoir !
Une fois qu’on respecte à la lettre les recettes, on s’aperçoit que finalement on a peu de liberté pour coder, puisque tout est réglé au millimètre. En fait votre seule liberté est dans la couche business.
Travailler avec un framework de grade entreprise, les contreparties
Un framework a une raison d’exister puisqu’il y a un marché, et ce marché c’est celui de l’entreprise, des moyennes et grosses applications. Il faut produire des applications robustes, dans un minimum de temps, et que cette application soit extensible. Et pour remplir ces objectifs, on ne peut pas faire autrement, on ne peut pas réinventer la roue à chaque fois.
Je n’ai plus l’impression d’être un artisan du web, mais plutôt un ouvrier qui va travailler selon des normes ISO, des process, je ne critique pas cela, car dès qu’on vise une certaine qualité logicielle, il faut passer par ces frameworks. Mais ce faisant on va faire toujours les mêmes choses.
C’est pour ça que j’ai abandonné l’idée de développer des connaissances en Java et C#, car de facto quand vous abordez des projets dans ces langages, vous vous retrouvez face à des léviathans.
Donc en bref, vous gagnez en bonne pratique et robustesse, qualité de l’application (bonne chose), mais c’est au détriment de la liberté.
Note : Ce n’est pas parce qu’un framework vous oblige à coder de telle façon qu’il n’est pas possible de sortir une application codée de façon dégueulasse.
Je ne sais pas où vous pouvez vous caser, mais le futur que vous envisagez n’est peut-être pas aussi intéressant que vous pensiez, faire des projets qui se ressemblent va finir par vous user, ce qui nous fait au problème suivant : trouverez vous le plaisir de coder si cela devient routinier?
PS : inutile de commenter, le débat peut se poursuivre sur Twitter.
Voilà une fonction intéressante en PHP, elle vus permet de redéfinir ou d’annuler carrément une fonction.
override_function
Annuler une fonction
override('fonction_origine','','');
Surcharger une fonction :
override_function('fonction_origine','$a,$b','nouvelle_fonction');
ou
override_function('fonction_origine','$a,$b','echo "un test";echo $a + $b;');
Ceci dit, je ne vous recommande pas de le faire, c’est juste une curiosité, car quitte à redéfinir une fonction autant en coder une, et encore, si une fonction ne vous satisfait pas comme utf8_encode() ou utf8_decode(), il existe une alternative qui fonctionne bien, dans notre cas c’est iconv().
Comment faire recharger la page automatiquement à chaque modification avec PHPStorm
Il existe un plugin pratique pour les développeur front end avec HPStorm, LiveEdit (édité par Jetbrain), pour ce faire il faut installer le plugin Chrome IDE Support.
Ensuite dans l’IDE PHPSTORM, il faut installer le plugin LiveEdit, Une fois ceci fait, faites un click droit sur le fichier et lancer debugger.
Comment installer le plugin LiveEdit de Jetbrains sur votre PHPStorm
Allez dans Préférences > Plugins, vous serez sur la page des plugins, si le plugin n’est pas encore installé, allez dans Marketplace, choisissez LiveEdit et installez.
Ensuite sur votre navigateur Chrome, il faut installer le plugin Chrome IDE Support. Lien fourni ci-dessus. Ce plugin permet d’envoyer et lire des informations avec PHPStorm, grâce à ce mécanisme de communication, vous pouvez débugger le javascript depuis votre éditeur PHPStorm !
Comment autoriser le rechargement de la page avec PHPStorm et LiveEdit
Dans PHPStorm, l’explorateur de fichier, faites un clic droit sur le fichier php que vous voulez lancer, cliquez sur Run.
LiveEdit Jetbrains
Comment démarrer une session de débug avec LiveEdit?
Pour débugger il suffit de cliquer sur Debug à la place de Run. Dans cette situation, vous pouvez débugger aussi bien le Javascript que le PHP ! Mettez « debugger » à l’endroit où vous voulez que le debug Javascript commence.
On a l’habitude de requêter une base MySql en PHP, mais sur une base Sql Server c’est moins facile à mettre en oeuvre. Microsoft n’a pas développé de driver pour la version 64 bit de WAMP, il a fallu se rabattre sur le driver Odbc.
Requêter vec ODBC n’est pas très difficile, mais plutôt rustique, ce dernier ne bénéficiant sans doute pas de toutes les optimisations (je pense), donc sur de faibles volumétries, ça le faire. J’ai dû le faire pour un récent projet où je devais attaquer la base SQL Server.
Pré requis
Placez un fichier phpinfo(), et regardez si le driver ODBC est installé, si non allez dans le fichier php.ini et vérifiez que la ligne est présente.
vous devez aussi être à l’aise avec le langage SQL, vous pouvez suivre un cours SQL sur Internet
Le driver ODBC lui-même
Su Windows vérifiez que le driver ODBC est installé avec la manipulation suivante :
Dans la boite d’entrée Cortana tapez : odbc
Cliquez sur « source de données odbc 64 bits »
Ici on a la version 13 du driver.
Connexion à la source de données
La grosse différence est la façon de se connecter à la base de données
odbc_exec exécute la requête, tandis que odbc_result lit un enregistrement. On lui passe deux arguments le premier est la ressource odbc, le second est le nom du champ, ou le numéro de colonne du champ
Parcourir les résultats
//Connaitre le nombre de résultats retournés:
echo odbc_num_rows($result);
Afficher un résultat
Pour une requête retournant un seul résultat, pas d’ambiguité, odbc_result($result, »Siret ») ou odbc_result($result,3) si la colonne Siret est en 4èmeposition.
Chercher une ligne de résultat spécifique:
$s = odbc_fetch_row($result,3);// on cherche la 3ème ligne
echo odbc_result($result,"SIRET");
Afficher une liste de résultats
Dans ce cas la meilleure façon est de faire une boucle while
Je mets la méthode là qui marche car je me suis pas mal emmerdé pour l’installer.
ImageMagick c’est quoi?
C’est un bibliothèque de fonction pour manipuler les images, en gros tout ce que vous pouvez faire avec Photoshop, vous pouvez le faire avec ImageMagick. Cette bibliothèque est écrite en C/C++, elle est très répandue et vous la trouverez sur toutes les plateformes Windows, Linux et Mac.
Elle est aussi disponible dans tous les langages majeurs, dont le PHP. Elle est installable dans un environnement de production comme en développement. Pour la majorité d’entre nous, pour la production c’est souvent un serveur Linux, et pour le développement c’est en majorité un PC sous Windows.
Et comme solution de développement, sur Windows j’utilise WAMP. Télécharger sur Sourceforge gratuitement.
Pour cerner encore plus le cas de figure que je vais traiter, c’est sous PHP 5.6 et 7, mais il reste encore à vérifier deux choses : votre installation WAMP est elle en 32 ou 64 bits? et est elle installée en Thread Safe ou Non Thread Safe?
Pour le Thread Safe ou non, reportez vous au lien, pour ce qui est du 32 ou 64 bits, rien de spécial à savoir sur la technologie, mais vous devez savoir si votre installation WAMP est en 64 ou 32 bits.
Comment Installer Imagemagick, les fichiers binaires
Ce sont les fichiers qui vont vraiment faire les manipulation des images, la bibliothèque Php va faire appel à eux. Il consiste en un fichier .exe à télécharger sur ce site.
Cliquez pour installer sur votre ordinateur, et allez voir les variables d’environnement (dans Windows tapez touche « WINDOWS » à côté de la touche controle, et « PATH »pour voir où c’est installé). Si PATH contient le chemin de ImgeMagick, normalement WAMP doit les voir.
Après l’installation de ImageMagick pour Windows, ouvrez une console DOS, tapez convert -version, vous avez normalement un message sur la version de convert. Cette manipulation sert à vérifier que c’est bien installé.
Installer la bibliothèque PHP qui va faire appel à ces exécutables
Télécharger sur le site officiel, c’est là où il va falloir savoir si c’est en 32 ou 64 bits, et surtout si c’est en Thread Safe ou non en Thread Safe (voir le lien précédent pour le savoir)
Dézippez et copier le fichier vers le répertoire c:/wamp64/bin/php/ext et modifier votre fichier php.ini en ajoutant ces deux lignes :
[Imagick]
extension=php_imagick.dll
Redémarrez WAMP. Faites un phpinfo() et vous devriez voir cette portion d’information :
Si vous voyez ça bingo ! A noter que le menu de WAMP ci dessous ne l’affiche pas, ce n’est pas grave, ce qui compte c’est le phpinfo().
Je vous le dis car j’ai perdu des heures en essayant de me baser dessus !
Pour connaitre en ligne de commande la liste des modules chargés
$ php -m
Note : vous ne verrez pas Imagemagick
Utilisation de ImageMagick dans vos scripts PHP
Installer correctement la DLL pour en configurant dans le php.ini est u vrai challenge (je n’ai pas réussi pour ma configuration), cependant, pas de panique vous pouvez très bien utiliser dans vos scripts php (après avoir redémarré votre ordinateur), en utilisant la fonction exec(), qui exécute les commande shell.
Exemple pour exécuter une conversion d’image d’un format à un autre :
Tout pour bien sélectionner la version du module pour PHP
Le contexte technique fondamental en HTTP
Différents serveurs web mettent en œuvre différentes techniques pour traiter les requêtes HTTP entrantes en parallèle. Une technique assez populaire est d’utiliser des threads — c’est-à-dire, le serveur web va créer/dédier un thread unique pour chaque requête entrante. Le serveur web Apache HTTP supporte de multiples modèles pour traiter les requêtes, dont l’un (appelé MPM ouvrier) utilise des threads. Mais il supporte un autre modèle de simultanéité appelé MPM prefork qui utilise des processus — c’est-à-dire que le serveur web créera/dédiera un seul processus pour chaque requête.
Il existe également d’autres modèles de concurrence complètement différents (utilisant des connecteurs asynchrones et des E/S), ainsi que d’autres qui combinent deux ou même trois modèles. Pour répondre à cette question, nous ne nous intéressons qu’aux deux modèles ci-dessus, en prenant l’exemple du serveur HTTP Apache.
Connaissance nécessaire sur la façon dont PHP « s’intègre » avec les serveurs web
PHP lui-même ne répond pas aux requêtes HTTP réelles — c’est le travail du serveur web. Nous configurons donc le serveur web pour transférer les requêtes vers PHP pour traitement, puis nous recevons le résultat et le renvoyons à l’utilisateur. Il y a plusieurs façons de chaîner le serveur web avec PHP. Pour Apache HTTP Server, le plus populaire est « mod_php ». Ce module est en fait PHP lui-même, mais compilé comme un module pour le serveur web, et donc il est chargé directement à l’intérieur.
Il existe d’autres méthodes pour enchaîner PHP avec Apache et d’autres serveurs web, mais mod_php est le plus populaire et servira aussi à répondre à votre question.
Vous n’aviez peut-être pas besoin de comprendre ces détails auparavant, parce que les sociétés d’hébergement et les distributions GNU/Linux viennent avec tout ce qui est préparé pour nous. Maintenant, quelle différence entre Thread Safe et non Thread Safe?!
Comme avec mod_php, PHP est chargé directement dans Apache, si Apache va gérer la simultanéité en utilisant son Worker MPM (c’est-à-dire, en utilisant Threads) alors PHP doit être capable d’opérer dans ce même environnement multi-thread — ce qui veut dire que PHP doit être thread-safe pour pouvoir jouer correctement avec Apache!
A ce stade, vous devriez penser « OK, donc si j’utilise un serveur web multi-threadé et que je vais intégrer PHP directement, alors je dois utiliser la version thread-safe de PHP ». Et ce serait une bonne idée. Cependant, il se trouve que la sécurité des threads de PHP est très contestée. C’est un terrain d’utilisation pour les initiés, si vous savez vraiment ce que vous faites.
Conclusion
Quand votre PHP est installé en CGI ou FastCGI, utilisez le Non Thread Safe, si c’est installé en tant que Module Apache, utilisez le Thread Safe
Au cas où vous vous poseriez la question, mon conseil personnel serait de ne pas utiliser PHP dans un environnement multi-threads si vous avez le choix!
Parlant seulement des environnements Unix, je dirais que heureusement, vous n’avez qu’ à penser à cela si vous allez utiliser PHP avec le serveur web Apache, auquel cas il vous est conseillé d’aller avec le MPM de préfork d’Apache (qui n’utilise pas de threads, et donc, thread-safe n’a pas d’importance) et toutes les distributions GNU/Linux que je connais prendront cette décision pour vous quand vous êtes Si vous allez utiliser d’autres serveurs web tels que nginx ou lighttpd, vous n’aurez pas la possibilité d’y intégrer PHP de toute façon. Vous allez voir comment utiliser FastCGI ou quelque chose d’égal qui fonctionne dans un modèle différent où PHP est totalement en dehors du serveur web avec plusieurs processus PHP utilisés pour répondre aux demandes à travers par exemple FastCGI. Dans ce cas, la sécurité des fils n’ a pas d’importance.
Quelles différences en thread safe et non thread safe?
Thread safe
La sécurité des threads est utilisée pour éviter les conflits lorsque des données partagées sont manipulées par différents threads. Elle est particulièrement importante lorsque des threads sont utilisés pour gérer des requêtes sur un serveur Web. Les versions « Thread Safe » permettent aux fichiers binaires de fonctionner correctement dans un environnement de serveur Web multi-thread en créant une copie locale de stockage pour chaque thread, ainsi les données ne se heurtent pas à un autre thread. En général lorsque PHP est installé en tant que module de Apache (vous le savez car vous touchez au fichier httpd.conf)
dans le contexte du multithreading, on doit garantir que différents threads ne touchent pas indépendemment aux données, ce qui mettrait sens dessus dessous les données. Par exemple un client A peut commander et payer le total du client B si ce n’est pas fait correctement.
Non thread safe
Les versions « non-thread safe » ne garantissent pas la sécurité des threads, ce qui les rend plus rapides à exécuter mais plus instables et sujettes aux blocages fréquents. Ces versions ne prennent en compte qu’un seul thread. Les fichiers binaires « non-thread safe » sont souvent utilisés lorsqu’il n’y a pas de besoin d’utiliser le multi-threading, comme dans le cas d’une interaction avec un serveur Web via le protocole FastCGI. Donc quand vous voyez fast CGI, c’est du non thread safe.
Comment savoir si PHP est installé en CGI ou en Module?
Pour voir quelle version de votre site web utilise, mettez un fichier contenant <? php phpinfo ();? > sur votre site et recherchez l’entrée API du serveur. Cela pourrait dire quelque chose comme CGI/FastCGI ou Apache 2.0 Handler.
Si vous regardez aussi la version en ligne de commande de PHP — la sécurité du thread n’a pas d’importance.
Enfin, si la sécurité du theading n’ a pas d’importance, quelle version devez-vous utiliser — Thread Safe ou Non Thread Safe? Je suppose que la version non-thread-safe est plus rapide et moins buggy, ou sinon ils auraient juste offert la version thread-safe et ne se seraient pas donné la peine de proposer ces deux alternatives !
Supplément
Comment savoir si son installation php est Thread Safe ou non Thread Safe?
sur Linux
$ php -i | grep Thread
Sur Windows
$ php -i | find "Thread"
SuPHP est un module qui permet de d’exécuter des script php avec les permissions de leur propriétaire.
Par défaut, c’est l’utilisateur Nobody qui exécute les scripts php.
Le problème c’est que pour que Nobody puisse exécuter un script, il faut que le script php ait les droits 777, c’est à dire que tout le monde peut modifier le fichier, ce qui pose des risques de sécurité.
Donc SuPHP va interdire l’exécution des scripts php par le user nobody, et l’assigner en général au propriétaire du fichier.
Mais cela veut dire que chaque site web doit avoir un propriétaire?
En effet. Les panels d’administrations comme Virtualmin, lorsque que vous créez un virtual host, se chargent de créer un utilisateur sous Linux et donc un espace home pour ce même utilisateur. La racine site web est en général sous le répertoire /home/utilisateur/www.
EN travaillant sur un script ecommerce ultra pourri mais qui est en prod et que je dois migrer vers un serveur avec une version PHP 5.4, je me suis aperçu qu’il y avait une erreur loggée dans error_log : il y avait deux définitions de la même constante. Et le scrit ne tournait donc pas sur le serveur, puisque après un test, avec un script php où je définissait deux fois la même constante, sur 5.3 ça tournait sans problème, la constante était aussi (presque) malléable qu’une variable, voici le script :
Bien que la constante puisse être redéfinie, sa valeur ne change pas.
sous PHP 5.4
$ php test.php
bonjourPHP Notice: Constant TO already defined in /home/user/test.php on line 4
PHP Stack trace:
PHP 1. {main}() /home/user/test.php:0
PHP 2. define('TO', 'au revoir') /home/user/test.php:4
On voit que le premier echo est exécuté, mais que le second déclenche une notice (ça peut être une erreur fatale).
Je pense que c’est une bonne chose (absolument !), soyons logique une constante ne peut être changée alors pourquoi autoriser la redéclaration? Heureusement que ça a changé et que PHP soit un langage plus rigoureux.
Bonus :
En PHP 5.3 vous pouvez utiliser un index d’un tableau qui n’existe pas sans qu’il vous geule dessus,
PHP Avancé : Profilez l’exécution de votre page Php.
Quand vous avez un certains niveau de Php ou quand vous travaillez avec des solutions open source comme Magento, et que tout rame, vous aurez envie de monitorer (on dit profiler) les performance de chaque script php.
XDEBUG est le programme souvent installé par défaut avec WAMP qui permet de profiler l’exécution d’un script.
Il génère un fichier texte avec les noms des fonctions et le temps d’exécution. Pour interpréter de façon plus lisible ces données, il faut sous Windows utiliser le programme Wincachegrind, et sous Linux c’est KCachegrind.
Pour télécharger Wincachegrind, attention ne plus aller le télécharger sur sourceforge, cette version pose problème car elle date. Voici le lien du fichier qui est compatible avec la dernière version des fichiers générés par XDEBUG.
la ligne importante à vérifier est xdebug.profile_enable_trigger = 1
donc allez sur votre page web que vous voulez profiler et ajoutez un paramètre dans l’url :
http://votresite.com/index.php?XDEBUG_PROFILE
chargez votre page et un fichier sera généré dans le répertoire c:/wamp64/tmp
Ouvrez votre programme Wincachegrind, et ouvrez le fichier généré, vous devriez avoir une fenêtre de ce style :
x
Vous pouvez naviguer dans la hiérarchie et regarder le temps d’exécution de chaque fonction. Cet outil est vraiment génial et vous permet de connaitre de manière intime le temps d’exécution de chaque script de régler les problèmes de lenteur.
Sur ce post j’avais décris comment installer Composer, mais les récentes version de composer ne marchent pas avec la version 5.4 de php, d’ou le besoin de mettre à jour vers php5.6
Lorsque vous faites une commande apt-get, l’OS va chercher dans une liste de dépôt sur Internet. Cette liste de sites de dépôt se trouve dna sun fichier sources.list, localisé dans /etc/apt/
Vous êtes connecté en tant qu’utilisateur root
Il vous faut renseigner ces deux lignes dans ce fichier en utilisant nano pour le plus simple:
deb http://packages.dotdeb.org wheezy-php56 all deb-src http://packages.dotdeb.org wheezy-php56 all
Cette petite introduction à pour but de vous montrer comment installe PhpUnit afin de démarrer votre premier test unitaire.
Prérequis : connaissance en programmation orientée objet avec Php, connaissance optionnelle de Composer.
Pour faire simple téléchargez l’archive Phar (un seul fichier) dans le répertoire de test.
Aller sur cette page pour une petite introduction en anglais:
https://phpunit.de/getting-started.html
Vous écrivez vos tests dans un fichier php, et vous allez lancer ce fichier en mode console:
phpunit fichierContenantTest.php
Si vous avez installer avec Composer, un fichier phpunit.xml est généré, le fait de lance phpUnit sans argument suffira à lancer la série de test codé dans le fichier xml.
Si vous voulez minimiser les risques d’injection SQL il faut utiliser PDO, n’utilisez plus Mysqli. Dites lui non svp.
Connexion à la base de données:
On est en programmation orientée objet donc utilisez le mot clé new pour instancier une connexion à une base de données.
$pdo = new \PDO($dsn, $user, $pass)
$dsn est une chaine qui défini une ressource de base de données,
$dsn = 'mysql:host=localhost;dbname=votre_base';
Lancer une requête SQL:
$sql = 'SELECT * FROM table';
$stmt = $pdo->prepare($sql);
Avec PDO vous utilisez des requêtes préparées (prepared statement), et ensuite on exécute
$stmt->execute();
et pour retirer les résultats :
$result = $stmt->fetchAll();
Je sais que vous êtes un programmeur curieux, donc vous allez voir la tête de l’objet retourné. Les données ne sont pas bonnes mais c’est pour vous donner la structure du tableau retourné.
On remarque que dans l’élément les informations sont doublées mais indexés de façon différent, on a les index numériques et les index alphanumériques.
PDO vous donne en fait le choix de travailler soit avec les tableaux associatifs soit les tableaux classiques.
Si ce sont les champs nommés du tableau associatif qui vous intéressent :
$result = $stmt->fetchAll(PDO::FETCH_ASSOC); // retourne un tableau associatif
$result = $stmt->fetchAll(PDO::FETCH_CLASS); // retourne une classe
$result = $stmt->fetch(PDO::FETCH_ASSOC); // retourne un seul résultat
Les requêtes préparées avec PDO
Avec les requêtes préparées, vous devez écrire une requêtes SQL avec des paramètres à l’intérieur et pas des variable PHP. L’intérêt est qu’avec ce genre de requêtes, vous vous évitez la plupart des injections SQL et aussi accessoirement les problèmes d’échappement de caractères spéciaux.
Requête PDO SQL avec une clause WHERE
Regardons comment on fait une requête plus évoluée:
$stmt->prepare('SELECT * FROM table WHERE id = :id');
$stmt->bindParam(':id',$id,PDO::PARAM_INT);
$stmt->execute();
Ici on met un masque dans la clause where et ensuite on attribue une valeur au masque, c’est ici tout l’intérêt de PDO (il y en a d’autres),
paramétrer la requête SQL de cette façon évite les injection SQL. On indique aussi quel est le type de variable on passe
On peut passer aussi par valeur au lieu d’une variable php
$stmt->bindValue(':id',50);
Une autre façon de passer des paramètres est d’utiliser des points d’interrogation
$stmt->prepare('SELECT * FROM table WHERE id = ?');
$stmt->bindValue(1,50,PDO::PARAM_INT);
Ici l’indice 1 correspond au premier point d’interrogation, quand vous en avez deux vous aurez un sur le premier bind et deux sur le second bind.
Insertion avec les requêtes préparées
Le principe des requêtes préparées est de ne pas mettre les valeurs à insérer directement dans la requêtes SQL, mais de les remplacer par des alias (placeholder) que l’on va populer ensuite.
#la requête SQL modifiée
$sql = "INSERT INTO users (nom, prenom, age) VALUES (:nom, :prenom, :age)";
#les paramètres à insérer sont mis dans un tableau
$params = ['nom' => $nom,'prenom' => $prenom,'age' => $age];
#on exécute la requête
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
#placeholder non nommé, dans ce cas respectez l'ordre
$sql = "INSERT INTO users (nom, prenom, age) VALUES (?,?,?)";
Mise à jour avec les requêtes préparées UPDATE
$sql = "UPDATE users SET name=?, surname=?, sex=? WHERE id=?";
$stmt= $pdo->prepare($sql);
$stmt->execute([$name, $surname, $sex, $id]);
ou
$sql = "UPDATE users SET name=?, surname=?, sex=? WHERE id=?";
$pdo->prepare($sql)->execute([$name, $surname, $sex, $id]);
Avec les paramètres nommés
$data = [
'name' => $name,
'surname' => $surname,
'sex' => $sex,
'id' => $id,
];
$sql = "UPDATE users SET name=:name, surname=:surname, sex=:sex WHERE id=:id";
$stmt= $pdo->prepare($sql);
$stmt->execute($data);
ou
$sql = "UPDATE users SET name=:name, surname=:surname, sex=:sex WHERE id=:id";
$pdo->prepare($sql)->execute($data);
Effacer (DELETE
$sql = "DELETE FROM users WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['id' => $id]);
// Syntaxe compacte (placeholder positionnel)
$pdo->prepare("DELETE FROM users WHERE id = ?")
->execute([$id]);
$sql = "DELETE FROM users WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['id' => $id]);
// Syntaxe compacte (placeholder positionnel)
$pdo->prepare("DELETE FROM users WHERE id = ?")
->execute([$id]);
Retourner le nombre d’occurences
$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$result = $con->prepare($sql);
$result->execute();
$number_of_rows = $result->fetchColumn();
Retourner le dernier id de la clé primaire (auto généré)
C’est vraiment très pratique, pas la peine de refaire un SELECT qui n’a d’ailleurs aucune garantie de retourner l’id de votre insertion si il y a beaucoup d’opérations d’insertion.
si votre serveur refuse de passer au vert, le mieux est de voir ce qui se passe sous le capot.
si votre Service Apache refuse de démarrer (pour ce faire aller dans Apache / Service et regardez si c’est le cas), ouvrez une fenetre DOS, et allez dans le répertoire du fichier httpd.exe (ce devrait être C:\wamp\bin\apache\apache2.4.9\bin changez la version Apache à votre convenance), et entrez l commande suivante :
$ httpd.exe -t
le flag -t va afficher le dump. La plupart du temps il s’agit d’un fichier vhost.conf mal configuré.
Qui n’a jamais fait d’include de fichiers externes en PHP? C’est même récurrent pour les programmeurs.
Avouez que c’est quand même lourd à la longue. Il existe une méthode depuis PHP 5.3 pour résoudre automatique le chemin des fichiers de classe, enfin presque. A condition de bien comprendre quelques notions fondamentales en PHP objet.
Autoloading qu’est ce que c’est?
Quand vous avez à instancier un objet:
myDeuche = new Voiture();
PHP doit trouver le chemin du fichier qui contient la déclaration de classe et le charger (Autoloading). Prenons soins de nommer le fichier de déclaration de classe avec le même nom que la classe. Et dans un fichier il y a une seule classe. Ces deux conditions sont nécessaires pour faire marcher l’autoloading.
Votre fichier peut être dans le même répertoire que celui contenant le script ci-dessus.
Ou il peut être dans un sous répertoire ou sous sous répertoire.
Comment lui faire savoir dans ce cas?
C’est là qu’interviennent les espaces de nom.
soit la déclaration suit:
//Voiture.php
namespace vehicule;
class Voiture{
//....suite du code
}
Ce fichier est obligatoirement dans le répertoire vehicule.
Ainsi lorsqu’on instancie l’objet Deuche, PHP va aller dans le répertoire vehicule pour chercher le fichier Voiture.php grâce à la correspondance du nom de classe (vous comprenez pourquoi on ne doit déclarer qu’une seule classe par fichier)
Historique et Évolution
L’autoloading a évolué avec PHP, particulièrement avec l’introduction de spl_autoload_register() dans PHP 5.1, qui a simplifié l’enregistrement de fonctions d’autoload personnalisées.
Les différentes méthodes d’autoloading
__autoload() (déprécié depuis PHP 7.2.0)
Cette fonction magique permettait de définir une méthode globale pour charger automatiquement les classes. Exemple :
function __autoload($className) {
include $className . '.php';
}
spl_autoload_register()
Il s’agit de la méthode recommandée pour enregistrer une ou plusieurs fonctions d’autoloading :
spl_autoload_register(function ($class) {
include 'classes/' . $class . '.class.php';
});
Autoloading PSR-4
La norme PSR-4 de PHP-FIG spécifie une manière standardisée d’autoloading des classes à partir de leurs namespaces. Elle est largement utilisée et soutenue par Composer.
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Autoloading avec Composer
Composer, le gestionnaire de dépendances pour PHP, utilise l’autoloading version PSR-4 pour inclure automatiquement les bibliothèques externes. Il crée un fichier vendor/autoload.php qui gère l’autoloading des classes définies dans les packages installés. Composer n’est pas fourni avec PHP il faut l’installer.
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
$log->warning('Foo');
$log->error('Bar');
Xdebug est un outil très utilisé pour profiler votre code PHP
Il vous génère un fichier de log qui exploité avec Wincachegrind (un analyseur de log dédié sous windows) ou Kcachegrin (sous Linux), vous pourrez voir les goulots d’étranglement de vos code PHP.
Pour installer sur Debian rien de plus simple, connecté sous root:
apt-get install php5-xdebug
Pour windows je ne vous fais pas la manip qui doit couler de source.
Ensuite ajoutez ces lignes dans le fichier php.ini :
[xdebug]
xdebug.remote_enable = off
xdebug.profiler_enable = off
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_name = “cachegrind.out.%u.%H_%R”
xdebug.profiler_output_dir = “c:/wamp/tmp”
xdebug.show_local_vars=0
xdebug.max_nesting_level=250
Attention en fonction de votre installation de WAMP, le chemin eput être différent, c’est soit wamp pour les version avant 3, et wamp64 pour les version 3.
Ensuite une fois que tout est installé, allez sur une url que vous voulez profiler, et ajoutez à la fin de l’url :
?XDEBUG_PROFILE
s’il y a déjà un autre paramètre :
?id=5&XDEBUG_PROFILE
Le fichier est enregistré dans le répertoire tmp.
Comme vous pouvez le voir les fichiers de xdebug commencent par « cachegrind.out » plus une heure ou date.
Pour paramétrer l’output dir, c’est à vous de choisir le meilleur répertoire, vérifiez qu’il soit autorisé en écriture. Si c’est généré sur votre serveur web, il suffit de le télécharger sur votre ordinateur et de l’analyser avec Wincachegrind.
Pour analyser ces logs générés, il vous faut sous Windows le programme Wincachegrind, une fois installé, ouvrez le fichier log généré et vous pourrez explorer les goulots d’étranglement. En effet tous les fichiers php qui s’exécutent sont profilés et vous avez vraiment un détail exceptionnel sur les temps d’exécution du moindre script php ainsi que leur temps d’exécution, c’est en regardant ce dernier paramètre que vous pourrez identifier les coupables d’un site web lent.
Comment allonger la durée d’exécution d’un script PHP?
Il est souvent frustrant lorsqu’on débute en PHP d’avoir une erreur 500 suite à un script qui met du temps à s’exécuter.
Dans la littérature PHP, vous avez la fonction set_time_limit(int $secondes), qui permet d’aller au-delà de la valeur par défaut de 30 secondes. Mais il y a une exception, si votre installation PHP est en safe mode, ça ne marche pas. On vous recommande d’aller dans le fichier php.ini pour configurer la variable d’environnement max_execution_time.
Mais pour des raisons de configuration, il se peut que même cela ne marche pas. Il faut aller encore plus bas au niveau d’Apache, et triturer une autre variable d’environnement.
Configurer Apache si vous avez accès au fichier de configuration
Si dans les logs Apache vous avez le message suivant :
mod_fcgid: read data timeout in 31 seconds
lisez ce qui suit si vous êtes sous Webmin mais à transposer pour d’autres panels:
Sous Webmin > Servers > Apache Webserver > Global configuration > Edit Config File
Il faut aller dans le fichier de configuration d’Apache et trouver la ligne qui contient :
IPCCommTimeout
au lieu de laisser la valeur par défaut à 31 passez la à 100 pour éviter des erreurs 500, dû à un dépassement des 31 secondes.
Pourquoi je vous dis ça? c’est parce que en googlant ce topic j’ai jamais réussi en runtime à lever cette limite, cette méthode est sûre.
Cette directive se trouve dans le le fichier de configuration Apache global ou sur chaque Vhost.
Mais devez vous toucher à cette varaible?
Il est des CMS ou l’on n’a pas envie de voir comment c’est fait, donc oui on va toucher à al configuration. Mais si vous êtes un peu plus aguerris, je vous propose en recvanche d’exévcuter vos script php en ligne de commande !
Exécuter un script php en ligne de commande
Si vous êtes sous Linux, vous pouvez exécuter n’importe quel script php de cette façon :
$ php monscript.php
En mode ligne de commande, (CLI : command line interface), vous n’avez pas de limite de durée comme en mode web. Pourquoi? parce qu’en mode web, vous avez une contrainte, en effet les internautes ne doivent pas poireauter devant votre site web, et il est donc considéré comme anormal que des scripts mettent des minute à s’exécuter.
Voici comment créer un lien qui va ouvrir un client email avec déjà le texte du email écrit dedans, utili si vous automatiser la création d’email personnalisés.
Vous aurez peut être envie un jour de pouvoir uploader des fichier dans un serveur web, afin de mettre en place une nouvelle version d’un script. Si vous pouvez automatiser cette tâche, vous aurez un grand gain de productivité. On peut imaginer que vous ayez déployé un CMs sur plusieurs serveurs web, et que vous vouliez mettre en place une mise à jour en trois fois rien de temps.
Ceci est possible en php, votre langage de programmation favori. Fini donc les laborieuses connexions à la main avec Filezilla, on va automatiser ça.
FTP en PHP avec CURL
Ce n’est pas l’option la plus simple. En effet, il faut disposer de la bibliothèque CURL (pas si difficile que ça en fait), mais surtout écrier plusieurs lignes de php :
ce script va charger le fichier test.txt de votre disque dur vers le serveur FTP et donc votre site web !
Mais comme toujours avec CURL, c’est fastidieux, il faut instancier l’objet CURL, injecter de paramètre et l’exécuter.
FTP en PHP plus simple avec les fonction FTP de PHP
Nos allons voir que c’est plus intuitif avec les fonction FTP de PHP.
En effet pour faire la même chose que le script ci-dessus:
// Ouverture de quelques fichiers pour lecture
$file = 'somefile.txt';
$fp = fopen($file, 'r');
// Mise en place d'une connexion basique
$conn_id = ftp_connect($ftp_server);
// Identification avec un nom d'utilisateur et un mot de passe
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
// Tente de charger le fichier $file
if (ftp_fput($conn_id, $file, $fp, FTP_ASCII)) {
echo "Chargement avec succès du fichier $file\n";
} else {
echo "Il y a eu un problème lors du chargement du fichier $file\n";
}
// Fermeture de la connexion et du pointeur de fichier
ftp_close($conn_id);
fclose($fp);
?>
Ici on crée une connexion FTP comme si on le faisait pour une connexion Mysql, on ouvre le fichier en local et on le met sur le serveur FTP. Avouez que c’est quand même plus lisible !
C’est très simple, il faut vous logger sur votre shell via putty en mode root (pour pouvoir installer des extension sous Linux il faut être en mode root.
Et ensuite tapez cette commande :
$ apt-get install php5-gd
Ou alors si vous n’êtes pas connecté en root, tapez cette commande et vous serez invité à entrer le mot de passe root.
$ sudo apt-get install php5-gd
l’installation dur une trentaine de seconde le temps de reconfigurer (automatiquement) le serveur web Apache
C’est un pur hasard si ce plugin pour Chrome s’appelle PHP Ninja, je n’ai aucune affiliation avec ce plugin.
De nos jours, à l’ère du multitasking, notre mémoir fait de plus en plus défaut, et l’on doit souvent revenir à la documentation de PHP. Je vais personnellement souvent sur php.net, même si je trouve que la navigation du site est bien faite, j’aurais souhaité accéder encore plus vite à la documentation sans ouvrir une nouvelle page web.
Grâce à ce plugin, ce rêve est réalisé.
Il ne marche que sous Chrome cependant et il n’y a pas d’équivalent proche sous Firefox. Pour l’installer allez dans votre navigateur chrome et aller le webstore et tapez simplement « PHP Ninja » et ensuite installez le plugin !
Maintenant un bouton à côté de la barre de recherche est disponible en permanence pour retrouver dans la documentation la fonction souhaitée.
PHP Ninja à l’usage
Une fois que vous avez installé le plugin, il vous suffit de cliquer dessus et de rentrer le nom de la fonction, vous aurez un texte qui est pompé sur le site php.net.
Toujours sur un serveur dédié, et sous Debian voici la procédure à faire pour accélérer votre site web:
Installez APC : aptitude install php-apc
Configurer le fichier php.ini en éditant le ichier « /etc/php5/conf.d/apc.ini » et en ajoutant: apc.enabled=1 apc.shm_segments=1 apc.shm_size=128
Redémarrez Apache
Créez une page web pour pourvoir monitorer les performances de ce cache (remplacez mysite par le bon répertoire de votre serveur) :gzip -dc /usr/share/doc/php-apc/apc.php.gz > /home/mysite/public_html/apc.php
Lorsque que vous avez des modifications à faire sur un logiciel open source, la dernière chose à faire est de modifier le code source, car vos modifications vont être balayées à la prochaine mise à jour.
Donc dans Magento, l’approche consiste à étendre le code d’origine, on dit étendre le Core.
Si vous voulez modifier le design en frontal, vous allez surcharger les blocks, qui sont à la base de la disposition visuelle.
Si vous voulez jouter ou modifier un comportement de base d’une méthode, vous allez surcharger le controleur.
Si vous voulez ajouter des champs supplémentaires à une entité, vous allez surcharger le modèle.
Si vous voulez ajouter une fonction helper ou modifier une fonction helper, vous allez surcharger un Helper.
Surcharger un modèle dans Magento
1/Créer un module avec une arborescence type
2/Déclarer votre module dans le fichier xml à placer dans le répertoire app/etc/
3/créer un fichier de configuration xml config.xml qui viendra se greffer au fichier principal de Magento
4/déclarer la classe à surcharger dans le fichier config.xml et le placer dans /etc du répertoire de votre module. Dans ce fichier vous allez entrer dans le noeud xml votre nouvelle classe, cette dernière étend la classe dont vous allez surcharger les fonctionnalités.
Surcharger un controller dans Magento
1/Pour overrider un controller, on n’utilise pas la balise norewrite
2/il y a un hook before et un after qui permet d’exécuter