is_file всегда возвращает false

5

Проблема

У меня возникла проблема с функцией PHP is_file().

Некоторые предварительные комментарии: я разрабатываю Ubuntu 12.04, 32-разрядный, используя PHP 5.5.10 и Apache 2.4.9.

В настоящее время я переписываю некоторый рабочий код, чтобы преобразовать его в библиотеку в Laravel (дополненную Facade и ServiceProvider). Я делаю это в основном для очистки кода, который я написал, когда был молодым и глупым (около 6 месяцев назад), и для проведения модульного тестирования. Библиотека, которую я пишу, предоставляет методы для заключения контракта (из которых два разных типа, с еще большим количеством) и поиск пути к PDF-документу (отсканированный бумажный контракт). Мои методы поиска пути работают нормально, и все тесты проходят.

В моем старом коде я использовал это:

/**
 * Get a scanned contract and return it to the client
 *
 * @param string $type
 * The contract type. Must be either static::CONTRACT1 or static::CONTRACT2.
 * 
 * @param string $contract_id
 * The contract ID
 *
 * @return Response
 */
public static function get($type, $contract_id)
{
    // get the file name
    //
    $results = static::getFileName($type, $contract_id);

    // did we find a file? if not, throw a ScannedContractNotFoundException
    //
    if(!$results)
        throw new \MyApplication\Exceptions\ScannedContractNotFoundException("No file found for $type contract $contract_id");

    // get the path and file name
    //
    $path = $results['path'];
    $name = $results['name'];

    // get the full path
    //
    $file = $path.$name;

    // get the file size
    //
    $contents = file_get_contents($file);
    $fsize = strlen($contents);

    // push the file to the client
    //
    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=\"".$name."\"");
    header("Content-length: $fsize");
    header("Cache-control: private");

    echo $contents;

    exit;
}

И это сработало отлично.

Теперь я пытаюсь переписать его, чтобы избавиться от echo и переместить код, который фактически выполняет работу по отправке файла на контроллер. Этот код будет выглядеть так:

$x = \MyApplication\Models\Contract1::find($id);

$file = \ScannedContracts::getFileName($x);

$path = $file["path"].$file["name"];

return \Response::download($path, $file["name"]);

Однако этот код бросает FileNotFoundException. Код, в котором генерируется исключение, выглядит следующим образом:

public function __construct($path, $checkPath = true)
{
    if ($checkPath && !is_file($path)) {
        throw new FileNotFoundException($path);
    }

...

Очевидно, что проблема связана с оператором if и, в частности, с вызовом is_file().

Я написал немного script, чтобы проверить это с помощью пути, который, как известно, хорош, и is_file() возвращает false.

Когда я копирую файл в свою "общедоступную" папку, он отлично работает.

В документация для функции is_file() есть комментарий, в котором указано, что разрешения для родительской папки должны быть +x. Я просмотрел разрешения, и папка выполнена в мире, как и родитель, и родитель, и правнук, и т.д.

Есть два возможных факторов: во-первых, файлы, с которыми я работаю, находятся на общем ресурсе CIFS/Samba. Я должен упомянуть, что рассматриваемые пути - это абсолютные пути к монтированной доле.

Ближайшая проблема с этим я нашел в SO PHP is_file возвращает false (неправильно) для общего ресурса Windows на Ubuntu, но это не имеет разрешения, Я также искал отчеты об ошибках PHP, но там ничего.

Во-вторых, некоторые из путей содержат пробелы. Я попытался убежать от них, как я могу себе представить, но это не помогает.

В отсутствие решения мне придется сделать это по-старому, но я действительно хотел сделать это, используя функции, которые предоставляет Laravel.

Вопросы

  • Нужно ли мне избегать пробелов в пути, переданном в is_file()?

  • Кто-нибудь знает об исправлении или обходном пути, которые не требуют: a) требуют изменения кода в сторонней библиотеке или b) требуют оптовых изменений разрешений или другой конфигурации на сервере CIFS/Samba?

Спасибо заранее!

  • 0
    1. -> да - вы не можете использовать пробелы, замените пробелы на %20 -> кроме того, что он должен работать должным образом -> единственное, что если файл является чем-то иным, чем «обычный файл», он не будет работать - но я не вижу, что вы пытаетесь получить доступ к «Специальным файлам» в любом случае :-P
  • 0
    Вы пытались в клипе сделать php -r 'var_dump(is_file("/path/to/your/win/share"));' ? И, кстати, apache имеет доступ для чтения в этой папке? нет ограничений open_base_dir? нет safe_mode?
Показать ещё 5 комментариев
Теги:

1 ответ

1

Я думаю, вам нужно санировать имена файлов при загрузке в каталог

function sanitize_file_name( $str ) {
    return preg_replace("/[^a-z0-9\.]/", "", strtolower($str));
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню