php-取消链接引发错误:资源暂时不可用
下面是一段代码:php-取消链接引发错误:资源暂时不可用,php,amazon-s3,unlink,Php,Amazon S3,Unlink,下面是一段代码: public function uploadPhoto(){ $filename = '../storage/temp/image.jpg'; file_put_contents($filename,file_get_contents('http://example.com/image.jpg')); $photoService->uploadPhoto($filename); echo("If file exists: ".file_
public function uploadPhoto(){
$filename = '../storage/temp/image.jpg';
file_put_contents($filename,file_get_contents('http://example.com/image.jpg'));
$photoService->uploadPhoto($filename);
echo("If file exists: ".file_exists($filename));
unlink($filename);
}
我正在尝试做以下事情:
回显时回显如果文件存在:1
回显(“如果文件存在:”.file_存在(“../storage/temp/image.jpg”)代码>
rename($filename,../storage/temp/renimage.jpg')代码>而不是取消链接($filename)代码>我得到一个错误:
重命名(../storage/temp/image.jpg,../storage/temp/renimage.jpg):进程无法访问该文件,因为其他进程正在使用该文件。(代码:32)
如果我删除函数调用$photoService->uploadPhoto($filename)代码>,一切正常
如果该文件正被另一个进程使用,那么在该进程完成并且该文件不再被任何进程使用后,如何取消该文件的链接?我不想用计时器
请帮忙!提前感谢。unlink方法返回bool值,因此您可以构建一个循环,使用一些wait()和重试限制来等待进程完成
另外,在取消链接上添加“@”,以隐藏访问错误
如果达到重试次数,则引发另一个错误/异常。必须处理类似的错误
您的$photoService
似乎出于某种原因保留了图像。。。
由于您没有共享$photoService
的代码,我的建议是这样做(假设您不再需要$photoService
):
unset()
方法将销毁给定的变量/对象,因此它无法“使用”(或使用)任何文件。我也遇到了同样的问题。S3客户端似乎不希望在执行取消链接之前解锁。如果将内容提取到变量中并将其设置为putObject数组中的“body”:
$fileContent = file_get_contents($filepath);
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $folderPath,
'Body' => $fileContent,
//'SourceFile' => $filepath,
'ContentType' => 'text/csv',
'ACL' => 'public-read'
));
看到这个答案:我花了一两个小时思考这个问题,最后意识到“暂时不可用”实际上是指“暂时”
在我的例子中,并发PHP脚本访问该文件,无论是写入还是读取。当unlink()
解决方案非常简单:使用(通常不太可取)@
防止错误显示给用户(当然,也可以阻止打印错误),然后再试一次:
$gone = false;
for ($trial=0; $trial<10; $trial++) {
if ($gone = @unlink($filename)) {
break;
}
// Wait a short time
usleep(250000);
// Maybe a concurrent script has deleted the file in the meantime
clearstatcache();
if (!file_exists($filename)) {
$gone = true;
break;
}
}
if (!$gone) {
trigger_error('Warning: Could not delete file '.htmlspecialchars($filename), E_USER_WARNING);
}
$gone=false;
对于($trial=0;$trial最简单的解决方案:
gc_collect_cycles();
unlink($file);
这是为我做的!
在将文件上传到AmazonS3之后,我就可以直接删除服务器上的文件
请看这里:
GuzzleHttp\Stream对象保留资源句柄,直到其
__通常,这意味着一旦流超出范围,就会释放资源,但有时,这取决于
关于PHP版本以及脚本是否已填充垃圾
收集器的缓冲区,垃圾收集可以延迟。
gc_collect_循环将强制收集器运行并调用u destruct
在所有无法访问的流对象上
:)作为旁注,您应该使用绝对文件路径而不是相对文件路径。在文件路径中使用$\u服务器['DOCUMENT\u ROOT']
,而不是。/
不要完全读取它,而是在回显(“如果文件存在:.file\u存在($filename))之前使用clearstatcache()
也许$photoService->uploadPhoto
会在您之前取消链接。使用唯一的名称而不是图像不是更好吗。jpg
,也许不同的请求会尝试在同一个文件上工作。@Martin不是在取消链接之后,而是在文件存在之前,谁知道uploadPhoto
会做什么。;-)我粘贴了链接,这样OP就可以阅读它,从而得到它。@justonundermillion,是的。我在实际代码中使用了唯一的名称生成器。上面给出的代码片段是为了在这里发布。这些都是旨在隐藏症状而不是解决问题的糟糕解决方案。不要使用@
错误抑制和等待只会占用服务器进程(当PHP等待时,它会循环CPU电源,不会暂停处理)@Martin,我同意。不建议使用@
。请注意,如果您运行的是Linux或MacOS或*BSD,则不必在删除它之前关闭所有句柄。。但如果您在MS Windows上运行php,则需要首先关闭所有句柄
gc_collect_cycles();
unlink($file);