Here is an apache2 htaccess example that prevents the downloading of phar-Archives by the user:
RewriteEngine on
RewriteRule ^(.*)\.phar$ - [F]
It triggers a "403 - Forbidden" message instead of delivering the archive.A extensão phar fornece uma maneira de colocar aplicações PHP inteiras em um único arquivo chamado "phar" (Arquivo PHP) para fácil distribuição e instalação. Além de fornecer este serviço, a extensão phar também fornece um método de abstração de formato de arquivo para criar e manipular arquivos tar e zip através da classe PharData, assim como o PDO fornece uma interface unificada para acessar diferentes bancos de dados. Ao contrário do PDO, que não pode converter entre bancos de dados diferentes, o Phar também pode converter entre os formatos de arquivo tar, zip e phar com uma única linha de código. Veja Phar::convertToExecutable() para um exemplo.
O que é phar? Arquivos phar são melhor caracterizados como uma maneira conveniente de agrupar vários arquivos em um único arquivo. Assim, um arquivo phar fornece uma maneira de distribuir uma aplicação PHP completa em um único arquivo e executá-la a partir desse arquivo sem a necessidade de extraí-la para o disco. Além disso, arquivos phar podem ser executados pelo PHP tão facilmente quanto qualquer outro arquivo, tanto na linha de comando quanto em um servidor web. Phar é como um pen drive para aplicações PHP.
Phar implementa essa funcionalidade por meio de um empacotador de fluxo. Normalmente, para usar um arquivo externo dentro de um script PHP, seria usado include:
Exemplo #1 Using an external file
<?php
include '/caminho/para/arquivo/externo.php';
?>
Pode-se pensar que o PHP está, na verdade, traduzindo
/caminho/para/arquivo/externo.php em um
empacotador de fluxo como arquivo:///caminho/para/arquivo/externo.php e,
nos bastidores, ele de fato usa as funções do empacotador de fluxo de arquivo simples para
acessar todos os arquivos locais.
Para usar um arquivo chamado arquivo.php contido em um arquivo phar
/caminho/para/meuphar.phar,
a sintaxe é muito semelhante à sintaxe file:// acima.
Exemplo #2 Usando um arquivo dentro de um arquivo phar
<?php
include 'phar:///caminho/para/meuphar.phar/arquivo.php';
?>De fato, é possível tratar um arquivo phar exatamente como se fosse um disco externo, usando qualquer uma das funções relacionadas a fopen(), opendir() e funções relacionadas a mkdir() para ler, alterar ou criar novos arquivos e diretórios dentro do arquivo phar. Isso permite que aplicações PHP completas sejam distribuídas em um único arquivo e executadas diretamente a partir dele.
O uso mais comum de um arquivo phar é distribuir uma aplicação completa em um único arquivo. Por exemplo, o Instalador PEAR, que acompanha as versões do PHP é distribuído como um arquivo phar. Para usar um arquivo phar distribuído desta forma, o arquivo pode ser executado na linha de comando ou por meio de um servidor web.
Os arquivos Phar podem ser distribuídos como arquivos tar,
arquivos zip ou como o formato de arquivo phar personalizado
projetado especificamente para a extensão phar. Cada formato de arquivo tem vantagens
e desvantagens. Os formatos de arquivo tar e zip podem ser lidos ou extraídos por qualquer
ferramenta de terceiros que possa ler o formato, mas que requer a extensão phar para
executar com PHP. O formato de arquivo phar é personalizado e exclusivo para a extensão phar,
e só pode ser criado pela extensão phar ou pelo pacote PEAR
» PHP_Archive, mas tem a
vantagem de que as aplicações criadas neste formato serão executadas mesmo se a extensão phar
não estiver habilitada.
Em outras palavras, mesmo com a extensão phar desabilitada, é possível executar ou incluir um arquivo baseado em phar. Acessar arquivos individuais dentro de um arquivo phar só é possível com a extensão phar, a menos que o arquivo phar tenha sido criado pelo PHP_Archive.
A extensão phar também é capaz de converter um arquivo phar de tar para zip ou para o formato de arquivo phar em um único comando:
Exemplo #3 Convertendo um arquivo phar do formato phar para tar
<?php
$phar = new Phar('meuphar.phar');
$pgz = $phar->convertToExecutable(Phar::TAR, Phar::GZ); // cria meuphar.phar.tar.gz
?>O Phar pode compactar arquivos individuais ou um arquivo inteiro usando a compactação gzip ou bzip2, e pode verificar a integridade do arquivo automaticamente por meio do uso de assinaturas MD5, SHA-1, SHA-256 ou SHA-512.
Por fim, a extensão Phar é voltada para a segurança e desabilita o acesso de gravação
aos arquivos Phar executáveis por padrão, além de exigir a desativação, em nível de sistema, da configuração
phar.readonly do php.ini para criar ou
modificar arquivos Phar. Arquivos tar e zip normais sem um stub executável
sempre podem ser criados ou modificados usando a classe PharData.
Se aplicações para distribuição estiverem sendo criadas, leia Como criar arquivos Phar. Se quiser mais informações sobre as diferenças entre os três formatos de arquivo suportados pelo Phar, leia Phar, Tar e Zip.
Se aplicações Phar estiverem sendo usadas, há dicas úteis em Como usar os Arquivos Phar.
A palavra phar é uma junção de PHP e
Archive e é vagamente baseada
no jar (Java Archive), familiar aos desenvolvedores Java.
A implementação para arquivos Phar é baseada no pacote PEAR » PHP_Archive, e os detalhes de implementação são semelhantes, embora a extensão Phar seja muito mais poderosa. Além disso, a extensão Phar permite que a maioria das aplicações PHP sejam executadas sem modificações, enquanto os arquivos Phar baseados em PHP_Archive geralmente exigem modificações extensas para funcionar.
Here is an apache2 htaccess example that prevents the downloading of phar-Archives by the user:
RewriteEngine on
RewriteRule ^(.*)\.phar$ - [F]
It triggers a "403 - Forbidden" message instead of delivering the archive.If you get blank pages when trying to access a phar web-page, then you probably have Suhosin on your PHP (like in Debian and Ubuntu), and you need to ad this to your php.ini to allow execution of PHAR archives :
suhosin.executor.include.whitelist="phar"Users should set the `sys_temp_dir` directive.
PHAR stores temporary files in either `sys_temp_dir` or the current working directory(CWD).
This is especially important if you're CWD is on a remote file system. Often web server clusters will share a common file system between each web server (using NFS, DFS, etc...). In such scenarios, if you don't set `sys_temp_dir` to a local directory, PHAR will be creating temporary files over the network, which will result in performance and functionality problems.Here is a very simple program for creating phar files with CLI. Note that it requires phar.readonly in php.ini set to false (Off).
<?php
$filename = "default";
$dir = "./";
$regex = "/^(?!.*build\\.php)(?:.*)$/";
$main = "main.php";
$shebang = "#!/usr/bin/env php";
$chmod = true;
for ($i = 0; $i < $argc; $i++) {
switch ($argv[$i]) {
case "-o":
$i++;
if ($i >= $argc) {
echo "Missing output file name" . PHP_EOL;
exit(1);
}
$filename = $argv[$i];
break;
case "-i":
$i++;
if ($i >= $argc) {
echo "Missing input directory name" . PHP_EOL;
exit(1);
}
$dir = $argv[$i];
break;
case "-p":
$i++;
if ($i >= $argc) {
echo "Missing regular expression pattern" . PHP_EOL;
exit(1);
}
$regex = $argv[$i];
break;
case "-m":
$i++;
if ($i >= $argc) {
echo "Missing main file" . PHP_EOL;
exit(1);
}
$main = $argv[$i];
break;
case "-b":
$i++;
if ($i >= $argc) {
echo "Missing shebang of file" . PHP_EOL;
exit(1);
}
$shebang = $argv[$i];
break;
case "--no-chmod":
$chmod = false;
break;
}
}
if (file_exists($filename)) unlink($filename);
$phar = new Phar($filename);
$phar->buildFromDirectory($dir, $regex);
$phar->setStub(($shebang ? $shebang . PHP_EOL : "") . $phar->createDefaultStub($main));
if ($chmod) {
chmod($filename, fileperms($phar) | 0700);
}when read via phar://, stream will unserialize object including phar file
Use this to create phar
<?php
// create new Phar
$phar = new Phar('lemon.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); ? >');
// add object of any class as meta data
class AnyClass {}
$object = new AnyClass;
$object->data = 'Chanh';
$phar->setMetadata($object);
$phar->stopBuffering();
?>
and read it by:
<?php
class AnyClass {
function __destruct() {
echo $this->data;
}
}
// output: Chanh
file_get_contents('phar://test.phar');
?>Here is a very simple class to build a phar file from a given source directory. You can use this for your own project and simple deployment.
But my main goal was to show how to use PHAR functions in a simple way.
<?php
class BuildPhar
{
private $_sourceDirectory = null;
private $_stubFile = null;
private $_outputDirectory = null;
private $_pharFileName = null;
/**
* @param $_sourceDirectory // This is the directory where your project is stored.
* @param $stubFile // Name the entry point for your phar file. This file have to be within the source
* directory.
* @param null $_outputDirectory // Directory where the phar file will be placed.
* @param string $pharFileName // Name of your final *.phar file.
*/
public function __construct($_sourceDirectory, $stubFile, $_outputDirectory = null, $pharFileName = 'myPhar.phar') {
if ((file_exists($_sourceDirectory) === false) || (is_dir($_sourceDirectory) === false)) {
throw new Exception('No valid source directory given.');
}
$this->_sourceDirectory = $_sourceDirectory;
if (file_exists($this->_sourceDirectory.'/'.$stubFile) === false) {
throw new Exception('Your given stub file doesn\'t exists.');
}
$this->_stubFile = $stubFile;
if(empty($pharFileName) === true) {
throw new Exception('Your given output name for your phar-file is empty.');
}
$this->_pharFileName = $pharFileName;
if ((empty($_outputDirectory) === true) || (file_exists($_outputDirectory) === false) || (is_dir($_outputDirectory) === false)) {
if ($_outputDirectory !== null) {
trigger_error ( 'Your output directory is invalid. We set the fallback to: "'.dirname(__FILE__).'".', E_USER_WARNING);
}
$this->_outputDirectory = dirname(__FILE__);
} else {
$this->_outputDirectory = $_outputDirectory;
}
$this->prepareBuildDirectory();
$this->buildPhar();
}
private function prepareBuildDirectory() {
if (preg_match('/.phar$/', $this->_pharFileName) == FALSE) {
$this->_pharFileName .= '.phar';
}
if (file_exists($this->_pharFileName) === true) {
unlink($this->_pharFileName);
}
}
private function buildPhar() {
$phar = new Phar($this->_outputDirectory.'/'.$this->_pharFileName);
$phar->buildFromDirectory($this->_sourceDirectory);
$phar->setDefaultStub($this->_stubFile);
}
}
//END Class
//Example Usage:
$builder = new BuildPhar(
dirname(__FILE__).'/_source',
'my_default_stub.php',
dirname(__FILE__).'/_output',
'my-phar-file.phar'
);