Php 在XSLTProcessor中传递容器对象

Php 在XSLTProcessor中传递容器对象,php,symfony,xslt,xslt-1.0,Php,Symfony,Xslt,Xslt 1.0,是否有任何方法可以传递或绑定容器对象并在XSLTProcessor中调用服务对象的方法。像这样的东西 XSLTProcessor::registerFunction(); //in php file. 在xsltStylesheet中 在“普通”php代码中,您可以执行以下操作 <?php class Foo { public function __construct($prefix) { $this->prefix = $prefix; }

是否有任何方法可以传递或绑定容器对象并在XSLTProcessor中调用服务对象的方法。像这样的东西

XSLTProcessor::registerFunction(); //in php file.
在xsltStylesheet中

在“普通”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') ), "\r\n";
echo call_user_func_array( array($fooB, 'myMethod'), array('id1') ), "\r\n";
在样式表中<代码>函数调用($objectId,$methodName)现在必须找到已在
$objectId
下注册的对象,然后像前面的示例一样调用该方法。
用于检索传递给函数的所有参数,即使是未在函数签名中声明的参数。切断前两个元素(即$objectId和$methodName),并将剩余数组作为参数传递给调用_user_func_数组

独立示例:

<?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;
}
顺便说一句:不要像我在本例中那样实现invoke()函数。我只是没能想出更好的方法来实现这个快速示例的register()/invoke()功能;-)

<?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