За последние 24 часа нас посетил 64161 программист и 1741 робот. Сейчас ищут 945 программистов ...

Перенаправление вывода

Тема в разделе "Прочие вопросы по PHP", создана пользователем ZuArt, 18 дек 2006.

  1. ZuArt

    ZuArt Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    14
    Симпатии:
    0
    Столкнулся с задачей, когда вывод в броузер всеми (ну или хотя-бы наиболее распространенными командами) должен производиться не напрямую а через другую функцию...

    т.е. процесс должен быть не таким:
    скрипт - echo (print и т.п.) - броузер

    а таким:
    скрипт - echo (print и т.п.) - ФУНКЦИЯ - броузер

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

    Пробовал воспользоваться простым объявлением глобальной функции для вывода
    Код (Text):
    1. function ФУНКЦИЯ($out)
    2. {
    3.  обработка $out;
    4.  echo $out;
    5. }
    , но заартачились прогеры - кто-то юзает простое echo, а кто-то предпочитает форматирование при выводе через print_r ...

    Попробовал переопределить через
    Код (Text):
    1. function ФУНКЦИЯ($out)
    2. {
    3.  обработка $out;
    4.  return $out;
    5. }
    6.  
    7. ob_start("ФУНКЦИЯ")
    вроде ничего - всех устроила по использованию, но нашли грабли - не отрабатывает она ни по выводу echo, print (сначала копит где-то в своем буфере), ни по flush - а многие пользуют эту функцию для отдачи кода в броузер, еще на этапе работы скрипта (пока скрипт еще работает - часть данных уже идет - довольно актуально при медленном канале и/или длительной работе скрипта)...

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

    Код (Text):
    1. $CLS = new cClass();
    2. function ФУНКЦИЯ($out)
    3. {
    4.  return $CLS->Функ($out);
    5. }
    6.  
    7. class sClass()
    8. {
    9.  function Функ($out)
    10.  {
    11.   обработка $out;
    12.   return $out;
    13.  }
    14. }
    последствия в случае совпадения имен глобальных функций, думаю, каждый может себе представить :evil: , если какаому-нить прогеру ударит в голову задать для своей функции такое-же имя (но с этим можно мириться, если административно обозначить екий набор "закрытых" имен, а в случае нарушения по шапке ему настучать - но неприятненько, все люди, в конце концов)

    Толковые идеи приветствуются.
    Основной упор нужно все-таки сделать именно на то, КАК можно заставить отрабатывать глобальную функцию вывода при каждом echo/print ну или хотя-бы по flush()
     
  2. ZuArt

    ZuArt Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    14
    Симпатии:
    0
    Да, еще тут на ухо нашептали, что может возникнуть ситуация, когда будет двойное переопределение - повтороное ob_start("...") вот тока с другой функцией - а это получится разрыв цепочки... а нужно, чтобы эта часть все-таки не терялась =( когда она будет отрабатываться - ДО или ПОСЛЕ нужной функции - это не суть, там в основном идет поиск некоторых сигнатур и внесение информации в БД о них...
     
  3. avm

    avm Активный пользователь

    С нами с:
    21 сен 2006
    Сообщения:
    597
    Симпатии:
    0
    Адрес:
    Москва
    То что вы делаете - ужас! Так нельзя. Займитесь проектированием всего приложения, а то складывается впечатление, что у вас "кто в лес кто по дрова".

    Вот решение для вашего (имхо клинического) случая.
    PHP:
    1. <?php
    2.  
    3. function app_flush($buffer_on_exit=false) {
    4.     if (isset($_SERVER['buffered_flag'])) {
    5.         // нас уже вызывали ранее и у нас уже есть "своя" буферизация
    6.         $buff = ob_get_contents();
    7.         ob_end_clean(); // очистим текущий буфер (он должен быть "наш", если какой-то урод не забыл закрыть свой)
    8.     } else {
    9.         if ($buffer_on_exit===false) {
    10.             // первый вызов
    11.             $_SERVER['buffered_flag'] = $buff = true;
    12.             register_shutdown_function(__FUNCTION__);
    13.         } else {
    14.             // произошло завершение скрипта
    15.             $buff = $buffer_on_exit;
    16.         }
    17.     }
    18.  
    19.     // если есть что обрабатывать - обрабатываем
    20.     if (!is_bool($buff) and strlen($buff)) {
    21.  
    22.         echo "<<<\n".trim($buff)."\n>>>\n\n";
    23.  
    24.     }
    25.  
    26.     // начинаем "свою" буферизацию
    27.     ob_start();
    28. }
    29.  
    30.  
    31. // -------------------------------------
    32.  
    33. app_flush();
    34.  
    35. print "1\n";
    36. print "2\n";
    37.  
    38. app_flush();
    39.  
    40. print "3\n";
    41. print "4\n";
    42.  
    43. app_flush(); // в конце вызывать необязательно, ведь мы уже об этом позаботились...
    44.  
    45. ?>
    но тут нужно чтобы тот кто отрывал свои буфера между вызовами успевал их корректно закрыть, иначе собъется все.
     
  4. avm

    avm Активный пользователь

    С нами с:
    21 сен 2006
    Сообщения:
    597
    Симпатии:
    0
    Адрес:
    Москва
    если будете соблюдать корректную логическую вложенность буферов - все будет нормально.
     
  5. ZuArt

    ZuArt Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    14
    Симпатии:
    0
    хм... т.е. предлагаете вообще отказаться от обработчика??? а просто заставить всех юзать СВОЮ функцию отправки данных броузеру, в которой уже заведомо вызывать нужный метод класса (т.к. именно в класс решили запихнуть обработку)

    А по поводу бардака - практически так и есть... кто в лес, кто по дрова =((( - единственное, что есть, дык это некоторый базовый класс, от которого все наследуются =(((

    ЗЫ. Предопределять метод в базовом классе низя, потому и не писал об этом - причина запутанная и тут объяснять долго, но низя и все тут =(((
     
  6. avm

    avm Активный пользователь

    С нами с:
    21 сен 2006
    Сообщения:
    597
    Симпатии:
    0
    Адрес:
    Москва
    я для кого интересно написал эту функцию? это и есть обработчик. вместо вашего flush() его вызывайте...
     
  7. ZuArt

    ZuArt Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    14
    Симпатии:
    0
    вот про что я и грю - это вызываемыая функция взамен стандартной flush... а я грил про "обработчик событи" отправки данных =)))

    потому и пояснил, что предложение заключаетс в отказе от callback-функции, и ручном вызове написанной Вами =)
     
  8. avm

    avm Активный пользователь

    С нами с:
    21 сен 2006
    Сообщения:
    597
    Симпатии:
    0
    Адрес:
    Москва
    ZuArt, имхо вам следует еще поизучать как работает буферизация в php...
     
  9. ZuArt

    ZuArt Активный пользователь

    С нами с:
    18 дек 2006
    Сообщения:
    14
    Симпатии:
    0
    =))) не спорю, такой задачи пока не стояло, а вот возникла и мне досталась =) - изучаю, буду даж оч. непротив, если торнете носом в ссылку, где есть что толково и понятно почитать =) - мы люди не гордые, когда торкают в хорошие ресурсы =))))
     
  10. avm

    avm Активный пользователь

    С нами с:
    21 сен 2006
    Сообщения:
    597
    Симпатии:
    0
    Адрес:
    Москва
    Я сказал поизучать, а не почитать. А если что-то и читать, так только мануал.
     
  11. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    +1

    а курить - сами знаете что (аватар не смотреть)!
     
  12. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    440Hz
    а! дак это самокрутка из распечатки мануала :)
     
  13. Xpert

    Xpert Активный пользователь

    С нами с:
    15 дек 2006
    Сообщения:
    47
    Симпатии:
    0
    Ну так...
    Открыл буфер в начале работы приложения... получил все данные
    закрыл буфер... получил данные из буфера... передал в ф-ю, а она пусть делает уже с инми все что ей хочется...