1

PHP関数をXMLで記述できますか?

<doThis>

doThis(){
bang bang bang!
}

</doThis>

simplexml_load_fileそして、その関数でオブジェクトを取得するために使用しますか?

$foo = simplexml_load_file($xmlAbove);
$foo->doThis();   //bang bang bang!
4

2 に答える 2

3

まず、このような「コード」を実行することによるセキュリティへの影響を常に考慮する必要があります。この XML ファイルのオリジンがリモートである場合、コードを実行すると、何でも実行される可能性があります。どうexec(rm -fR /some/important/path);ですか?それとも、すべてを削除するデータベース呼び出しですか? 送信者とコードの間には非常に強力な信頼関係が必要であり、中間者攻撃やその他の攻撃を防ぐための強力なセキュリティ プロトコルも必要です。

ご質問には、直接は出来ません。コメントされているように、XML はコードではなくデータであり、移植可能であると想定されています。つまり、この XML を受け入れる別のクライアントにとって、PHP コードは無意味になります。

ただし、使用できますeval。多分このように:

eval($foo->doThis);

注:これはまったくお勧めしません。これは XML の本来の用途ではなく、多くの問題があります。どうか、別の方法を考えてください。

于 2013-02-15T05:47:03.323 に答える
2

XML は処理命令(PI)と呼ばれる埋め込みをサポートしています。有効な XML は次のようになります。

<doThis><?php
doThis()
{
   bang bang bang!
}    
?></doThis>

これは、PHP 言語で知っていることとよく似ています。ただし、サポートとは、そこに処理命令を入れることができるということだけを意味しますが、それらの命令の処理は XML の仕事ではありません。

また、使用する XML パーサー ( SimpleXML ) には、命令を処理するための専用サポートがありません。代わりにDOMDocumentを使用できます。XML側からは以上です。

PHP側では、代わりに関数を呼び出したいときに、何らかの方法で関数を定義するという問題があります。また、PHP コードは他の部分では無効です (おそらく、簡単な質問をまとめたからでしょう)。多分これはより良いです:

<doThis><?php
    function doThis()
    {
        return 'bang bang bang!';
    }
?></doThis>

小さな DOM ベースのパーサー (ここでは と呼びますPiDOMDocument) を使用すると、これをクラス/オブジェクトに変換できます。

$doc = new PiDOMDocument();
$doc->loadXML($xml);
$obj = $doc->getObject();
echo $obj->doThis();

echo最後の行の出力は次のとおりです。

bang bang bang!

(驚きを鎮める)。これを内部的に SimpleXMLElement にマップして、上記のサンプル コードに効率化することができます。

$foo = simplexml_load_string($xml, 'PiSimpleXMLElement');
echo $foo->doThis();   //bang bang bang!

これは次のように機能します。

/**
 * SimpleXMLElement integration of PiDOMDocument
 */
class PiSimpleXMLElement extends SimpleXMLElement
{
    public function __call($name, $args) {
        $doc = new PiDOMDocument();
        $doc->loadXML($this->asXML());
        $callback = array($doc->getObject(), $name);
        return call_user_func_array($callback, $args);
    }
}

PHP プロセッサとして、evalまたはinclude(どちらも基本的には同じです) を使用できます。PHP は直接実行されるため、コードに致命的な解析エラーがある場合、スクリプト全体に致命的なエラーが発生します。この PHP のデフォルトの動作が気に入らない場合は、そのようなエラーを評価する前に文字列を解析できます。同様token_get_all()に、この例も参照してください。またはこの例

オンライン デモ/サンプル コードevalでunvalidated を gist として選択しました。

于 2013-02-15T09:28:39.283 に答える