PHAR neboli PHp ARchive je archív podobně jako JAR v Javě. Dokáže vytvořit balík mnoha souborů, nejen PHP. Ten lze pak vkládat do jiných projektů nebo přímo spouštět z příkazové řádky. Nejznámější aplikace šířená jako PHAR je určitě Composer.
Pro tvorbu PHAR souborů lze využít třídu Phar přímo v PHP, nebo aplikaci Box. Dnešní díl je ale především o první metodě, tedy nativní třídě. Soubory PHAR mohou být také zabezpečeny a podepsány. Realita ale trochu pokulhává, viz článek na Sucuri.net.
Jak na to
Nejjednodušší způsob je vložit celou aplikaci do složky app, vedle složky vytvořil skript build.php a ten následně spustit s obsahem níže. Ve složce app může být klidně zabalen celý vendor s autoloaderem od Composeru. A hlavně tam musí být tzv. entry point neboli soubor, který se spustí jako první.
V základu je zakázáno měnit PHAR soubory a kód skončí neošetřenou výjimkou PharException. Proto je nutné změnit v souboru php.ini phar.readonly z 1 na 0. Ukázka build soubor, kterým se sestavuje Composer je dostupná v jeho repozitáři.
// Pokud se nepovede změnit mód, // je nutné změnu provést přímo v php.ini souboru ini_set("phar.readonly", 0); if (ini_get("phar.readonly") != 0) { die("Nelze zmenit phar.readonly mode"); } $pharFile = 'app.phar'; // Odstranění starých PHAR souborů if (file_exists($pharFile)) { unlink($pharFile); } // Vytvoří nový PHAR $phar = new Phar($pharFile); $phar->startBuffering(); // Povinné pro vlastní stub $phar->buildFromDirectory("app"); // Vytvoří základní STUB s výchozím entry pointer index.php // Soubor index.php musí být rovněž ve složce app $defaultStub = $phar->createDefaultStub("index.php"); $phar->setStub("#!/usr/bin/env php \n".$defaultStub); $phar->stopBuffering(); echo "{$pharFile} vytvoren";
Pozor na spouštění serverem
Apache v základu není nakonfigurovaný tak, aby soubory s příponou .phar spouštěl jako PHP skript. Pokud se na něj někdo odkáže, bude mu vrácen zdrojový kód. Je proto vhodné, vkládat PHAR soubory do složek, kam přístup není, nebo jej zakázat přes htacess. A protože ze serveru se přímo spouštět nejspíše nebude, může se upravit i základní stub.
Vlastní stub
Stub je úvodní část programu, která říká, jak jej zpracovávat. Základní stub obsahuje plno logiky pro správné vrácení i souborů v něm uložených. To je ale zbytečné, protože serverem se přímo PHAR spouště nebude. Proto se může stub trochu zjednodušit.
$defaultStub = <<<'EOF' #!/usr/bin/env php <?php /* * Toto je ukázkový PHAR soubor * * S minimálním stubem, který vše spustí */ Phar::mapPhar(); include 'phar://'.__FILE__.'/index.php'; __HALT_COMPILER(); EOF; $phar->setStub($defaultStub);
Jak na vlastní složky a podsložky
Pokud není možné všechny soubory vložit do složky app, je nutné vše postupně přidat ručně. Zde je nutné zachovávat správné pojmenování, aby všechny include našly správnou cestu k souboru.
// buildFromIterator zaručí stejnou strukturu včetně složek src a vendor v tomto případě
$phar->buildFromIterator( new RecursiveIteratorIterator( new RecursiveDirectoryIterator(__DIR__.'/src', RecursiveDirectoryIterator::SKIP_DOTS) ), __DIR__ ); $phar->buildFromIterator( new RecursiveIteratorIterator( new RecursiveDirectoryIterator(__DIR__.'/vendor', RecursiveDirectoryIterator::SKIP_DOTS) ), __DIR__ ); // Možné je soubor do PHARu vložit pod jiným jménem $phar->addFile(__DIR__."/index.php", 'entry.php'); // Pak je nutné upravit stub $defaultStub = $phar->createDefaultStub("entry.php"); // Nebo v případě vlastního nahradit include na entry include 'phar://'.__FILE__.'/entry.php';
Použití PHARu v ostatních PHP skriptech
Přesto, že Apache nejspíše PHAR spouštět nebude, nic nebrání tomu jej používat ve vlastních skriptech. Jednoduše lze se soubory provést include jednotlivých souborů, případně získat jejich obsah ať už se jedná o PHP skript nebo binární obrázek.
// Lze specifikovat celou přesnou cestu k souboru include 'phar://app.phar/helpers/functions.php'; // Funkce prettify je v souboru functions.php v PHARu výše echo prettify("test"); // Phar rovněž obsahuje obrázek $logo = file_get_contents("phar://app.phar/assets/logo.png"); file_put_contents("test.png", $logo);
Vlastní zkušenosti nebo použití PHP archívů PHAR můžete sdílet v komentářích
K tomuto článku již není možné přidávat další komentáře