gpt4 book ai didi

php - 使用 phar Stream 写入 PharData 文件

转载 作者:IT王子 更新时间:2023-10-29 00:06:02 28 4
gpt4 key购买 nike

当我尝试这样做时:

$phar = new PharData('./phar.tar', 0, null, Phar::TAR);
$phar->addEmptyDir('test');

file_put_contents('phar://./phar.tar/test/foo.txt', 'bar');

我收到以下错误:

Warning: file_put_contents(phar://./phar.tar/test/foo.txt): failed to open stream: Cannot create phar './phar.tar', file extension (or combination) not recognised or the directory does not exist

我可以使用 file_get_contents 但 shouldn't file_put_contents work too


为了让事情变得更奇怪,我尝试了@hakre 在他的评论中提出的想法,并且成功了!

$phar = new PharData('./phar.tar', 0, null, Phar::TAR);
$phar->addEmptyDir('test');

if (file_exists('./phar.phar') !== true)
{
symlink('./phar.tar', './phar.phar');
}

file_put_contents('phar://./phar.phar/test/foo.txt', 'bar');
var_dump(file_get_contents('phar://./phar.tar/test/foo.txt')); // string(3) "bar"

最佳答案

简介

我认为这基本上与您正在使用 Phar::TAR 文件这一事实有关,因为

file_put_contents("phar://./test.tar/foo.txt", "hello world");
^
|+---- Note this tar

返回

Warning: file_put_contents(phar://./test.tar/foo.txt): failed to open stream: Cannot create phar './test.tar', file extension (or combination) not recognized or the directory does not exist

同时

file_put_contents("phar://./test.phar/foo.txt", "hello world"); // Works file
^
|+---- Note This phar

返回

//No Errors

了解问题

如果你看一个 detail example在 PHP 文档中,这是过去 2 年 中的一个已知问题,给出的示例如下

例子

$p = new PharData(dirname(__FILE__) . '/phartest.zip', 0, 'phartest', Phar::ZIP);
$p->addFromString('testfile.txt', 'this is just some test text');

// This works
echo file_get_contents('phar://phartest.zip/testfile.txt');

// This Fails
file_put_contents('phar://phartest.zip/testfile.txt', 'Thist is text for testfile.txt');

$context = stream_context_create(array(
'phar' => array(
'compress' => Phar::ZIP
)
));

// This Fails
file_put_contents('phar://phartest.zip/testfile.txt', 'Thist is text for testfile.txt', 0, $context);

// This works but only with 'r' readonly mode.
$f = fopen('phar://C:\\Inetpub\\wwwroot\\PACT\\test\\phartest.zip\\testfile.txt', 'r');

替代工作

不要使用.tar.zip,您的文件有扩展名,但要按照PHP DOC 中的说明设置压缩

我是什么意思?

$context = stream_context_create(array(
'phar' => array(
'compress' => Phar::GZ //set compression
)
));

file_put_contents('phar://sample.phar/somefile.txt', "Sample Data", 0, $context);
^
|= Use phar not tar

建议

我真的认为您应该坚持使用 PharData 是可以实现的,并且已经证明可以工作。唯一的办法是

我必须使用 file_put_contents

然后编写您自己的包装器并使用 stream_wrapper_register 注册它 这是一个简单的 Prof of Concept

stream_wrapper_register("alixphar", "AlixPhar");
file_put_contents('alixphar://phar.tar/test/foo.txt', 'hey');
^
|+-- Write with alixphar

echo file_get_contents('alixphar://phar.tar/test/foo.txt'),PHP_EOL;
echo file_get_contents('phar://phar.tar/test/foo.txt'),PHP_EOL;

输出

hey     <----- alixphar
hey <----- phar

注意:此类不应在生产中使用...它只是一个示例,并且会导致某些测试用例失败

class AlixPhar {
private $pos;
private $stream;
private $types;
private $dir;
private $pharContainer, $pharType, $pharFile, $pharDir = null;
private $fp;

function __construct() {
$this->types = array(
"tar" => Phar::TAR,
"zip" => Phar::ZIP,
"phar" => Phar::PHAR
);
// your phar dir to help avoid using path before the phar file
$this->dir = __DIR__;
}

private function parsePath($path) {
$url = parse_url($path);
$this->pharContainer = $url['host'];
$this->pharType = $this->types[pathinfo($this->pharContainer, PATHINFO_EXTENSION)];
if (strpos($url['path'], ".") !== false) {
list($this->pharDir, $this->pharFile, , ) = array_values(pathinfo($url['path']));
} else {
$this->pharDir = $url['path'];
}
}

public function stream_open($path, $mode, $options, &$opened_path) {
$this->parsePath($path);
$this->stream = new PharData($this->dir . "/" . $this->pharContainer, 0, null, $this->pharType);
if (! empty($this->pharDir))
$this->stream->addEmptyDir($this->pharDir);

if ($mode == "rb") {
$this->fp = fopen("phar://" . $this->pharContainer . "/" . $this->pharDir . "/" . $this->pharFile, $mode);
}
return true;
}

public function stream_write($data) {
$this->pos += strlen($data);
$this->stream->addFromString($this->pharDir . "/" . $this->pharFile, $data);
return $this->pos;
}

public function stream_read($count) {
return fread($this->fp, $count);
}

public function stream_tell() {
return ftell($this->fp);
}

public function stream_eof() {
return feof($this->fp);
}

public function stream_stat() {
return fstat($this->fp);
}
}

关于php - 使用 phar Stream 写入 PharData 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14102585/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com