Запуск PHP файла при прямом обращении к картинке
16.10.2025 10:06:19 pm
Идея такая, необходимо запускать PHP файл, если картинку открывают по прямой ссылке (Пример: "site/file/pic/poll/2025/10/16/500.jpg"). Если картинка встроена в страницу, через тег
Для решения кое что брал тут: Блог: Как запретить прямой просмотр изображений на PHP и Nginx. Написал такой Nginx код:
Файл file.php запускается, если есть совпадение URL картинки. Проблема в том, что файл стартует при загрузки картинки, как по прямой ссылке, так и через тег
Как определить, не знаю. Пробовал так:
Не помогло. Потому что не до конца разобрался, как с этим надо работать...
<img>
, то ни какие манипуляции не нужны.Для решения кое что брал тут: Блог: Как запретить прямой просмотр изображений на PHP и Nginx. Написал такой Nginx код:
# Права доступа к файлам (Прямое обращение)
location ~* ^/file/(attachment|pic/(photo|poll|video))/(.*)\.(jpg|jpeg|gif|png)$ {
# Проверка наличия файла до перехода на file.php
set $file "$document_root/file/$1/$3.$4";
if (!-f $file) {
return 404;
}
# Переход к обработке PHP-скриптом
rewrite ^/file/(.*)$ /file.php?file=$1 last;
}
# End: Права доступа к файлам (Прямое обращение)
Файл file.php запускается, если есть совпадение URL картинки. Проблема в том, что файл стартует при загрузки картинки, как по прямой ссылке, так и через тег
<img>
.Как определить, не знаю. Пробовал так:
# Проверка заголовка Referer
valid_referers none blocked server_names ~.site$;
# Если Referer не соответствует домену, возвращаем 403
if ($invalid_referer) {
return 403;
}
Не помогло. Потому что не до конца разобрался, как с этим надо работать...
- Жалоба
17.10.2025 08:27:27 am
Ещё не пробовал, просто размышляю над таким вариантом:
Либо же выполнять все проверки и отдавать картинку в file.php:
Сократив при этом Nginx:
Это пока наброски, которые необходимо допиливать.
location ~* ^/file/(attachment|pic/(photo|poll|video))/(.*)\.(jpg|jpeg|gif|png)$ {
# Проверка существования файла
set $file "$document_root/file/$1/$3.$4";
if (!-f $file) {
return 404;
}
# Проверка реферера
valid_referers blocked server_names danfa.net;
if ($invalid_referer) {
# Если реферер неверный или отсутствующий, переадресовываем на file.php
rewrite ^/file/(.*)$ /file.php?file=$1 last;
}
}
Либо же выполнять все проверки и отдавать картинку в file.php:
<?php
// file.php
$file = $_GET['file']; // относительный путь к файлу
$fullPath = dirname(__DIR__) . '/file/' . $file;
// Проверка существования файла
if (!file_exists($fullPath)) {
header($_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
exit;
}
// Проверка реферера
$allowedReferers = ['yourdomain.ru', 'www.yourdomain.ru'];
$referer = isset($_SERVER['HTTP_REFERER']) ? parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) : '';
if (!in_array($referer, $allowedReferers)) {
// Запрашивали напрямую или внешний реферер
header('Content-Type: application/octet-stream');
header('Content-Disposition: inline; filename="' . basename($file) . '"');
readfile($fullPath);
exit;
}
// Если реферат верный, отдаём файл напрямую
header('Location: https://yourdomain.ru/file/'.$file);
exit;
Сократив при этом Nginx:
location ~* ^/file/(attachment|pic/(photo|poll|video))/(.*)\.(jpg|jpeg|gif|png)$ {
# Все запросы идут на file.php
rewrite ^/file/(.*)$ /file.php?file=$1 last;
}
Это пока наброски, которые необходимо допиливать.
17.10.2025 06:40:32 pm
Ещё один вариант у меня был (Nginx: map):
И:
Не помогло мне.
# Определим мапу для проверки реферера
map $http_referer $referrer_check {
"~^danfa\.net$" 0; # Валидные рефереры
default 1; # Значение по умолчанию (запрос невалиден)
}
И:
# Права доступа к файлам (Прямое обращение)
location ~* ^/file/(attachment|pic/(photo|poll|video))/(.*)\.(jpg|jpeg|gif|png)$ {
# Проверка наличия файла до перехода на file.php
set $file "$document_root/file/$1/$3.$4";
if (!-f $file) {
return 404;
}
# Проверка реферера
# valid_referers server_names ~.danfa.net$;
if ($referrer_check) {
# Переход к обработке PHP-скриптом
rewrite ^/file/(.*)$ /file.php?file=$1 last;
}
}
# End: Права доступа к файлам (Прямое обращение)
Не помогло мне.
17.10.2025 08:12:10 pm
Остановился на варианте:
И файл file.php:
# Права доступа к файлам (Прямое обращение)
location ~* ^/file/(attachment|pic/(photo|poll|video))/(.*)\.(jpg|jpeg|gif|png)$ {
# Проверка наличия файла до перехода на file.php
set $file "$document_root/file/$1/$3.$4";
if (!-f $file) {
return 404;
}
# Проверка реферера
valid_referers server_names ~.danfa.net$;
if ($invalid_referer) {
# Переход к обработке PHP-скриптом
rewrite ^/file/(.*)$ /file.php?file=$1 last;
}
}
# End: Права доступа к файлам (Прямое обращение)
И файл file.php:
<?php
// ini_set('display_errors', 'On');
// error_reporting(E_ALL);
ob_start();
define('PHPFOX', true);
define('PHPFOX_DS', DIRECTORY_SEPARATOR);
define('PHPFOX_DIR', dirname(__FILE__) . PHPFOX_DS);
include(PHPFOX_DIR . 'include' . PHPFOX_DS . 'init.inc.php');
$file = phpfox::getParam('core.dir_file') . phpfox::getLib('request')->get('file');
// Проверки прав доступа
// Установка заголовков
header('Content-Type: ' . mime_content_type($file));
header('Content-Length: ' . filesize($file));
// Чтение и вывод изображения
readfile($file);
ob_end_flush();