PHP set multipart or form data - php

I am trying to work with a html file using the following but I am having an issue doing it with the PHP api. I already have the files ready on the server but I cannot figure out how to set the multipart/form data using the following code to do the conversion. Lets say I have a html file in the same folder how do I use it in the following code for conversion.
Code for conversion :
<?php
//set POST variables
$fields = array('from' => 'markdown',
'to' => 'pdf',
'input_files[]' => "#/".realpath('markdown.md').";type=text/x-markdown; charset=UTF-8"
);
//open connection
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //needed so that the $result=curl_exec() output is the file and isn't just true/false
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
?>

Since PHP 5.5, the # format for specifying a file path is no longer valid, and the value will be sent as a raw string. Instead try curl_file_create. Also, regardless of version, don't forget to set CURLOPT_POST variable to true as well. This code also assumes you have read access to the file being uploaded.
<?php
$url = 'http://c.docverter.com/convert';
$fields = [
'from' => 'markdown',
'to' => 'pdf',
'input_files[]' => (PHP_VERSION_ID < 50500) ? '#' . realpath('markdown.md') : curl_file_create('markdown.md')
];
$result_file = 'uploads/result.pdf';
//open connection
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $fields,
CURLOPT_RETURNTRANSFER => true
]);
$result = curl_exec($ch);
curl_close($ch);
file_put_contents($result_file, $result);

Related

CURL_SETOPT_ARRAY Not working inside a function, but works alone [duplicate]

