Настроение сейчас - уже лучше :)
Работая над одним проектом базирующимся на Zend Framework, мы с коллегой столкнулись с серьезной проблемой, очевидного решения которой так и не смогли нарыть в Интернетах. Поэтому, хочу написать о нем здесь, что бы наше решение не кануло в Лету и возможно пригодилось бы еще кому-то.
Постановка задачи:
Итак, задача на самом деле простейшая - поместить каталоги изображений в область сайта недоступную для публичного просмотра. В дальнейшем выдавать изображения посредстом скрипта, в качестве параметра которому передавалось бы, например, имя фала. Контролировать выдачу с учетом таблицы прав доступа Zend и текущей роли пользователя.
Суть проблемы:
Как оказалось проблема заключалась в том, что даже простейший код работающий с графикой через GD возвращал в браузер вместо ожидаемой картинки только текущий URI, котрый был альтернативным текстом прописанным Zend'ом в теге img.
То есть следующий код выдавал в браузер набор байт, сохранив которые можно было просмотреть картинку через любой вьювер графики, но в браузере мы получали только путь, точно такой же как в адресной строке.
header("Content-type: image/gif");
$img_src=imagecreatefromgif($src);
imagegif($img_src);
В переменной $src, разумеется, находился сформированный ранее путь к реальному файлу.
Попытки решения:
Решение этой проблемы затянулось. Перелопатив и рунет и западные ресурсы мы то тут, то там нападали на след похожего поведения Zend. У кого-то не генерировались капчи, кто-то не мог вывести графику из BLOB полей базы. многим помогало отключение Layout'ов и Рендера в функции инициализации Контроллера:
function init()
{
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
}
Однако нам все это не подходило. Рендер у нас был отключен изначально, лэйауты мы не использовали. Однако, проблема оставалась нерешенной и возможно осталась бы такой еще долго, если бы не FirePHP и внимательность моего товарища. Как выяснилось в stand-alone выводе той же картинки таким методом (то есть без Zend (которое кстати, как известно, работает на "Ура!")) выводило в браузер чистый Response, то есть картинку начинающуюся с таких байтов:
ÿØÿà�JFIF�
в то время как такой же код работающий в Zend выдавал на выходе несколько другой набор:
ÿØÿà�JFIF�
Эти три лишних байта и послужили как причиной неприятной проблемы, так и ключем к разгадке.
Решение задачи:
Решить пробелму нам помогла банальность, к которой мы пришли методом проб и ошибок (пробовали убирать закрывающий тег PHP в конце первичного загрузчика, прописывали перед ним вывод хотя бы одного байта).
В итоге оказалось, что в начале всех подключаемых к контроллеру модулей в том числе и в файлах самописных предков нашего Контроллера следует убрать все лишние пустые строки в начале файлов! То есть влияние на вывод оказывала даже пустая строка между комментариями в начале файла и непосредственным описанием класса.
НЕ ТАК:
0.
1. <?php
2.
/**
3.
* Модуль главного Контроллера
4.
*
5.
* @author Smile @rT
6.
* @version development
7.
* @since 08.11.2008
8.
*/
9.
10. require_once 'lib/our/Standard_Controller_Actions.php';
11.
class ReaderController extends StandardControllerAction
12.
{
13.
...
А ТАК:
0. <?php
1.
/**
2.
* Модуль главного Контроллера
3.
*
4.
* @author Smile @rT
5.
* @version development
6.
* @since 08.11.2008
7.
*/
8. require_once 'lib/our/Standard_Controller_Actions.php';
9.
class ReaderController extends StandardControllerAction
10.
{
11.
...
То есть фактически проблема для новичка :) Банальная и простейшая, доступно описанная, например здесь, однако с той лишь разницей, что Zend выдал не знакомую и банальную ошибку, а прибавил к нашей картинке лишних три (бывало и шесть) байт, что и приводило к тому, что она не отображалась!
Так что, думаю, всегда можно найти может и не очевидное, но действенное решение. :)