Есть ли альтернатива php readfile() на сервере в безопасном режиме?

Я размещаю свой сайт на виртуальном хостинге, который недавно перевел сервер в безопасный режим (даже не предупредив об этом). Я использую функцию загрузки файлов с сервера с помощью функции readfile() (я использую php). Сейчас в safe_mode эта функция больше недоступна. Есть ли замена или обходной путь для обработки ситуации, когда файл сможет быть загружен пользователем?

Спасибо


person Maor Barazany    schedule 13.06.2011    source источник
comment
Не работает, я уже пробовал, но у меня появляется пустой экран Word для файлов .docx или просто ошибка для файлов pdf и т. д.   -  person Maor Barazany    schedule 13.06.2011
comment
Какое сообщение об ошибке вы получаете? Учитывая, что safe_mode устарел, вы можете переключайте хосты, если они недавно включили его. В любом случае, напишите своему хостеру электронное письмо с просьбой расслабиться safe_mode.   -  person Gordon    schedule 13.06.2011
comment
Это не поможет, так как они утверждают, что это уменьшает количество взломов серверов, и это виртуальный хостинг, поэтому я не могу их убедить - это их новая политика, я могу просто поменять хосты, если захочу, но У меня там около 20 сайтов клиентов, и начать перемещать их всех сейчас будет головной болью. Интересно, есть ли обходной путь для обработки загрузки файла, насчет этого чертового хостинга я буду думать позже, что делать.   -  person Maor Barazany    schedule 13.06.2011
comment
Я получаю следующую ошибку: Предупреждение ›: readfile() отключен по соображениям безопасности в /home/full/path/to/my/script.php в строке 146.   -  person Maor Barazany    schedule 13.06.2011
comment
@Maor переключение может быть небольшой головной болью, но сообщение хостеру, что он потеряет 20 дополнительных клиентов, если они не предложат решение, может заставить их передумать. И, как я уже сказал, он устарел, поэтому, если они когда-нибудь захотят перейти на php.next, им все равно придется найти другое решение.   -  person Gordon    schedule 13.06.2011
comment
В этом случае безопасный режим не влияет на readfile(). Документы говорят, что файл и каталог должны принадлежать тот же пользователь, который выполняет скрипт, это то, что проверяется в безопасном режиме. В этом случае readfile() полностью отключен, что скорее делает disable_functions.   -  person binaryLV    schedule 13.06.2011
comment
@Gordon - Поскольку это виртуальный хостинг, у меня все мои сайты там в 2 учетных записях, поэтому, что касается хостинговой компании, они потеряют 1 клиента (меня) с двумя платными учетными записями. Их решение состоит в том, чтобы обновить учетную запись с общей до VPS, но это в 12 раз дороже...   -  person Maor Barazany    schedule 13.06.2011
comment
@binaryLV - поэтому, если они отключили функцию readfile() с помощью disable_functions, а не с помощью безопасного режима, это все равно не решит проблему, поскольку они не разрешат снова использовать эту функцию.   -  person Maor Barazany    schedule 13.06.2011
comment
@Maor, хотя это и не решает проблему, но может направить вас в правильном направлении. Знание причины проблемы является частью решения.   -  person binaryLV    schedule 13.06.2011


Ответы (2)


Как я писал в комментариях, readfile() отключается включением его в директиву disable_functions php.ini. Это не имеет ничего общего с безопасным режимом. Попробуйте проверить, какие функции отключены, и посмотрите, можете ли вы использовать какие-либо другие функции файловой системы, чтобы делать то, что делает readfile().

Чтобы просмотреть список отключенных функций, используйте:

var_dump(ini_get('disable_functions'));

Вы можете использовать:

// for any file
$file = fopen($filename, 'rb');
if ( $file !== false ) {
    fpassthru($file);
    fclose($file);
}

// for any file, if fpassthru() is disabled
$file = fopen($filename, 'rb');
if ( $file !== false ) {
    while ( !feof($file) ) {
        echo fread($file, 4096);
    }
    fclose($file);
}

// for small files;
// this should not be used for large files, as it loads whole file into memory
$data = file_get_contents($filename);
if ( $data !== false ) {
    echo $data;
}

// if and only if everything else fails, there is a *very dirty* alternative;
// this is *dirty* mainly because it "explodes" data into "lines" as if it was
// textual data
$data = file($filename);
if ( $data !== false ) {
    echo implode('', $data);
}
person binaryLV    schedule 13.06.2011
comment
Это отключенные функции - readfile, system, shell_exec, proc_terminate, proc_nice, proc_open, pclose, popen, passthru, pcntl_fork, pcntl_exec, posix_kill, pcntl_signal, ini_restore, posix_getpwuid, escapeshellarg, escapeshellcmd. Я собираюсь попробовать ваши предложения сверху - person Maor Barazany; 13.06.2011
comment
ты король! fpassthru, кажется, работает просто отлично. Большое большое спасибо. Я также хотел проголосовать за него, но я не могу, пока у меня не будет еще 2 балла репутации (новый пользователь здесь..) - person Maor Barazany; 13.06.2011

Я предполагаю, что вы используете readfile для загрузки удаленных файлов, как вы сказали, «с сервера». Если это так, ваша проблема не в безопасном режиме, а в том, что открытие URL-адресов с обычными функциями файла php больше не разрешено (настройка allow_url_fopen отключена).

В этом случае вы можете использовать функции curl PHP для загрузки файлов. Кроме того, file_get_contents является допустимой альтернативой.

person cweiske    schedule 13.06.2011
comment
Я использую небольшой плагин, который использует функцию readfile() для загрузки файла с сайта (сервера) на компьютер пользователя. Все работало нормально, пока недавно хостинговая компания не включила safe_mode. Это сообщение об ошибке, которое я получаю - Предупреждение ›: readfile() отключен по соображениям безопасности в /home/full/path/to/my/script.php в строке 146. - person Maor Barazany; 13.06.2011