更快的PHP XSL处理器

时间:2012-11-06 19:54:38

标签: php xslt

我们目前使用php XSL处理器构建作为我们的Web应用程序的模板引擎。其中依次使用libxslt库。它的速度似乎不令人满意。是否有更快/更好的XSL处理引擎可以与PHP一起使用?或者有没有办法加速libxslt安装?

3 个答案:

答案 0 :(得分:1)

我遇到了同样的性能问题。当我在Windows下运行时,我编写了一个类,它是我通过COM访问的msxml的包装器。这比本机PHP XSL转换快得多。 (当然,如果你没有运行Windows,这根本不会帮助你。)

我将在这里包含一些代码,通常需要注意的是我不是PHP大师,而且我没有做出任何完美的承诺:

class xsltransform {
    private $xmlfilename;
    private $xslfilename;
    private $xslt;
    private $xslDoc;
    private $xmlDoc;
    private $xslProc;
    private $parameters = array();
    public function __construct() {
        $this->xslt = new COM("Msxml2.XSLTemplate.6.0");
        $this->xslDoc = new COM("Msxml2.FreeThreadedDOMDocument.6.0");
        $this->xslDoc->async = false;
        //to allow xsl:import in xsl since security changes in MSXML 6.0
        //http://msdn.microsoft.com/en-us/library/windows/desktop/ms763800(v=vs.85).aspx
        $this->xslDoc->resolveExternals = true;
        //to allow xsl:document in xsl since security changes in MSXML 6.0
        $this->xslDoc->setProperty("AllowDocumentFunction", true);
        $this->xmlDoc = new COM("Msxml2.DOMDocument.6.0");
        $this->xmlDoc->async = false;
    }
    private function loadxml() {
        $this->xmlDoc->load($this->xmlfilename);
        $this->checkParseError($this->xmlDoc, "xmlDoc, filename={$this->xmlfilename}");
    }   
    private function loadxsl() {
        $this->xslDoc->load($this->xslfilename);
        $this->checkParseError($this->xslDoc, "xslDoc, filename={$this->xslfilename}");    

    }
    private function addParameters() {
        foreach ($this->parameters as $name => $value) {
            $this->xslProc->addParameter($name, $value, '');
        }

    }                    
    public function setxmlfilename($filename) {
        $this->xmlfilename = $filename;    
    }
    public function setxslfilename($filename) {        
        $this->xslfilename = $filename;    
    }
    public function addProperty($name, $value) {
        $this->parameters[$name] = $value;
    }
    private function checkParseError($doc, $message = '') {
        if ($doc->parseError->errorCode) {
            print("XML Parse Error (" . $message . "): " . $doc->parseError->errorCode . $doc->parseError->reason);
            exit; 
        }
    }
    private function loadAndTransform() {
        $this->loadxsl();
        $this->xslt->stylesheet = $this->xslDoc;
        $this->xslProc = $this->xslt->createProcessor();
        $this->xslProc->input = $this->xmlDoc;
        $this->addParameters();
        $this->xslProc->transform();
    }
    public function output() {
        $this->loadxml();
        $this->loadAndTransform();            
        return $this->xslProc->output;
    }
    public function transform($xmlText) {
        $this->xmlDoc->loadXML($xmlText);
        $this->checkParseError($this->xmlDoc, "xmlDoc");
        $this->loadAndTransform();            
        return $this->xslProc->output;
    }
}; 



function xslTransform($xmlfilename, $xslfilename, $params) {
    $scriptPath = (dirname(__FILE__));
    $xslfilenameabsolute = "{$scriptPath}'\\..\\xsl\\{$xslfilename}";
    if (!file_exists($xmlfilename)) {
        die("{$xmlfilename} does not exists.");
    }
    if (!file_exists($xslfilenameabsolute)) {
        die("{$xslfilenameabsolute} does not exists.");
    }
    $xsltransform = new xsltransform();
    $xsltransform->setxmlfilename($xmlfilename);
    $xsltransform->setxslfilename($xslfilenameabsolute);
    foreach($params as $key=>$param) {
        $xsltransform->addProperty($key, $param, '');
    }
    return $xsltransform->output();
}

答案 1 :(得分:0)

对XSLT使用本机PHP支持,它的内存使用率很低。这确实为DOMDocument和XSLTProcessor类创建了一个依赖项,可以在XSL.dll for PHP 5中找到它。

答案 2 :(得分:0)

是的,PHP使用Libxslt of libxml2,对于15岁XSLT1 standandard来说,它是如此受欢迎,也许是最安全且更快(!)XSLT处理器。因此,这是最好的解决方案......在XSLT社区迁移到XSLT2的环境中(非常复杂且比v1慢),因为对于2014的服务器机器,性能问题就会消失。


提高XSLT1的性能

有许多方法可以改进处理,范围从XML-get到XSLT-processed-cache。

  1. 您正在使用"大型XML文件"?为什么?今天,您可以拆分到SQL数据库中的记录 with PostgreSQL,并仅使用SQL和/或XPath检索必须使用的片段。

  2. 重用(XSLT' s和XML')DOM转换的对象:请参阅ex. method chaining with DOMDocument

  3. 检查并简化您的XSLT:就像在任何MVC上下文中一样,MVC-View不能用作"图灵完整算法",而只是一个占位符和循环解析器(请参阅T. Parr 20042008)。所以基准测试,将性能与简单的性能进行比较。
    重要:好的,如果你需要&#34;辅助方法&#34;和模板中的其他快速(如trim!)或复杂函数,不要尝试将XSLT1用作XSLT2(!),XSLT1不适用于它......而是使用registerPHPFunctions as showed in this tutorial < /强>

  4. 缓存:增益效果的最后机会...如果多次使用,可以缓存您的XSLT ,请参阅this good answer about XSLT-caching in PHPthis other option


  5. 替代 Libxslt of Libxml2 处理XSLT1?我不建议浪费时间。但是,如果你真的需要复杂的模板,而不是浪费时间使用XSLT1,请使用XSLT2!

    使用PHP的解决方案:哼......是问题,请参阅discussion here,其中出现了一个可能的解决方案Saxon/C,这是唯一一个不是Java的免费且优秀的XSLT2处理器,并且有一个PHP端口......但是是beta(v0.3.1)。