PHP8 使用 Phar Archives简介

2024-02-19 15:45 更新

Phar 归档在概念上类似于 Java JAR 归档,但都是定制的 满足 PHP 应用程序的需求和灵活性。Phar 档案是 用于在单个文件中分发完整的 PHP 应用程序或库。一个 Phar 存档应用程序的使用方式与任何其他 PHP 应用程序完全相同:

php coolapplication.phar
  

使用 Phar 存档库与使用任何其他 PHP 库相同:

<?php
include 'coollibrary.phar';
?>

流包装器提供了 phar 扩展的核心,并且 这里 详细解释。 phar 流包装器允许使用 PHP 的标准文件函数 fopen()、opendir() 和 其他处理常规文件的。流包装器支持所有 对文件和目录的读/写操作。pharphar

<?php
include 'phar://coollibrary.phar/internal/file.php';
header('Content-type: image/jpeg');
// phars can be accessed by full path or by alias
echo file_get_contents('phar:///fullpath/to/coollibrary.phar/images/wow.jpg');
?>

Phar 类实现了用于访问的高级功能 文件和用于创建 PHAR 档案。这里详细解释了 Phar 类。

<?php
try {
// open an existing phar
$p = new Phar('coollibrary.phar', 0);
// Phar extends SPL's DirectoryIterator class
foreach (new RecursiveIteratorIterator($p) as $file) {
// $file is a PharFileInfo class, and inherits from SplFileInfo
echo $file->getFileName() . "\n";
echo file_get_contents($file->getPathName()) . "\n"; // display contents;
}
if (isset($p['internal/file.php'])) {
var_dump($p['internal/file.php']->getMetadata());
}

// create a new phar - phar.readonly must be 0 in php.ini
// phar.readonly is enabled by default for security reasons.
// On production servers, Phars need never be created,
// only executed.
if (Phar::canWrite()) {
$p = new Phar('newphar.tar.phar', 0, 'newphar.tar.phar');
// make this a tar-based phar archive, compressed with gzip compression (.tar.gz)
$p = $p->convertToExecutable(Phar::TAR, Phar::GZ);

// create transaction - nothing is written to newphar.phar
// until stopBuffering() is called, although temporary storage is needed
$p->startBuffering();
// add all files in /path/to/project, saving in the phar with the prefix "project"
$p->buildFromIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/path/to/project')), '/path/to/');

// add a new file via the array access API
$p['file1.txt'] = 'Information';
$fp = fopen('hugefile.dat', 'rb');
// copy all data from the stream
$p['data/hugefile.dat'] = $fp;

if (Phar::canCompress(Phar::GZ)) {
$p['data/hugefile.dat']->compress(Phar::GZ);
}

$p['images/wow.jpg'] = file_get_contents('images/wow.jpg');
// any value can be saved as file-specific meta-data
$p['images/wow.jpg']->setMetadata(array('mime-type' => 'image/jpeg'));
$p['index.php'] = file_get_contents('index.php');
$p->setMetadata(array('bootstrap' => 'index.php'));

// save the phar archive to disk
$p->stopBuffering();
}
} catch (Exception $e) {
echo 'Could not open Phar: ', $e;
}
?>

此外,可以使用任何 支持的对称哈希算法(MD5、SHA1、SHA256 和 SHA512,如果启用了 ext/hash) 以及使用 OpenSSL 使用非对称公钥/私钥签名。自 利用 OpenSSL 签名,您需要生成公钥/私钥对,并且 使用私钥通过 Phar::setSignatureAlgorithm() 设置签名。此外,公钥 使用以下代码提取:

<?php
$public = openssl_get_publickey(file_get_contents('private.pem'));
$pkey = '';
openssl_pkey_export($public, $pkey);
?>

必须保存在它验证的 Phar 存档旁边。如果 phar 存档 保存为 ,必须保存公钥 as ,否则 phar 将无法验证 OpenSSL 签名。

/path/to/my.phar/path/to/my.phar.pubkey

Phar 类还提供了 3 个静态方法,Phar::webPhar()、Phar::mungServer() 和 Phar: :interceptFileFuncs(),它们至关重要 打包专为在常规文件系统和基于 Web 的应用程序上使用而设计的 PHP 应用程序。Phar::webPhar() 实现了一个前端控制器,该控制器将 HTTP 调用路由到正确的 在 Phar 档案中的位置。Phar::mungServer() 用于修改 用于欺骗处理这些值的应用程序的数组。Phar::interceptFileFuncs() 指示 Phar 拦截对 fopen()、file_get_contents()、opendir() 和  所有基于统计的函数(file_exists()、is_readable() 等)和 将所有相对路径路由到 Phar 存档中的位置。$_SERVER

例如,打包流行的 phpMyAdmin 应用程序的发行版以用作 phar 存档需要 只有这个简单的脚本,然后可以作为常规文件访问 修改用户/密码后从您的 Web 服务器:phpMyAdmin.phar.tar.php

<?php
@unlink('phpMyAdmin.phar.tar.php');
copy('phpMyAdmin-2.11.3-english.tar.gz', 'phpMyAdmin.phar.tar.php');
$a = new Phar('phpMyAdmin.phar.tar.php');
$a->startBuffering();
$a["phpMyAdmin-2.11.3-english/config.inc.php"] = '<?php
/* Servers configuration */
$i = 0;

/* Server localhost (config:root) [1] */
$i++;
$cfg[\'Servers\'][$i][\'host\'] = \'localhost\';
$cfg[\'Servers\'][$i][\'extension\'] = \'mysqli\';
$cfg[\'Servers\'][$i][\'connect_type\'] = \'tcp\';
$cfg[\'Servers\'][$i][\'compress\'] = false;
$cfg[\'Servers\'][$i][\'auth_type\'] = \'config\';
$cfg[\'Servers\'][$i][\'user\'] = \'root\';
$cfg[\'Servers\'][$i][\'password\'] = \'\';


/* End of servers configuration */
if (strpos(PHP_OS, \'WIN\') !== false) {
$cfg[\'UploadDir\'] = getcwd();
} else {
$cfg[\'UploadDir\'] = \'/tmp/pharphpmyadmin\';
@mkdir(\'/tmp/pharphpmyadmin\');
@chmod(\'/tmp/pharphpmyadmin\', 0777);
}';
$a->setStub('<?php
Phar::interceptFileFuncs();
Phar::webPhar("phpMyAdmin.phar", "phpMyAdmin-2.11.3-english/index.php");
echo "phpMyAdmin is intended to be executed from a web browser\n";
exit -1;
__HALT_COMPILER();
');
$a->stopBuffering();
?>


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号