702

Actually I want to read the contents that come after the search query, when it is done. The problem is that the URL only accepts POST methods, and it does not take any action with GET method...

I have to read all contents with the help of domdocument or file_get_contents(). Is there any method that will let me send parameters with POST method and then read the contents via PHP?

Gui Imamura
  • 536
  • 8
  • 25
Fred Tanrikut
  • 8,681
  • 4
  • 15
  • 7

15 Answers15

1328

CURL-less method with PHP5:

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

See the PHP manual for more information on the method and how to add headers, for example:

maraca
  • 7,323
  • 3
  • 20
  • 41
dbau
  • 14,839
  • 2
  • 19
  • 31
  • 67
    It's worth noting that if you decide to use an array for the headers, do NOT end the keys or values with '\r\n'. stream_context_create() will only take the text up to the first '\r\n' – raptor May 23 '13 at 14:58
  • 12
    A URL can be used as a filename with `file_get_contents()` only if the fopen wrappers have been enabled. See http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen – Pino Nov 27 '13 at 14:05
  • 4
    @I love `file_get_contents()` – deadlock Dec 01 '13 at 13:05
  • 1
    I tried this but I got back the whole contents of the file :( – Robert Johnstone Jul 24 '15 at 13:14
  • 14
    Is there a specific reason for not using CURL? – JacobF Aug 31 '15 at 14:54
  • 1
    The main reason for me is that `file_get_contents()` is way more intuitive than CURL. – kalvn Nov 23 '15 at 10:49
  • 42
    @jvannistelrooy CURL for PHP is an extension which may not exist in all environments whereas `file_get_contents()` is part of PHP's core. Also, using an extension unnecessarily can widen the attack surface of your app. E.g. Google [php curl cve](https://www.google.com/search?q=php+curl+cve) – Pocketsand Oct 12 '16 at 07:54
  • Note, you can't make a raw post request with this. – Goose Dec 01 '16 at 16:30
  • 2
    For this code also, my localhost sending GET method. Please tell how to enable POST – Sri P Dec 13 '16 at 07:14
  • Is there a way to use this native PHP method yet save the response into a file as a stream instead of reading the entire thing into memory? I know Guzzle can do it but I prefer a native solution. – GGGforce Apr 19 '17 at 09:47
  • 1
    Apparently there is by using `fopen` instead of `file_get_contents` and then using `fread` on the url and `fwrite` to the dump file. – GGGforce Apr 19 '17 at 10:06
  • 3
    bool(false) i get?? – Miomir Dancevic Aug 30 '17 at 07:50
  • @GGGforce Yes, [php.net has this example](http://php.net/manual/en/function.fread.php#example-2870): `$fp = fopen($url, ...); $contents= stream_get_contents($fp);` I.e. you don't even need `fread`. – CPHPython Apr 20 '18 at 09:41
  • Are there any changes / enhancements to this if using PHP 7.x? – Neal Davis Oct 28 '18 at 19:45
  • 1
    Sorry for spamming but YOU ARE A LIFE SAVER. I was trying to fix a bunch of errors for the last 5 hours and with this I eliminated them all at once. THANK YOU!!! – Theofanis Mar 12 '19 at 14:47
  • 1
    One thing to note: if you are sending the POST request body as JSON: for the header, use `Content-Type: application/json`; for content, use `json_encode` instead of `http_build_query`: `json_encode($data)`. – mannykary Sep 20 '19 at 04:20
  • In order to use the described method of error handling `if ($result === FALSE) { /* Handle error */ }` one needs to take care of the PHP Warning error that happens on non-200 responses. See https://stackoverflow.com/questions/272361/how-can-i-handle-the-warning-of-file-get-contents-function-in-php I also recommend looking into the `$http_response_header` magic global variable to make `file_get_contents` a full HTTP client. – Tilman May 03 '20 at 23:57
  • @Tilman to avoid those issues (including `file_get_contents`), you might prefer a combo of other native **stream** functions. I wrote [an alternative cURL-less answer](https://stackoverflow.com/a/49939132/6225838) about them in this same thread. – CPHPython May 10 '20 at 21:28
  • @Goose You can make a raw post request. You don't have to set the Content-Type to urlencoded and use http_build_query, but instead provide a different Content-Type and the raw content as a string (may contain binary data). – Benedikt M. May 20 '21 at 20:42
160

You could use cURL:

<?php
//The url you wish to send the POST request to
$url = $file_name;

//The data you want to send via POST
$fields = [
    '__VIEWSTATE '      => $state,
    '__EVENTVALIDATION' => $valid,
    'btnSubmit'         => 'Submit'
];

//url-ify the data for the POST
$fields_string = http_build_query($fields);

//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, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);

//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); 

//execute post
$result = curl_exec($ch);
echo $result;
?>
YanDatsiuk
  • 1,355
  • 2
  • 15
  • 27
Fred Tanrikut
  • 8,681
  • 4
  • 15
  • 7
  • 3
    this one worked for me because the page I am sending to a page that has no content so the file_get_contents version didn't work. – CommentLuv Oct 27 '12 at 18:47
  • 10
    file_get_contents solution doesn't work on PHP configurations with allow_url_fopen Off (like in shared hosting). This version uses curl library and I think is most "universal" so I give you my vote – Dayron Gallardo Aug 26 '14 at 11:42
  • 93
    You didn't site where you copied this code sample from: http://davidwalsh.name/curl-post – efreed May 18 '15 at 18:06
  • 4
    Although it is not very important, the CURLOPT_POSTFIELDS parameter data actually doesn't need to be converted to a string ("urlified"). Quote: "This parameter can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data." Link: http://php.net/manual/en/function.curl-setopt.php. – Edward Mar 23 '16 at 16:00
  • 2
    Also, no offence for writing it differently, but I don't know why the CURLOPT_POST parameter is specified as a number here as it says to set it to a boolean on the manual page. Quote: "CURLOPT_POST: TRUE to do a regular HTTP POST." Link: http://php.net/manual/en/function.curl-setopt.php. – Edward Mar 23 '16 at 16:04
  • 1
    What is the purpose of doing `count($fields)`? Why not set it to 1? – Nubcake Mar 27 '17 at 17:32
  • Works just fina! – David Kariuki Jul 28 '19 at 14:41
75

I use the following function to post data using curl. $data is an array of fields to post (will be correctly encoded using http_build_query). The data is encoded using 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 mentions that http_build_query may be omitted since curl will correctly encode array passed to CURLOPT_POSTFIELDS parameter, but be advised that in this case the data will be encoded using multipart/form-data.

I use this function with APIs that expect data to be encoded using application/x-www-form-urlencoded. That's why I use http_build_query().

Dima L.
  • 2,945
  • 27
  • 27
  • Passing array to CURLOPT_POSTFIELDS causes data to be encoded using multipart/form-data which may not be desirable. – Dima L. Mar 25 '18 at 16:26
  • The user did ask for file_get_contents, so he needs a solution for changing the default_stream_context – Radon8472 Aug 01 '18 at 11:18
  • To clarify: I think @DimaL. is responding to a comment that has been deleted; `http_build_query` converts `$data` array to a string, avoiding output as multipart/form-data. – ToolmakerSteve Apr 24 '19 at 14:15
  • @Radon8472 - `... CURLOPT_RETURNTRANSFER, true` results in `$response` containing the contents. – ToolmakerSteve Apr 24 '19 at 14:33
  • @ToolmakerSteve as I said, the question was for `file_get_contents` and your solution needs CURL what many people dont have. so your solution is maybe working, but it is not answering the question how to do this with the native builtin file/stream functions. – Radon8472 Apr 26 '19 at 08:30
  • @Radon8472 - Thanks. But note: 1) it isn't my answer. 2) the question is `Is there any method that will let me send parameters with POST method and then read the contents via PHP` - file_get_contents is simply something that OP tried - he did not specify what should or should not be included in the solution. 3) Sorry if I misunderstood your comment - I responded to it because I thought you were saying that Dima's answer would not return the information needed. If that isn't what you were saying, then disregard my comment. 4) This much later, its all about what might help other people, not OP. – ToolmakerSteve Apr 26 '19 at 16:19
46

I recommend you to use the open-source package guzzle that is fully unit tested and uses the latest coding practices.

Installing Guzzle

Go to the command line in your project folder and type in the following command (assuming you already have the package manager composer installed). If you need help how to install Composer, you should have a look here.

php composer.phar require guzzlehttp/guzzle

Using Guzzle to send a POST request

The usage of Guzzle is very straight forward as it uses a light-weight object-oriented 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);
Community
  • 1
  • 1
Andreas
  • 2,565
  • 20
  • 30
  • 7
    It would be useful to know what advantages this has over the native PHP solution already posted, and the cURL one too. – artfulrobot Dec 06 '16 at 11:01
  • 12
    @artfulrobot: The native PHP-solution has lots of problems (e.g. connecting with https, certificate verification, etc.pp.), which is why almost every PHP developer uses cURL. And why not use cURL in this case? It's simple: Guzzle has a straight-forward, easy, light-weight interface which abstracts all those "low-level cURL handling problems" away. Almost everyone developing modern PHP uses Composer anyway, so using Guzzle is just really simple. – Andreas Dec 06 '16 at 11:47
  • 2
    Thanks, I know guzzle is popular, however there are use cases when composer causes grief (e.g. developing plugins for bigger software projects that might already use a (different version) of guzzle or other dependencies), so it's good to know this info to make a decision about which solution will be most robust – artfulrobot Dec 06 '16 at 11:53
  • 1
    @Andreas while you are right, this is a good example of more and more abstraction leading to less and less understanding of low-level technology thus leading to more and more devs not knowing what they are doing there anyway and not beeing able to debug even a simple request. – clockw0rk Aug 17 '20 at 13:22
  • 1
    @clockw0rk Unfortunately, you're right about that. But still abstraction (to some extent) is useful and saves a lot of time and mistakes / potential bugs. Obviously, everyone using Guzzle should still be able to debug requests and also have a basic understanding of networking and how HTTP works. – Andreas Aug 19 '20 at 07:00
29

I'd like to add some thoughts about the curl-based answer of Fred Tanrikut. I know most of them are already written in the answers above, but I think it is a good idea to show an answer that includes all of them together.

Here is the class I wrote to make HTTP-GET/POST/PUT/DELETE requests based on curl, concerning just about the response body:

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;
    }
}

