файл exists() не работает в php5 внутри цикла while

file_exists не работает. Я просмотрел несколько примеров и до сих пор не пошел. Программа не обнаруживает файл. Путь мой файл /etc/ВСП/плит OSB/PHPAPI/записи.MP3 и корневой сайт находится внутри плит OSB. Расположение этого файла находится внутри PHPAPI, поэтому я не помещаю полный путь в file_put_contents. Программа способна сделать оригинальную запись.mp3, но не любые добавленные версии.

<?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;
}
 ?>

8 ответов


ваша проблема с file_put_contents. Вам нужно указать полный путь, и вы указываете только имя файла. Попробуй!--2-->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. определено a const SAVE_PATH = "/var/www/osbs/";
  2. используйте новую константу везде. Нет больше относительного иногда и абсолютного иногда, это все абсолютное.
  3. используется константа в file_put_contents (ЭТО ФАКТИЧЕСКОЕ ИСПРАВЛЕНИЕ, ВАМ НУЖЕН ПОЛНЫЙ ПУТЬ ЗДЕСЬ)
  4. добавлена дополнительная проверка, чтобы убедиться RecordingUrl isset, иначе вы получите предупреждение PHP, когда оно не установлено.

проблема, кажется, в первой строке вашего скрипта:

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

Это позволит назначить recording.mp3 to $actual_filename. Затем вы проверяете recording.mp3.mp3 путем объединения расширения с именем файла. Я думаю, вы хотите использовать PATHINFO_BASENAME который вернет расширение filename sans.


вы уверены насчет пути? /PHPAPI ищет файл внутри /PHPAPI не /var/www/osbs/PHPAPI/. Вы должны проверить на .


вы должны поместить все свои логические в


вы забыли путь с 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"]));

вы путаетесь между URL-адресом файла и его путь

ваш корень httdoc(или public_html) -/var/www/osbs / PHPAPI

но ваш корень файловой системы -'/'

попробовать

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

в вашем коде много плохих практик


'file_exists' и несколько других вызовов файлов, таких как fstat, кэшируются php. Это описано в руководстве для file_exists. Ваш первый вызов, когда файл не существует, сохраняется и возвращается в последующих вызовах. Используйте clearstatcache () между вызовами, чтобы очистить кэш.


"маленький" рефакторинг:

  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"));
    }