2012-04-11 18 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);'で試したことがないのであれば、ファイルの所有権を確認してみてください。 – Prix

+0

@Hakre - 変更を元に戻す...簡単なエラーがある場合は、コメントまたは回答として記入してください。ただし、それは自分のスクリプトではありませんので、誰かが間違った考えをしたり、等 – Wil

+0

@Prix - 前にリンク解除を聞いたこともないので、今は読んでいません...(参考、これは私の最初のPHPスクリプトです...確かにプロはありません)。 – Wil

答えて

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を無効にしている場合は、データを出力バッファに直接渡すこともできますが、リモートサーバからヘッダを解析して転送することはできません。

+0

私はここでの努力のために+1を与えましたが、私は確かにそれからたくさんのことを学んでいますが、私が書いたスクリプトはすでに制作に行きました。私ができるならそれを修正したいと思います...私が逃したバグ。私がすぐに修正できない場合(現時点でリンク解除メソッドを試している)、私はあなたのバージョンを試してみます。 – Wil

+0

@Wil上記のコードは、質問に表示されるコードの代わりにドロップするだけですぐに使えるはずです。あなたが変更する必要があるのは、 '$ url'が正しいことを確認するための最初の行だけです。このバージョンは 'wget'アプローチよりもかなり高速でリソース効率が良いでしょう。これは、ディスクにデータを書き込むことはなく、クライアントに送る前にファイル全体をサーバに転送するのではなく、すぐにクライアントにデータを送信し始めます。 。 – DaveRandom

+0

私は専門家でもなく、すべてのことを理解していませんが、 'php://'ビットが作成されているのを見ています私は誰かが最初のものがダウンロードを終了する前に訪問するとどうなるのだろうかと思います...これはばかげている場合は申し訳ありません、私はちょうど確かめたいです。 – Wil

関連する問題