Improvements

  • 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)

Example of usage

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

Testing

You can also make some cool service tests by using this simple class.

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}]');
    }
}
mwatzer
  • 746
  • 1
  • 9
  • 11
  • For me, it says *"Uncaught Error: Call to undefined method HTTPRequester::HTTPost()"*. I have simply pasted your class into my .php file. Anything else I need to do? – LinusGeffarth Feb 04 '18 at 18:54
  • 1
    Can you please post your code? It's pretty hard to guess what's wrong without any code snippet. – mwatzer Feb 13 '18 at 23:52
  • As I said, I've literally copied yours into my plain php file and it gave me this error. – LinusGeffarth Feb 14 '18 at 01:27
  • Ok I tested the code five mintues ago ... it worked fine. I just copied the content into a new file, and added the lines $var = HTTPRequester::HTTPPost('some http url', array()); var_dump($var); and as I expected the call was working... Have you enabled the curl extension? If you run ubuntu or debian for example you have to make sure that the **php-curl** extension is installed – mwatzer Feb 14 '18 at 02:01
  • 1
    Ok now I see the issue,.. it was wrong in the example! You have to call HTTPRequester::HTTPPost() instead of HTTPRequester::HTTPost() – mwatzer Mar 06 '18 at 08:59
  • 1
    Ah. That one's easy to miss. I had to read your comment like 5x before I spotted the extra *P*. Thanks! – LinusGeffarth Mar 06 '18 at 09:24
  • This solves my problem on 403 forbidden error on using file_get_contents. Cheers! – Jomar Gregorio Jun 23 '18 at 06:22
