Файл PHP не загружается

Обновлено: 04.07.2024

Не знаете, как исправить ошибку «Файл загрузки WordPress вместо открытия в браузере» на вашем веб-сайте? Это распространенная проблема, с которой мы все иногда сталкиваемся на нашем веб-сайте WordPress.

Недавно один из моих друзей также столкнулся с этой проблемой. Всякий раз, когда кто-то открывает его веб-сайт, файл с именем «index.php» загружается в их систему вместо того, чтобы открывать веб-сайт в их браузерах.

Если вы также получаете эту проблему в своем блоге, не беспокойтесь. Здесь, в этом руководстве, мы покажем вам, как без проблем удалить эту проблему с вашего веб-сайта как можно скорее.

Итак, не теряя времени, давайте приступим к устранению этой проблемы…

Оглавление

Загрузить файл WordPress вместо открытия в браузере

Существуют десятки причин, которые могут вызвать проблему загрузки файлов вместо их открытия в браузере. Но в основном вы получаете эту проблему из-за плохого хостинг-провайдера, любого плагина deflect in cache, который вы используете на своем веб-сайте, или вы испортили файл .htaccess.

Вам не нужно беспокоиться ни об одной из этих причин, потому что мы покажем вам точные методы, как исправить ошибку «Загрузить файл WordPress вместо открытия в браузере», как профессионал. 😁

Решение для исправления загрузки файла WordPress вместо открытия сайта

Вот лучший способ исправить ошибку «Загрузка файла WordPress вместо открытия в браузере» без каких-либо проблем.

1. Обновите свой сервер

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

Чтобы решить эту проблему, вам нужно проверить, доступно ли обновление у вашего хостинг-провайдера. Если доступно какое-либо обновление, вам необходимо обновить его как можно скорее.

Если ваш веб-сайт размещен у провайдера виртуального хостинга, я рекомендую вам обратиться в службу поддержки и поделиться с ними проблемой. В большинстве случаев они обновят и обновят свой сервер, и проблема будет устранена на вашем веб-сайте. Но если ваш веб-сайт размещен на выделенном сервере или сервере VPS, вы должны обновить его самостоятельно, используя команду, которой я делюсь ниже.

Если вы используете систему на базе Debian, такую ​​как Ubuntu, выполните приведенную ниже команду.

Если вы используете любую систему Red Hat Enterprises, такую ​​как Centos, выполните приведенную ниже команду.

После того как ваш сервер будет обновлен с помощью приведенной выше команды, введите приведенную ниже команду, чтобы перезагрузить сервер. Эта команда будет работать на всех хостингах Linux (например, Ubuntu и CentOS).

💡 Совет от профессионалов:

  • Если вы не уверены, какую операционную систему вы используете на своем сервере, вы можете использовать обе приведенные выше команды, чтобы проверить, какая из них работает для вас.

2. Удалить плагин кэширования из WordPress

Если обновление сервера вам не поможет, вы можете попробовать удалить подключаемый модуль кеша, который вы используете на своем веб-сайте. Наиболее распространенным плагином, который вызывает эту проблему, является плагин WP Super Cache.

Но если вы используете какой-либо другой плагин кэширования, а не WP Super Cache, я также советую вам временно удалить его со своего сервера и проверить, возникает ли эта проблема на вашем веб-сайте.

Как я могу получить доступ к панели администратора во время этой проблемы?

Если ваша панель управления wp-admin все еще открывается, попробуйте деактивировать и удалить плагин кеша оттуда. Вы также можете попробовать удалить файл плагина из панели SSH или cPanel, перейдя в каталог «public_html > wp-content > plugins» и удалив их, используя «rm -rf имя-папки-плагина».

3. Удалите код addHandler из файла .htaccess

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

Вот строка, которую нужно удалить из файла .htaccess.

Эти строки представляют собой код addHandler, который обычно добавляется на серверах и хостингах на основе cPanel. И не беспокойтесь, удаление этих строк ни в коем случае не навредит вашему сайту (только если вы удалили правильные строки из файла .htaccess).

4. Заменить полный файл .htaccess

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

Это файл WordPress .htaccess по умолчанию, и если из-за этого вы загружаете файл, а не открываете его в браузере, это решит проблему.

В большинстве случаев этот код наверняка подойдет для вашего веб-сайта. Но если у вас все еще возникает проблема, я рекомендую вам переустановить веб-сайт WordPress. Вы можете использовать этот метод, чтобы просто переустановить любую версию WordPress на своем веб-сайте.

5. Сменить хостинг-провайдера

Если ни один из других методов вам не подходит, я настоятельно рекомендую перейти к другому поставщику веб-хостинга. Это потому, что если ваш сайт останется таким в течение длительного времени, вы начнете терять свой рейтинг Google, и постепенно ключевые слова вашего сайта будут снижаться в поисковой выдаче.

Если вы хотите сменить хостинг, я рекомендую GreenGeeks, SiteGround, Cloudways и Flywheel для людей, которым не нужен выделенный сервер или неуправляемый сервер VPS. Вы также можете использовать купон «TheGuideX» в облачных сервисах, чтобы получить бесплатные кредиты в размере 30 долларов США на свой счет, которых достаточно для бесплатного веб-хостинга на 3 месяца.

Часто задаваемые вопросы (FAQ)

Здесь я делюсь некоторыми распространенными проблемами, которые часто задают наши читатели, и их решениями.

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

Мы не совсем уверены, что вызывает эту проблему, но в основном после применения методов, о которых мы рассказали выше, вы не столкнетесь с подобными проблемами в будущем.

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

Что такое усиление безопасности WordPress?

Защита WordPress — это процесс, в ходе которого вы повысите безопасность своего веб-сайта WordPress, если столкнетесь с какими-либо эксплойтами. Для этого в Интернете доступно множество скриптов и инструментов для повышения безопасности WordPress.

Что вы предпочтете для кэширования своего веб-сайта?

В основном я предпочитаю использовать WP Rocket на своем веб-сайте вместе с кешем CloudFlare. Плагин WP Rocket работает безупречно, и вы никогда не столкнетесь с подобной проблемой после использования WP Rocket в качестве плагина кэширования.

Заключение

Итак, если вы также оказались здесь из-за того, что ваш PHP-файл загружается, а не выполняется, то я надеюсь, что вы, ребята, нашли эти методы такими же полезными, как и я. Подобные проблемы очень распространены в WordPress, и это один из лучших способов, которые я лично предпочитаю для решения подобных проблем, и он работает как шарм для меня.

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

Если вы знаете какие-либо другие способы решения этой проблемы, сообщите мне об этом в разделе комментариев ниже.

В этом руководстве вы узнаете, как принудительно загрузить файл с помощью PHP.

Скачивание файлов с помощью PHP

Обычно вам не обязательно использовать какой-либо серверный язык сценариев, такой как PHP, для загрузки изображений, zip-файлов, pdf-документов, exe-файлов и т. д. Если такой файл хранится в общедоступной папке, вы можете просто создайте гиперссылку, указывающую на этот файл, и всякий раз, когда пользователь нажимает на ссылку, браузер автоматически загружает этот файл.

Пример

Нажатие ссылки, указывающей на файл PDF или файл изображения, не приведет к его прямой загрузке на жесткий диск. Он откроет файл только в вашем браузере. Далее вы можете сохранить его на жесткий диск. Однако по умолчанию файлы zip и exe загружаются на жесткий диск автоматически.

Принудительная загрузка с помощью PHP

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

Давайте создадим файл с именем "image-gallery.php" и поместим в него следующий код.

Пример

Если вы внимательно посмотрите на приведенный выше пример кода, вы обнаружите, что ссылка для скачивания ведет к файлу "download.php", URL-адрес также содержит имя файла изображения в виде строки запроса. Кроме того, мы использовали функцию PHP urlencode() для кодирования имен файлов изображений, чтобы их можно было безопасно передавать в качестве параметра URL, поскольку имена файлов могут содержать небезопасные символы URL.

Вот полный код файла "download.php", который вызывает загрузку изображения.

Пример

Точно так же вы можете принудительно загрузить другие форматы файлов, такие как word doc, pdf и т. д.

Регулярное выражение в приведенном выше примере (строка № 8) просто не разрешает те файлы, имя которых начинается или заканчивается символом точки ( . ), например, разрешает имена файлов например kites.jpg или Kites.jpg , myscript.min.js, но не разрешайте kites.jpg. или .kites.jpg .

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

Как правило, для загрузки файла с расширениями exe и zip не требуется PHP-скрипт. Если местоположение файла этого типа установлено в атрибуте href элемента привязки, то файл загружается автоматически, когда пользователь щелкает ссылку для загрузки. Некоторые файлы, такие как файлы изображений, файлы PDF, текстовые файлы, файлы CSV и т. д., не загружаются автоматически, а вместо этого открываются в браузере, когда пользователь щелкает ссылку для загрузки.Эти файлы можно принудительно загрузить в PHP с помощью функции readfile(), которая не загружается автоматически. В этом руководстве показано, как принудительно загрузить любой файл с помощью сценария PHP.

Проверить ссылки для скачивания

Ранее упоминалось, что файлы zip и exe загружаются автоматически, без использования PHP-скрипта. Сначала создайте файл HTML со следующим кодом. Здесь четыре элемента привязки определены для загрузки четырех типов файлов. Эти типы файлов включают файлы TEXT, ZIP, PDF и JPG.

Скачать.html

Вывод
Появится следующее диалоговое окно для загрузки файла после нажатия на ссылку zip-файла. Затем пользователь может загрузить файл или открыть его в диспетчере архивов.



Если щелкнуть файл изображения, оно автоматически откроется в браузере, как показано в следующем выводе. Вы должны сохранить файл, чтобы сделать копию файла изображения на локальном диске. Точно так же, когда вы нажимаете на ссылки на файлы PDF и TEXT, содержимое файла будет открыто в браузере без загрузки файла. Решением этой проблемы является принудительная загрузка файла с помощью встроенной функции PHP readfile().


Загрузить файл с помощью функции readfile()

Функция readfile() используется в скрипте PHP для принудительной загрузки любого файла из текущего местоположения или файла с путем к файлу. Синтаксис этой функции приведен ниже.

Синтаксис
int readfile ( string $filename [, bool $use_include_path = false [, resource $context ]] )

Эта функция может принимать три аргумента. Первый аргумент является обязательным, а два других аргумента необязательны. Первый аргумент, $filename, хранит имя файла или имя файла с путем загрузки. Значение по умолчанию второго параметра, $use_include_path, равно false и будет установлено в true, если имя файла с путем используется в первом аргументе. Третий аргумент, $context, используется для указания ресурса потока контекста. Эта функция возвращает количество байтов, прочитанных из файла, указанного в первом аргументе. Использование этой функции показано в следующих двух примерах.

Пример 1: Загрузка файла с именем файла

В этом примере мы создадим HTML-файл со следующим кодом, где имя файла будет передано в качестве параметра URL-адреса с именем path, а значение этого параметра будет передано в PHP-файл с именем download. php.

скачать2.html

Мы создадим файл PHP со следующим кодом для принудительной загрузки файла. Здесь функция isset() используется для проверки того, определен ли $_GET[‘path’]. Если переменная определена, функция file_exists() используется для проверки существования файла на сервере. Затем функция header() используется для установки необходимой информации заголовка перед использованием функции readfile(). Функция basename() используется для получения имени файла, а функция pngдля чтения размера файла в байтах, который будет показан в диалоговом окне открытия для загрузки файла. Функция flush() используется для очистки выходного буфера. Здесь функция readfile() используется только с именем файла.

скачать.php

if ( isset ( $_GET [ 'path' ] ) )
{
//Прочитать имя файла
$filename = $_GET [ 'path' ] ;
//Проверяем, существует файл или нет
if ( file_exists ( $filename )) {

//Определить информацию заголовка
header ('Content-Description: File Transfer'); заголовок
('Content-Type: application/octet-stream');
header ("Cache-Control: no-cache, must-revalidate");
заголовок ("Истекает: 0");
header ('Content-Disposition: вложение; имя_файла="' .базовое имя ( $filename ). '"' );
header ('Content-Length:' .size ($filename));
заголовок ('Pragma: public');

//Очистить системный буфер вывода
flush() ;

//Чтение размера файла
readfile ( $filename ) ;

//Выход из сценария
die() ;
}
else {
echo "Файл не существует." ;
}
}
else
echo "Имя файла не определено."
?>

Вывод
После нажатия на ссылку загрузки файла изображения появится следующий вывод. Размер файла изображения rose.jpg составляет 27,2 КБ, как показано в диалоговом окне. Вы можете загрузить файл, выбрав переключатель «Сохранить файл» и нажав кнопку «ОК».


Пример 2. Загрузка файла с путем к файлу

Если файл существует в указанном месте, путь к файлу необходимо указать в URL-адресе.В этом примере мы создадим файл HTML со следующим кодом, который передаст имя файла с путем к файлу:

скачать3.html

Мы создадим файл PHP со следующим кодом для загрузки файла по пути к файлу. PHP-код в предыдущем примере будет немного изменен для загрузки файла по указанному пути. Функция clearstatecache() используется для очистки ранее сохраненного кеша. В функции readfile() используются два аргумента.

скачать2.php

if ( isset ( $_GET [ 'path' ] ) )
{
//Прочитайте URL-адрес
$url = $_GET [ 'path' ] ;

< /?php>

//Проверяем, существует ли путь к файлу
if ( file_exists ( $url )) {

//Определить информацию заголовка
header ('Content-Description: File Transfer'); заголовок
('Content-Type: application/octet-stream');
заголовок ('Content-Disposition: вложение; имя_файла="'. базовое имя ($url). '"');
header ('Content-Length:' .size ($url));
заголовок ('Pragma: public');

//Очистить системный буфер вывода
flush() ;

//Чтение размера файла
readfile ( $url , true ) ;

//Выход из сценария
die() ;
}
else {
echo "Путь к файлу не существует." ;
}
}
echo "Путь к файлу не определен."

Вывод
После нажатия на ссылку загрузки файла PDF появится следующий вывод.


Видеоруководство

Заключение

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

Об авторе

Фахмида Есмин

Я веду курсы веб-программирования. Мне нравится писать статьи или учебные пособия на различные темы в области ИТ. У меня есть канал на YouTube, на котором публикуются различные учебные пособия по Ubuntu, Windows, Word, Excel, WordPress, Magento, Laravel и т. д.: Справка Tutorials4u.

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

Возвращаемые значения

Возвращает количество байтов, прочитанных из файла в случае успеха, или false в случае ошибки

Ошибки/Исключения

В случае сбоя выдается E_WARNING.

Примеры

Приведенный выше пример выведет что-то похожее на:

Открыть/Сохранить диалог

Примечания

Примечание:

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

URL-адрес можно использовать в качестве имени файла с этой функцией, если включена оболочка fopen. См. fopen() для более подробной информации о том, как указать имя файла. См. Поддерживаемые протоколы и оболочки для получения ссылок на информацию о возможностях различных оболочек, заметок об их использовании и информации о любых предопределенных переменных, которые они могут предоставлять.

См. также

  • fpassthru() — выводит все оставшиеся данные по указателю файла
  • file() — считывает весь файл в массив
  • fopen() — открывает файл или URL-адрес
  • включить – включить
  • требовать — требовать
  • virtual() — выполнение подзапроса Apache
  • file_get_contents() — считывает весь файл в строку

Пользовательские заметки 36 заметок

Просто примечание для тех, у кого проблемы с именами, содержащими пробелы (например, "test test.pdf").

В примерах (в 99% случаев) вы можете найти
header('Content-Disposition: attachment; filename='.basename($file));

но правильный способ установить имя файла заключается в заключении его в кавычки (двойные кавычки):
header('Content-Disposition: attachment; filename="'.basename($file).'"' );

flobee.at.gmail.dot.com поделился функцией "readfile_chunked". Это работает, но вы можете столкнуться с исчерпанием памяти, используя "fread". Между тем, «stream_copy_to_stream», похоже, использует тот же объем памяти, что и «readfile». По крайней мере, когда я тестировал функцию «скачать» для моей библиотеки https://github.com/Simbiat/HTTP20 в файле 1,5 ГБ с ограничением памяти 256 МБ, это было так: «fread» я получил пиковое использование памяти ~ 240 МБ, в то время как с "stream_copy_to_stream" - ~150M.
Это не означает, что вы можете полностью избежать исчерпания памяти: если вы читаете слишком много за раз, вы все равно можете столкнуться с этим.Вот почему в моей библиотеке я использую вспомогательную функцию ("speedLimit"), чтобы вычислить, будет ли выбранное ограничение скорости соответствовать доступной памяти (при этом оставляя некоторый запас).
Вы можете прочитать комментарии в самом коде для получения более подробной информации и поднимите вопросы к библиотеке, если вы считаете, что что-то там не так (тем более, что на момент написания этого она находится в стадии разработки), но пока я могу получить с ней согласованное поведение.

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

$local_file = 'file.zip' ;
$download_file = 'name.zip' ;

// устанавливаем ограничение скорости загрузки (=> 20,5 кбит/с)
$download_rate = 20,5 ;
if( file_exists ( $local_file ) && is_file ( $local_file ))
заголовок («Управление кешем: частный»);
header ('Content-Type: application/octet-stream');
header ('Content-Length:' .size ($local_file));
заголовок ( 'Content-Disposition: filename=' . $download_file );

смыть ();
$file = fopen ( $local_file , "r" );
while(! feof ( $file ))
// отправляем текущую часть файла в браузер
print fread ( $file , round ( $download_rate * 1024 ));
// сброс содержимого в браузер
flush ();
// спать одну секунду
sleep ( 1 );
>
fclose ( $file );>
else die( 'Ошибка: файл ' . $local_file . ' не существует!' );
>

относительно php5:
я обнаружил, что уже есть обсуждение @php-dev о readfile() и fpassthru(), где будет доставлено ровно 2 МБ.

поэтому вы можете использовать это на php5 для получения больших файлов
function readfile_chunked ( $filename , $retbytes = true ) $chunksize = 1 *( 1024 * 1024 ); // сколько байтов на блок
$buffer = '' ;
$cnt = 0 ;
// $handle = fopen($filename, 'rb');
$handle = fopen ($filename, 'rb');
if ($handle === false) return false;
>
в то время как (! feof ($handle)) $buffer = fread ($handle, $chunksize);
эхо $buffer ;
if ($retbytes) $cnt += strlen ($buffer);
>
>
$status = fclose ($handle);
if ($retbytes && $status) return $cnt; // вернуть число. байты доставлены, как это делает readfile().
>
возврат $status ;

Мой скрипт корректно работает в IE6 и Firefox 2 с файлами любого типа (надеюсь :))

function DownloadFile($file) < // $file = include path
if(file_exists($file)) header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: вложение; имя_файла='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Срок действия: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Длина содержимого: ' .размер файла($file));
ob_clean();
смыть();
прочитать файл($файл);
выход;
>

Запуск на Apache 2 (WIN32) PHP5

Чтобы избежать риска самим выбирать, какие файлы загружать, возясь с запросом и делая такие вещи, как вставка "../" в "имя файла", просто помните, что URL-адреса не являются путями к файлам, и нет никаких причин, по которым сопоставление между ними должно быть настолько буквальным, как «download.php?file=thingy.mpg», что приводит к загрузке файла «thingy.mpg».

Это ваш скрипт, и вы полностью контролируете, как он сопоставляет запросы файлов с именами файлов и какие запросы извлекают какие файлы.

Но даже в этом случае, как всегда, никогда НИЧЕГО не доверяйте в запросе. Базовый принцип безопасности первого дня в школе.

Всегда использовать MIME-тип 'application/octet-stream' не оптимально. Большинство, если не все браузеры, просто загружают файлы этого типа.

Если вы используете правильные типы MIME (и встроенный Content-Disposition), браузеры будут иметь лучшие действия по умолчанию для некоторых из них. Например. в случае изображений браузеры будут отображать их, что, вероятно, вам и нужно.

Чтобы доставить файл с правильным типом MIME, проще всего использовать:

header('Content-Type: ' . mime_content_type($file));
header('Content-Disposition: inline; filename="'.basename($file).'"');

Примечание по поводу функции smartReadFile от gaosipov:

Измените индексы совпадений preg_match на:

$begin = intval($matches[1]);
if( !empty($matches[2])) $end = intval($matches[2]);
>

В противном случае $begin будет установлен на соответствие всему разделу, а $end — на то, что должно быть началом.

Подробнее об этом см. в разделе preg_match.

Всем, у кого были проблемы с чтением больших файлов в память с помощью Readfile(), проблема заключается не в самой функции Readfile(), а в том, что у вас включена буферизация вывода. Просто отключите буферизацию вывода непосредственно перед вызовом Readfile(). Используйте что-то вроде ob_end_flush().

Во избежание ошибок
просто следите за тем, разрешена ли косая черта "/" в начале параметра $file_name.

В моем случае при попытке отправить PDF-файлы через PHP после регистрации доступа
в PHP 7.1 необходимо удалить начало "/".

$size = размер файла ( $location );
$time = дата ('r', время_файла ($location));

$begin = 0 ;
$end = $size ;

header ("Content-Type: $mimeType");
header ( 'Cache-Control: public, must-revalidate, max-age=0' );
header ('Pragma: no-cache');
заголовок ('Accept-Ranges: bytes');
header ('Content-Length:' .($end - $begin));
header ("Content-Range: bytes $begin - $end / $size");
header ("Content-Disposition: inline; filename= $filename");
заголовок ("Content-Transfer-Encoding: binary\n");
заголовок ("Последнее изменение: $time");
заголовок ('Соединение: закрыть');

$cur = $begin ;
fseek ($fm, $begin, 0);

smartReadFile ( "/tmp/filename" , "myfile.mp3" , "audio/mpeg" )
?>

Чтение больших файлов fread может быть медленным, но это единственный способ прочитать файл в строгих границах. Вы можете изменить это и добавить fpassthru вместо fread и while, но он отправляет все данные с самого начала --- это было бы неэффективно, если запрос составляет байты от 100 до 200 из файла размером 100 МБ.

При использовании описанной здесь функции readfile_chunked с файлами размером более 10 МБ или около того у меня по-прежнему возникают ошибки памяти. Это потому, что авторы пропустили все важные функции flush() после каждого чтения. Итак, это правильный файл чтения с фрагментами (который на самом деле вообще не является файлом чтения и, вероятно, должен быть отправлен в passthru(), fopen() и popen() только для того, чтобы браузеры могли найти эту информацию):

функция readfile_chunked ($filename, $retbytes = true) <
$chunksize = 1 *(1024 * 1024); // сколько байтов на блок
$buffer = '' ;
$cnt = 0 ;
// $handle = fopen($filename, 'rb');
$handle = fopen ($filename, 'rb');
if ( $handle === false ) <
return false ;
>
в то время как (! feof ($handle)) <
$buffer = fread ($handle, $chunksize);
эхо $buffer ;
ob_flush();
смыть ();
if ($retbytes) <
$cnt += strlen ($buffer);
>
>
$status = fclose ($handle);
if ( $retbytes && $status ) <
return $cnt ; // вернуть число. байты доставлены, как это делает readfile().
>
возврат $status ;

>
?>

Все, что я добавил, — это flush(); после эхо-линии. Обязательно включите это!

Если вам повезло, что вы не находитесь на виртуальном хостинге и у вас установлен apache, посмотрите на установку mod_xsendfile.
Это был единственный способ, который я нашел для защиты и передачи очень больших файлов с помощью PHP (гигабайты).
Это также оказалось намного быстрее практически для любого файла.
Доступные директивы изменились со времени другого примечания об этом, и XSendFileAllowAbove был заменен на XSendFilePath, чтобы обеспечить больший контроль над доступом к файлам за пределами webroot.

Скачать исходный код.

Установить с помощью: apxs -cia mod_xsendfile.c

Затем, чтобы использовать его в своем скрипте:
$file = '/tmp/blah/foo.iso' ;
$download_name = basename ( $file );
if ( file_exists ( $file )) заголовок ('Content-Type: application/octet-stream');
заголовок ( 'Расположение содержимого: вложение; имя_файла=' . $download_name );
заголовок ( 'X-Sendfile: ' . $file );
выход;
>
?>

Просто примечание: если вы используете bw_mod (текущая версия 0.6) для ограничения пропускной способности в Apache 2, он *не будет* ограничивать пропускную способность во время событий чтения файла.

Вместо использования
header ('Content-Type: application/force-download');
?>
использовать
заголовок ('Content-Type: application/octet-stream');
?>
В некоторых браузерах возникают проблемы с принудительной загрузкой.

Использование фрагментов скрипта принудительной загрузки, добавление функций базы данных MySQL и сокрытие местоположения файла в целях безопасности было тем, что нам было нужно для загрузки файлов wmv из творений наших участников без запроса медиаплеера, а также для защиты самого файла и использования только запросы к базе данных. Что-то подобное ниже, очень настраиваемое для частного доступа, удаленных файлов и поддержания порядка в ваших онлайн-медиа.

переключатель ($file_extension) <
case "wmv": $ctype="video/x-ms-wmv"; перерыв;
по умолчанию: $ctype="application/force-download";
>

// требуется для IE, иначе Content-disposition игнорируется
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');

header("Pragma: public");
header("Срок действия: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: video/x-ms-wmv");
header("Content-Type: $ctype");
header("Расположение содержимого: вложение; имя_файла=\"".basename($filename)."\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".@filesize($filename));
set_time_limit(0);
@readfile("$fileurl") или die("Файл не найден.");

$donwloaded = "загрузки + 1";

if ($_GET["hit"]) <
mysql_query("UPDATE ibf_movies SET downloads = $donwloaded WHERE ");

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

$filename = "file.csv";
$filepath = "/path/to/file/" . $имя_файла;

// Закрытие сеансов, чтобы пользователь не ждал, пока
// загрузка завершится (при необходимости раскомментируйте)
//session_write_close();

set_time_limit(0);
ignore_user_abort(false);
ini_set('output_buffering', 0);
ini_set('zlib.output_compression', 0);

$chunk = 10 * 1024 * 1024; // байт на блок (10 МБ)

$fh = fopen($filepath, "rb");

