2013-12-12 3 views
2

Мы создаем скрипт PHP для кэширования изображений на жестком диске (ext4) сервера (Debian Wheezy с SELinux, Apache, PHP 5.3.26).PHP file_get_contents() иногда возвращает нулевые байты/false

Что-то вроде следующего кода используется:

$data = "..."; 
$file = "cached_foo_1234.jpg"; 
if (!is_file($file)) file_put_contents($file, $data); 

Позже в сценарии, и тот же файл открыт для чтения:

$content = file_get_contents($file); 

Несмотря на правильные данные на жестком диске, иногда $ контент пуст, затягивая время, когда файл записывается в файловую систему. Функция filesize() показывает то же поведение.

В файлах журналов отсутствуют ошибки (аудит, php и т. Д.). Размещение clearstatcache() поверх file_get_contents() или блокировка файла с LOCK_EX в файле_put_contents() не помогает. Сценарий получает доступ параллельно с тем же именем файла. Apache возвращает существующие кэшированные изображения, а также напрямую без PHP.

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

Почему мы получаем нулевые байты, когда пытаемся прочитать файл из файловой системы?

+0

ли пользователь работает веб-сервер имеет разрешения на г/ш/х файловой системы/каталога? Кроме того, это файл где-то за пределами webroot? – Braiam

+0

'file_get_contents' не * смотрит * на консультативные блокировки, не менее подчиняется им. Вам нужно блокировать как читателя *, так и автора. – Charles

+0

Пользователь имеет соответствующие права. Проблема возникает иногда, не всегда. Почему файлы имеют одинаковое поведение? – olliiiver

ответ

1

Пошел через эту проблему и обнаружил, что она вызвана, если имя файла содержит запрещенный символ и становится недействительным.

Чтобы удалить недопустимые символы в имени файла использовать:

$bad = array_merge(
    array_map('chr', range(0,31)), 
    array("<", ">", ":", '"', "/", "\\", "|", "?", "*")); 
$result = str_replace($bad, "", $filename); 

Filename practice

Смежные вопросы