PHAR ("PHp ARchive") è il nome di una libreria PHP che può essere utilizzata per archiviare intere applicazioni all'interno di un unico file. In questo modo verranno semplificate non soltanto le operazioni di distribuzione ed installazione, ma anche la procedura per la messa in produzione degli script: gli archivi PHAR funzionano infatti senza necessità di estrazione.
Questa estensione è diventata disponibile come funzionalità predefinita a partire dalla versione 5.3 di PHP, ma, poiché precedentemente era disponibile tramite repository PECL, non rappresenta una novità assoluta. Concettualmente fornisce agli sviluppatori PHP una soluzione molto simile a quella dei file JAR ("Java ARchive") per Java, ma è stata pensata specificatamente per le applicazioni Web e necessita unicamente di PHP per processare i file.
Requisiti di sistema
Come anticipato, l'estensione PHAR è immediatamente disponibile con PHP in versione 5.3 o successive, potrà però essere utilizzata anche con la versione 5.2.1 reperendo la libreria PHAR 2.0.0 via PECL; per quanto riguarda le funzionalità a corredo, sarà opportuno poter utilizzare:
- gli iteratori SPL (Standard PHP Library), una raccolta di classi ed interfacce per la soluzione di problematiche standard comunemente disponibile con PHP;
- le librerie di compressione zlib e bzip2 per PHP, PHAR infatti è in grado di effettuare operazioni di generazione, accesso in lettura, scrittura e conversione di archivi tra i formati ZIP, TAR e PHAR;
- l'estensione OpenSSL di PHP, in questo modo sarà possibile disporre delle firme per verificare l'integrità degli archivi.
È da sottolineare che, date le correzioni apportate per la soluzione di un bug a carico dello stream zlib.deflate, è consigliabile utilizzare come minimo la versione 5.2.6 di PHP, pur raccomandando quando possibile l'aggiornamento all'ultimo rilascio effettuato dagli sviluppatori del linguaggio.
Per quanto riguarda le impostazioni del file di configurazione php.ini, si deve tenere conto che, in fase di produzione e per ragioni di sicurezza, PHP dovrebbe gestire gli archivi PHAR in sola lettura; in fase di sviluppo è invece opportuno modificare il valore predefinito ("1" o "on") della direttiva phar.readonly disattivandola:
phar.readonly = 0
Da segnalare anche la direttiva phar.require_hash che forzerà tutti gli archivi PHAR a contenere delle firme in uno standard per la cifratura supportato, l'abilitazione di tale opzione (che è poi l'impostazione predefinita) impedirà che vengono processati archivi che non le contengono.
Struttura e funzionamento di un archivio PHAR
Le funzionalità PHAR sono implementate attraverso un apposito prefisso per il flusso di dati, denominato stream wrapper, che nel caso specifico è phar://; per cui gli archivi prodotti saranno accessibili e gestibili da qualsiasi funzione PHP per la manipolazione dei file che fornisca il supporto per tale wrapper.
Strutturalmente un archivio PHAR può presentare quattro componenti:
- un file matrice o di "bootstrap" denominato Stub;
- un file MANIFEST, concettualmente simile a quelli già in uso per i file JAR, contenente le informazioni relative all'archivio;
- i file che compongono l'applicazione;
- una firma per le verifiche d'integrità.
Tra gli elementi elencati è importante al momento soffermarsi sullo stub. Il file è importante nel processo di avvio poiché viene inizializzato ogniqualvolta si esegue un archivio PHAR (tecnicamente viene definito anche come un "loader"). Il file viene utilizzato quando si effettua l'inclusione diretta di un file .phar, ad esempio:
include_once("file_phar.phar");
mentre non viene utilizzato quando ad essere incluso è un file contenuto nell'archivio:
include_once("phar://application.phar/nome_file.php");
Il codice del file di stub di presenta a livello sintattico come quello di un qualsiasi altro file PHP, esso però dovrà terminare con una chiamata alla funzione __HALT_COMPILER
che si occuperà di arrestare il compilatore dopo l'esecuzione; il delimitatore ?>
potrà essere incluso o no dopo __HALT_COMPILER
, ma non ci dovrà essere più di uno spazio tra il ";" successivo alla funzione e il tag di chiusura, altrimenti la libreria non sarà in grado di processare il MANIFEST
.
Creazione e utilizzo di un archivio PHAR
Ora che sono note le caratteristiche strutturali di un archivo PHAR, vediamo come crearne uno. Il primo passaggio da effettuare sarà quello di creare un semplice file contenente una classe, il suo codice verrà salvato in un file denominato MyClass.php:
<?php
// dichiarazione della classe
class MyClass {
var $myMessage;
// dichiarazione del metodo di classe
public
function myMethod() {
$this->myMessage = "Il mio primo archivio con PHAR.";
echo $this->myMessage;
}
}
// generazione dell'ogetto di classe per istanza
$myObject = new myClass();
// esecuzione del metodo
$myObject->myMethod();
?>
Tale classe svolgerà l'elementare funzione di stampare un messaggio testuale, il file che la contiene sarà richiamato all'interno dello Stub che verrà memorizzato in un file omonimo (Stub.php) in cui sarà presente il seguente codice:
<?php
// chiamata alla classe tramite stream wrapper
include_once "phar://NuovoProgetto.phar/MyClass.php";
// arresto dell'esecuzione da parte del compilatore
__HALT_COMPILER();
?>
Il prossimo passaggio sarà quello relativo alla creazione del PHAR e lo vedremo nella prossima pagina.
La creazione del PHAR avverrà tramite l'esecuzione di un file (CreaPhar.php) che non verrà ricompreso all'interno dell'archivio generato:
<?php
// blocco di controllo per le eccezioni
try {
// inizializzazione dell'oggetto di classe
$phar = new Phar("NuovoProgetto.phar");
// inserimento in archivio di un file
$phar->addFile("Stub.php");
// impostazione del file inserito quale Stub del PHAR
$phar->setStub( $phar->createDefaultStub("Stub.php") );
// inserimento di un secondo file in archivio
$phar->addFile("MyClass.php");
// definizione dell'algoritmo per la firma
$phar->setSignatureAlgorithm(Phar::SHA1);
}
// gestione delle eccezioni
catch (Exception $e) {
echo "Rilevato un problema nella creazione dell'archivio: ", $e;
}
?>
Passiamo alla descrizione del codice. Il file proprosto inserirà all'interno di un blocco di controllo la procedura relativa alla creazione per istanza dell'archivio (NuovoProgetto.phar), ad esso verrà aggiunto, tramite il metodo addFile()
, un nuovo file che, immediatamente dopo, verrà impostato come Stub per l'avvio dell'applicazione attraverso il metodo setStub()
; verrà poi aggiunto un secondo file, cioè quello che sarà richiamato dallo Stub, e infine si procederà con la definizione dell'algoritmo (in questo caso SHA1) per le verifiche d'integrità.
Il passaggio finale richiederà la creazione di un file che, includendo l'archivio, permetterà l'inzializzazione dello Stub consentendo al compilatore di eseguire l'applicazione:
<?php
// inclusione del file di progetto
include_once("NuovoProgetto.phar"); ?>
Per comodità dello sviluppatore sarà possibile chiamare tale file index.php, in modo che sia immediatamente reperibile dalla directory di appartenenza, per cui digitando, per esempio,:
http://127.0.0.1/percorso_cartella_phar/
l'applicazione produrrà l'output desiderato.
Opzionalmente, sarà possibile convertire l'archivio .phar in un altro formato, ad esempio quello relativo ad un algoritmo di compressione; il codice seguente consentirà ad esempio di convertire un file PHAR tramite archiviazione TAR e compressione GZip:
<?php
try {
// inizializzazione dell'oggetto di classe
$phar = new Phar("NuovoProgetto.phar");
// conversione in un altro formato compatibile
$tgz = $phar->convertToExecutable(Phar::TAR, Phar::GZ);
}
catch (Exception $e) {
echo "Errore di archiviazione: ", $e;
}
?>
Vantaggi e svantaggi nell'utilizzo degli archivi Phar
La possibilità di creare singoli archivi contenenti intere applicazioni realizzate in PHP costituisce indubbiamente un grande vantaggio per lo sviluppatore, ma anche l'utilizzo di PHAR presenta delle limitazioni che dovranno essere prese in considerazione; per quanto riguarda gli aspetti positivi relativi a tale funzionalità è possibile fare riferimento a:
- la possibilità di testare simultaneamente più versioni di uno specifico archivio;
- l'immediatezza delle procedura di aggiornamento delle versioni correnti di un file PHAR;
- il livello di prestazioni paragonabile a quello delle applicazioni non archiviate grazie all'ottimizzazione della libreria PHAR;
- la possibilità di includere tutti i file, comprese le dipendenze, in un unico archivio;
- una minore esposizione delle applicazioni ad eventuali attacchi di tipo elementare dovuta ad una struttura differente rispetto agli script non archiviati.
Tra i possibili svantaggi è possibile citare
- il maggior tempo necessario per apportare delle modifiche alle singole componenti dell'applicazione;
- l'accesso più difficoltoso ai file, anche quelli per la documentazione quando archiviati;
- la mancanza di un supporto per gli aggiornamenti incrementali, per cui ogni upgrade richiederà il salvataggio manuale di una nuova versione del file Phar nella Web root;
- la compatibilità non garantita con tutti i server Web.
Va poi rammentato che la generazione di archivi PHAR rappresenta un meccanismo per l'accesso alle applicazioni tramite un singolo file e non un sistema automatico per il loro deploy (passaggio alla fase di produzione).
Conclusioni
L'estensione PHAR di PHP è una soluzione per l'archiviazione di applicazioni Web in un singolo file che potrà essere utilizzato immediatamente e senza la necessità di una "scompattazione"; nel corso di questa trattazione sono state descritte le loro caratteristiche sintattiche e strutturali nonché le operazioni necessarie per la loro creazione e il funzionamento all'interno di una Web root.