首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP DomDocument,重用XSLTProcessor,是稳定/安全的吗?

PHP DomDocument,重用XSLTProcessor,是稳定/安全的吗?
EN

Stack Overflow用户
提问于 2013-08-06 16:56:18
回答 2查看 603关注 0票数 1

我正在使用下面的函数,但不确定它是否总是安全的.是吗?没有DOM-内存或“残余XSLT”在那里?

代码语言:javascript
复制
   function XSLproc_reuse($domXsl) {
      static $XSLproc=NULL;
      if (!$XSLproc)
           $XSLproc = new XSLTProcessor();
      return $XSLproc->importStylesheet($domXsl); // STABLE?
   }

未来对它没有“意外副作用”?

PS:我的XSLT处理有一些奇怪的错误.因此,在这里张贴一个(许多其他的)假设,以检查是否确定或必须避免。这个在XPath中更明显,请参见另一个相关问题

另一种方法是重用更多的处理表(我在库中使用的),也可以重用导入的XSLT:

代码语言:javascript
复制
   function XSLproc_reuse2($nameOrDomXsl='', $domXsl=NULL) {
      static $XSLproc=NULL;
      static $name='';

      if (!$XSLproc)
                $XSLproc = new XSLTProcessor();
      // else reune of the already initialized $XSLproc.

      if (is_object($nameOrDomXsl))
                return $XSLproc->importStylesheet($nameOrDomXsl); // STABLE?
      elseif ($nameOrDomXsl==$name);
                return $XSLproc;  // imported in the last call, STABLE?
      else { // recording for future reuse:
                $name = $nameOrDomXsl;
                return $XSLproc->importStylesheet($domXsl);
      }
   }
EN

回答 2

Stack Overflow用户

发布于 2013-11-20 09:25:37

要理解这个问题,了解XSLTProcessor如何在内部存储数据以及调用XSLTProcessor::importStylesheet后发生了什么非常重要。实现该类的代码位于php源代码的\ext\xsl\xsltprocessor.c中。

这个解释必须简化一些--用纯php 'c‘编写。php对象中的内容--就с而言,函数只是在全局上下文中操作。

Web需要了解如何以及如何处理导入的数据:

  1. XSLTProcessor::accept样式表接受DOMDocumentSimpleXMLElement的对象。
  2. 导入发生的第一件事(从409行源,docp是一个importStylesheet参数) // php _libxml_import_node (在\ext\libxml\libxml.c中)只是通过php对象指针获取//实际的xmlNodePtr XMLlib2对象指针。nodep = php_libxml_import_node(docp TSRMLS_CC);if (nodep) { doc = nodep->doc;} if (doc == NULL) { php_error(E_WARNING,“无效文档”);RETURN_FALSE;} //Next是xmlCopyDoc的原始注释和调用,生成样式表的复制//。我回答的主要内容。/* libxslt使用_private,所以我们必须复制导入的样式表文档,否则节点代理将变得一团糟*/ newdoc = xmlCopyDoc(doc,1);.//在这里,我们使用libxslt函数创建内部样式表对象。 sheetp = xsltParseStylesheetDoc(newdoc); ..。 //之后,一些行将它们存储到//XSLTProcessor类实例的内部变量中。php_xsl_set_object(id,sheetp TSRMLS_CC);
  3. importStylesheet之后,您可以使用$stylesheet对象做任何您想做的事情--它不影响XSLTProcessor的工作,因为它使用$stylesheet的副本。但是,如果不再次调用$stylesheet,您就不能刷新或更新importStylesheet

XSLTProcessor::transformToDoc (php_xsl_apply_stylesheet -从477行相同来源)和其他transform方法是什么?它们中的每一个都分配它们的输出类型(在XSLTProcessor::transformToDoc情况下为XSLTProcessor::transformToDoc),并使用内部sheetp对象(在importStylesheet中创建)来转换数据。

在评论后编辑

  1. 关于“什么时候”和/或“为什么”重用无效的条件的一些词语。重用是有效的,每次您需要多次使用transformTo时都推荐使用transformTo。如果样式表在大型样式表上使用xsl:key,则应该重用,因为需要额外的XML节点遍历。
  2. 缓存仅仅是XSLTProcessor对象没有任何意义-这个对象的构造器不分配任何东西。XSLproc_reuse2是有意义的,应该被使用。您可以在$stylesheet使用中缓存xsl:key复制和遍历过程。不是指针,而是所有的对象及其内部。

s some more words about how the转换文档工作:

  1. 分配新的DOMDocument对象。
  2. 如果$stylesheet有xsl:key,它会复制您的$doc参数。
  3. xsltNewTransformContextxsltApplyStylesheetUserlibxslt制作缆车。
  4. 返回DOMDocument

XSLTProcessorlibxslt中没有任何惩罚代码,其中XSLTProcessor重用错误。在使用xslcache 0.7.2之前,我尝试使用这个项目,并将其调优到使用out站点。这是我的经验。当时,我们使用XSLT作为模板引擎,并使用大型XSLT模板(在3~5MB的简化代码中)。在这种情况下,importStylesheet的缓存具有很大的性能提升。但是没有任何机会缓存transformToDoc结果--每次您称之为它时,libxslt使用内存中的两个已准备好的对象进行dom操作,并给出新对象作为结果。

票数 1
EN

Stack Overflow用户

发布于 2013-11-21 21:58:56

使用静态定义全局状态,即定义为“不稳定”。它可以从程序中的任何地方更改。使用对象可以获得一个本地状态(在对象实例中)。我也建议使用数组。这样它就可以为不同的文件存储多个处理器。

代码语言:javascript
复制
class XsltFactory {

  private $_processors = array();

  public function get($file) {
    if (!isset($this->_processors[$file])) {
      $xslDom = new DOMDocument();
      $xslDom->load($file);
      $xslProc = new XSLTProcessor();
      $xslProc->importStylesheet($xslDom);
      return $this->_processors[$file] = $xslProc;
    }
    return $this->_processors[$file];
  }
}

$xsltFactory = new XsltFactory();
var_dump(
  htmlspecialchars(
    $xsltFactory->get($template)->transformToDoc($xmlDom)->saveXml()
  )
);

提高性能的一个更好的解决方案是xslcache。它在进程中缓存$xslt->importStyleSheet($filename)的结果。如果进程被重用,那么编译的xsl也是如此。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18086094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档