php – 如何在CURL请求中为XPLAN API构建edai.Search方法的第三个参数?

前端之家收集整理的这篇文章主要介绍了php – 如何在CURL请求中为XPLAN API构建edai.Search方法的第三个参数?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试在API上运行搜索,该API要求我的查询数据被设置为嵌套在 XML请求中的 XML.我将发布我的整个课程和方法调用(我发送给iress技术支持),以便可以对其进行全面审核,并且在任何人都可以访问相同API的情况下,他们可以立即为自己重现问题.
class XMLCurler
{
    private $username = '[redacted]';
    private $password = '[redacted]';
    private $url = 'https://[redacted].xplan.iress.com.au/RPC2/';
    public $ch;     // the curl handle
    public $token;  
    public $results;

    public function __construct() {
        if ($this->connect()) {
            if ($this->login()) {
                echo "<div class=\"success\">Successful Connection & Login. Token: {$this->token}</div>";
            }
        }
    }

    public function __destruct() {
        if ($this->ch) {
            $this->disconnect();
        }
    }

    public function connect() {
        if (!$this->ch = curl_init($this->url)) { // generate curl handle
            echo "<div class=\"error\">CURL Error While Connecting (check url)";
            return false;
        }
        return true;
    }

    public function disconnect() {
        curl_close($this->ch);
    }

    public function processResponse($response) {
        if (!$response) {
            echo "<div class=\"error\">CURL Error While Attempting to Login - No XML token string<br><b>",curl_error($this->ch),"</b></div>";
            return false;
        }
        $decoded = xmlrpc_decode($response);
        if (is_array($decoded) && xmlrpc_is_fault($decoded)) {
            echo "<div class=\"error\">Error Response: {$decoded['faultString']} ({$decoded['faultCode']})</div>";
            return false;
        }
        return $decoded;    
    }

    public function login() {
        $postfields = xmlrpc_encode_request('edai.Login',array($this->username,$this->password));  // package as xml
        curl_setopt($this->ch,CURLOPT_HTTPHEADER,array('Content-Type: text/xml'));
        curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($this->ch,CURLOPT_POSTFIELDS,$postfields);
        curl_setopt($this->ch,CURLOPT_SSL_VERIFYHOST,0);      // not advised,I need to find out how to avoid this
        curl_setopt($this->ch,CURLOPT_SSL_VERIFYPEER,I need to find out how to avoid this

        if (!$token = $this->processResponse(curl_exec($this->ch))) {
            return false;
        }
        if (!preg_match("~^[\w+]{20}$~",$token)) {
            echo "<div class=\"error\">Invalid/Unexpected Token Generated<br><b>$token</b>";
            return false;
        }
        $this->token = $token;  // cache the valid token
        return true;
    }

    public function listChildren($path) {
        $method = "edai.ListChildren";
        $request = xmlrpc_encode_request($method,array($this->token,$path));

        echo "<div class=\"notice\">XMLRPC Encoded Request (for $method): <pre>",htmlentities($request),"</pre></div>";

        curl_setopt($this->ch,$request);       
        if (!$results = $this->processResponse(curl_exec($this->ch))) {
            return false;
        }
        $this->results = $results;  // cache the valid results
        return true;
    }


    public function search($basepath,$queryxml) {
        $method = "edai.Search";

        /** Desperate/Manual xml construction ...
         * $xml = new DOMDocument("1.0","utf-8");
         * $xml->appendChild($methodCall = $xml->createElement("methodCall"));
         * $methodCall->appendChild($methodName = $xml->createElement("methodName"));
         * $methodCall->appendChild($params = $xml->createElement("params"));

         * $params->appendChild($param1 = $xml->createElement("param"));
         * $param1->appendChild($value1 = $xml->createElement("value"));
         * $value1->appendChild($string1 = $xml->createElement("string"));

         * $params->appendChild($param2 = $xml->createElement("param"));
         * $param2->appendChild($value2 = $xml->createElement("value"));
         * $value2->appendChild($string2 = $xml->createElement("string"));

         * $params->appendChild($param3 = $xml->createElement("param"));
         * $param3->appendChild($value3 = $xml->createElement("value"));
         * $value3->appendChild($string3 = $xml->createElement("string"));
         * $string3->appendChild($EntitySearch = $xml->createElement("EntitySearch"));
         * $EntitySearch->appendChild($SearchResult1 = $xml->createElement("SearchResult"));
         * $SearchResult1->setAttribute("field","first_name");

         * $EntitySearch->appendChild($SearchResult2 = $xml->createElement("SearchResult"));
         * $SearchResult2->setAttribute('field',"last_name");

         * $EntitySearch->appendChild($SearchQuick = $xml->createElement("SearchQuick"));
         * $SearchQuick->appendChild($s = $xml->createElement("s"));

         * $xpath = new DOMXPath($xml);
         * $result1 = $xpath->query("//methodName");
         * $result1->item(0)->nodeValue = $method;

         * $result2 = $xpath->query("//params/param[1]/value/string");
         * $result2->item(0)->nodeValue = $this->token;
         * $result3 = $xpath->query("//params/param[2]/value/string");
         * $result3->item(0)->nodeValue = "entitymgr/client";

         * $result4 = $xpath->query("//SearchQuick/s");
         * $result4->item(0)->nodeValue = "last_name:Smith";

         * $xml->formatOutput = true;
         * $request = $xml->saveXML();
         */

         /** Desperately attempted passing array ...
          * $queryarray = array(
          *     "EntitySearch" => array(
          *         array(
          *             "SearchResult" => array(
          *                 "@attr" => array(
          *             "field" => "first_name"
          *                 )
          *             )
          *         ),*             array(
          *             "SearchResult" => array(
          *                 "@attr" => array(
          *                     "field" => "last_name"
          *                 )
          *             )
          *         ),*         array(
          *             "SearchQuick" => array(
          *                 "s" => "last_name:Smith"
          *             )
          *         )
          *     )
          * );
          */

        $request = xmlrpc_encode_request($method,$basepath,$queryxml));  // this mutates the nested $queryxml string
            // Causes:
                //Error Response: UNKNOWN(CORBA.UNKNOWN(omniORB.UNKNOWN_PythonException,CORBA.COMPLETED_MAYBE)) (-32505)
        //$request = html_entity_decode($request);  // repair encoded entities
        //$request = preg_replace('~(?:>\K\s+)|(?:\s+(?=<))~','',$request);  // strip every whitespace character between tags (hack)
            // Causes:
                // Error Response: ExpatError(Syntax error: line 1,column 0 (byte 0)) (-32505)
        echo "<div class=\"notice\">XMLRPC Encoded Request (for $method): <pre>",$request);
        if (!$results = $this->processResponse(curl_exec($this->ch))) {
            return false;
        }
        $this->results = $results;  // cache the valid results
        return true;
    }
}

以下是我打电话的方式. edai.ListChildren起作用,因为我不必发送任何XML数据. edai.Search不起作用,因为我无法在XML请求中正确准备XML查询.

$XC = new XMLCurler();

/* edai.ListChildren works as desired/expected */
$path = "/entitymgr/client";
if ($XC->listChildren($path)) {
    echo "<div>List of Children Successful.<pre>";
    var_export($XC->results);
    echo "</pre></div>";
}

/* edai.Search does not work */
$basepath = "entitymgr/client";
$queryxml = <<<XML
<EntitySearch>
 <SearchResult field="first_name"/>
 <SearchResult field="last_name"/>
 <SearchQuick><s>last_name:Smith</s></SearchQuick>
</EntitySearch>
XML;
if ($XC->search($basepath,$queryxml)) {
    echo "<div>Search Successful.<pre>";
    var_export($XC->results);
    echo "</pre></div>";
}

这是the attempted request and error message.

这是the relevant portion of the manual I was provided (XPLAN XML-RPC EXTERNAL DATA ACCESS INTERFACE 7 May 2013)

我几周前联系了iress.com,他们叫我松散地确认我有权访问API,并告诉我他们已经联系了 – 跟进电话没有发生我会喜欢回到这个项目的工作.

我确实知道史密斯的姓氏与我的查询相符.

我没有Python经验,所以错误响应对我没有帮助.我做了比我发布的更多的冰雹尝试,但我厌倦了浪费我的时间.我不知道第三个参数是否要嵌套在< value>,< param>,< struct>,< string>,< array>,< xml>或其他内容中完全.

如果有人对如何为请求准备XML查询有任何建议,我将运行它们并提供反馈.

我也很高兴收到关于类设计,安全性问题以及完全不同的PHP方法的建议,以便让edai.Search返回一些有用的数据.

根据@ThW的要求,这里是xml尝试的集合及其各自的错误响应:https://pastebin.com/dYtwXWxz

在黑暗中拍摄,因为我无法直接测试API …

也许xmlrpc_encode_request调用可以使用命名参数:

$params = [
    'context' => $this->token,'basepath' => $basepath,// try with a leading slash,too,in spite of the docs listing it w/o one
    'queryxml' => $queryxml,];
$request = xmlrpc_encode_request($method,$params);  // this mutates the nested $queryxml string

如果这不起作用,请停止使用代码并安装SoapUIPostmanInsomnia或类似代码,并手动构建您的请求.

我怀疑你会在半小时内收到一份工作请求,并且可以向后工作以调试你的代码/重写你的代码.如果我可以访问API,我会为你做的.

要检查的事项:

>编码是否有所作为(应该是utf8而不是)?>需要将XML查询视为字符串,因此请确保在GUI客户端发出请求时将其编码/包装在CDATA标记中.根据您选择的客户端,可能会为您完成,只需确保完成

猜你在找的PHP相关文章