实际上,我想读取搜索查询之后的内容,当它完成时。问题是URL只接受POST方法,它不采取任何行动与GET方法…

我必须在domdocument或file_get_contents()的帮助下读取所有内容。有没有什么方法可以让我用POST方法发送参数,然后通过PHP读取内容?


当前回答

上面的无卷曲方法的另一种替代方法是使用本机流函数:

stream_context_create (): 创建并返回带有options预置中提供的任何选项的流上下文。 stream_get_contents (): 与file_get_contents()相同,不同之处在于stream_get_contents()操作的是已经打开的流资源,并以字符串形式返回剩余内容,最大长度为maxlength字节,从指定的偏移量开始。

具有这些功能的POST函数可以简单地像这样:

<?php

function post_request($url, array $params) {
  $query_content = http_build_query($params);
  $fp = fopen($url, 'r', FALSE, // do not use_include_path
    stream_context_create([
    'http' => [
      'header'  => [ // header array does not need '\r\n'
        'Content-type: application/x-www-form-urlencoded',
        'Content-Length: ' . strlen($query_content)
      ],
      'method'  => 'POST',
      'content' => $query_content
    ]
  ]));
  if ($fp === FALSE) {
    return json_encode(['error' => 'Failed to get contents...']);
  }
  $result = stream_get_contents($fp); // no maxlength/offset
  fclose($fp);
  return $result;
}

其他回答

如果你这样做的话,还有另一个CURL方法。

一旦您了解了PHP curl扩展的工作方式,将各种标志与setopt()调用结合起来,这就非常简单了。在这个例子中,我有一个变量$xml,它保存了我准备发送的xml -我将把它的内容发布到示例的测试方法。

$url = 'http://api.example.com/services/xmlrpc/';
$ch = curl_init($url);

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
//process $response

首先初始化连接,然后使用setopt()设置一些选项。它们告诉PHP我们正在发出post请求,并且我们正在发送一些数据,提供数据。CURLOPT_RETURNTRANSFER标志告诉curl将输出作为curl_exec的返回值而不是输出。然后我们进行调用并关闭连接-结果显示在$response中。

尝试PEAR的HTTP_Request2包来轻松地发送POST请求。或者,您可以使用PHP的curl函数或使用PHP流上下文。

HTTP_Request2还使模拟服务器成为可能,因此您可以轻松地对代码进行单元测试

我更喜欢这个:

function curlPost($url, $data = NULL, $headers = []) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5); //timeout in seconds
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_ENCODING, 'identity');

    
    if (!empty($data)) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    if (!empty($headers)) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }

    $response = curl_exec($ch);
    if (curl_error($ch)) {
        trigger_error('Curl Error:' . curl_error($ch));
    }

    curl_close($ch);
    return $response;
}

使用的例子:

$response=curlPost("http://my.url.com", ["myField1"=>"myValue1"], ["myFitstHeaderName"=>"myFirstHeaderValue"]);

如果你碰巧使用Wordpress来开发你的应用(它实际上是一种获得授权、信息页面等非常简单的东西的方便方式),你可以使用下面的代码片段:

$response = wp_remote_post( $url, array('body' => $parameters));

if ( is_wp_error( $response ) ) {
    // $response->get_error_message()
} else {
    // $response['body']
}

它使用不同的方式来发出实际的HTTP请求,这取决于web服务器上可用的内容。有关更多详细信息,请参阅HTTP API文档。

如果你不想开发一个自定义主题或插件来启动Wordpress引擎,你可以在Wordpress根目录下的一个单独的PHP文件中执行以下操作:

require_once( dirname(__FILE__) . '/wp-load.php' );

// ... your code

它不会显示任何主题或输出任何HTML,只是hack away Wordpress api !

我想补充一些关于Fred Tanrikut基于卷曲的回答的想法。我知道大部分问题已经写在上面的答案中,但我认为给出一个包括所有问题的答案是个好主意。

下面是我编写的基于curl进行HTTP-GET/POST/PUT/DELETE请求的类,只涉及响应体:

class HTTPRequester {
    /**
     * @description Make HTTP-GET call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPGet($url, array $params) {
        $query = http_build_query($params); 
        $ch    = curl_init($url.'?'.$query);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-POST call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPost($url, array $params) {
        $query = http_build_query($params);
        $ch    = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-PUT call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPut($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'PUT');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
    /**
     * @category Make HTTP-DELETE call
     * @param    $url
     * @param    array $params
     * @return   HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPDelete($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
}

改进

Using http_build_query to get the query-string out of an request-array.(you could also use the array itself, therefore see: http://php.net/manual/en/function.curl-setopt.php) Returning the response instead of echoing it. Btw you can avoid the returning by removing the line curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);. After that the return value is a boolean(true = request was successful otherwise an error occured) and the response is echoed. See: http://php.net/en/manual/function.curl-exec.php Clean session closing and deletion of the curl-handler by using curl_close. See: http://php.net/manual/en/function.curl-close.php Using boolean values for the curl_setopt function instead of using any number.(I know that any number not equal zero is also considered as true, but the usage of true generates a more readable code, but that's just my opinion) Ability to make HTTP-PUT/DELETE calls(useful for RESTful service testing)

用法示例

GET

$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));

POST

$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));

PUT

$response = HTTPRequester::HTTPPut("http://localhost/service/foobar.php", array("putParam" => "foobar"));

删除

$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));

测试

您还可以通过使用这个简单的类来进行一些很酷的服务测试。

class HTTPRequesterCase extends TestCase {
    /**
     * @description test static method HTTPGet
     */
    public function testHTTPGet() {
        $requestArr = array("getLicenses" => 1);
        $url        = "http://localhost/project/req/licenseService.php";
        $this->assertEquals(HTTPRequester::HTTPGet($url, $requestArr), '[{"error":false,"val":["NONE","AGPL","GPLv3"]}]');
    }
    /**
     * @description test static method HTTPPost
     */
    public function testHTTPPost() {
        $requestArr = array("addPerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPost($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPPut
     */
    public function testHTTPPut() {
        $requestArr = array("updatePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPut($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPDelete
     */
    public function testHTTPDelete() {
        $requestArr = array("deletePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPDelete($url, $requestArr), '[{"error":false}]');
    }
}