public static function transform($xmlstr, $fn) { static::$fn = $fn; if (self::$done == TRUE) { trigger_error("Xml2Html::transform() called twice?"); } $outputDom = new \DOMDocument(); $outputDom->loadXML($xmlstr); $matches = NULL; //добываем имя стиля из хмл-а (или xmlreader?) if ($outputDom->firstChild->nodeType == XML_PI_NODE && $outputDom->firstChild->target == "xml-stylesheet") { if (preg_match("/href\\s*=\\s*\"(.+)\"/", $outputDom->firstChild->data, $matches)) { $xsl = new \DomDocument(); //error_log(print_r($_SERVER,true));exit; $xsl_file = dirname($_SERVER["SCRIPT_FILENAME"]) . "/" . str_replace("http://" . $_SERVER["HTTP_HOST"] . dirname($_SERVER["PHP_SELF"]), "", $matches[1]); $xsl->load($xsl_file); $proc = new \XSLTProcessor(); $proc->importStyleSheet($xsl); //регистрируем на себя обращения к файлам stream_wrapper_unregister("file") or die(__FILE__ . __LINE__); stream_wrapper_register("file", static::CLASSNAME) or die(__FILE__ . __LINE__); //вешаем на обработчик выхода ловушку - если вложенный скрипт попытается сделать exit или die register_shutdown_function(function () { stream_wrapper_unregister("file") or die(__FILE__ . __LINE__); stream_wrapper_restore("file") or die(__FILE__ . __LINE__); if (self::$done != TRUE) { error_log("AHTUNG! restart php now!"); //тут не прокатывает trigger_error() - зовем напрямую UncaughtFatalErrorExceptionHandler(new \FatalErrorException("do not use EXIT() in included script")); } }); //на время трансформации ставим свой специальный обработчик ошибок set_error_handler(array(static::CLASSNAME, "xsltErrorHandler")); $xsltResult = $proc->transformToXML($outputDom); restore_error_handler(); if (self::$xsltErrors != NULL) { //а сообщаем об ошибках как обычно trigger_error("XSLTProcessor::transformToXml(): " . \Happymeal\Port\Adaptor\Data\Xml2Html::$xsltErrors); } //ставим маркер что управление нам вернули self::$done = TRUE; unset($proc, $xsl); //восстанавливаем дефолтный streamwrapper для file:// stream_wrapper_restore("file") or die(__FILE__ . __LINE__); } } self::$done = TRUE; unset($outputDom); return isset($xsltResult) ? $xsltResult : $xmlstr; }
/** * проверялка корректности завершения работы * если вложенный скрипт завершился раньше и не вернул управление - ошибка */ public static function checkDone() { stream_wrapper_unregister("file") or die(__FILE__ . __LINE__); stream_wrapper_restore("file") or die(__FILE__ . __LINE__); if (self::$done != TRUE) { error_log("AHTUNG! restart php now!"); //тут не прокатывает trigger_error() - зовем напрямую UncaughtFatalErrorExceptionHandler(new \FatalErrorException("do not use EXIT() in included script")); } }