Can anyone show me how to do a PHP cURL with an HTTP POST?
I want to send data like this:
username=user1, password=passuser1, gender=1
To www.example.com
I expect the cURL to return a response like result=OK. Are there any examples?
<?php
//
// A very simple PHP example that sends a HTTP POST to a remote site
//
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close($ch);
// Further processing ...
if ($server_output == "OK") { ... } else { ... }
?>
Procedural
// set post fields
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init('http://www.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
Object oriented
<?php
// mutatis mutandis
namespace MyApp\Http;
class CurlPost
{
private $url;
private $options;
/**
* #param string $url Request URL
* #param array $options cURL options
*/
public function __construct($url, array $options = [])
{
$this->url = $url;
$this->options = $options;
}
/**
* Get the response
* #return string
* #throws \RuntimeException On cURL error
*/
public function __invoke(array $post)
{
$ch = \curl_init($this->url);
foreach ($this->options as $key => $val) {
\curl_setopt($ch, $key, $val);
}
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, \CURLOPT_POSTFIELDS, $post);
$response = \curl_exec($ch);
$error = \curl_error($ch);
$errno = \curl_errno($ch);
if (\is_resource($ch)) {
\curl_close($ch);
}
if (0 !== $errno) {
throw new \RuntimeException($error, $errno);
}
return $response;
}
}
Usage
// create curl object
$curl = new \MyApp\Http\CurlPost('http://www.example.com');
try {
// execute the request
echo $curl([
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
]);
} catch (\RuntimeException $ex) {
// catch errors
die(sprintf('Http error %s with code %d', $ex->getMessage(), $ex->getCode()));
}
Side note here: it would be best to create some kind of interface called AdapterInterface for example with getResponse() method and let the class above implement it. Then you can always swap this implementation with another adapter of your like, without any side effects to your application.
Using HTTPS / encrypting traffic
Usually there's a problem with cURL in PHP under the Windows operating system. While trying to connect to a https protected endpoint, you will get an error telling you that certificate verify failed.
What most people do here is to tell the cURL library to simply ignore certificate errors and continue (curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);). As this will make your code work, you introduce huge security hole and enable malicious users to perform various attacks on your app like Man In The Middle attack or such.
Never, ever do that. Instead, you simply need to modify your php.ini and tell PHP where your CA Certificate file is to let it verify certificates correctly:
; modify the absolute path to the cacert.pem file
curl.cainfo=c:\php\cacert.pem
The latest cacert.pem can be downloaded from the Internet or extracted from your favorite browser. When changing any php.ini related settings remember to restart your webserver.
A live example of using php curl_exec to do an HTTP post:
Put this in a file called foobar.php:
<?php
$ch = curl_init();
$skipper = "luxury assault recreational vehicle";
$fields = array( 'penguins'=>$skipper, 'bestpony'=>'rainbowdash');
$postvars = '';
foreach($fields as $key=>$value) {
$postvars .= $key . "=" . $value . "&";
}
$url = "http://www.google.com";
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1); //0 for a get request
curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,3);
curl_setopt($ch,CURLOPT_TIMEOUT, 20);
$response = curl_exec($ch);
print "curl response is:" . $response;
curl_close ($ch);
?>
Then run it with the command php foobar.php, it dumps this kind of output to screen:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Title</title>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<body>
A mountain of content...
</body>
</html>
So you did a PHP POST to www.google.com and sent it some data.
Had the server been programmed to read in the post variables, it could decide to do something different based upon that.
It's can be easily reached with:
<?php
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.domain.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$response = curl_exec($ch);
var_export($response);
1.Step by step
Initialize the cURL session:
$url = "www.domain.com";
$ch = curl_init($url);
If your request has headers like bearer token or defining JSON contents you have to set HTTPHEADER options to cURL:
$token = "generated token code";
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // for define content type that is json
'bearer: '.$token, // send token in header request
'Content-length: 100' // content length for example 100 characters (can add by strlen($fields))
)
);
If you want to include the header in the output set CURLOPT_HEADER to true:
curl_setopt($ch, CURLOPT_HEADER, false);
Set RETURNTRANSFER option to true to return the transfer as a string instead of outputting it directly:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
To check the existence of a common name in the SSL peer certificate can be set to 0(to not check the names), 1(not supported in cURL 7.28.1), 2(default value and for production mode):
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
For posting fields as an array by cURL:
$fields = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
Execute cURL and return the string. depending on your resource this returns output like result=OK:
$result = curl_exec($ch);
Close cURL resource, and free up system resources:
curl_close($ch);
2.Use as a class
The whole call_cURL class that can be extended:
class class_name_for_call_cURL {
protected function getUrl() {
return "www.domain.com";
}
public function call_cURL() {
$token = "generated token code";
$fields = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
$url = $this->getUrl();
$output = $this->_execute($fields, $url, $token);
// if you want to get json data
// $output = json_decode($output);
if ($output == "OK") {
return true;
} else {
return false;
}
}
private function _execute($postData, $url, $token) {
// for sending data as json type
$fields = json_encode($postData);
$ch = curl_init($url);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // if the content type is json
'bearer: '.$token // if you need token in header
)
);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
Using the class and call cURL:
$class = new class_name_for_call_cURL();
var_dump($class->call_cURL()); // output is true/false
3.One function
A function for using anywhere that needed:
function get_cURL() {
$url = "www.domain.com";
$token = "generated token code";
$postData = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
// for sending data as json type
$fields = json_encode($postData);
$ch = curl_init($url);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // if the content type is json
'bearer: '.$token // if you need token in header
)
);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
This function is usable just by:
var_dump(get_cURL());
Curl Post + Error Handling + Set Headers [thanks to #mantas-d]:
function curlPost($url, $data=NULL, $headers = NULL) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
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;
}
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
function curlPost($url, $data) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error !== '') {
throw new \Exception($error);
}
return $response;
}
I'm surprised nobody suggested file_get_contents:
$url = "http://www.example.com";
$parameters = array('username' => 'user1', 'password' => 'passuser1', 'gender' => '1');
$options = array('http' => array(
'header' => 'Content-Type: application/x-www-form-urlencoded\r\n',
'method' => 'POST',
'content' => http_build_query($parameters)
));
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
it's simple, it works; I use it in an environment where I control the code at both ends.
even better, use json_decode (and set up your code to return JSON)
$result = json_decode(file_get_contents($url, false, $context), TRUE);
this approach invokes curl behind the scenes, but you don't jump through as many hoops.
Answer refined from this original answer elsewhere on Stack Overflow:
PHP sending variables to file_get_contents()
If the form is using redirects, authentication, cookies, SSL (https), or anything else other than a totally open script expecting POST variables, you are going to start gnashing your teeth really quick. Take a look at Snoopy, which does exactly what you have in mind while removing the need to set up a lot of the overhead.
A simpler answer IF you are passing information to your own website is to use a SESSION variable. Begin php page with:
session_start();
If at some point there is information you want to generate in PHP and pass to the next page in the session, instead of using a POST variable, assign it to a SESSION variable. Example:
$_SESSION['message']='www.'.$_GET['school'].'.edu was not found. Please try again.'
Then on the next page you simply reference this SESSION variable. NOTE: after you use it, be sure you destroy it, so it doesn't persist after it is used:
if (isset($_SESSION['message'])) {echo $_SESSION['message']; unset($_SESSION['message']);}
Here are some boilerplate code for PHP + curl
http://www.webbotsspidersscreenscrapers.com/DSP_download.php
include in these library will simplify development
<?php
# Initialization
include("LIB_http.php");
include("LIB_parse.php");
$product_array=array();
$product_count=0;
# Download the target (store) web page
$target = "http://www.tellmewhenitchanges.com/buyair";
$web_page = http_get($target, "");
...
?>
Examples of sending form and raw data:
$curlHandler = curl_init();
curl_setopt_array($curlHandler, [
CURLOPT_URL => 'https://postman-echo.com/post',
CURLOPT_RETURNTRANSFER => true,
/**
* Specify POST method
*/
CURLOPT_POST => true,
/**
* Specify array of form fields
*/
CURLOPT_POSTFIELDS => [
'foo' => 'bar',
'baz' => 'biz',
],
]);
$response = curl_exec($curlHandler);
curl_close($curlHandler);
echo($response);
If you try to login on site with cookies.
This code:
if ($server_output == "OK") { ... } else { ... }
It May not works if you try to login, because many sites return status 200, but the post is not successful.
The easy way to check if the login post is successful is to check if it setting cookies again. If in output have a Set-Cookies string, this means the posts are not successful and it starts a new session.
Also, the post can be successful, but the status can redirect instead of 200.
To be sure the post is successful try this:
Follow location after the post, so it will go to the page where the post does redirect to:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
And than check if new cookies existing in the request:
if (!preg_match('/^Set-Cookie:\s*([^;]*)/mi', $server_output))
{echo 'post successful'; }
else { echo 'not successful'; }
Easiest is to send data as application/json. This will take an array as input and properly encodes it into a json string:
$data = array(
'field1' => 'field1value',
'field2' => 'field2value',
)
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type:application/json',
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resultStr = curl_exec($ch);
return json_decode($resultStr, true);

