Pull to refresh

Comments 23

Похожий подход видел в джумле, ой как намучался я в свое время с доработкой её плагинов. Такое решение имеет право на жизнь, но с ним лучше быть осторожным.
Это одноразовые решения, когда надо срочно-срочно, а движок ещё не подготовлен. Имеет право на жизнь, чего уж. ob_handlers для этого и предназначены.
И правда. Поправил.
Использую этот метод каждый год первого апреля, чтобы на сайте глобально заменить что-нибудь на что-нибудь более смешное.
ob_start(f_callback);

хм, а не так ли:
ob_start('f_callback');


? :)
В каких-то старых версиях так и было. Сам когда-то натыкался на то, что на dev был 5.3, а ресурс на каком-то старом вертелся. При запуске на dev всё ругалось, а на продашне работало как следует.
Чудовищная ошибка. Причем чудовищна она своей примитивностью и многократной описанностью в мануалах.

ob_start(f_callback);
=> интепретатор ищет константу f_callback
=> не находит
=> за значение необъявленной константы принимается ее имя
=> генерируется warning
=> ob_start('f_callback');

Зачем Вы так издеваетесь над PHP?

Что мешает написать
ob_start( function() use ($buffer) {
// some code here
});
?
О чем и речь. Даже мануал об этом пишет.
Так я так никогда и не делал. Просто говорю, что видел такую запись. Ну и сейчас предположил что в старых версиях PHP, с которыми я не работал и которые не изучал, этот момент работает несколько иначе. В первом преложении прошлого коммента я пропустил слово «возможно» после «версиях» — оттого и непонимание вышло. Прошу прощения, постараюсь более так коряво не излагать мысли.
Пожалуй, вы правы.
Этот ужасный костыль на является «изящными способами использования буферизации вывода в php». Это сгодится как временное решение на два дня, пока разработчик учится делать «find. -exec sed -i» в папке с шаблонами, или где там захардкодены эти урлы, чтобы со временем понять, зачем нужно использовать в проете константы или сервисы управления сслыками.
Простите, но вы точно читали сам пост? Речь идет не о вшитых в шаблон ссылках, а ссылках в постах на форуме сайта. Или вы «find. -exec sed -i» будете к базе применять?
Читал, но каюсь, почему-то не заметил этого факта.
Увы, довольно часто оказывается, что CMS уже использует в своем коде ob_ функции, а значит их использование становится крайне затруднительным.
В чём трудность? Они прекрасно стакаются, и даже можно получить текущий уровень глубины через ob_get_level чтобы проверить, не открылся ли лишний буфер внутри обёртки. Проблема в другом — когда вам достаётся сайт с такой вот магией, и вы понятия не имеете почему и по каким законам что-то меняется и где именно: в index.php, в init.php или ещё где-то.
Допустим, мне надо перехватить полный вывод страницы.
В обычном случае я пишу ob_start('f_callback'); или ob_start(); $data=ob_get_clean();
Но если после моего ob_start есть другой ob_start, то он же переопределяет колл-бэк функцию и я уже не могу получить весь вывод в переменную, без модификаций других ob_start, искать которые порой довольно накладно, а если код еще зашифрован ZENDом, то вообще невозможно.
Если я ошибаюсь, буду признателен за объяснение, как мне получить весь вывод в переменную, при использовании в произвольных местах CMS ob_ функций, без их модификации.
Когда вы сделаете ob_start(); <...> $content = ob_get_clean(); — то весь вывод будет в переменной $content, независимо от того, какие между ними открывались и закрывались буферы и где. Главное, чтобы они закрывались, иначе можно словить последний открытый буфер. По поводу каллбеков, вот строка из официального мануала: «Буферы вывода помещаются в стэк, то есть допускается вызов ob_start() после вызова другой активной ob_start(). При этом необходимо вызывать ob_end_flush() соответствующее количество раз. Если активны несколько callback-функций, вывод последовательно фильтруется для каждой из них в порядке вложения.»

Можете приветси пример кода, который переопределяет каллбек-функцию или как-то глючит при вложении буферов друг в друга?
Реально полезное применение ob_* — рефакторинг спагетти-кода. Заключаем блок, в котором нет возможности и/или желания сейчас разбираться в «скобки»
ob_start();
// spagetti code here...
$result = ob_get_clean();
echo $result;

Потом выделяем всё это, кроме echo, в функцию/метод (посылаю лучи JetBrains, чтобы был безопасный рефакторинг куска процедурного кода не только в функцию, но и в метод, или функции в метод)
class SpagettiWrapper {
  public function show() {
    ob_start();
    // spagetti code here...
    return ob_get_clean();
  }
}

$spagetti = new SpagettiWrapper();
echo $spagetti->show();

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

Вернее можем «зажать» её тестами и либо рефакторить сразу, либо оставить до поры до времени.
UFO just landed and posted this here
Sign up to leave a comment.

Articles