Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在对xplanapi的CURL请求中构造edai.Search方法的第三个参数?_Php_Xml_Curl - Fatal编程技术网

Php 如何在对xplanapi的CURL请求中构造edai.Search方法的第三个参数?

Php 如何在对xplanapi的CURL请求中构造edai.Search方法的第三个参数?,php,xml,curl,Php,Xml,Curl,我试图在一个API上运行搜索,该API要求将我的查询数据样式设置为嵌套在XML请求中的XML。我将发布我的整个类和方法调用(我将其发送给iress技术支持),以便对其进行全面审查,并且在任何人都有机会访问相同的API的情况下,他们可以立即为自己重现该问题 class XMLCurler { private $username = '[redacted]'; private $password = '[redacted]'; private $url = 'https://

我试图在一个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, 0);      // not advised, 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, CURLOPT_POSTFIELDS, $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, array($this->token, $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>" , htmlentities($request) , "</pre></div>";

        curl_setopt($this->ch, CURLOPT_POSTFIELDS, $request);
        if (!$results = $this->processResponse(curl_exec($this->ch))) {
            return false;
        }
        $this->results = $results;  // cache the valid results
        return true;
    }
}
"; } /*搜索不起作用*/ $basepath=“entitymgr/client”; $queryxml=结果); 回声“; } 这是

这是:

几周前,我联系了iress.com,他们打电话给我,松散地确认我有权访问API,并告诉我他们会联系的——后续电话还没有发生,我想继续这个项目

我确实知道,有一个姓
Smith
与我的查询相匹配


我没有Python经验,因此错误响应对我没有帮助。我做了比我发布的更多的hail mary尝试,但我厌倦了浪费时间。我不知道第三个参数是否应该嵌套在
一个黑暗中的快照中,因为我无法测试t他直接

xmlrpc_encode_请求调用可能与命名参数有关:

如果这不起作用,请停止乱搞代码,安装或类似的程序,并手动构造您的请求

我怀疑你会在半小时内收到一个工作请求,并且可以从中向后调试代码/重写代码。如果我有权访问API,我会为你这样做

检查事项:

  • 编码有区别吗(应该是utf8而不是utf8)

  • XML查询需要被视为字符串,因此当GUI客户端发出请求时,请确保它以编码/包装的CDATA标记结束。根据您选择的客户端的不同,它可能会为您完成,只需确保它已完成即可


不幸的是,在亲自与IRESS支持人员交谈并继续调查之后(尽管编写了一本手册说明如何与API集成),API的唯一许可用途是“使用东芝扫描仪上载文档”


为了获得访问权限,IRESS和该公司的法律团队需要在上述修订的url中起草新的许可证文件。这不太可能是一项快速的工作。

事实证明,错误不在我的php代码中(后来我进一步开发了该代码以更好地处理响应数据),而是我发送的xml查询

而不是使用文档建议的内容:

姓:史密斯
使用以下等效有效表达式:

史密斯
为了澄清这一点,我正在寻求php支持,但之所以包含python标记,是因为我的错误响应是用python编写的——请参阅类代码块底部附近的注释尝试和错误响应。我建议将其分解为一个带有静态XML的简单curl请求。这样,您就可以分析差异了。问题与t无关他是我的类的
search
方法。即使我在没有
xmlrpc\u encode\u request()
的情况下手动/静态地编写3参数xml,我也不知道正确的语法。我尝试了很多组合(我不想发布).无论如何,我会接受这个建议,尝试一些硬编码的尝试。@ThW我刚刚编辑了我的问题,将一批硬编码的xml字符串输入到curl中。每次尝试后都会立即出现错误响应。如果您有时间,请看一看。我很高兴提出任何其他逻辑建议。Python错误不是他的错lp发送给这里的任何人,因为我们无法访问服务器的源。它们总是意味着您的请求不符合预期的SOAP API方法调用预期。请尝试找到一个工作静态示例,然后从我刚才尝试的(以下多种组合)返回:键入元素(否),在基本路径后添加斜杠(否,无论如何,此值的使用之前是
$queryxml
上的语法错误),将硬编码/嵌套的queryxml字符串包装在
]>
(否)添加了
(否)感谢您提供的服务,但以上所有内容都没有用处。我现在不打算考虑安装其他软件——至少在API支持部门回复我说我的总体方法无法工作之前是这样(我相信经过一些调整后会这样)。做对你有用的事情,但安装额外的软件实际上是一项简化的工作,而不是一项复杂的工作。你仍然在部分地与代码搏斗,包括一个实验性的PHP函数。摆脱所有这些垃圾,只需发出几个简单的ol'HTTP请求,就可以帮助你找到前进的道路。在这一点上,我不是在寻找解决方案时使用实验性调用。在确定正确的语法后,我将调查函数是否阻碍了成功。
$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>";
}
$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
<SearchQuick><s>last_name:Smith</s></SearchQuick>
<SearchByField field="last_name" op="equal"><s>Smith</s></SearchByField>