How do I send this CURL in PHP [duplicate]

Can anyone show me how to do a PHP cURL with an HTTP POST?
I want to send data like this:
username=user1, password=passuser1, gender=1
To www.example.com
I expect the cURL to return a response like result=OK. Are there any examples?
<?php
//
// A very simple PHP example that sends a HTTP POST to a remote site
//
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close($ch);
// Further processing ...
if ($server_output == "OK") { ... } else { ... }
?>
Procedural
// set post fields
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init('http://www.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
Object oriented
<?php
// mutatis mutandis
namespace MyApp\Http;
class CurlPost
{
private $url;
private $options;
/**
* #param string $url Request URL
* #param array $options cURL options
*/
public function __construct($url, array $options = [])
{
$this->url = $url;
$this->options = $options;
}
/**
* Get the response
* #return string
* #throws \RuntimeException On cURL error
*/
public function __invoke(array $post)
{
$ch = \curl_init($this->url);
foreach ($this->options as $key => $val) {
\curl_setopt($ch, $key, $val);
}
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, \CURLOPT_POSTFIELDS, $post);
$response = \curl_exec($ch);
$error = \curl_error($ch);
$errno = \curl_errno($ch);
if (\is_resource($ch)) {
\curl_close($ch);
}
if (0 !== $errno) {
throw new \RuntimeException($error, $errno);
}
return $response;
}
}
Usage
// create curl object
$curl = new \MyApp\Http\CurlPost('http://www.example.com');
try {
// execute the request
echo $curl([
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
]);
} catch (\RuntimeException $ex) {
// catch errors
die(sprintf('Http error %s with code %d', $ex->getMessage(), $ex->getCode()));
}
Side note here: it would be best to create some kind of interface called AdapterInterface for example with getResponse() method and let the class above implement it. Then you can always swap this implementation with another adapter of your like, without any side effects to your application.
Using HTTPS / encrypting traffic
Usually there's a problem with cURL in PHP under the Windows operating system. While trying to connect to a https protected endpoint, you will get an error telling you that certificate verify failed.
What most people do here is to tell the cURL library to simply ignore certificate errors and continue (curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);). As this will make your code work, you introduce huge security hole and enable malicious users to perform various attacks on your app like Man In The Middle attack or such.
Never, ever do that. Instead, you simply need to modify your php.ini and tell PHP where your CA Certificate file is to let it verify certificates correctly:
; modify the absolute path to the cacert.pem file
curl.cainfo=c:\php\cacert.pem
The latest cacert.pem can be downloaded from the Internet or extracted from your favorite browser. When changing any php.ini related settings remember to restart your webserver.
A live example of using php curl_exec to do an HTTP post:
Put this in a file called foobar.php:
<?php
$ch = curl_init();
$skipper = "luxury assault recreational vehicle";
$fields = array( 'penguins'=>$skipper, 'bestpony'=>'rainbowdash');
$postvars = '';
foreach($fields as $key=>$value) {
$postvars .= $key . "=" . $value . "&";
}
$url = "http://www.google.com";
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1); //0 for a get request
curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,3);
curl_setopt($ch,CURLOPT_TIMEOUT, 20);
$response = curl_exec($ch);
print "curl response is:" . $response;
curl_close ($ch);
?>
Then run it with the command php foobar.php, it dumps this kind of output to screen:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Title</title>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<body>
A mountain of content...
</body>
</html>
So you did a PHP POST to www.google.com and sent it some data.
Had the server been programmed to read in the post variables, it could decide to do something different based upon that.
It's can be easily reached with:
<?php
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.domain.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$response = curl_exec($ch);
var_export($response);
1.Step by step
Initialize the cURL session:
$url = "www.domain.com";
$ch = curl_init($url);
If your request has headers like bearer token or defining JSON contents you have to set HTTPHEADER options to cURL:
$token = "generated token code";
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // for define content type that is json
'bearer: '.$token, // send token in header request
'Content-length: 100' // content length for example 100 characters (can add by strlen($fields))
)
);
If you want to include the header in the output set CURLOPT_HEADER to true:
curl_setopt($ch, CURLOPT_HEADER, false);
Set RETURNTRANSFER option to true to return the transfer as a string instead of outputting it directly:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
To check the existence of a common name in the SSL peer certificate can be set to 0(to not check the names), 1(not supported in cURL 7.28.1), 2(default value and for production mode):
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
For posting fields as an array by cURL:
$fields = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
Execute cURL and return the string. depending on your resource this returns output like result=OK:
$result = curl_exec($ch);
Close cURL resource, and free up system resources:
curl_close($ch);
2.Use as a class
The whole call_cURL class that can be extended:
class class_name_for_call_cURL {
protected function getUrl() {
return "www.domain.com";
}
public function call_cURL() {
$token = "generated token code";
$fields = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
$url = $this->getUrl();
$output = $this->_execute($fields, $url, $token);
// if you want to get json data
// $output = json_decode($output);
if ($output == "OK") {
return true;
} else {
return false;
}
}
private function _execute($postData, $url, $token) {
// for sending data as json type
$fields = json_encode($postData);
$ch = curl_init($url);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // if the content type is json
'bearer: '.$token // if you need token in header
)
);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
Using the class and call cURL:
$class = new class_name_for_call_cURL();
var_dump($class->call_cURL()); // output is true/false
3.One function
A function for using anywhere that needed:
function get_cURL() {
$url = "www.domain.com";
$token = "generated token code";
$postData = array(
"username" => "user1",
"password" => "passuser1",
"gender" => 1
);
// for sending data as json type
$fields = json_encode($postData);
$ch = curl_init($url);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
'Content-Type: application/json', // if the content type is json
'bearer: '.$token // if you need token in header
)
);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
This function is usable just by:
var_dump(get_cURL());
Curl Post + Error Handling + Set Headers [thanks to #mantas-d]:
function curlPost($url, $data=NULL, $headers = NULL) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
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;
}
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
function curlPost($url, $data) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error !== '') {
throw new \Exception($error);
}
return $response;
}
I'm surprised nobody suggested file_get_contents:
$url = "http://www.example.com";
$parameters = array('username' => 'user1', 'password' => 'passuser1', 'gender' => '1');
$options = array('http' => array(
'header' => 'Content-Type: application/x-www-form-urlencoded\r\n',
'method' => 'POST',
'content' => http_build_query($parameters)
));
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
it's simple, it works; I use it in an environment where I control the code at both ends.
even better, use json_decode (and set up your code to return JSON)
$result = json_decode(file_get_contents($url, false, $context), TRUE);
this approach invokes curl behind the scenes, but you don't jump through as many hoops.
Answer refined from this original answer elsewhere on Stack Overflow:
PHP sending variables to file_get_contents()
If the form is using redirects, authentication, cookies, SSL (https), or anything else other than a totally open script expecting POST variables, you are going to start gnashing your teeth really quick. Take a look at Snoopy, which does exactly what you have in mind while removing the need to set up a lot of the overhead.
A simpler answer IF you are passing information to your own website is to use a SESSION variable. Begin php page with:
session_start();
If at some point there is information you want to generate in PHP and pass to the next page in the session, instead of using a POST variable, assign it to a SESSION variable. Example:
$_SESSION['message']='www.'.$_GET['school'].'.edu was not found. Please try again.'
Then on the next page you simply reference this SESSION variable. NOTE: after you use it, be sure you destroy it, so it doesn't persist after it is used:
if (isset($_SESSION['message'])) {echo $_SESSION['message']; unset($_SESSION['message']);}
Here are some boilerplate code for PHP + curl
http://www.webbotsspidersscreenscrapers.com/DSP_download.php
include in these library will simplify development
<?php
# Initialization
include("LIB_http.php");
include("LIB_parse.php");
$product_array=array();
$product_count=0;
# Download the target (store) web page
$target = "http://www.tellmewhenitchanges.com/buyair";
$web_page = http_get($target, "");
...
?>
Examples of sending form and raw data:
$curlHandler = curl_init();
curl_setopt_array($curlHandler, [
CURLOPT_URL => 'https://postman-echo.com/post',
CURLOPT_RETURNTRANSFER => true,
/**
* Specify POST method
*/
CURLOPT_POST => true,
/**
* Specify array of form fields
*/
CURLOPT_POSTFIELDS => [
'foo' => 'bar',
'baz' => 'biz',
],
]);
$response = curl_exec($curlHandler);
curl_close($curlHandler);
echo($response);
If you try to login on site with cookies.
This code:
if ($server_output == "OK") { ... } else { ... }
It May not works if you try to login, because many sites return status 200, but the post is not successful.
The easy way to check if the login post is successful is to check if it setting cookies again. If in output have a Set-Cookies string, this means the posts are not successful and it starts a new session.
Also, the post can be successful, but the status can redirect instead of 200.
To be sure the post is successful try this:
Follow location after the post, so it will go to the page where the post does redirect to:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
And than check if new cookies existing in the request:
if (!preg_match('/^Set-Cookie:\s*([^;]*)/mi', $server_output))
{echo 'post successful'; }
else { echo 'not successful'; }
Easiest is to send data as application/json. This will take an array as input and properly encodes it into a json string:
$data = array(
'field1' => 'field1value',
'field2' => 'field2value',
)
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type:application/json',
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resultStr = curl_exec($ch);
return json_decode($resultStr, true);

