Проверьте, может ли строка быть путем (без предупреждения) - PullRequest
0 голосов
/ 19 сентября 2018

Как я могу проверить, является ли строка допустимым путем в PHP без предупреждения, если строка не является допустимым путем?

Когда я использую file_get_contents, is_file, realpath, file_exists со строкой, которая не является путем, я получаю следующее предупреждение.

"function_name ()" ожидает, что параметр 1 является допустимым путем, строка задана в [...]

Итак, как определить, может ли строка быть допустимым путем или нет.


Какого черта вы хотите сделать?Вы можете спросить ...

Хорошо, я хочу создать такую ​​функцию.

funtion my_smart_function( string $path_or_content )
{
    $content = is_file_without_warning_if_not_a_valid_path( $path_or_content )
             ? file_get_contents( $path_or_content )
             :                    $path_or_content;
    // do nice stuff with my $content
}

Иногда $path_or_content будет допустимым путем к файлу, а иногда $path_or_content будет содержимым самого файла (например, двоичные данные изображения, созданного на лету, который даже не имеет пути (по крайней мере, пока)).В последнем случае все эти функции, связанные со строками, которые я упомянул выше (например, file_exists()), будут выдавать предупреждение (см. Цитату выше).


Что-то, о чем мне интересно.
realpath('xyz')не выдает предупреждение, но
realpath( file_get_contents('path/to/actual/image.jpg') ) делает ...

Так что realpath и другие функции, упомянутые выше, различают string или string, которыеявляется допустимым путем . Так как же мы можем сделать это заранее?

Ответы [ 4 ]

0 голосов
/ 12 июля 2019

file_exists не проверяет, является ли путь допустимым и имеет недокументированное поведение.В то же время нет функции, чтобы проверить, является ли путь действительным или нет.Минимальная проверка может быть такой, как предложено Barmar: return strpos($path, "\0") === false

Однако, как правило, вы не хотите, чтобы непечатаемые символы в именах файлов тоже не было, поэтому было бы вполне справедливым предположение просто использовать функцию ctype_print перед прохождением путина file_exists (в соответствии с предложением Daan).

Немного фона

Даже если все используют file_exists, чтобы проверить ... этот файл существует, этотФункция (и некоторые другие) делает больше, чем это.

Если быть точным, он возвращает null, если путь не является допустимым (то есть содержит \0).Это ошибка PHP 1019 *.

Это очень запутанное поведение.Даже если документация говорит, что file_exists "Возвращает TRUE, если файл или каталог, указанный в filename, существует; иначе FALSE.", Это не текущее поведение реализации.

Согласно чьему-либо из сообщества PHP:

Нет, file_exists не проверяет допустимые пути.Он проверяет, существует ли «файл».Предполагается, что путь, который вы указываете, действителен, потому что в противном случае он не может существовать.

0 голосов
/ 19 сентября 2018

Я верю, что это именно то, что вы хотите.ctype_print проверяет, доступны ли для печати все символы в предоставленной строке.Если это так, передайте его file_exists.

function my_smart_function( $path_or_content )
{

    $content = ctype_print($path_or_content) && file_exists( $path_or_content )
             ? file_get_contents( $path_or_content )
             :                    $path_or_content;

    // do nice stuff with my $content
}
0 голосов
/ 19 сентября 2018

Это разумное время для использования модификатора @ для подавления ошибок.

funtion my_smart_function( string $path_or_content )
{
    $content =      @file_exists( $path_or_content )
             ? file_get_contents( $path_or_content )
             :                    $path_or_content;
}

Если это неверный путь, file_exists() вернет значение Falsey, а @будет препятствовать тому, чтобы он жаловался на плохую строку.

В Linux единственным символом, который не разрешен в пути, является нулевой байт.Так что вы можете просто проверить это:

if (strpos($path_or_contents, "\0") === false) {
    return file_get_contents($path_or_contents);
} else {
    return $path_or_contents;
}
0 голосов
/ 19 сентября 2018

Я думаю, что вы пропустили file_exists функцию.Из документации:

file_exists - проверяет, существует ли файл или каталог

bool file_exists ( string $filename )

Возвращает TRUE, если файл или каталог, указанный в имени файла, существует;ЛОЖЬ в противном случае.

...