2017-06-08 22 views
8

file_exists不工作。我已經看了幾個例子,但仍然沒有去。程序不檢測文件。我的文件的路徑是/var/www/osbs/PHPAPI/recording.mp3,網站的根目錄是osbs。這個文件的位置在PHPAPI中,這就是爲什麼我不把完整路徑放在file_put_contents中的原因。該程序能夠製作原始的recording.mp3,但不能附加任何版本。file_exists()不工作在php5裏面while循環

<?php 
$actual_name = pathinfo("PHPAPI/recording.mp3",PATHINFO_FILENAME); 
$original_name = $actual_name; 
$extension = pathinfo("PHPAPI/recording.mp3",PATHINFO_EXTENSION); 

if ($_GET["RecordingUrl"]) { 
    if (file_exists("/var/www/osbs/PHPAPI/".$actual_name.".".$extension)) { 
     $actual_name = find_new_name($original_name, $extension); 
    } 
    else { 
     $actual_name = $original_name; 
    } 
    $name = $actual_name.".".$extension; 
    file_put_contents($name, file_get_contents($_GET["RecordingUrl"])); 
} 

function find_new_name ($file, $extension) { 
    $name = $file.".".$extension; 
    $i = 0; 
    while(file_exists("/var/www/osbs/PHPAPI/".$name)){ 
     $new_name = $file.$i; 
     $name = $new_name.".".$extension; 
     $i++; 
    } 
    return $new_name; 
} 
?> 
+0

這是一個巨大的安全問題:'file_get_contents($ _ GET [「RecordingUrl」])' – greg0ire

+0

@ greg0ire我知道它僅用於測試。我通常會使用$ _POST – fixnode

+2

你很搞笑 – greg0ire

回答

2

你的問題是與file_put_contents。您需要指定完整路徑,並且只指定文件名。嘗試使用echo ing $name之前,你會發現它不是一個路徑,只是一個文件名。

我建議你設置一個常量在路徑的文件的開頭,而不是有時依賴於相對路徑,有時依賴於絕對路徑。

<?php 
const SAVE_PATH = "/var/www/osbs/"; 

$actual_name = pathinfo(SAVE_PATH."PHPAPI/recording.mp3",PATHINFO_FILENAME); 
$original_name = $actual_name; 
$extension = pathinfo(SAVE_PATH."PHPAPI/recording.mp3",PATHINFO_EXTENSION); 

if (isset($_GET["RecordingUrl"]) && $_GET["RecordingUrl"]) { 
    if (file_exists(SAVE_PATH."PHPAPI/".$actual_name.".".$extension)) { 
     $actual_name = find_new_name($original_name, $extension); 
    } 
    else { 
     $actual_name = $original_name; 
    } 
    $name = $actual_name.".".$extension; 

    file_put_contents(SAVE_PATH.'PHPAPI/'.$name, file_get_contents($_GET["RecordingUrl"])); 
} 

function find_new_name ($file, $extension) { 
    $name = $file.".".$extension; 
    $i = 0; 
    while(file_exists(SAVE_PATH."PHPAPI/".$name)){ 
     $new_name = $file.$i; 
     $name = $new_name.".".$extension; 
     $i++; 
    } 
    return $new_name; 
} 
?> 

我改變了:

  1. 定義的const SAVE_PATH = "/var/www/osbs/";
  2. 到處使用恆新。有時候沒有更多的相對有時和絕對的,這都是絕對的。
  3. 使用的常數file_put_contents這是實際的FIX,你需要一個完整路徑這裏
  4. 加入額外的檢查,以確保RecordingUrl isset,否則你會得到一個PHP警告,當它沒有設置。
2

你確定這條路嗎? /PHPAPI尋找/PHPAPI中的文件,而不是預期的/var/www/osbs/PHPAPI/。您應該檢查PHPAPI/$filename

+0

/var/www/osbs/PHPAPI是如果要SSH進入服務器的完整路徑,但是,此域的apache文檔根目錄是osbs文件夾。所以/ PHPAPI是文件夾和recording.mp3是它應該查找的原始文件。 /PHPAPI/recording.mp3是路徑。如果原始文件不存在,則從$ _GET創建它,但是如果它存在,則附加一個計數器編號給它 – fixnode

