Update of our PHP library

Update of our PHP library

This week we are updating our PHP programming library. We released the first version of this library in 2011. In 12 years, the PHP language has evolved a lot. So we update our library to take advantage of the improvements that have appeared since.





The current version of PHP is 8.2, but in 2011 the stable version that everyone was using was PHP 5.3. Our library has been designed to be executed with this version.

At that time, PHP was an untyped language, but since PHP 7.1 typing has made its appearance. Typing in PHP offers several advantages for the developers. It allows type errors to be detected earlier in the development process, as type errors are caught at compile time rather than at run time. It also improves the readability and documentation of the code.


Typing of our library


As you can see, we have decided to modify our library and to "type" our programming API. For example, here is the declaration of the RegisterHub method of the YAPI class and the set_beacon method of the YModule class.

public static function RegisterHub(string $url, string &$errmsg = ''): int
....
public function set_beacon(int $newval): int
...



This typing allows the compiler to detect at compile time the error in the following code:

$m = YModule::FirstModule();
$m->set_beacon(true);



The compiler, as well as any good modern IDE, indicates that we cannot pass a boolean to set_beacon. The correct solution is to pass the numeric constant YModule::BEACON_ON defined in our library.

$m = YModule::FirstModule();
$m->set_beacon(YModule::BEACON_ON);



Some remarks


In PHP, the size of the integers depends on the architecture of the PHP server. On a machine with 64-bit PHP, the largest representable integer is 9'223'372'036'854'775'807. But, the 32-bit version of PHP does not permit the representations of an integer larger than 2'147'483'648.

In order to work around this limitation, we decided to use the float type for all methods that can work with an integer that could not fit on a 32-bit integer.

In practice, these cases only concern a few methods that use a number of milliseconds to represent a moment or a time. This is for example the case of the SetCacheValidity method.

public function SetCacheValidity(float $cacheValidityMs): void
...



It may seem strange to use a float type, but in this way we have the same behavior regardless of the architecture of your installation.

Backward compatibility


Of course, these changes are not without consequences on the portability of our library. Indeed, if typing was introduced in PHP 7.0, it evolved and it was democratized with PHP 8.0.

We decided to base our library on PHP 8.x. This means that our library works perfectly with any version of PHP still currently supported.

However, in order not to abandon our customers who have older installations, we maintain a version compatible with PHP 7.1. which dates from 2016.

In the library archive you find two subdirectories:

  • php8 which contains the version for PHP 8.x
  • php7 which contains the version for PHP >=7.1


Note that the Sources subdirectory where all the source files were stored no longer exists. If you had a script that automatically copied files from the archive, you need to modify it to use the php8 or php7 subdirectory

PHP PSR


In the archive of the library, there is also a phpPSR subdirectory. It is a version of the library that follows the PSR recommendations.

To simplify, this version has the same code as the php8 version but each class is stored in a separate file. Moreover, this version uses a Yoctopuce\YoctoAPI namespace .

These changes make our library much easier to use with installations that use autoload.

Here is an example that uses the autoload instead of the require or import function.

<?php

use Yoctopuce\YoctoAPI\YAPI;
use Yoctopuce\YoctoAPI\YModule;

YAPI::RegisterHub("http://127.0.0.1:4444/");
$module = YModule::FirstModule();
while (!is_null($module)) {
  printf("%s (%s)\n", $module->get_serialNumber(), $module->get_productName());
  $module = $module->nextModule();
}
YAPI::FreeAPI();



As we can see, we have to use the use keyword to import each class of our library.

This version is also available via composer. It can be added as a dependency to your project with the following command:

composer require yoctopuce/yoctoapi



This composer package is very useful if you use a framework like Symfony. Unlike our old package, this one declares a namespace and does not pollute the global namespace anymore.

<?php

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



Add a comment No comment yet Back to blog












Yoctopuce, get your stuff connected.