2012-04-11 140 views
0

基本上,我使用php腳本代理一個文件,然後直接刪除它...只是,該文件沒有刪除,我無法解決原因。爲什麼我不能從php腳本中刪除文件?

這是一個有點超出上下文,所以,高興地解釋更多,如果你需要它。

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; 
} 
+3

您是否嘗試過使用'unlink($ file);'如果您還不行,請嘗試驗證文件的所有權以及php對您使用的內容以及文件權限。 – Prix 2012-04-11 13:08:46

+0

@Hakre - 撤銷您的更改...如果有一個簡單的錯誤,請在評論或答案中寫下,但這不是我的腳本,因此,有人可能會得到錯誤的想法或在該行上找到答案等等 – Wil 2012-04-11 13:18:00

+0

@Prix - 之前從未聽說過取消鏈接,所以,現在...現在閱讀它...(僅供參考,這是我的第一個PHP腳本...當然沒有專業版)。 – Wil 2012-04-11 13:18:54

回答

2

試試這個代碼,這將不會創建一個需要被刪除本地文件:

// 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; 

它使用了捲曲等的fopen()方法,因爲它允許一個簡單的實體到輸出緩衝區,以及在主體完全收到之前訪問遠程服務器的響應頭。這是使用PHP進行代理的最節約資源的方式。

如果您的服務器禁用了allow_url_fopen,您可能可以使用cURL,它也允許您將數據直接傳遞到輸出緩衝區,但不允許您從遠程服務器解析和轉發標頭。

+0

我已經給了你+1的努力,我肯定從中學到了很多,但是,我寫的腳本已經投入生產,我寧願修復它,如果我可以......沒有刪除的文件是錯過了我錯過的東西。如果我無法快速修復它(現在只是嘗試解除鏈接的方法),我一定會嘗試你的版本。 – Wil 2012-04-11 13:36:18

+0

@Wil上面的代碼應該適用於你的開箱即用,如果你只是放棄它代替你在問題中顯示的代碼。唯一需要改變的是第一行,以確保'$ url'是正確的。這個版本比'wget'方法快很多,資源效率更高,因爲它永遠不會將數據寫入磁盤,並且立即開始將數據發送給客戶端,而不是在將整個文件發送到客戶端之前將整個文件傳輸到服務器上。 – DaveRandom 2012-04-11 13:39:56

+0

對不起聲音啞巴,但是,如果同時運行多個人,這個腳本是完全安全的......我不是專家,也不瞭解所有的東西,但是,看到'php://'位正在製作我想知道如果其他人在第一個人下載完成之前訪問會發生什麼情況......對不起,如果這是愚蠢的,我只是想確認一下。 – Wil 2012-04-11 13:50:36