Aquí está la pieza de código:
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); }Estoy tratando de hacer las siguientes cosas:
If file exists: 1 when echo("If file exists: ".file_exists('../storage/temp/image.jpg')); .unlink(../storage/temp/image.jpg): recurso temporalmente no disponible
Si uso rename($filename,'../storage/temp/renimage.jpg'); en lugar de unlink($filename); me sale un error:
rename(../storage/temp/image.jpg,../storage/temp/renimage.jpg): El proceso no puede acceder al archivo porque lo está utilizando otro proceso. (código: 32)
Si elimino la función, llame a $photoService->uploadPhoto($filename); , todo funciona perfectamente bien.
Si el archivo está siendo utilizado por otro proceso, ¿cómo lo desvinculo después de que el proceso se haya completado y el archivo ya no esté siendo utilizado por ningún proceso? No quiero usar temporizadores.
¡Por favor ayuda! Gracias por adelantado.
Solución más simple:
gc_collect_cycles(); unlink($file);¡Lo hace por mí! Inmediatamente después de cargar un archivo en Amazon S3, me permite eliminar el archivo en mi servidor.
Consulte aquí: https://github.com/aws/aws-sdk-php/issues/841
El objeto GuzzleHttp\Stream retiene un identificador de recursos hasta que se llama a su método __destruct. Normalmente, esto significa que los recursos se liberan tan pronto como una secuencia queda fuera del alcance, pero a veces, según la versión de PHP y si un script ya llenó el búfer del recolector de elementos no utilizados, la recolección de elementos no utilizados puede aplazarse. gc_collect_cycles obligará al recopilador a ejecutarse y llamar a __destruct en todos los objetos de flujo inalcanzables.
:)
Solo tuve que lidiar con un error similar.
Parece que su $photoService se aferra a la imagen por alguna razón... Dado que no compartió el código de $photoService , mi sugerencia sería hacer algo como esto (suponiendo que ya no necesite $photoService ):
[...] echo("If file exists: ".file_exists($filename)); unset($photoService); unlink($filename); } El método unset() destruirá la variable/objeto dado, por lo que no puede "usar" (o donde quiera que lo haga) ningún archivo.
Me senté sobre este problema durante una o dos horas y finalmente me di cuenta de que "temporalmente no disponible" en realidad significa "temporalmente".
En mi caso, los scripts PHP concurrentes acceden al archivo, ya sea escribiendo o leyendo. Y cuando el proceso de unlink() tuvo un mal momento, todo falló.
La solución fue bastante simple: use el (generalmente no muy recomendable) @ para evitar que el error se muestre al usuario (claro, uno también podría evitar que los errores se impriman), y luego inténtelo de nuevo:
$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); } Después de resolver este problema y empujar mi suerte aún más, también podría desencadenar el problema "Recurso no disponible temporalmente" con file_put_contents() . Misma solución, ahora todo funciona bien.
Si soy lo suficientemente inteligente y/o la desvinculación falla en el futuro, reemplazaré la @ por ob_start() , para que el mensaje de error me indique el error exacto.