Я только что обсудил с моим товарищем по команде расположение загруженных пользователем изображений в галерее изображений. Я хотел бы получить более полное представление о методах, которые мы предлагаем.
Мой напарник по команде написал действие + контроллера, которое вызывает file_get_contents
для файла изображения, помещенного в папку, недоступную для публичного просмотра (т. Е. Вне public_html
на сервере), и отображает его в заголовке. Это безопасно, но, поскольку мы используем Zend Framework, оно также сканируется медленно - каждый вызов контроллера изображения обходится нам примерно в 500 мс лага из-за выполнения запросов начальной загрузки. Это раздражает, поскольку представление галереи изображений отображает более 20 изображений одновременно.
Короче говоря, соответствующий код будет:
class ImageController extends Zend_Controller_Action {
public function showAction () {
$filename = addslashes($this->_getParam('filename'));
if(!is_file($filename)) {
$filename = APPLICATION_PATH.'/../public/img/nopicture.jpg';
}
$this->_helper->viewRenderer->setNoRender(true);
$this->view->layout()->disableLayout();
$img = file_get_contents($filename);
header('Content-Type: image/jpeg');
$modified = new Zend_Date(filemtime($filename));
$this->getResponse()
->setHeader('Last-Modified',$modified->toString(Zend_Date::RFC_1123))
->setHeader('Content-Type', 'image/jpeg')
->setHeader('Expires', '', true)
->setHeader('Cache-Control', 'public', true)
->setHeader('Cache-Control', 'max-age=3800')
->setHeader('Pragma', '', true);
echo $img;
}
}
Тогда, в представлении, мы просто называем:
<img src="<?php echo $this->url(array('controller' => 'image', 'action' => 'show', 'filename' => PATH_TO_HIDDEN_LOCATION.'/filename.jpg')); ?>" />
У меня другой подход: я предпочитаю хранить исходные изображения в скрытом месте, но как только они будут запрошены, скопируйте их в общедоступное место и предоставьте ссылку на него (с дополнительным механизмом, запускаемым cron , чтобы время от времени стирать каталог общедоступных изображений, чтобы не тратить пространство, и robots.txt
, указывающий Google не индексировать каталог). Решение помещает файлы (по несколько в каждый данный момент) в общедоступный каталог (при условии, что один знает имя файла), но также требует только помощника вида, таким образом, не запускает загрузчик:
class Zend_View_Helper_ShowImage extends Zend_View_Helper_Abstract {
public function showImage ($filename) {
if (!file_exists(PUBLIC_PATH."/img/{$filename}")) {
if (!copy(PATH_TO_HIDDEN_FILES."/{$filename}",PUBLIC_PATH."/img/{$filename}"))
$url = PUBLIC_PATH.'/img/nopicture.jpg';
else
$url = PUBLIC_PATH."/img/{$filename}";
} else {
$url = PUBLIC_PATH."/img/{$filename}"
}
return "{$url}";
}
}
С помощью этого помощника вызов очень прост в представлении:
<img src="<?php echo $this->showImage('filename.jpg'); ?>" />
Вопрос: Представляет ли мой подход угрозу безопасности, как заявляют мои коллеги? Каковы потенциальные риски этого? И, самое главное, перевешивают ли угрозы безопасности, если таковые имеются, 10-секундный выигрыш при загрузке страницы?
На случай, если это имеет значение: мы работаем над порталом сообщества, в котором зарегистрировано около 15 000 пользователей, а галереи - очень часто используемая функция.
* Код, который я вставил, является отредактированной, упрощенной версией того, что придумал каждый из нас - просто чтобы показать механику обоих подходов.