I am using PHP (WAMPServer) to receive a form submission, and then CURL to pass the file to another server for processing.
Here is an example to illustrate (not the actual code):
$data = array(
'file' => '#'.$_FILES['key']['tmp_name']
);
Here's what I'm using for CURL... and as I was pasting the code I noticed that I still have http_build_query() in my code... so, that must be the problem.
$CURL = curl_init();
curl_setopt($CURL, CURLOPT_URL, $operation['callback']);
$query_string = http_build_query($arguments);
curl_setopt($CURL, CURLOPT_POSTFIELDS, $query_string);
curl_setopt($CURL, CURLOPT_POST, TRUE);
curl_setopt($CURL, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($CURL);
curl_close($CURL);
return $result;
My problem is that the last server isn't receiving the file. Instead, the data is passed as a key-value pair.
$_POST contains 'file' => '#c:\wamp\tmp\xyz.tmp'
What I would prefer, is that the files was transferred, and $_FILES has information about it.
Don't build an http query for the CURLOPT_POSTFIELDS. Curl can directly accept an array of fields and do its own encoding/mangling.
By building your own query, you're 'hiding' the # that indicates a file upload and CURL will not trigger its upload mechanisms.
In other words, this will fix things:
$data = array(
'file' => '#'.$_FILES['key']['tmp_name']
);
curl_setopt($CURL, CURLOPT_POSTFIELDS, $data);
if you add your CURL method code, we could better answer you...
Try to transfer the file as binary, and add the filesize in the header in your curl.
Related
I have an existing PHP script, which essentially connects to 2 databases each on a different server and performs a few MySQL queries on each. The ultimate results are stored in a data array which is used to write said results into a JSON file.
All of this works perfectly. The data is inserted into the mysql table correctly and the JSON file is exactly the way it should be.
However, I need to add a block to the end of my script that makes a POST request to one of our affiliate's API and upload the info there. We're currently manually uploading this JSON file to the api instance but we have the configuration data for their server to use in a POST request now so that when this script is run it automatically sends the data rather than us having to manually update it.
The main thing is I'm not exactly sure how to go about that. I've started with code for doing this but I'm not familiar with cURL so I don't know the best way to structure this in php.
Here is an example the affiliate gave me in cURL command line syntax:
curl \
-H "Authorization: Token AUTH_TOKEN" \
-H "Content-Type: CONTENT_TYPE" \
-X POST \
-d '[{"email": "jason#yourcompany.com", "date": "8/16/2016", "calls": "3"}]'
\
https://endpoint/api/v1/data/DATA_TYPE/
I have my auth token, my endpoint URL and my content type is JSON, which can be seen in my code below. Also, I have an array instead of the example for the body above.
and here's the affected part of my code:
//new array specifically for the final JSON file
$content2 = [];
//creating array for new fetch since it now has the updated extension IDs
while ($d2 = mysqli_fetch_array($data2, MYSQLI_ASSOC)) {
// Store the current row
$content2[] = $d2;
}
// Store it all into our final JSON file
file_put_contents('ambitionLog.json', json_encode($content2, JSON_PRETTY_PRINT ));
//Beginning code to upload to Ambition API via POST
$url = 'endpoint here';
//Initiate CURL
$ch = curl_init($url);
//JSON data
$jsonDataEncodeUpload = json_encode($content2, JSON_PRETTY_PRINT);
//POST via CURL
curl_setopt($ch, CURLOPT_POST, 1);
//attach JSON to post fields
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncodeUpload);
//set content type
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
//execuate request
$postResult = curl_exec($ch);
So, like I said, nothing about the file or the data needs to be changed, I just need to have this cURL section take the existing array that's being written to a JSON file and upload it to the API via post. I just need help making my php syntax for curl match the command line example.
Thanks for any possible help.
Have you tried with file_get_contents ( http://en.php.net/file_get_contents ).
$postdata = http_build_query(
array(
'var1' => 'some content',
'var2' => 'doh'
)
);
$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://example.com/submit.php', false, $context);
I have found the answer on stackoverflow How to post data in PHP using file_get_contents?
Here is worked example of code. Check $err may be it will be helpful.
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST('data'));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
$result = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);
I need to upload 3 files along with variables in post data. This is what my call looks like -
$data['type1'] = new CurlFile($file1);
$data['type2'] = new CurlFile($file2);
$data['type3'] = new CurlFile($file3);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data, "var1: $val1", "var2: $val2");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data', "headkey: $headkeyValue"));
I am not able to get $app->request()->post('var1'); from slim framework. It is empty.
I am able to get the headkey from the Header as $app->request()->headers('headkey');
I am able to get the data in $_FILES
Here the sample curl request
$curlFile = curl_file_create($uploaded_file_name_with_full_path);
$post = array('val1' => 'value','val2' => 'value','file_contents'=> $curlFile );
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$your_url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result=curl_exec ($ch);
curl_close ($ch);
Don't forget to put the appropriate header.
You can also find good source here
Curl File Upload
to send file via CURL. Make sure that you are passing your file on file_contents key in above code.
It's due to the fact that all files uploaded with HTTP POST method are in $_FILES global variable. That's why you cannot access files by this way
$app->request()->post('val1');
but you can by using $_FILES
$_FILES description
An associative array of items uploaded to the current script via the HTTP POST method. The structure of this array is outlined in the POST method uploads section.
This is what I did in alignment to ssingh's answer:
$data['type1'] = new CurlFile($file1);
$data['type2'] = new CurlFile($file2);
$data['type3'] = new CurlFile($file3);
//New Code Added
$data['var1'] = "$val1";
$data['var2'] = "$val2";
//removed the trailing string
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
I am trying to post to a REST service using PHP cURL but I'm after running into a bit of difficulty (this being that I've never used cURL before!!).
I've put together this code:
<?php
error_reporting(E_ALL);
if ($result == "00")
{
$url = 'http://127.0.0.1/xxxxxx/AccountCreator.ashx'; /*I've tried it a combination of ways just to see which might work */
$curl_post_data = array(
'companyName' =>urlencode($companyName),
'mainContact' =>urlencode($mainContact),
'telephone1' =>urlencode($telephone1),
'email' => urlencode($email),
'contact2' => urlencode($contact2),
'telephone2' => urlencode($telephone2)
'email2' => urlencode($email2);
'package' => urlencode($package)
);
foreach($curl_post_data as $key=>$value) {$fields_string .=$key. '=' .$value.'&';
}
rtrim($fields_string, '&');
die("Test: ".$fields_string);
$ch = curl_init();
curl_setopt ($ch, CURLOPT, $url);
curl_setopt ($ch, CURLOPT_POST, count($curl_post_data));
curl_setopt ($ch, CURLOPT_POSTFIELDS, $fields_string);
$result = curl_exec($ch);
curl_close($ch);
Following this, my code sends an email and performs an IF statement. I know this works okay, I only started running into trouble when I tried to insert this cURL request.
I've tried this however it doesn't run. As I am integrating with payment partners, it just says:
Your transaction has been successful but there was a problem connecting back to the merchant's web site. Please contact the merchant and advise them that you received this error message. Thank you.
The exact error that was received was a HTTP 500 error.
Thanks.
foreach($curl_post_data as $key=>value) {$fields_string .=$key. '=' .value.'&';
value here is missing a dollar i guess
foreach($curl_post_data as $key => $value) {$fields_string .=$key. '=' .$value.'&';
have you tried die($fields_string); to see what are you actually sending to the merchant?
First of all: are you testing locally? Because that IP you're using is not a valid server address.
The constant to set the URL is called CURLOPT_URL:
curl_setopt ($ch, CURLOPT_URL, $url);
Also CURLOPT_POST must be true or false ( http://php.net/curl_setopt ), not a number (except for 1 maybe):
curl_setopt ($ch, CURLOPT_POST, true);
Here's some POST sample code: PHP + curl, HTTP POST sample code?
It would be best if you can provide your PHP version.
As of PHP 5, some handy functions are bundled in the core instead of separate PECL libraries.
// If you are working with normal HTTP requests, simply do this.
$curl_post_data = http_build_query($curl_post_data);
curl_setopt($ch, CURLOPT, $url);
// This is a boolean option, although passing non-zero integer
// will be type-casted to TRUE, count() is not the proper way.
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curl_post_data);
// If you really want the next statement be meaningful, do this.
// Otherwise your HTTP response will be passed directly into
// the output buffer.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
Keep in mind that CURLOPT_POSTFIELDS in PHP supports file uploads, by adding a '#' character followed by a full file path as the value.
You don't want to call http_build_query() on such situations.
Sample code for file upload
$curl_post_data = array('file1' => '#/home/user/files_to_be_uploaded');
While you can optionally specify MIME type, see the documentation for more information.
As said, check your PHP version first. This feature only works in PHP 5, AFAIK there are companies still hosting PHP 4.x in their servers.
Have a look at http_build_query
I'm trying to send form fields and file to a web service using php curl. The form has already been passed from a browser to a proxy php client web app and I'm trying to forward it to the web service.
When I pass an array to curl_setopt like this:
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $this->fields);
I get a Array to String notice although it is meant to take an array. Here's my array that is passed to $this->fields in the constructor.
$fields = array('title'=>$title,
'content'=>$content,
'category'=>$category,
'attachment'=>$_FILES['attachment']);
If I pass a string using http_build_query my web serivce complains about not having multipart/form data.
If I then force the multipart/form enctype using curl_setopt I get an error saying there's no boundary:
org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
Any ideas?
The array to string notice you have with the following code :
$fields = array(
'title'=>$title,
'content'=>$content,
'category'=>$category,
'attachment'=>$_FILES['attachment']
);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $fields);
is not because of you're passing an array as 3rd parameter to curl_setopt : it's because you're passing an array for attachment.
If you want to pass a file this way, you should pass its absolute path, pre-pending a # before it :
$fields = array(
'title'=>$title,
'content'=>$content,
'category'=>$category,
'attachment'=> '#' . $_FILES['attachment']
);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $fields);
(This is supposing that $_FILES['attachment'] contains the full path to your file -- up to you to change this code so it's using the right data, if needed)
As a reference, quoting the manual page of curl_setopt, for the CURLOPT_POSTFIELDS option :
The full data to post in a HTTP "POST" operation.
To post a file, prepend a filename with # and use the full path.
This can either be passed as a urlencoded string like 'para1=val1¶2=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.
try this,
$filePath = "abc\\xyz.txt";
$postParams["uploadfile"] = "#" . $filePath;
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, 'https://website_address');
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, $postParams);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
if (curl_errno($ch))
{
echo curl_error($ch);
exit();
}
curl_close($ch);
How can I make a post request to a different php page within a php script? I have one front end computer as the html page server, but when the user clicks a button, I want a backend server to do the processing and then send the information back to the front end server to show the user. I was saying that I can have a php page on the back end computer and it will send the information back to the front end. So once again, how can I do a POST request to another php page, from a php page?
Possibly the easiest way to make PHP perform a POST request is to use cURL, either as an extension or simply shelling out to another process. Here's a post sample:
// where are we posting to?
$url = 'http://foo.com/script.php';
// what post fields?
$fields = array(
'field1' => $field1,
'field2' => $field2,
);
// build the urlencoded data
$postvars = 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, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
// execute post
$result = curl_exec($ch);
// close connection
curl_close($ch);
Also check out Zend_Http set of classes in the Zend framework, which provides a pretty capable HTTP client written directly in PHP (no extensions required).
2014 EDIT - well, it's been a while since I wrote that. These days it's worth checking Guzzle which again can work with or without the curl extension.
Assuming your php install has the CURL extension, it is probably the easiest way (and most complete, if you wish).
Sample snippet:
//set POST variables
$url = 'http://domain.com/get-post.php';
$fields = array(
'lname'=>urlencode($last_name),
'fname'=>urlencode($first_name),
'email'=>urlencode($email)
);
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
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);
//close connection
curl_close($ch);
Credits go to http://php.dzone.com.
Also, don't forget to visit the appropriate page(s) in the PHP Manual
index.php
$url = 'http://[host]/test.php';
$json = json_encode(['name' => 'Jhonn', 'phone' => '128000000000']);
$options = ['http' => [
'method' => 'POST',
'header' => 'Content-type:application/json',
'content' => $json
]];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
test.php
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
echo $data['name']; // Jhonn
For PHP processing, look into cURL. It will allow you to call pages on your back end and retrieve data from it. Basically you would do something like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL,$fetch_url);
curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt ($ch,CURLOPT_USERAGENT, $user_agent;
curl_setopt ($ch,CURLOPT_CONNECTTIMEOUT,60);
$response = curl_exec ( $ch );
curl_close($ch);
You can also look into the PHP HTTP Extension.
Like the rest of the users say it is easiest to do this with CURL.
If curl isn't available for you then maybe
http://netevil.org/blog/2006/nov/http-post-from-php-without-curl
If that isn't possible you could write sockets yourself
http://petewarden.typepad.com/searchbrowser/2008/06/how-to-post-an.html
For those using cURL, note that CURLOPT_POST option is taken as a boolean value, so there's actually no need to set it to the number of fields you are POSTing.
Setting CURLOPT_POST to TRUE (i.e. any integer except zero) will just tell cURL to encode the data as application/x-www-form-urlencoded, although I bet this is not strictly necessary when you're passing a urlencoded string as CURLOPT_POSTFIELDS, since cURL should already tell the encoding by the type of the value (string vs array) which this latter option is set to.
Also note that, since PHP 5, you can use the http_build_query function to make PHP urlencode the fields array for you, like this:
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
Solution is in target="_blank" like this:
http://www.ozzu.com/website-design-forum/multiple-form-submit-actions-t25024.html
edit form like this:
<form method="post" action="../booking/step1.php" onsubmit="doubleSubmit(this)">
And use this script:
<script type="text/javascript">
<!--
function doubleSubmit(f)
{
// submit to action in form
f.submit();
// set second action and submit
f.target="_blank";
f.action="../booking/vytvor.php";
f.submit();
return false;
}
//-->
</script>
Although not ideal, if the cURL option doesn't do it for you, may be try using shell_exec();
CURL method is very popular so yes it is good to use it. You could also explain more those codes with some extra comments because starters could understand them.