コードは次のとおりです。
_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);
}
_
私は次のことをしようとしています:
echo("If file exists: ".file_exists('../storage/temp/image.jpg'));
のときに_If file exists: 1
_をエコーします。unlink(../ storage/temp/image.jpg):リソースが一時的に利用できません
rename($filename,'../storage/temp/renimage.jpg');
の代わりにunlink($filename);
を使用すると、エラーが発生します。
rename(../ storage/temp/image.jpg、../storage/temp/renimage.jpg):別のプロセスによって使用されているため、プロセスはファイルにアクセスできません。 (コード:32)
関数呼び出し$photoService->uploadPhoto($filename);
を削除すると、すべてが完全に正常に機能します。
ファイルが別のプロセスで使用されている場合、プロセスが完了し、ファイルがどのプロセスでも使用されなくなった後、ファイルのリンクを解除するにはどうすればよいですか?タイマーは使いたくない。
助けてください!前もって感謝します。
同様のエラーに対処する必要がありました。
あなたの_$photoService
_が何らかの理由で画像を保持しているようです...あなたは_$photoService
_のコードを共有していなかったので、私の提案はこのようなことをすることです(あなたがそうしないと仮定して) _$photoService
_がもう必要です):
_[...]
echo("If file exists: ".file_exists($filename));
unset($photoService);
unlink($filename);
}
_
unset()
メソッドは、指定された変数/オブジェクトを破棄するため、ファイルを「使用」(または使用する)ことはできません。
私はこの問題に1、2時間座って、ついに「一時的に利用できない」とは本当に「一時的に」を意味することに気づきました。
私の場合、同時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);
}
_
この問題を解決し、運をさらに推し進めた後、file_put_contents()
を使用して「リソースが一時的に利用できません」という問題をトリガーすることもできます。同じ解決策で、今ではすべてが正常に機能します。
賢明であるか、将来リンク解除に失敗した場合は、_@
_をob_start()
に置き換えるので、エラーメッセージで正確なエラーを知ることができます。
最も簡単な解決策:
gc_collect_cycles();
unlink($file);
私のためにそれをしますか! Amazon S3にファイルをアップロードした直後に、サーバー上のファイルを削除できます。
ここを参照してください: https://github.com/aws/aws-sdk-php/issues/841
GuzzleHttp\Streamオブジェクトは、その__destructメソッドが呼び出されるまでリソースハンドルを保持します。通常、これは、ストリームがスコープから外れるとすぐにリソースが解放されることを意味しますが、PHPバージョンと、スクリプトがガベージコレクターのバッファーをまだ満たしているかどうかによっては、ガベージコレクションがgc_collect_cyclesは、コレクターを強制的に実行し、到達不能なすべてのストリームオブジェクトに対して__destructを呼び出します。
:)
私も同じ問題を抱えていました。 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'
));
この回答を参照してください: AWS S3ヘルパーがファイルをアップロードした後にファイルのロックを解除する方法は?