Posting a file with cURL doesn't work with # at the beginning of the path

So I'm trying to send files to another page using cURL, along with other POST variables. Most of it works, except the file sending. But it only doesn't work on my localhost. When it's uploaded to the hosted web server, it works exactly like it should.
I also don't want to use CURLFile because the web server doesn't support it.
Here is the code:
// Output the image
imagejpeg($fileData['imageBackground'], $newFileName, 75);
// Get Old Background
$query['getBackground'] = $this->PDO->prepare("SELECT backgroundImage FROM accounts WHERE token = :token");
$query['getBackground']->execute(array(':token' => $token));
$queryData = $query['getBackground']->fetch(PDO::FETCH_ASSOC);
$verificationKey = self::newVerificationKey($token);
// Send the file to the remote
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uploadURL);
curl_setopt($ch, CURLOPT_POST, true);
$postArgs = array(
'action' => 'updateBackground',
'verificationKey' => $verificationKey,
'file' => '#' . realpath($newFileName),
'oldBackground' => $queryData['backgroundImage']
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
unlink($newFileName);
Thanks in advance!
Most likely your webserver is running an older version which supports the "#" - but not curlfile. Your local machine supports curlfile - but not the "#" (in the default configuration)...
You can use
if (class_exists("CurlFile")){
$postArgs = array(
'action' => 'updateBackground',
'verificationKey' => $verificationKey,
'file' => new CurlFile($newFileName),
'oldBackground' => $queryData['backgroundImage']
);
}else{
$postArgs = array(
'action' => 'updateBackground',
'verificationKey' => $verificationKey,
'file' => '#' . realpath($newFileName),
'oldBackground' => $queryData['backgroundImage']
);
}
which is recommended, because the #-way is considered unsafe, so use CurlFile, when available.
However, to have the #-way working lokaly as well, you can use
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
This defaulted to false prior to PHP 5.5, but defaults to true for later versions.
Note, play arround with the "order". There seems to be an issue with CURLOPT_POSTFIELDS beeing somewhat sensitive to existing options. So
curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
might not work, while
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs);
might.

