I work in my free time to improve the win32service extension to make it great and easier to use. The future version is 1.0.0 only for PHP 8.
I’m excited about this future version.
What is the planned changes?
This extension needs a little cleanup. In many cases, the Windows version is checked. All this check will be removed because VS16 is used to build PHP 8 and this extension works only on Windows 7 SP1 and newer or Windows 2012 R2 or newer.
With PHP 8 a new ValueError exception is available. Many checks will be added to improve the work of this extension. Especially the win32_create_service function.
And the last, same as many other functions in PHP extensions, all function who returns an error code will be changed to throw an exception. All PHP Errors and some PHP Warning will be changed by throwing an exception.
What is the side effect to change?
You need to change your code when you upgrade your project to PHP 8.
The Win32Service project provides a PHP library and a Symfony Bundle. Both will be upgraded to PHP 8 on a new major version.
My Actual To-do List
All this plan needs more work. This is my to-do list but you can help me.
Upgrade the extension code.
Write more tests for the extension.
Update the English PHP documentation for Win32Service.
Update the French PHP documentation for Win32Service.
Update the PHP library win32service/service-library.
Update the Symfony Bundle win32service/win32servicebundle.
PHP CS Fixer c’est quoi ? A quoi sert PHP CS Fixer ?
PHP CS Fixer est un outil permettant de vérifier et corriger le formatage du code PHP selon le code style défini dans la configuration du projet (fichier .php_cs.dist ou .php_cs).
Le style code est une convention qui définit comment doit être écrit le code. Par exemple l’emplacement des accolades des structures de contrôle, des classes, des fonctions, les espaces autour d’un signe égal, etc.
Cela permet de faciliter la lecture du code pour tout le monde.
Le PHP-FIG a défini plusieurs conventions dont la dernière en date est la PSR-12. Il existe également des conventions plus spécifiques comme le Coding Standards de Symfony.
Pourquoi ne plus y penser ?
Le style de code est une nécessité, mais très franchement c’est frustrant quand l’intégration continue échoue à cause du style code.
Tout comme voir des messages de commit tels que fix style code, fix cs ou cs ou bien d’autre encore.
Il existe une solution pour ne plus y penser et l’appliquer tout de même, le hook (crochet) GIT pre-commit.
Un hook (crochet en français) est un point d’extension d’une application permettant à l’utilisateur d’exécuter des actions qu’il a lui-même définies. En général, ce sont des scripts Shell.
Pré requis
Cette procédure a été écrite pour les systèmes GNU/Linux. La compatibilité pour les Mac est quasi assurée. Pour Windows, il est nécessaire d’adapter la procédure au système.
PHP 7 et PHP CS Fixer doivent être installé sur le poste qui exécute les commandes GIT. Si PHP CS Fixer n’est pas installé, suivre la procédure d’installation globale manuelle.
Pour ce blog post, PHP CS Fixer est installé à cet emplacement /usr/local/bin/php-cs-fixer. Pour connaitre l’emplacement du binaire exécuter la commande type php-cs-fixer.
Le projet sur lequel vous choisissez de définir ce hook contient déjà une configuration pour PHP CS Fixer (fichier .php_cs.dist ou .php_cs).
Ajout d’un hook sur un dépôt
Pour ne pas perturber les projets qui ne dispose pas de configuration ou qui n’ont pas de fichier PHP, le hook vérifie la présence du fichier de configuration .php_cs.dist et n’appliquera les modifications que sur les fichiers PHP inclus dans le commit.
Pour l’ajouter, se placer dans le dossier de votre projet puis ouvrir le fichier .git/hooks/pre-commit (il peut déjà exister ou devra être ajouté).
Puis coller le contenu du script suivant :
#!/bin/sh
ROOT=$(dirname "$0")
ROOT=$(dirname "$ROOT")
ROOT=$(dirname "$ROOT")
echo "php-cs-fixer pre commit hook start"
# Modifier le chemin de PHP CS Fixer ici si votre binaire n'est pas installé au même endroit :
PHP_CS_FIXER="/usr/local/bin/php-cs-fixer"
HAS_PHP_CS_FIXER=false
if [ -x "$PHP_CS_FIXER" ]; then
HAS_PHP_CS_FIXER=true
else
echo "PHP CS Fixer not installed into $PHP_CS_FIXER"
fi
#PHP_CS_CONFIG=
for file in .php_cs.dist .php_cs
do
if [ -f "$ROOT/$file" ]; then
echo PHP CS Fixer config file found in projet at $file
PHP_CS_CONFIG=$file
fi
done
if [ "x$PHP_CS_CONFIG" = "x" ]; then
echo "No PHP CS Fixer config file found !"
HAS_PHP_CS_FIXER=false
fi
if $HAS_PHP_CS_FIXER; then
git status --porcelain | grep -e '^[AM]\(.*\).php$' | cut -c 3- | while read line; do
$PHP_CS_FIXER fix --config=$ROOT/$PHP_CS_CONFIG --verbose "$line";
git add "$line";
done
else
echo ""
echo "Please install php-cs-fixer, see:"
echo ""
echo " https://github.com/FriendsOfPHP/PHP-CS-Fixer#installation"
echo ""
fi
echo "php-cs-fixer pre commit hook finish"
Il est nécessaire de s’assurer que ce fichier est exécutable grâce à cette commande : chmod u+x .git/hooks/pre-commit.
Exécuter la commande dans un terminal après s’être placé dans le dossier de votre projet.
Pour tester son efficacité, modifier le placement d’accolade dans un fichier PHP du projet puis ajouter un commit.
PHP CS Fixer est exécuté sur chaque fichier modifié pour corriger le style code avant le commit.
Ajout d’un hook pour tous les dépôts
Maintenant que notre hook fonctionne, nous pouvons l’ajouter au modèle de dépôt GIT. Ainsi tout nouveau dépôt disposera du hook.
La première étape consiste à définir un dossier de template pour les nouveaux dépôts GIT.
Exécuter la commande git config --global init.templatedir '~/.git-templates'
Le dossier n’existant pas, nous allons l’ajouter à notre dossier utilisateur avec cette commande mkdir -p ~/.git-templates/hooks
Toujours depuis le dossier du projet où le hook a été ajouté exécuter la commande suivante pour copier le hook cp .git/hooks/pre-commit ~/.git-templates/hooks/
Cette fois, nous allons nous assurer que tout le monde peut l’exécuter avec cette commande : chmod a+x ~/.git-templates/hooks/pre-commit.
Ajouter le hook sur un dépôt existant
Maintenant que le hook est dans le template de GIT, il est possible de l’ajouter à un projet existant en exécutant la commande : git init dans le dossier du projet.
Pour les dépôts ayant déjà un hook pre-commit, il ne sera pas modifié.
Besoin d’aide pour mettre en place cette solution ? Contactez-moi !
Il est nécessaire de s’assurer que ce fichier est exécutable grâce à cette commande : chmod u+x .git/hooks/pre-commit.
Exécuter la commande dans un terminal après s’être placé dans le dossier de votre projet.
Pour tester son efficacité, modifier le placement d’accolade dans un fichier PHP du projet puis ajouter un commit.
PHP CS Fixer est exécuté sur chaque fichier modifié pour corriger le style code avant le commit.
Dans la continuité du précédent article sur PHP 8, voici une modification qui aura une incidence sur notre code et son bon fonctionnement sur cette nouvelle version majeure de PHP.
Fournir un objet en argument à la place d’un entier provoque une exception TypeError, mais que se passe-t-il si le type est correct, mais que la valeur ne l’est pas ? À partir de PHP 8 un grand nombre de méthodes lèveront une exception ValueError.
Cette modification aura plus de conséquences sur le code devant être compatible avec PHP 7 et PHP 8 et dont la valeur des arguments est fournie par l’utilisateur ou le développeur.
La solution la plus simple est de valider la donnée avant son usage. Par validation, je recommande la vérification du type de donnée, mais également de son contenu (regex, liste exhaustive des valeurs acceptées, nettoyeur HTML par exemple). La vérification aura également un avantage en termes de sécurité, mais j’en reparlerais sûrement dans un autre bloc post.
Concrètement, à quoi faut’il s’attendre dans PHP 8 ?
Voici comment réagit la fonction password_hash avec un argument invalide dans PHP 8 :
Interactive shell
php > echo phpversion();
8.0.0-dev
php >
php > $return = password_hash('test', PASSWORD_ARGON2I, ['threads' => 0]);
Warning: Uncaught ValueError: Invalid number of threads in php shell code:1
Stack trace:
#0 php shell code(1): password_hash('test', 'argon2i', Array)
#1 {main}
thrown in php shell code on line 1
php >
Ici, je passe un nombre incorrect de fils d’exécution à utiliser pour le calcul de la somme de contrôle du mot de passe. PHP lève une exception spécifique de type ValueError.
Dans votre code, si vous réalisez des tests similaires à if (is_string($return) === false) {}, il sera nécessaire de capturer l’exception par une structure de code try catch pour gérer les cas d’erreur en PHP 8.
Maintenant, comment rendre notre code compatible avec PHP 7 et 8 ?
Voici un exemple de code :
<?php
try {
$return = password_hash('test', PASSWORD_ARGON2I, ['threads' => 0]);
// Test du retour de la fonction
if (is_string($return) === false) {
throw new ValueError('Error with password_hash function, see the PHP logs to more details.');
}
} catch (ValueError $e) {
var_dump($e);
// Traitement de l'erreur
}
Pour PHP 7, il est nécessaire de définir la classe ValueError, car elle n’existe pas. Cependant, plutôt que définir cette classe dans tous vos projets, utilisez la librairie polyfill pour PHP 8.0 réalisée par Symfony.
La mise à jour du code est donc possible dès maintenant pour nos projets et nos librairies.
Après avoir aperçu la modification du comportement, voici la liste des méthodes PHP qui peuvent émettre une exception ValueError :
Dans la continuité du précédent article sur PHP 8, voici les modifications de l’extension multi-byte string qui peuvent avoir une incidence sur notre code et son bon fonctionnement sur cette nouvelle version majeure de PHP.
Alias de fonction ou fonctions supprimées
mbregex_encoding -> mb_regex_encoding
mbereg -> mb_ereg
mberegi -> mb_eregi
mbereg_replace -> mb_ereg_replace
mberegi_replace -> mb_eregi_replace
mbsplit -> mb_split
mbereg_match -> mb_ereg_match
mbereg_search -> mb_ereg_search
mbereg_search_pos -> mb_ereg_search_pos
mbereg_search_regs -> mb_ereg_search_regs
mbereg_search_init -> mb_ereg_search_init
mbereg_search_getregs -> mb_ereg_search_getregs
mbereg_search_getpos -> mb_ereg_search_getpos
mbereg_search_setpos -> mb_ereg_search_setpos
func_overload supprimée
La directive de configuration INI mbstring.func_overload a été supprimée avec les constantes afférentes MB_OVERLOAD_MAIL, MB_OVERLOAD_STRING, et MB_OVERLOAD_REGEX. Tout comme la récupération des informations func_overload et func_overload_list via la méthode mb_get_info.
Autres modifications de comportement
Le tableau de résultat passé en référence dans l’argument &$result est maintenant obligatoire pour la fonction mb_parse_str.
Le modificateur e pour la fonction mb_ereg_replace a été supprimé. Il est nécessaire d’utiliser la fonction mb_ereg_replace_callback à la place.
Si la valeur de l’argument pattern de la fonction mb_ereg_replace n’est pas une chaîne de caractère, il sera transformé en chaine de caractère. Pour retrouver le comportement de PHP 7, il est nécessaire d’ajouter explicitement la fonction chr. Ce comportement ne peut pas être détecté par l’analyse statique du code.
La valeur de l’argument needle des fonctions suivantes mb_strpos, mb_strrpos, mb_stripos, mb_strripos, mb_strstr, mb_stristr, mb_strrchr et mb_strrichr ne peuvent plus être vides. Ce comportement ne peut pas être détecté par l’analyse statique du code.
Il n’est plus possible de fournir l’encodage en 3e argument à la fonction mb_strrpos. Il est obligatoire de saisir 0 pour la valeur de l’argument offset.
Conclusion
Comme pour de nombreuses améliorations, il est possible de détecter les modifications à apporter grâce à l’analyse statique. Certaines modifications peuvent même être réalisées automatiquement avec un outil de migration tel que Rector.
Restez à l’écoute, je vais réaliser d’autre article sur les modifications apportées par PHP 8 ayant une incidence sur notre code.
The version 8 of PHP is scheduled for December 2020. All active extension must be upgrading their code to need a run with the new version.
Actually in development, the version 1.0 of the extension Win32Service will be compliant only with PHP 8. The version 1.0.0-dev is already upgraded and usable for tests. You can download the snapshot build of PHP for Windows (on the bottom of the page) and the Win32Service extension DLL on the GitHub repository.
Currently, version 1.0 of the Win32Service extension is building only for the x64 architecture and for two PHP mode (NTS and TS).
Maintained version
For the future, Win32Service version 0.4 will be maintained for all PHP 7 maintained versions. And Win32Service version 1.0 will be maintained for all PHP 8 maintained versions.
La version 8 de PHP est prévue pour décembre 2020. Toutes les extensions actives doivent mettre à jour leur code pour avoir besoin d’une exécution avec la nouvelle version.
La version 1.0 de l’extension Win32Service est en cours de développement et ne sera compatible qu’avec PHP 8. La version 1.0.0-dev est déjà mise à jour et utilisable pour les tests. Vous pouvez télécharger la version snapshot de PHP pour Windows (en bas de la page) et la DLL d’extension Win32Service sur le dépôt GitHub.
Actuellement, la version 1.0 de l’extension Win32Service est compilée uniquement pour l’architecture x64 et pour deux modes PHP (NTS et TS).
Versions maintenues
La version 0.4 sera maintenue pour les versions maintenues de PHP 7. La version 1.0 sera maintenue pour les versions maintenues de PHP 8.
La future version de PHP est encore en cours de développement (sortie prévue pour décembre 2020) mais la liste des nouveautés déjà réalisées est déjà accessible. Elle n’est cependant pas encore figée.
Vous avez surement entendu parler du JIT (Just in time) de PHP 8 mais cela changera-t-il quelque chose à notre quotidien ? Pour certains oui.
Pour la plupart des développeurs, une version majeure implique une migration du code. Dans le cas de l’évolution de notre code à quoi faut-il s’attendre ?
Les avertissements et avis ont été revus
Dans ce nombreux cas PHP remontait un avertissement ou un avis, nombreux sont ceux qui ont été transformés en erreur.
Un certain nombre d’avertissements ont été convertis en exceptions d’erreur :
Tentative d’écriture dans une propriété d’une variable qui n’est pas un objet. Auparavant, cette action crée implicitement un objet stdClass pour les chaînes nulles, fausses et vides.
Tentative d’ajout d’un élément dans un tableau pour lequel la clé PHP_INT_MAX est déjà utilisée.
Tentative d’utilisation d’un type non valide (tableau ou objet) comme clé de tableau ou décalage de chaîne.
Tentative d’écriture dans un index de tableau d’une valeur scalaire.
Tentative d’utilisation de la fonction unpack sur une variable qui n’est pas un tableau ou un Traversable.
Les méthodes et comportements dépréciés ont été supprimés
La possibilité de supprimer une variable avec le cast (unset) ne sera plus possible.
Les constructeurs de classe style PHP 4 ne sont plus utilisable. Il faut remplacer le nom de la méthode constructeur par __construct. La fonction sera une fonction comme une autre.
<?php
class MaClass {
public function MaClass() {
}
}
Il est nécessaire de déclarer explicitement les alias :
trait T1 {
function func() {}
}
trait T2 {
function func() {}
}
class MaClass {
use T1 {
func as otherFunc;
}
use T2 {
func as otherFunc2;
}
function func() {}
}
Avec PHP 8, les méthodes abstraites présentes dans les traits seront vérifiées. Ainsi le code suivant est invalide :
trait MyTrait {
abstract private function neededByTrait(): string;
}
class MyClass {
use MyTrait;
// Error, because of return type mismatch.
private function neededByTrait(): int { return 42; }
}
Autres modifications entrainant un changement de comportement
L’utilisation de « parent » dans une classe sans parent entrainera une erreur fatale lors de la compilation.
L’opérateur @ ne supprime plus les erreurs fatales. Il sera nécessaire d’adapter les gestionnaires d’erreur qui utilise error_reporting. Pour détecter une erreur silencieuse, il faut utiliser ce code : if (!(error_reporting() & $err_no)) { return; /* Silenced */ }
La priorité de l’opérateur de concaténation a changé par rapport à décalages de bits et addition ainsi que soustraction. Ainsi dans le code suivant l’opération sera réalisée avant la concaténation echo 'Total '. $a + $b;. PHP RFC : Change the precedence of the concatenation operator
Les fonctions désactivées sont désormais traitées exactement comme les fonctions inexistantes. L’appel d’une fonction désactivée la signalera comme inconnue et la redéfinition d’une fonction désactivée est désormais possible.
Les opérateurs arithmétiques et au niveau du bit (+, -, *, /, **,%, <<, >>, &, |, ^, ~, ++, -) vont maintenant systématiquement lancer une TypeError lorsque l’un des opérandes est un tableau, ressource ou objet non surchargé. La seule exception à cela est l’opération de fusion des tableaux, qui reste prise en charge. PHP RFC : Stricter type checks for arithmetic/bitwise operators
Conclusion
PHP 8 apporte de nombreuses nouveautés certaines attendue et déjà connue, car déprécié dans les précédentes versions de PHP. Utilisons le temps qu’il reste avant la sortie pour tester et corriger nos applications avec cette nouvelle version de PHP.
Nos outils d’aide à la migration tels que PHPCompatibility et Phan sont déjà en cours d’évolution pour tenir compte des nouveautés de PHP 8.
J’ai mis à disposition une version en ligne de PHPCompatibility et Phan sur le site phptools.online permettant le test de bout de code PHP.
Pendant ce temps, les frameworks tels que Symfony ont déjà commencé le travail de correction pour PHP 8.
Restez à l’écoute, je vais réaliser d’autre article sur les modifications apportées par PHP 8 ayant une incidence sur notre code.
Les cookies utilisés sur ce site sont soit techniques, soit pour le suivi respectueux de votre vie privée. Plus d'information
The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.