提问



实际上我想读取搜索查询后的内容,完成后。问题是URL只接受POST方法,并且它不采用GET方法的任何操作......


我必须在domdocumentfile_get_contents()的帮助下阅读所有内容。是否有任何方法可以让我用POST方法发送参数,然后通过PHP读取内容?

最佳参考


PHP5的CURL-less方法:


$url = 'http://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');

// use key 'http' even if you send the request to https://...
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    )
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }

var_dump($result);


有关该方法以及如何添加标头的更多信息,请参阅PHP手册,例如:



  • stream_context_create :http://php.net/manual/en/function.stream-context-create.php


其它参考1


我确实尝试了这个并且工作正常......正如我所要求的那样.. [28]


<?php
$url = $file_name;
$fields = array(
            '__VIEWSTATE'=>urlencode($state),
            '__EVENTVALIDATION'=>urlencode($valid),
            'btnSubmit'=>urlencode('Submit')
        );

//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
$fields_string = rtrim($fields_string,'&');

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

//execute post
$result = curl_exec($ch);
print $result;
?>

其它参考2


我使用以下函数使用curl发布数据。 $ data是要发布的字段数组(将使用http_build_query正确编码)。使用application/x-www-form-urlencoded编码数据。


function httpPost($url, $data)
{
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($curl);
    curl_close($curl);
    return $response;
}


@Edward提到可以省略http_build_query,因为curl将正确编码传递给CURLOPT_POSTFIELDS参数的数组,但是请注意,在这种情况下,数据将使用multipart/form-data进行编码。


我将此函数与API一起使用,期望使用application/x-www-form-urlencoded编码数据。这就是我使用http_build_query()的原因。

其它参考3


我建议你使用经过完全单元测试的开源软件包,并使用最新的编码方法。[29]


安装Guzzle


转到项目文件夹中的命令行,然后键入以下命令(假设您已经安装了包管理器编写器)。如果您需要有关如何安装Composer的帮助,请查看此处。[30]


php composer.phar require guzzlehttp/guzzle


使用Guzzle发送POST请求


Guzzle的使用非常简单,因为它使用了轻量级的面向对象的API:


// Initialize Guzzle client
$client = new GuzzleHttp\Client();

// Create a POST request
$response = $client->request(
    'POST',
    'http://example.org/',
    [
        'form_params' => [
            'key1' => 'value1',
            'key2' => 'value2'
        ]
    ]
);

// Parse the response object, e.g. read the headers, body, etc.
$headers = $response->getHeaders();
$body = $response->getBody();

// Output headers and body for debugging purposes
var_dump($headers, $body);

其它参考4


如果你这样做,还有另一种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。

其它参考5


如果您有任何机会使用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文档。[32]


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


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

// ... your code


它不会显示任何主题或输出任何HTML,只是破解Wordpress API!

其它参考6


我想补充一些关于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;
    }
}


改进




  • 使用http_build_query从请求数组中获取查询字符串。(您也可以使用数组本身,因此请参阅:http://php.net/manual/en/function.curl-setopt.php)

  • 返回响应而不是回显它。顺便说一句,你可以通过删除行 curl_setopt($ ch,CURLOPT_RETURNTRANSFER,true); 来避免返回。之后返回值是一个布尔值(true =请求成功,否则发生错误)并回显响应。
    请参阅:http://php.net/en/manual/function.curl-exec.php

  • 使用 curl_close 清除会话结束和删除卷曲处理程序。请参阅:http://php.net/manual/en/function.curl-close.php

  • 使用 curl_setopt 函数的布尔值而不是使用任何数字。(我知道任何不等于零的数字也被视为true,但使用true会生成更易读的代码,但是那只是我的意见)

  • 能够进行HTTP-PUT/DELETE调用(对RESTful服务测试很有用)



使用示例



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"));


DELETE



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


测试



您也可以使用这个简单的类进行一些很酷的服务测试。[33] [34] [35]


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}]');
    }
}

其它参考7


我一直在寻找类似的问题,并找到了更好的方法。所以这就是它。


您只需将以下行放在重定向页面上(例如page1.php)即可。


header("Location: URL", TRUE, 307); // Replace URL with to be redirected URL, e.g. final.php


我需要这个来重定向REST API调用的POST请求。此解决方案能够使用发布数据以及自定义标头值重定向。[36]


这是参考链接。[37]

其它参考8


上面 curl-less 方法的另一个替代方法是使用本机流函数:



  • stream_context_create():


      使用 options 预设中提供的任何选项创建并返回流上下文。[39]


  • stream_get_contents():


      与file_get_contents()相同,除了stream_get_contents() 对已经打开的流资源进行操作并返回字符串中的剩余内容,最多为 maxlength 字节,从指定的偏移开始。[40] [41]




这些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) {
    fclose($fp);
    return json_encode(['error' => 'Failed to get contents...']);
  }
  $result = stream_get_contents($fp); // no maxlength/offset
  fclose($fp);
  return $result;
}

其它参考9


还有一个你可以使用


<?php
$fields = array(
    'name' => 'mike',
    'pass' => 'se_ret'
);
$files = array(
    array(
        'name' => 'uimg',
        'type' => 'image/jpeg',
        'file' => './profile.jpg',
    )
);

$response = http_post_fields("http://www.example.com/", $fields, $files);
?>


点击此处了解详情[42]

其它参考10


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


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