我有一个间歇性的文件上传错误,只发生在Travis:
Warning: file_put_contents(/tmp/customerDownload_1502892540/image.png): failed to open stream: Permission denied (500 Internal Server Error)
这是一个在PHP 7.1 Docker容器上运行的Symfony 2.8项目。有一个Behat场景可以测试管理员上传文件和用户下载。我创建文件的方法如下:
/**
* @param string $fileContents
* @param Media $file
* @return File
*/
private function createLocalTemporaryFile(string $fileContents, Media $file): File
{
$tmpDir = '/tmp/customerDownload_' . time();
if (!file_exists($tmpDir)) {
mkdir($tmpDir);
}
$tmpFilePath = $tmpDir . '/' . $file->getName();
file_put_contents($tmpFilePath, base64_decode($fileContents));
$tmpFile = new File(realpath($tmpFilePath));
return $tmpFile;
}
大约20%的时间失败,这是一个重要的数额。但从不在本地或在生产中。我已尝试在/tmp
上设置权限以包含www-data
用户:组,但它无效。我很困惑为什么它不能将内容放到它首先创建的目录中的文件中。
任何人都可以建议为什么会发生这种情况,或者如何确保它不会发生?
答案 0 :(得分:0)
我认为这是某种竞争条件和文件命名问题。我正在使用相同的文件进行测试,也许测试运行得足够快,以至于它试图写一个文件而不能。将方法更新为以下内容并且到目前为止在12次测试中都没有失败。
/**
* @param string $fileContents
* @param Media $file
* @return File
*/
private function createLocalTemporaryFile(string $fileContents, Media $file): File
{
$tmpDir = '/tmp/' . uniqid('customerDownload_', true);
mkdir($tmpDir);
$tmpFilePath = $tmpDir . '/' . $file->getName();
file_put_contents($tmpFilePath, base64_decode($fileContents));
$tmpFile = new File(realpath($tmpFilePath));
return $tmpFile;
}