是否有任何方法可以在XSLTProcessor中传递或绑定Container对象并调用Service对象的方法。一些类似的东西。
XSLTProcessor::registerFunction(); //in php file.
在xslt样式表中
<xslt:value-of select="php:function('serviceobject::serviceObjectMethod',string($xsltProcessingVariable))"/>
在"普通"php代码中,您可以执行类似的操作
<?php
class Foo {
public function __construct($prefix) {
$this->prefix = $prefix;
}
public function myMethod($id) {
return sprintf('%s#%s', $this->prefix, $id);
}
}
$fooA = new Foo('A');
$fooB = new Foo('B');
echo call_user_func_array( array($fooA, 'myMethod'), array('id1') ), "rn";
echo call_user_func_array( array($fooB, 'myMethod'), array('id1') ), "rn";
也就是说,不是只给call_user_func_array
函数的名称,而是传递array($obj, 'methodName')
来调用实例方法
不幸的是,php:function(...)
似乎不起作用,我还没有找到另一种简单/干净的方法。
但是您可以在查找表string_id->object中注册您的对象,然后使用类似的东西
select="php:function('invoke', 'obj1', 'myMethod', string(@param1), string(@param2))"
在样式表中。function invoke($objectId, $methodName)
现在必须找到已在$objectId
下注册的对象,然后像前面的示例一样调用该方法
func_get_args()允许您检索传递给函数的所有参数,即使是那些没有在函数签名中声明的参数。切掉前两个元素(即$objectId和$methodName),并将剩余的数组作为参数传递给call_user_func_array。
独立示例:
<?php
class Foo {
public function __construct($prefix) {
$this->prefix = $prefix;
}
public function myMethod($id) {
return sprintf('%s#%s', $this->prefix, $id);
}
}
function invoke($objectId, $methodname)
{
static $lookup = array();
$args = func_get_args();
if ( is_null($methodname) ) {
$lookup[$objectId] = $args[2];
}
else {
$args = array_slice($args, 2);
return call_user_func_array( array($lookup[$objectId], $methodname), $args);
}
}
// second parameter null -> register object
// sorry, it's just a quick hack
// don't do this in production code, no one will remember after two weeks
invoke('obj1', null, new Foo('A'));
invoke('obj2', null, new Foo('B'));
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStyleSheet(new SimpleXMLElement( style() ));
echo $proc->transformToXML(new SimpleXMLElement( document() ));
function document() {
return <<<EOB
<doc>
<element id="id1" />
<element id="id2" />
</doc>
EOB;
}
function style() {
return <<<EOB
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
<xsl:output method="text"/>
<xsl:template match="element">
Obj1-<xsl:value-of select="php:function('invoke', 'obj1', 'myMethod', string(@id))"/>
|||
Obj2-<xsl:value-of select="php:function('invoke', 'obj2', 'myMethod', string(@id))"/>
</xsl:template>
</xsl:stylesheet>
EOB;
}
打印
Obj1-A#id1
|||
Obj2-B#id1
Obj1-A#id2
|||
Obj2-B#id2
顺便说一句:不要像我在这个例子中那样实现invoke()函数。我只是没能想出一个更好的方法来实现这个快速示例的register()/invoke()功能;-)