if ($fh === false) <
echo "Невозможно открыть файл";
>

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: вложение; имя_файла=" ' . $filename . '"');
header('Срок действия: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header(' Длина содержимого: ' .размер файла($filepath));

// Повторяем чтение до конца файла
while (!feof($fh)) <
echo fread($handle, $chunk);

ob_flush(); // сбросить вывод
flush();
>

Независимая от mime-типа принудительная загрузка также может быть выполнена с помощью:

(. )
header("Срок действия истекает: понедельник, 26 июля 1997 г., 05:00:00 по Гринвичу"); // когда-то в прошлом
header("Last-Modified: " . gmdate("D, d MYH:i:s") . " GMT");
header("Content-type: application/x-download");
header("Content-Disposition: вложение; имя файла=");
header("Content-Transfer-Encoding: binary");
?>< /p>

Помните, если вы создаете сценарий принудительной загрузки, как указано ниже, вы ДЕЗИНФИЦИРУЕТЕ ВАШ ВВОД!

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

Тестируйте, в частности, такие строки, как «..», что делает возможным обход каталога. Если возможно, разрешайте только символы a–z, A–Z и 0–9 и делайте возможным загрузку только из одной «папки загрузки».

В исходном коде C эта функция просто открывает путь в режиме чтения+бинарного, без блокировки и использует fpassthru()

Если вам нужно заблокированное чтение, используйте fopen(), flock(), а затем напрямую fpassthru().

Я заметил необычное поведение Internet Explorer 6, на которое стоит обратить внимание. На моем сайте есть ссылка на скрипт, который выводит XML-файл в браузер со следующим кодом:

header('Content-Type: application/octet-stream');
header('Content-Disposition: вложение; filename="'.$filename.'"');
@readfile ($файл);

Когда популярный параметр IE «Повторное использование окна для запуска ярлыков» снят (доступ к этому параметру осуществляется в меню «Сервис» > «Свойства обозревателя» > вкладка «Дополнительно»), этот сценарий выводит файл в браузер и открывает его в другом окне, если пользователь нажимает кнопку «Открыть» в приглашении IE. Однако, если этот параметр установлен и повторно используются окна браузера, он откроется поверх страницы, на которой была нажата ссылка для доступа к скрипту.

Если я вместо этого установлю для параметра целевой ссылки html значение «_blank», сценарий откроется в новом окне, как и ожидалось, если установлен флажок «Повторное использование окна для запуска ярлыков». Но если этот параметр не отмечен, выходной XML-файл откроется в новом окне, а также будет открыто еще одно пустое окно с адресом скрипта в дополнение к нашему исходному окну.

Это далеко не идеально, и нет никакого способа узнать, отмечена ли у пользователей эта опция или нет. Мы застряли с явной вероятностью того, что половина наших посетителей увидит либо раздражающее третье пустое окно, либо сценарий, записывающий их исходное окно, в зависимости от их настройки «Повторное использование окна для запуска ярлыков».

Это один из способов сделать это, однако этого можно избежать. Например, в Zend Framework вы можете сделать

// Контроллер действий
публичная функция someAction()

$response = $this -> _response;

// Отключаем отрисовку вида и макета
$this -> _helper -> viewRenderer -> setNoRender ();
$this -> _helper -> layout ()-> disableLayout ();

// Обрабатываем файл
$file = 'whatever.zip' ;
$bits = @file_get_contents ( $file );
if( strlen ( $bits ) == 0 ) $response -> setBody ( 'Извините, мы не смогли найти запрошенный файл для загрузки.' );
>
else $response -> setHeader ('Content-type', 'application/octet-stream', true);
$response -> setBody ($bits);
>
>

Если вы, ребята, знаете, как оценить возвращаемые значения функции "stat", чтобы избежать использования "is_file" или "is_readable" (или "is_dir"), сообщите мне об этом или просто напишите здесь.

Если вам не нужно делать ничего особенного для 404, "header('HTTP/1.x xxx xxxxx');" может быть внутри функции.

$stat = @stat($filename);
$etag = sprintf ('%x-%x-%x', $stat ['ino'], $stat ['size'], $stat ['mtime'] * 1000000);

заголовок ('Истекает:');
заголовок ('Cache-Control:');
заголовок ('Прагма:');

Недавно я получил фишинговое письмо необычайно плохого качества; «Пожалуйста, немедленно войдите в систему по следующей ссылке, так как мы ваш банк, вы знаете» -иш. Ссылка указывает на неубедительный URL с .php в конце.

Я спрашивал себя, почему они могут использовать PHP-скрипт вместо того, чтобы просто имитировать внешний вид данной страницы и отправлять введенные данные в форму.

Я действительно не хочу щелкать ссылку, чтобы узнать, но я хотел бы узнать, что этот PHP-файл собирается делать. Есть ли способ загрузить скрипт, например, с помощью клиентского JavaScript?

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

Есть ли другие безопасные способы анализа этого файла и его поведения?

Файл PHP выполняется на стороне сервера и НЕ МОЖЕТ ничего сделать с вашим веб-браузером. Что он может сделать, так это динамически генерировать вредоносный код на стороне клиента, который может вызвать у вас проблемы.

Если вы не хотите, чтобы ваш веб-браузер загружал и выполнял потенциально вредоносный код на стороне клиента, вы можете использовать wget для загрузки выходных данных в файл, который затем можно открыть в Блокноте. Единственная потенциальная проблема заключается в том, что код PHP может обнаружить, что вы не используете веб-браузер, поэтому он может просто вывести пустой файл. Возможно, вам потребуется отправить некоторые заголовки, имитирующие реальную строку UA.

@Zaibis В основном ты прав. Технически URL-адрес, оканчивающийся на «.php», может привести к запуску любого кода, а не только PHP. И технически сервер не мог ответить на запрос. Оба сценария крайне редки.

Никто еще не говорил, что любой доступ к URL-адресу из спама (или что-то в этом роде), особенно если он содержит идентификатор (теоретически адрес без идентификатора также может быть отправлен только вам), может позволить спамеру/фишеру знайте, что вы сделали это, и поощряйте его рассылать больше спама или продавать ваш адрес кому-то другому. Сервер можно настроить для запуска некоторого кода при ответе на любой запрос, также заканчивающийся на ".html".

6 ответов 6

Если сервер настроен правильно, вы не сможете загрузить файл PHP. Он будет выполняться при вызове через веб-сервер. Единственный способ увидеть, что он делает, — это получить доступ к серверу через SSH, FTP или каким-либо другим способом.

Это связано с тем, что PHP является серверным языком, все действия выполняются на сервере, а затем результаты отправляются в ваш браузер (который находится на клиентской стороне).

Если вы боитесь возиться со своей системой, вы можете использовать Virtualbox с виртуальной машиной Ubuntu и открыть страницу оттуда. Если вы сделаете снимок виртуальной машины после установки и до совершения опасных действий, вы сможете позже вернуться к этому снимку и отменить все, что сценарий мог сделать с виртуальной машиной.

Многие фишинговые письма ссылаются на страницы, размещенные на взломанных веб-сайтах, со слабыми паролями, поэтому, возможно, можно получить доступ, просто подобрав их. Конечно, вы не получите от этого слишком многого.

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

и отменить все, что мог бы сделать скрипт => кроме всего сетевого трафика, исходящего от виртуальной машины, в конце концов, она подключена к Интернету.

@GustavoRodrigues Вы ничего не получите от этого, кроме потенциального тюремного заключения за несанкционированный доступ к компьютерной системе. Не пытайтесь получить доступ к потенциально скомпрометированному серверу.

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

Если вы хотите проверить, что отправлено вашему клиенту, и избежать каких-либо нежелательных последствий, используйте текстовый редактор, например Блокнот, чтобы открыть URL-адрес. То есть используйте «Файл» → «Открыть», но откройте URL-адрес, а не настоящий файл.

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

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

Код на стороне сервера PHP не удаляется. PHP-скрипт управляет обработкой на стороне сервера; серверный код вообще не отправляется клиенту. Этот ответ позволяет проверить, что на самом деле отправляется в браузер, но без риска выполнения какого-либо клиентского кода.

Файл .php выполняется на стороне сервера, поэтому, к сожалению, нет возможности получить исходный код. Однако вы можете попробовать манипулировать URL-адресом в надежде, что системный администратор допустил ошибку.

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

Если забывчивый системный администратор сделал копию файла .php для целей резервного копирования, вы можете получить эту копию без запуска /usr/bin/php

Поиск этих оставшихся файлов – сложная задача, поэтому вам стоит воспользоваться инструментами автоматизированного анализа URL-адресов.

Наконец, я рекомендую использовать curl для проведения этих экспериментов, потому что он не будет выполнять JavaScript или Flash на вашем компьютере.

Нет, нельзя, потому что PHP выполняется на сервере. Конец.

  1. Нет необходимости получать код, поскольку он не выполняется на вашем компьютере, поэтому для вас нет риска для безопасности.
  2. PHP будет обслуживать веб-сайты так же, как и любые другие, так что ответа, специфичного для PHP, не будет.

Однако, если сервер правильно настроен, он не сможет загружать файлы PHP.

Недавно я имел удовольствие исправить это в проекте, который я унаследовал, поэтому я знаю об этом. Можно напрямую загрузить PHP-скрипты, указав имя нужного скрипта вместо $_GET[], что будет учитываться.

По правде говоря, вам нужно немного удачи, чтобы обнаружить возможную уязвимость, и вам также нужно выяснить, как устроена файловая система сервера (например, каков относительный путь интересующего вас скрипта). по сравнению со скриптом, содержащим LFI-уязвимость) Так что, если вы планируете исследовать сервер, используйте песочницу/ВМ. Возможно, вам повезет, если сервер действительно плохо настроен, как следует из комментария Густаво Родригеса.

Таким образом, HTML-форма может ссылаться на blah.php, который содержит фрагмент кода php, код, окруженный тегами php, который проверяет, введен ли пароль = 1234, но если вы запустите wget blah.php, вы не увидите этот код. (даже если веб-сервер, поддерживающий php, позволил вам получить blah.php напрямую, не перенаправляя вас на получение какого-либо другого файла... на самом деле это не тот blah.php на сервере, который вы получаете). Это blah.php, обработанный сервером с удаленным php-кодом и замененным тем, что выводит php. Или с любым кодом на стороне клиента (html/javascript) должен отображаться определенный код php.

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

Читайте также: