Art*_*gas 19 php zip tempdir file
我有一个脚本来检查包含许多匹配的PDF +文本文件的zipfile.我想解压缩,或者以某种方式从zipfile中读取文本文件,然后从文本文件中挑选一些信息,看看文件版本是否正确.
我正在寻找一个tempnam()
函数来找到一个等价来制作一个tempdir,但也许有人有更好的解决方案来解决这个问题.
indexfile看起来像这样.(->
适用于TAB char).我已经完成了从文本文件中提取版本的功能,并检查它是否已正确,它只是解包,tmpdir或其他一些我正在寻找的解决方案.
1000->filename->file version->program version->customer no->company no->distribution
2000->pagenumber->more info->more info->...
Run Code Online (Sandbox Code Playgroud)
Mar*_*ler 29
非常简单(我从PHP手册中部分获取):
<?php
function tempdir() {
$tempfile=tempnam(sys_get_temp_dir(),'');
// you might want to reconsider this line when using this snippet.
// it "could" clash with an existing directory and this line will
// try to delete the existing one. Handle with caution.
if (file_exists($tempfile)) { unlink($tempfile); }
mkdir($tempfile);
if (is_dir($tempfile)) { return $tempfile; }
}
/*example*/
echo tempdir();
// returns: /tmp/8e9MLi
Run Code Online (Sandbox Code Playgroud)
请参阅:http://de.php.net/manual/en/function.tempnam.php
请看下面的Will的解决方案.
=>我的答案不应该是已接受的答案.
Wil*_*ill 15
所以我首先在PHP.net上找到了Ron Korving的帖子,然后我修改了它以使其更安全(从无限循环,无效字符和不可写的父目录)并使用更多的熵.
<?php
/**
* Creates a random unique temporary directory, with specified parameters,
* that does not already exist (like tempnam(), but for dirs).
*
* Created dir will begin with the specified prefix, followed by random
* numbers.
*
* @link https://php.net/manual/en/function.tempnam.php
*
* @param string|null $dir Base directory under which to create temp dir.
* If null, the default system temp dir (sys_get_temp_dir()) will be
* used.
* @param string $prefix String with which to prefix created dirs.
* @param int $mode Octal file permission mask for the newly-created dir.
* Should begin with a 0.
* @param int $maxAttempts Maximum attempts before giving up (to prevent
* endless loops).
* @return string|bool Full path to newly-created dir, or false on failure.
*/
function tempdir($dir = null, $prefix = 'tmp_', $mode = 0700, $maxAttempts = 1000)
{
/* Use the system temp dir by default. */
if (is_null($dir))
{
$dir = sys_get_temp_dir();
}
/* Trim trailing slashes from $dir. */
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
/* If we don't have permission to create a directory, fail, otherwise we will
* be stuck in an endless loop.
*/
if (!is_dir($dir) || !is_writable($dir))
{
return false;
}
/* Make sure characters in prefix are safe. */
if (strpbrk($prefix, '\\/:*?"<>|') !== false)
{
return false;
}
/* Attempt to create a random directory until it works. Abort if we reach
* $maxAttempts. Something screwy could be happening with the filesystem
* and our loop could otherwise become endless.
*/
$attempts = 0;
do
{
$path = sprintf('%s%s%s%s', $dir, DIRECTORY_SEPARATOR, $prefix, mt_rand(100000, mt_getrandmax()));
} while (
!mkdir($path, $mode) &&
$attempts++ < $maxAttempts
);
return $path;
}
?>
Run Code Online (Sandbox Code Playgroud)
那么,让我们试一试:
<?php
echo "\n";
$dir1 = tempdir();
echo $dir1, "\n";
var_dump(is_dir($dir1), is_writable($dir1));
var_dump(rmdir($dir1));
echo "\n";
$dir2 = tempdir('/tmp', 'stack_');
echo $dir2, "\n";
var_dump(is_dir($dir2), is_writable($dir2));
var_dump(rmdir($dir2));
echo "\n";
$dir3 = tempdir(null, 'stack_');
echo $dir3, "\n";
var_dump(is_dir($dir3), is_writable($dir3));
var_dump(rmdir($dir3));
?>
Run Code Online (Sandbox Code Playgroud)
结果:
/var/folders/v4/647wm24x2ysdjwx6z_f07_kw0000gp/T/tmp_900342820
bool(true)
bool(true)
bool(true)
/tmp/stack_1102047767
bool(true)
bool(true)
bool(true)
/var/folders/v4/647wm24x2ysdjwx6z_f07_kw0000gp/T/stack_638989419
bool(true)
bool(true)
bool(true)
Run Code Online (Sandbox Code Playgroud)
zel*_*nix 11
如果在Linux上运行mktemp
并访问该exec
函数,则另一个选项如下:
<?php
function tempdir($dir=NULL,$prefix=NULL) {
$template = "{$prefix}XXXXXX";
if (($dir) && (is_dir($dir))) { $tmpdir = "--tmpdir=$dir"; }
else { $tmpdir = '--tmpdir=' . sys_get_temp_dir(); }
return exec("mktemp -d $tmpdir $template");
}
/*example*/
$dir = tempdir();
echo "$dir\n";
rmdir($dir);
$dir = tempdir('/tmp/foo', 'bar');
echo "$dir\n";
rmdir($dir);
// returns:
// /tmp/BN4Wcd
// /tmp/foo/baruLWFsN (if /tmp/foo exists, /tmp/baruLWFsN otherwise)
?>
Run Code Online (Sandbox Code Playgroud)
这避免了上面的潜在(尽管不太可能)种族问题并且具有与该tempnam
功能相同的行为.
我想对@Mario Mueller 的回答进行改进,因为他的回答受可能的竞争条件的影响,但我认为以下内容不应该是:
function tempdir(int $mode = 0700): string {
do { $tmp = sys_get_temp_dir() . '/' . mt_rand(); }
while (!@mkdir($tmp, $mode));
return $tmp;
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为如果已经存在则mkdir
返回,导致循环重复并尝试另一个名称。false
$tmp
另请注意,我已经添加了 处理$mode
,默认情况下确保该目录只能由当前用户访问,否则mkdir
默认情况下0777
。
强烈建议您使用关闭功能来确保在不再需要目录时删除该目录,即使您的脚本以意外方式退出*。为方便起见,我使用的完整函数会自动执行此操作,除非将$auto_delete
参数设置为false
.
// Deletes a non-empty directory
function destroydir(string $dir): bool {
if (!is_dir($dir)) { return false; }
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
if (is_dir("$dir/$file")) { destroydir("$dir/$file"); }
else { unlink("$dir/$file"); }
}
return rmdir($dir);
}
function tempdir(int $mode = 0700, bool $auto_delete = true): string {
do { $tmp = sys_get_temp_dir() . '/' . mt_rand(); }
while (!@mkdir($tmp, $mode));
if ($auto_delete) {
register_shutdown_function(function() use ($tmp) { destroydir($tmp); });
}
return $tmp;
}
Run Code Online (Sandbox Code Playgroud)
这意味着默认情况下,任何由 by 创建的临时目录tempdir()
都将拥有 权限,0700
并且会在您的脚本结束时自动删除(连同其内容)。
注意:*如果脚本被终止,情况可能并非如此,为此您可能还需要考虑注册信号处理程序。