PHP FFI: Introduzione – Parte 1


Introduzione

Dalla versione 7.4 di PHP, abbiamo finalmente accesso alle funzioni di interoperabilità tra diversi linguaggi e PHP: la FFI o Interfaccia di Funzione Esterna.

Cosa è la FFI?
È semplicemente la capacità di utilizzare una libreria esterna (.dll o .so) direttamente in PHP, senza dover creare un'estensione PHP.
Già, solo con uno script PHP!
È, tra le altre cose, ciò che ha reso Python così famoso e gli ha permesso di avere così tante funzionalità.

La cosa fantastica della FFI è che uno sviluppatore PHP che non è un esperto in C/Rust/Go/Kotlin (elenco non esaustivo) può finalmente collegarsi da solo a una libreria esterna. Quindi, se hai un progetto con un bisogno molto specifico, una libreria proprietaria, o qualunque cosa, e non hai troppo carico, puoi affrontare direttamente lo sviluppo del suo utilizzo.
Succede raramente, ma qui da partITech, abbiamo dovuto sviluppare moduli PHP. Di conseguenza, sviluppare la connessione con la libreria in PHP dovrebbe rendere la procedura molto più semplice e rapida da implementare.

Certo, questa funzionalità ha un costo, poiché, anche se la procedura consente uno sviluppo più rapido, non è veloce quanto un vero modulo PHP scritto in C/C++.
Infatti, l'accesso alle strutture con FFI è attualmente due volte più lento rispetto a un modulo nativo. Pertanto, non si raccomanda l'uso della FFI per migliorare le prestazioni della propria applicazione. Tuttavia, può aiutarti molto a ridurre l'uso della memoria su processi molto esigenti. (fonte https://www.php.net/manual/en/intro.ffi.php).

Bene, bando alle ciance e alla chiacchierata. Ciò che vogliamo vedere è il codice.
Quindi, propongo che diamo un'occhiata a diversi problemi riscontrati durante i nostri test. Ovviamente, ogni progetto è diverso, ma se questo articolo può aiutarti a mettere le mani nel "motore", ne saremo felici.

L'Hello World

Il test di benchmark di base rimane il famoso "Hello World", quindi iniziamo il nostro viaggio nel meraviglioso mondo della FFI con una funzione C che ci restituirà "Hello World".

hello.c

#include <stdio.h>

 const char * hello() {
   return "Hello, World!";
}

hello.h

export const char * hello();

Ora possiamo compilare.

gcc -c hello.c

Chiediamo a gcc di creare la nostra libreria condivisa, il famoso file .so.

gcc -shared -o hello.so hello.o

Ecco fatto! Ora abbiamo il nostro materiale per giocare direttamente in PHP-ffi.

Ecco il codice PHP che ci permette di chiamare la nostra funzione hello().

hello.php

#!/usr/bin/php8.1
<?php
$ffi = FFI::cdef(
    "const char *hello();",
    __DIR__ ."/hello.so"
);

echo $ffi->hello();
chmod +x hello.php
./hello.php
Hello, World!

Spiegazioni:

Il metodo cdef ci permette di creare un nuovo oggetto FFI. Il primo parametro è una stringa contenente la definizione della nostra libreria. Non siamo obbligati a mettere tutta l'informazione della libreria, solo ciò che ci interessa.

Da notare che se si utilizzano file di header un po' complessi, c'è una buona probabilità che si blocchi direttamente. Da quanto ho potuto utilizzare, ho sistematicamente ricreato e semplificato i file di definizione.
Vedremo in un altro esempio come creare e utilizzare direttamente un file di intestazione troppo grande per essere inserito direttamente nel nostro script. Può diventare rapidamente complicato 😊

Il secondo parametro è la nostra libreria condivisa. Non c'è un vero bisogno di spiegare.

Infine, chiameremo direttamente la funzione e faremo l'echo del risultato.

Semplice... Basilare.

Possiamo passare a un esempio un po' più avanzato? Ci vediamo nella seconda parte del nostro dossier sul meraviglioso mondo delle Interfacce di Funzione Esterna.

PHP FFI: Passaggio di parametri e utilizzo del motore zend - parte 2

Grazie a Thomas Bourdin, Cédric Le Jallé e Stéphane Pechard per il loro aiuto, consigli e revisione.