25

There's another CURL method if you are going that way.

This is pretty straightforward once you get your head around the way the PHP curl extension works, combining various flags with setopt() calls. In this example I've got a variable $xml which holds the XML I have prepared to send - I'm going to post the contents of that to example's test method.

$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

First we initialised the connection, then we set some options using setopt(). These tell PHP that we are making a post request, and that we are sending some data with it, supplying the data. The CURLOPT_RETURNTRANSFER flag tells curl to give us the output as the return value of curl_exec rather than outputting it. Then we make the call and close the connection - the result is in $response.

Community
  • 1
  • 1
Josip Ivic
  • 3,431
  • 8
  • 36
  • 54
24

If you by any chance are using Wordpress to develop your app (it's actually a convenient way to get authorization, info pages etc even for very simple stuff), you can use the following snippet:

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

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

It uses different ways of making the actual HTTP request, depending on what is available on the web server. For more details, see the HTTP API documentation.

If you don't want to develop a custom theme or plugin to start the Wordpress engine, you can just do the following in an isolated PHP file in the wordpress root:

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

// ... your code

It won't show any theme or output any HTML, just hack away with the Wordpress APIs!

24

Another alternative of the curl-less method above is to use the native stream functions:

  • stream_context_create():

    Creates and returns a stream context with any options supplied in options preset.

  • stream_get_contents():

    Identical to file_get_contents(), except that stream_get_contents() operates on an already open stream resource and returns the remaining contents in a string, up to maxlength bytes and starting at the specified offset.

A POST function with these can simply be like this:

<?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;
}
CPHPython
  • 6,842
  • 2
  • 41
  • 58
  • 1
    This CURL-less method worked fine for me to validate reCAPTCHA from google. This answer converges with this google code: https://github.com/google/recaptcha/blob/master/src/ReCaptcha/RequestMethod/Post.php – Xavi Montero Oct 12 '18 at 16:41
  • 1
    You don't have to use `fclose()` if `$fp` is `false`. Because `fclose()` expects a resource is parameter. – Floris Dec 03 '19 at 15:44
  • 1
    @Floris Edited it just now and indeed the [*fclose* docs](https://www.php.net/manual/en/function.fclose.php) mentions "The file pointer must be valid". Thank you for noticing that! – CPHPython Dec 03 '19 at 16:54
  • 1
    I tried this, and I wasn't able to parse the 'post' data within my api.. I am using json_decode(file_get_contents("php://input"))) Any ideas?; Edit: By changing the content type header to application/json, it worked. Thanks! – obey Dec 29 '20 at 15:55
13

Here is using just one command without cURL. Super simple.

echo file_get_contents('https://www.server.com', false, stream_context_create([
    'http' => [
        'method' => 'POST',
        'header'  => "Content-type: application/x-www-form-urlencoded",
        'content' => http_build_query([
            'key1' => 'Hello world!', 'key2' => 'second value'
        ])
    ]
]));
Liga
  • 2,298
  • 3
  • 21
  • 34
11

The better way of sending GET or POST requests with PHP is as below:

<?php
    $r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
    $r->setOptions(array('cookies' => array('lang' => 'de')));
    $r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));

    try {
        echo $r->send()->getBody();
    } catch (HttpException $ex) {
        echo $ex;
    }
