Thursday, April 12, 2012

Why can't I delete the file from a php script?

Basically, I am proxying a file using a php script and then deleting it straight after... only, the file isn't deleting and I can't work out why.


this is a little out of context, so, happy to explain more should you need it.


exec("wget http://xxxx/123_" .$matches[1] . " --no-check-certificate -P /usr/share/nginx/www/" );
 
 $file = "/usr/share/nginx/www/123_" . $matches[1];
 
 if (file_exists($file)) {
     header('Content-Type: text/plain');
     header('Content-Length: ' . filesize($file));
     ob_clean();
     flush();
     readfile($file);
     exec("rm /usr/share/nginx/www/123_" . $matches[1] );
 
     exit;
 }
 



Answer:


Try this code, which will not create a local file that needs to be deleted:
// Define URL 
$url = "http://xxxx/123_{$matches[1]}"; 
 // Open pointer to remote resource if (!$remoteFP = @fopen($url, 'r')) { 
  header("{$_SERVER['SERVER_PROTOCOL']} 500 Internal Server Error"); 
  exit; } 
 // Get content length and type from remote server's headers 
$length = $type = NULL; foreach ($http_response_header as $header) { // Loop headers (see http://php.net/manual/en/reserved.variables.httpresponseheader.php) 
  list($name, $val) = explode(':', $header, 2); // Split to key/value 
  switch (strtolower(trim($name))) { // See if it's a value we want 
    case 'content-length': 
      $length = (int) trim($val); 
      break; 
    case 'content-type': 
      $type = trim($val); 
      break; 
  } 
  if ($length !== NULL && $type !== NULL) break; // if we have found both we can stop looping } 
 // Send headers if ($type === NULL) $type = 'text/plain'; 
header("Content-Type: $type"); if ($length) header("Content-Length: $length"); // Only send content-length if the server sent one. You may want to do the same for content-type. 
 // Open a file pointer for the output buffer 
$localFP = fopen('php://output', 'w'); 
 // Send the data to the remote party 
stream_copy_to_stream($remoteFP, $localFP); 
 // Close streams and exit 
fclose($remoteFP); 
fclose($localFP); exit; 
This uses the fopen() approach over cURL etc because it allows one to forward the entity straight to the output buffer, as well as giving access to the remote server's response headers before the body have been fully received. It is the most resource-efficient way to proxy using PHP.
If your server has allow_url_fopen disabled, you may be able to use cURL, which will also allow you to pass the data straight to the output buffer, but does not allow you to parse and forward the headers from the remote server.

No comments:

Post a Comment