Непонятки с headers_sent()

untied

Сдвинутый новичок
Непонятки с headers_sent()

В моем скрипте несколько файлов подключаются с помощью include(). Заранее неизвестно, какие именно файлы подключаются. Поэтому в одном случае нужно сохранить вывод данных подключенными скриптами и распечатать. А в другом случае нужно отследить вызов header("Location: ..."), который может быть сделан в одном из подключаемых файлов, и, соответственно, уже больше ничего не печатать.

Выглядит это примерно так:
PHP:
$a_filelist = array(); // список подключаемых файлов
$h_fileoutput = array(); // хэш выводимых данных

// ... - здесь заполняется массив $a_filelist именами нужных файлов

foreach ( $a_filelist as $file )
{
    ob_start();
    include($file);
    $h_fileoutput[$file] = ob_get_contents();
    ob_end_clear();
}

if ( !headers_sent() )
{
    // печатаем содержимое хэша по определенному алгоритму
    // сам алгоритм в данном случае не важен
}
else
{
    // один из подключенных файлов вызвал команду
    // header("Location: ...");
    // печатать ничего не нужно
}
Ну дык вот. Я обнаружил, что независимо от того, есть вызов в подключенном файле функции header() или нет такого вызова -- функция headers_sent() всегда выдает FALSE (то есть блок 'else' не выполняется вообще никогда).
В мануале по Output control я прочел, что вызов функции ob_start() никак не влияет на отправку header-ов. Однако, что-то работает неправильно.

Как можно исправить такую ситуацию? Мне нужно отслеживать вызов функции header() подключаемыми файлами.
 

SiMM

Новичок
Re: Непонятки с headers_sent()

Автор оригинала: untied
в одном случае нужно сохранить вывод данных подключенными скриптами и распечатать. А в другом случае нужно отследить вызов header("Location: ..."), который может быть сделан в одном из подключаемых файлов, и, соответственно, уже больше ничего не печатать.
Почему бы в одном из этих подключаемых файлов просто не сделать [m]exit[/m]?
 

untied

Сдвинутый новичок
Вызов exit() был бы хорошим решением, но есть еще один нюанс!
Подключаемый файл может выдать такой заголовок:
PHP:
header("Content-type: image/jpeg");
И в данном случае необходимо распечатать вывод именно этого одного файла, а вывод других файлов не печатать.
Функция headers_sent() (если б она нормально работала) позволяет определить имя файла, откуда произошел вызов функции header(). Поэтому никаких проблем и с такой ситуацией не было бы.
Но увы и ах. :confused:
 

SiMM

Новичок
Ты сам себе усложняешь жизнь - какой смысл делать ob_start при выводе графики? Что мешает сделать просто вывод картинки и exit? Зачем ты вообще приплёл сюда ob_start? Что-то не похоже на то, что в нём была необходимость.
 

untied

Сдвинутый новичок
Это скрипт шаблонизатора. А подключаемые файлы -- "фрагменты", выводимую информацию которых нужно впихнуть на соответствующие места шаблона страницы.
В общем, я так думаю, что нужно самостоятельно написать аналог функции header() и вызвать ее из подключаемых файлов.

Распечатка данных и вызов exit() -- решение проблемы. Но тут немного идеология нарушается. Получается, что подключаемый фрагмент может вызвать останов всего шаблонизатора. Он, конечно, может вызвать останов, ему не запретишь... Но такое решение все-таки не совсем корректно.
 

SiMM

Новичок
Автор оригинала: untied
Распечатка данных и вызов exit() -- решение проблемы. Но тут немного идеология нарушается. Получается, что подключаемый фрагмент может вызвать останов всего шаблонизатора. Он, конечно, может вызвать останов, ему не запретишь... Но такое решение все-таки не совсем корректно.
Ничего страшного - по моему, у тебя идеология нарушена изначально :)
PHP FAQ: Самые основы. ОЧЕНЬ ВАЖНОЕ ЗАМЕЧАНИЕ - какой смысл во всяких шаблонизаторах при редиректе и выводе картинок - лично мне до сих пор не ясно.
 

untied

Сдвинутый новичок
Да смысл вот какой. То, что я назвал "фрагментами" -- это скрипты php или статические страницы html, которые шаблонизатор подключает с помощью include(). Один и тот же фрагмент может иметь несколько функций. К примеру, фрагмент гостевой книги. В одном случае он выводит форму с полями для заполнения. В другом случае он получает данные из полей и сохраняет их в базе, потом делает редирект на страницу, где выводится список всех записей в гостевой. Управляет поведением фрагмента параметр action. Скажем, когда идет вызов action=edit -- выводится форма. Когда action=save данные сохраняются и делается редирект.

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

Благодарю за бесценный совет, SiMM, но то, какие данные умеет выводить PHP, я как-нибудь знаю. И не пытаюсь вывести всю страницу сразу с картинками и оформлением одним запросом к шаблонизатору. Картинки выводятся отдельным запросом <IMG SRC="..."> но опять же через шаблонизатор.
Взаимный добрый совет: не надо считать всех вокруг идиотами. Это самое типичное и вредоносное заблуждение практически любого программера. И практически всегда такое суждение неверно. ;)
 

SiMM

Новичок
Автор оригинала: untied
Картинки выводятся отдельным запросом <IMG SRC="..."> но опять же через шаблонизатор.
Нафига козе баян?
не надо считать всех вокруг идиотами
Это твоё субъективное мнение, посему можешь оставить его при себе.
Не вижу смысла ставить костыли, если сама задача выглядит большим костылём. Можно подумать, что до сих пор никто не пользовался шаблонизаторами и схожими идеями построения приложений - однако, заметь, никому в голову не приходило проверять, уходил ли уже заголовок. Как ты думаешь, почему?
 
Сверху