Posting a form with several form fields and file using PHP curl

I am trying to post a form with some text input fields to my api, I also want to upload a file to the server at the same time. I did some research and came up with the following code as per suggestions from various websites, but it does not seem to work.
First Approach:
$cfile = new CURLFile('/home/xyz/myimge.jpg', 'image/jpeg', 'mymage.jpg');
$params = array(
"userid_id" => "some id #",
"file" => $cfile,
"name" => "test_file",
"gallery" => "myalbum"
);
$uri = 'http://myserver.com/somedir/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$response_data = curl_exec($ch);
//var_dump(curl_getinfo($ch));
//var_dump($response_data);
curl_close( $ch );
unset( $ch );
Second Approach:
$cfile = new CURLFile('/home/xyz/myimge.jpg', 'image/jpeg', 'mymage.jpg');
$params = array(
"userid_id" => "some id #",
"name" => "test_file",
"gallery" => "myalbum"
);
$params = array('item' => http_build_query($params), 'file' => $cfile );
$uri = 'http://myserver.com/somedir/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$response_data = curl_exec($ch);
//var_dump(curl_getinfo($ch));
//var_dump($response_data);
curl_close( $ch );
unset( $ch );
As per documentation, passing an array to CURLOPT_POSTFIELDS will encode the data as multipart/form-data. and I should get my form fields as $_POST array and the uploaded file as $_FILES array. Using both of these approaches, I get all my form fields in my receiving php template as post variables, but I do not get the file.
When I check the ccurl_getinfo output for content_type, I see it is :
["content_type"]=>
string(9) "text/html"
and not "multipart/form-data" as suggested in the documentation. Setting the content_type explicitly as "multipart/form-data" using curl_setopt also does not have any effect.
Many forums suggest using '#'.$filename format for submitting the file, but this seems to be deprecated as per PHP documentation. I am on PHP 5.5, and suggested way of uploading the file is forming a CURLFile object, which is what I am doing here.
Can any one suggest what is wrong in the above code?
Seems your approach is perfect, but there is a silly mistake.
You can try by adding extra header information. Hope it will work.
$headers = array("Content-Type:multipart/form-data");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

Submit form on one server, process it and then post results to another domain

I have a form on one page with the action set to /process.php
Within the process.php I have the validation of the form and also it writes to a database on the server it sits on.
What I'd like to do after it has written to the database, is post the variables to another domain that will then process those variables differently.
Example using curl:
$name = 'Test';
$email = 'test#gmail.com';
$ch = curl_init(); // initialize curl handle
$url = "http://domain2.com/process.php";
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // times out after 10s
curl_setopt($ch, CURLOPT_POST, 1); // set POST method
curl_setopt($ch, CURLOPT_POSTFIELDS, "text=$name&name=$email"); // post fields
$data = curl_exec($ch); // run the whole process
curl_close($ch);
Example without curl: http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl/
you can use file_get_contents for the same.
Example:
$name="foobar";
$messge="blabla";
$postdata = http_build_query(
array(
'name' => $name,
'message' => $message
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = #file_get_contents('http://yourdomain.com/process_request.php', false, $context);
if($http_response_header[0]=="HTTP/1.1 404 Not Found"):
echo "iam 404";
elseif($http_response_header[0]=="HTTP/1.1 200 OK"):
echo "iam 200";
else:
echo "unknown error";
endif;

Categories