1. Вы можете положить файл так, чтобы его вообще не было видно вебсерверу. А отдавать файл скриптом, проверяя, как Вам угодно, авторизацию, права, и тд. Например следующая структура приложения:
/webroot/getfile.php
/storage/
/storage/file1.jpg
/storage/file2.jpg
/storage/file3.jpg
веб сервер знает только о /webroot/
тоесть по урлу site.ru/getfile.php будет доступен файл getfile.php
а запрашивать нужные Вам фалйы будете по урлу site.ry/getfile.php?file=file1.jpg
пример срипта :
php.net/manual/ru/function.readfile.php<?php
$file = '../'.$_GET['file'];
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
Этот вариант плох тем, что напрегает сервер лишними загрузками PHP. Есть более экономичный по памяти способ отдать файл
2. Опять кладете файлы в недоступное из вне сервера, и генерируете на них симлинки с очень длинным и трудно подбираемым именем(например 250 случайных символов), временные
Php скрипт, при запросе site.ru/getfile.php?file=file1.jpg создат нужный симлинг и вернет редирект на него: site.ru/longlonglongname
Cруктура директорий будет такая
/webroot/getfile.php
/webroot/longlonglongname -> ../storage/file1.jpg
/storage/
/storage/file1.jpg
/storage/file2.jpg
/storage/file3.jpg
При таком подходе, непосредсвено при отдаче файла PHP работать не будет, файл будет доступен из вне по длинному, не подбираемому наугад урлу. Через, например, 3 часа, нужно удалить ссылку