Как очистить ранее эхо-элементы в PHP

В php есть ли способ очистить/удалить все ранее эхо- или напечатанные элементы?

Например:

<?php

echo 'a';
print 'b';

// some statement that removes all printed/echoed items

echo 'c';

// the final output should be equal to 'c', not 'abc'

?>

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


person edt    schedule 29.06.2009    source источник
comment
Если вы делаете это в качестве меры безопасности, вы, вероятно, делаете это неправильно. Вам следует подумать о другом подходе к проблеме. Может быть, создать еще один вопрос о том, в чем ваша проблема?   -  person Carlos Lima    schedule 29.06.2009
comment
Я использую oci_execute, и если запрос завершится ошибкой, будет выведено сообщение ‹b›warning‹/b›. Но я обрабатываю ошибку отдельно и не хочу сообщения оракула. Так что этот вопрос применим и в этом сценарии   -  person Adarsha    schedule 14.10.2010


Ответы (5)


<?php

ob_start();
echo 'a';
print 'b';

// some statement that removes all printed/echoed items
ob_end_clean();

echo 'c';

// the final output is equal to 'c', not 'abc'

?>

Функции буферизации вывода

Функции буферизации вывода также полезны при хакерских атаках для принуждения функций, которые печатают только для возврата строк, т.е.

<?php
ob_start();
var_dump($myVar);
$data = ob_get_clean();
// do whatever with $data
?>
person Matthew Scharley    schedule 29.06.2009
comment
Существуют ли настройки apache для включения/отключения буферизации вывода для нескольких страниц? - person Pacerier; 09.03.2013
comment
Вы также можете использовать ob_end_flush() для вывода операторов, следующих за ob_start(), вместо того, чтобы отбрасывать их. См. us3.php.net/ob_start. - person Vern Jensen; 21.01.2014
comment
@Matthew: очень помог! - person vkGunasekaran; 20.03.2014

в то время как @monoxide прав, лучше найти более интуитивные способы сделать то же самое. например.:

<?php
$val_to_print = $a;
if( $need_to_change==true ) 
    $val_to_print = $b;
// when you are sure you won't have to change again...
echo $val_to_print;
?>

Ваше здоровье,

младший

person jrharshath    schedule 29.06.2009
comment
Он беспокоится о том, что кто-то меняет на него файлы, которые он не контролирует, так что, хотя вы правы, вы не обращаетесь к тому, что его беспокоит. - person Matthew Scharley; 29.06.2009
comment
Кроме того, иногда люди упускают из виду EOL в конце включаемых файлов, что может привести к хаосу, если вам нужно отправить заголовок() позже... - person Matthew Scharley; 29.06.2009
comment
@monoxide Рискуя полностью уйти от темы, вы можете опустить последний закрывающий тег PHP в конце файла, что является хорошим способом полностью устранить эту проблему. - person Josh; 29.06.2009
comment
+1 за проблему с EOF. Эта проблема заняла у меня несколько дней назад, чтобы отладить. И только благодаря случайности я нашла его. - person Steve Cooke; 26.04.2015

В идеале вы не должны выводить ничего, что вы в конечном итоге не хотите печатать. Держите свою логику отдельно от презентации, чтобы меньше разочаровываться.

При этом вы можете обратиться к параметрам буферизации вывода в PHP.

person Sampson    schedule 29.06.2009

Если это отладочный вывод и информация о состоянии программы, о которой вы беспокоитесь, возможно, trigger_error может быть ближе к тому, что вам нужно, например:

trigger_error ("Attempting to load report #{$report_id}.", E_USER_NOTICE);

Когда ваш скрипт находится в производстве, он не будет показывать никаких ошибок, поскольку обычно они отключены или зарегистрированы. Также лучше делать фатальные ошибки с помощью E_USER_ERROR, а не с помощью die().

ob_start ();
require ($filename);
$html = ob_get_clean ();

Вышеупомянутое также будет включать файл и давать вам его содержимое в виде строки.

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

person Meep3D    schedule 29.06.2009
comment
Или, возможно, намного лучше, если вы используете $html, полученный от get_clean(), и помещаете его в тело своей страницы вместо того, чтобы испортить заголовки и позиционирование большей части вашей страницы. - person Matthew Scharley; 29.06.2009

Если хакер, скажем, имеет доступ к вашему файлу PHP, он также сможет удалить оператор, очищающий выходной буфер.

Если вы делаете это, потому что позволяете своим пользователям загружать PHP-скрипты, позвольте мне сказать вам, что это очень плохая идея.

В обоих случаях выполнение того, о чем вы просите, добавляет 0 безопасности.

person Andrew Moore    schedule 29.06.2009
comment
У меня есть функция ajax, которая предоставляет имя/местоположение файла для включения в мой php-документ. Я использую функцию parse_url, чтобы запретить любые значения, которые являются абсолютными путями (до включения файла). Включенный файл должен содержать только любой массив. Я обернул массив в ob_start и ob_end_clean, чтобы удалить любое эхо-содержимое. Видите ли вы какие-либо потенциальные проблемы безопасности с этим? - person edt; 29.06.2009
comment
Много на самом деле. Это означает, что ваш злоумышленник может выполнить любой файл php в вашей системе. Вам лучше иметь один файл php для каждого массива и вызывать этот файл напрямую. - person Andrew Moore; 29.06.2009
comment
Спасибо за отзыв. Чтобы программа работала, пользователь должен иметь возможность добавлять собственные значения массива. В дополнение к вышесказанному я также теперь потребовал, чтобы включаемый файл содержал подстроку. Например, строка должна содержать bar. foo.php не может быть включен. foo_bar.php может быть включен. Итак, пока в системе нет других файлов, содержащих foo, программа должна быть в безопасности. Это правильно? В очередной раз благодарим за помощь. Очень признателен. - person edt; 29.06.2009
comment
Посмотрим... ../bar/../../delete_all.php: еще вызовется. Просто нет возможности защитить себя. Почему бы не хранить сериализованные значения в базе данных и не извлекать их по идентификатору? Таким образом, у вас может быть foobar.php?id=20, что намного безопаснее, чем foobar.php?file=someArbPath. - person Andrew Moore; 30.06.2009
comment
Или другой способ сделать это — полностью отключить элементы пути, такие как «..», что может решить множество проблем безопасности такого рода. - person Matthew Scharley; 30.06.2009
comment
Я не могу хранить предварительно созданные значения в базе данных, потому что скрипт является подключаемым модулем JQuery. Пользователи должны иметь возможность вводить любой относительный путь. Я изменил логику своего скрипта, так что путь должен быть относительным (не абсолютным), последняя часть пути должна содержать foo, а имя подключаемого файла должно содержать foo. Будет ли это работать? - person edt; 30.06.2009
comment
@ed: всегда есть способы избежать ограничений пути. Я не понимаю, как jQuery мешает вам получать данные из базы данных. Работа будет выполняться PHP, а не jQuery... Все, что вам нужно сделать, это указать jQuery на этот PHP-файл с помощью соответствующей строки запроса. И если плагин действительно жестко запрограммирован таким образом, что его невозможно настроить, возможно, вам следует изменить плагин. - person Andrew Moore; 30.06.2009
comment
Вот связанный вопрос: stackoverflow.com/questions/1066930/ - person edt; 01.07.2009