Cette semaine, nous mettons à jour notre librairie de programmation PHP. Nous avons publié la première versions de cette librairie en 2011. En 12 ans, le langage PHP a beaucoup évolué. Nous mettons donc à jour notre librairie pour profiter des améliorations qui sont apparues depuis.
La version actuelle de PHP est 8.2, mais en 2011 la version stable que tout le monde utilisait était PHP 5.3. Notre librairie a donc été pensée pour être exécutée en avec cette version.
A cette époque, PHP était une langages non typé, mais depuis PHP 7.1 le typage a fait son apparition. Le typage en PHP offre plusieurs avantages pour les développeurs. Il permet de détecter les erreurs de type plus tôt dans le processus de développement, car les erreurs de type seront levées lors de la compilation plutôt que lors de l'exécution. Cela améliore aussi la lisibilité et la documentation du code.
Le typage de notre librairie
Vous l'aurez compris, nous avons décidé de modifier notre librairie et de "typer" notre API de programmation. Par exemple, voici lae déclaration de la méthode RegisterHub de la classe YAPI ainsi que la méthode set_beacon de la classe YModule.
....
public function set_beacon(int $newval): int
...
Ce typage permet de détecter à la compilation l'erreur dans le code suivant:
$m->set_beacon(true);
Le compilateur, ainsi que n'importe quel bon IDE moderne, indiquera que l'on ne peut pas passer un booléen à set_beacon. La solution correcte est de passer la constante numérique YModule::BEACON_ON définit dans notre librairie.
$m->set_beacon(YModule::BEACON_ON);
Quelques remarques
En PHP, la taille des entiers dépend de l'architecture du serveur PHP. Sur une machine avec un PHP 64 bits, l'entier le plus grand représentable est 9'223'372'036'854'775'807. Mais, la version 32-bits de PHP ne permet pas de représenter un entier de plus de 2'147'483'648.
Afin de contourner cette limitation, nous avons décidé d'utiliser le type float pour toutes les méthodes qui peuvent travailler avec un entier qui ne tiendrait pas sur un entier 32-bits.
Dans la pratique, ces cas ne concernent que quelques méthodes qui utilisent un nombre de milliseconde pour représenter un moment ou un délais. C'est par exemple le cas de la méthode SetCacheValidity.
...
Cela peut sembler étrange d'utiliser un type float, mais de cette manière nous avons le même comportement quelque soit l'architecture de votre installation.
Backward compatiblité
Bien évidement, ces changements ne sont pas sans conséquence sur la portabilité de notre librairie. En effet, si le typage a été introduit en PHP 7.0, il a évolué et il s'est démocratisé avec PHP 8.0.
Nous avons décidé de baser notre librairie sur PHP 8.x. C'est-à-dire que notre librairie fonctionne parfaitement avec n'importe quelle version de PHP actuellement encore supportée.
Toutefois, afin de ne pas abandonner nos clients qui ont des installations plus anciennes, nous maintenons une version compatible avec PHP 7.1. qui date de 2016.
Dans l'archive de la librairie vous trouverez donc deux répertoires:
- php8 qui contient la version pour PHP 8.x
- php7 qui contient la version pour PHP >=7.1
Notez que le sous-répertoire Sources dans lequel tous les fichiers sources étaient stocké n'existe plus. Si vous aviez un script qui copiait automatiquement les fichiers depuis l'archive, il faut le modifier pour qu'il utilise le sous-répertoire php8 ou php7
PHP PSR
Dans l'archive de la librairie, il y a aussi un sous-répertoire phpPSR. Il s'agit d'une version de la librairie qui suis les recommandations PSR.
Pour simplifier, cette version est de même code que la version php8 mais chaque classe est stockée dans un fichier séparé. De plus, cette version utilise un namespace Yoctopuce\YoctoAPI.
Ces changements rendent notre librairie beaucoup plus facilement utilisable avec des installations qui utilisent l'autoload.
Voici un exemple qui utilise l'autoload au lieu de la fonction require ou import.
...
Comme on le voit, il faut utiliser le mot clef use pour importer chaque classe de notre librairie.
Cette version est aussi disponible via composer. Elle peut être ajoutée comme dépendance à votre projet à l'aide de la commande suivante:
composer require yoctopuce/yoctoapi
Ce package composer est très utile si vous utilisez un framework comme Symfony. Contrairement à notre ancien package, celui-ci déclare un namespace et ne pollue plus l'espace de nom global.
namespace App\Controller;
use ApiPlatform\Api\UrlGeneratorInterface;
use App\Service\HeaterService;
use App\Service\MailReportService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Yoctopuce\YoctoAPI\YAPI_Exception;
use Yoctopuce\YoctoAPI\YNetwork;
use Yoctopuce\YoctoAPI\YAPI;
class YoctopuceControlerController extends AbstractController
{
#[Route('/callback', name: 'yoctopuce_controler')]
public function index(HeaterService $service, MailReportService $report): Response
{
$error = "";
try {
$parameter = $this->getParameter('yocto_callback_cache_directory');
$hash = $this->getParameter('yocto_callback_md5_hash');
$auth = "md5:$hash";
YAPI::SetHTTPCallbackCacheDir($parameter);
if (YAPI::TestHub("$auth@callback", 10, $error) == YAPI::SUCCESS) {
YAPI::RegisterHub("$auth@callback");
$network = YNetwork::FirstNetwork();
$yhub = $network->module();
$serialNumber = $yhub->get_serialNumber();
$service->CallbackLogic($serialNumber);
return new Response("done.");
}
} catch (YAPI_Exception $ex) {
$report->reportFatalException("Yoctopuce callback error", $ex);
return new Response($ex->getMessage());
}
...
}
}