+0

這不提供問題的答案。要批評或要求作者澄清,請在其帖子下方留言。 - [來自評論](/評論/低質量帖/ 16357314) –

+0

@ShawnMehan我回答Taluses答案很清楚。 – fixnode

2

這個問題似乎是在你的腳本的第一行:

$actual_name = pathinfo("PHPAPI/recording.mp3", PATHINFO_FILENAME); 

這將分配給recording.mp3$actual_filename。然後您通過將擴展名連接到文件名來檢查recording.mp3.mp3。我想你想使用PATHINFO_BASENAME這將返回文件名sans擴展名。

+0

這沒有幫助。即使我將路徑更改爲(file_exists(「/ PHPAPI/recording.mp3」))file_exists仍然失敗 – fixnode

+1

很可能您的[include path](http://php.net/manual/en/function.set-include -路徑。php)不包含包含PHPAPI文件夾的目錄。轉儲get_include_path以獲取它將查找文件夾的目錄列表,如果根目錄不在其中,則需要先將其添加或使用該文件夾的完整路徑。 – sjdaws

1

您是文件的URL及其路徑之間的混淆

你httdoc(或的public_html)的根是在/ var/WWW/OSBS/PHPAPI

,但你的文件系統根是'/'

嘗試

file_put_contents(__DIR__.'/'.$name, file_get_contents($_GET["RecordingUrl"])); 

有很多的陋習在你的代碼

1

你忘了路徑與file_put_contents()。 它應該是:

file_put_contents("PHPAPI/".$name, file_get_contents($_GET["RecordingUrl"])); 

或者:

file_put_contents("/var/www/osbs/PHPAPI/".$name, file_get_contents($_GET["RecordingUrl"])); 
2

你必須把你的所有邏輯在find_new_name()功能。這將做你的代碼更清晰

if ($_GET["RecordingUrl"]) { 
    $name = find_new_name("PHPAPI/recording.mp3"); 
    file_put_contents($name, file_get_contents($_GET["RecordingUrl"])); 
} 

function find_new_name($name) { 
    $info = pathinfo($name); 
    $name = $info['basename']; 
    $i = 0; 
    while (file_exists("$info[dirname]/$name")) { 
    $name = sprintf('%s%d.%s', $info['filename'], ++$i, $info['extension']); 
    } 
    return "$info[dirname]/$name"; 
} 
+0

只有回答指出這一點,我會說這是主要的罪魁禍首。 Sane函數FTW。但是我必須承認,這可以進一步改進,以便可以重新使用文件名中的現有數字,並且在檢測到空閒(例如並行上傳)之後創建文件的情況下,該功能可以繼續找到* next *新名稱。 – hakre

0

「file_exists」和其他一些文件調用像FSTAT由PHP緩存。這在file_exists的手冊中有記錄。文件不存在時的第一個呼叫將保存並在隨後的呼叫中返回。在調用之間使用'clearstatcache()'來清除緩存。

0

「小」重構:

  1. 絕對路徑處處
  2. 透明功能,更不言自明的名字,簡單使用的說法
  3. 防範惡意輸入($ _ POST真的不減產它)
  4. 爲什麼file_put_contents()時,要真正地複製()

    <?php 
    
    define("SRC_PATH", "/var/www/osbs/whereverYourSrcIs/"); 
    define("SAVE_PATH", "/var/www/osbs/PHPAPI/"); 
    
    function findAvailableName($name) { 
        $i = 1; 
        $pathinfo = pathinfo($name); 
        while(file_exists($name)) { 
         $name = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . "." . $i++ . "." . $pathinfo['extension']; 
        } 
        return $name; 
    } 
    
    if (isset($_GET["RecordingUrl"]) && $_GET["RecordingUrl"]) { 
    
        if (strpos('/' . $_GET['RecordingUrl'] . '/', '/../') !== false) { 
         die("invalid input, don't be evil"); 
        } 
    
        copy(SRC_PATH . $_GET["RecordingUrl"], findAvailableName(SAVE_PATH . "recording.mp3")); 
    }