?>

The code is taken from official documentation here http://docs.php.net/manual/da/httprequest.send.php

Imran Zahoor
  • 1,732
  • 1
  • 21
  • 27
5

I was looking for a similar problem and found a better approach of doing this. So here it goes.

You can simply put the following line on the redirection page (say page1.php).

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

I need this to redirect POST requests for REST API calls. This solution is able to redirect with post data as well as custom header values.

Here is the reference link.

Arindam Nayak
  • 7,138
  • 4
  • 28
  • 45
  • 1
    This answers how to *redirect a page request* not *How do I send a POST request with PHP?* Sure this would forward any POST parameters but that is not at all the same thing – Wesley Smith Nov 04 '16 at 01:46
  • @DelightedD0D, Sorry I did not get the difference between `redirect a page request with POST param` vs `send POST request`. For me purpose of both is same, correct me if I am wrong. – Arindam Nayak Nov 04 '16 at 07:00
  • 1
    *Is there any method that will let me send parameters with POST method and then read the contents via PHP?* The OP wants thier php script to construct a set of POST parameters and send them to another php page and for their script to receive the output from that page . This solution would simply accept an already POSTed set of values and forward them to another page. They are pretty different. – Wesley Smith Nov 04 '16 at 07:48
4

[Edit]: Please ignore, not available in php now.

There is one more which you can use

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

Click here for details

Code
  • 1,248
  • 2
  • 21
  • 34
3

Try PEAR's HTTP_Request2 package to easily send POST requests. Alternatively, you can use PHP's curl functions or use a PHP stream context.

HTTP_Request2 also makes it possible to mock out the server, so you can unit-test your code easily

cweiske
  • 27,869
  • 13
  • 115
  • 180
2

Based on the main answer, here is what I use:

function do_post($url, $params) {
    $options = array(
        'http' => array(
            'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
            'method'  => 'POST',
            'content' => $params
        )
    );
    $result = file_get_contents($url, false, stream_context_create($options));
}

Example usage:

do_post('https://www.google-analytics.com/collect', 'v=1&t=pageview&tid=UA-xxxxxxx-xx&cid=abcdef...');
Basj
  • 29,668
  • 65
  • 241
  • 451
  • Hi Basj. I don't understand. I tried your example & it didn't work for me. Could you please show a usage for some URL like `https://jsonplaceholder.typicode.com/todos/1`? Thanks in advance – Love and peace - Joe Codeswell Jan 18 '21 at 21:12
0

I prefer this one:

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;
}

Usage example:

$response=curlPost("http://my.url.com", ["myField1"=>"myValue1"], ["myFitstHeaderName"=>"myFirstHeaderValue"]);
MSS
  • 2,820
  • 20
  • 25