1. PHP / Говнокод #13296

    +143

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    function handle($handler) {
        //...
        ob_start();
        include("./handlers/$handler.php");
        $result = ob_get_contents();
        ob_end_clean();
        return $result;
    }

    Требуется результат работы внешнего скрипта вывести посреди работы внутреннего. Есть ли варианты без голимой буферизации выходного потока?

    Запостил: vistefan, 03 Июля 2013

    Комментарии (26) RSS

    • Не говно, а нормальная практика. Альтернатив без вмешательства в код внешнего скрипта (в т.ч. своим кодом, наподобие автозамены echo/print) нет.
      Ответить
      • > Не говно
        Враньё. Практика говно, просто по-другому никак.
        Ответить
        • Ну разве что поюзать шаблонизатор, который сам парсит все это дело.
          Ответить
          • Поподробнее?
            Ответить
            • Ну смарти какой-нибудь и ему подобные. Или там не шаблон а просто уже написанный кем-то ранее скрипт?
              Ответить
              • Просто получение выхлопа скрипта в переменную, имхо, довольно странное желание. Можно узнать о задаче какие-нибудь подробности?
                Ответить
                • Собственно говоря, это и есть шаблонизатор. Пишутся внешние скрипты-обработчики, при инклюде они попадают в одну область видимости с данными, к которым могут обратиться и на основании них вывести что-нибудь. Затем этот их выхлоп подставляется в html-шаблон. Можно было бы заставить все такие обработчики быть php-файлами, содержащими функцию, возвращающую строку, и тогда обошлось бы без буферизации вывода. Но мешанина кода и разметки была бы в самом обработчике.
                  Ответить
                  • Понятно. Т.е. хендлер генерит кусок хтмля, который потом отдается другому шаблонизатору, которому нужны именно строки. А в хендлере для удобства юзаются конструкции в духе <?= dsad ?>. Ну тогда мой скромный пыхоопыт подсказывает, что, кроме ob_* походу, больше вариантов и нет...
                    Ответить
                    • Да ладно, тут уже сказали, что так принято делать в пыхокругах. Зато этот шаблонизатор в 50 пыхострок без ООП, естественно, повзоляет довольно неплохо разделить вёрстку ланные и бизнес-логику.
                      Ответить
    • разве что интерполяция смущает...
      Ответить
      • Что вы имеете ввиду?
        Ответить
        • include("./handlers/$handler.php");
          вот это очень зря
          Ответить
          • Ну смотря откуда взят handler. Если из конфига, то почему нет? Чем бы дитя не тешилось, лишь бы аргументы скрипта в include не передавало.
            Ответить
            • эту $handler проверять и перепроверять
              Ответить
              • Какова вероятность, что злой одмин устроит диверсию через конфиг?
                Ответить
                • не одмин, а погроммист
                  Ответить
                  • Перед использованием $handler, проверяется есть ли он в массиве $handlers, который в свою очередь формируется на основании json-конфига.
                    Ответить
    • Да что ж вы, православные! Да неужто буферизация выхода и инклюд - нормальная практика?! А как же потенциальные конфликты имён при инклюде? А зечем мне вообще инклюдить в свой скрипт левый код, ради получения его вывода? Я был более чем уверен, что есть стандартная функция, возвращающая строку и принимающая имя скрипта, внутри которой порождается копия интерпретатора, не зависящая от внешнего скрипта, и ОП-кода можно было бы избежать. Что может быть проще для интерпретатора-то?
      Ответить
      • Только через консоль. Не факт, что в целевой среде она будет доступна. К тому же, подозреваю, этому "хэндлеру" понадобится что-то из окружения, т.е. ещё морока с правильной передачей параметров... Ну и max_execution_time не учитывается в консольной версии - корявый хендлер, "подключаемый" таким макаром, может покусать ваш сервер.
        Ответить
      • Ну я например так делал. Это чисто для отображения шаблонов. Например при формировании мыла в html. В symfony 1.4 тот же принцип используется в include_partial(), только проверок больше.
        function render_file( $filename, $params = array() )
        {
            $output = '';
            
            if ( file_exists( $filename ) )
            {
                foreach ( $params as $variable => $value )
                    $$variable = $value;
                    
                ob_start();
                require( $filename );
                $output .= ob_get_contents();
                ob_end_clean();
            }
            
            return $output;
        }
        Ответить
      • Можете называть PHP фракталом плохого дизайна, но это обычная практика во всех фреймворках и во всех CMS. Даже функцию php_check_syntax из PHP изъяли.

        Если не хочется вызывать консольный интерпретатор через командную строку, то придётся искать подходящее расширение где-нибудь в PECL. Например, runkit умеет создавать песочницу для включаемых файлов:
        http://www.php.net/manual/ru/function.runkit-import.php
        Ответить
        • > обычная практика
          Что ж, буду спокоен. Я разнервничался, когда выдавил из себя оп-код, но если уж такое говно стандартно для пыхомира, не буду искать альтернатив.
          Ответить
      • А что плохого в инклуде локального файла с именем из конфига?
        Ответить
        • В контексте -- пожалуй, ничего.
          Ответить
          • Ну лошади понятно, что с юзерским именем делать нельзя.
            Ответить
    • Кэп, ты где?
      Ответить

    Добавить комментарий