簡體   English   中英

從XSLT調用PHP非靜態成員函數

[英]Call a PHP non-static member function from XSLT

在PHP中,可以使用XSLTProcessor::registerPHPFunctions()允許從XSLT代碼中調用PHP函數,如下所示:

<xsl:copy-of select="php:function('myfunc', 'param1')/*" />

您也可以使用::表示法在對象上調用靜態成員函數:

<xsl:copy-of select="php:function('myclass::myfunc', 'param1')/*" />

但是,我想調用一個非靜態函數,該函數屬於啟動XSLT轉換的類。

如何在XSLT中使用php:function來調用PHP對象上的非靜態成員函數?

(我的意思是我該如何在XSLT中指定該對象,以及用什么語法指示要調用該對象的成員函數。)

不依賴於全局變量的解決方案將是首選!

好的,我想我已經解決了這個問題,但這有點狡猾。 歡迎其他答案。

以這個示例類為例:

class Example {
    protected $greet;
    public function __construct($g) {
        $this->greet = $g;
    }
    public function greeting($name) {
        return $this->greet . ' ' . $name;
    }
}

然后,您將需要以下幫助程序功能:

// Serialise the object and replace ASCII null characters with @NULL@
function xsltSerialize($object)
{
    return str_replace("\0", '@NULL@', serialize($object));
}

// Unserialise $object (of type $className) and call $func
function callMember($className, $object, $func, $param)
{
    $rf = new ReflectionMethod($className, $func);
    $o = unserialize(str_replace('@NULL@', "\0", $object));
    return $rf->invoke($o, $param);
}

然后,您可以像這樣使用它:

// This is the object that will get called from within the XSL.  Note
// that we are passing a parameter to the constructor which gets saved
// in the object instance, so we will know later whether we have the
// original object back again.
$e = new Example('Hello');

// Pass the object to the XSL code, after serialising it
$xsl->setParameter('', 'obj', xsltSerialize($e));

然后在XSLT中,調用PHP callMember()函數,提供類的原始名稱,序列化的對象,要調用的函數以及該函數的參數。

Output is
<xsl:value-of select="php:function('callMember', 'Example', $obj, 'greeting', 'everyone')"/>

最終結果是,在對象的正確實例上調用了成員函數:

Output is Hello everyone

單詞“ Hello”表明保留了在XSLT外部的構造函數中設置的值,“所有人”表明從XSLT傳入的參數也使其通過。

此方法有很多缺點:

  1. 先進行序列化再進行反序列化會浪費大量資源,並且如果進行過多次或在大型對象上執行,則會影響性能。
  2. 並非所有對象都可以序列化。
  3. 只能將固定數量的參數傳遞給該函數,因此對於不同數量的參數,您將需要不同版本的callMember()
  4. 由於序列化過程,XSLT調用將在對象的副本而非原始對象上進行操作。 因此,一旦函數返回,對對象所做的任何更改都會丟失。 (狀態甚至不會在對同一對象的兩次XSLT調用之間保留。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM