Posting with PHP and Curl, deep array - php

I'm trying to post via curl, I've been using the same code over and over again with no problem but now I need to be able to use an array for posts (i'm not sure if there's a proper term for that?).
I should clarify that it's specifically a file i'm trying to post, but I can't get it working with a string either so I don't think it's too do with that.
This is absouletly fine:
$uploadData = array();
$uploadData['uploads'] = "#".$file;
$uploadData['iagree'] = 'on';
This doesn't appear to work:
$uploadData = array();
$uploadData['uploads'][0] = "#".$file;
$uploadData['iagree'] = 'on';
In the second example i'm trying to replicate an input with the attribute name="uploads[]"
Obviously i'm trying to curl an external site, but if I experiment curling a page on my own server so that I can see what's being sent, I can see that the uploads array is being converted to a string:
print_r($_POST);
print_r($_FILES);
returns:
Array
(
[uploads] => Array
[iagree] => on
)
Array
(
)
This is my full Curl:
$uploadData = array();
$uploadData['uploads'][] = "#".$file;
$uploadData['iagree'] = 'on';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $theLink);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $uploadData);
$upload_response = curl_exec($ch);
curl_close($ch);
I've tried to give as much information as possible, but if i've missed something feel free to ask and i'll provide more.
Other than that, does anyone have any suggestions or solutions?

$uploadData['uploads[]'] = "#".$file; and passing it as an array should work, just keep in mind you need the absolute path to the file.
There is no mechanism in 'simple' HTTP (multipart/form-data or application/x-www-form-urlencoded) to send 'arrays'. However, PHP interprets the [ & ] characters in key-value pairs as special. PHP is alone in that AFAIK, it's not a HTTP mechanism, it's just the parsing of input PHP does, as is replacing .'s in the name of values with _. Curl is a 3rd party package which lives seperately from PHP, and as such does not understand multidimensional arrays.

Try passing the query string:
$uploadData = 'uploads[]=#' . $file . '&iagree=on&uploads[]=#' . $file2;
See if that works for you.
EDIT
Reading through the manual, the string needs to be urlencoded, try this:
$uploadData = urlencode('uploads[]=#' . $file . '&iagree=on&uploads[]=#' . $file2);
Received this information from the curl_setopt() man page:
Note:
Passing an array to CURLOPT_POSTFIELDS will encode the data as multipart/form-data, while passing a URL-encoded string will encode the data as application/x-www-form-urlencoded.
I may have used the urlencode improperly, try this:
$uploadData = 'uploads[]=' . urlencode('#' . $file) . '&iagree=' . urlencode('on') . '&uploads[]=' . urlencode('#' . $file2);
UPDATE
Ok this is my last shot at it. Reading through some user comments at the curl page I found something about serializing the sub-array. So:
$uploadData = array('iagree' => 'on', 'uploads' => serialize(array('#' . $file)));
Hopefully that is the key. If that does not work...well it may not be possible to do.
Give that a shot and see if it works. (Sorry for the trial and error, I do not have a method to test it!)

Related

transfer of data on URL click

I am new to JSON data transfer. I want to make a user click on a link in a webpage and that should redirect the user to another page with his login credentials in the url and display it there. Now this all I want to send and receive through JSON . I am working on PHP environment. I am adding a short code on which I am working but not knowing how to proceed exactly.
send.php
<?php
$data = '{ "user" : [
{ "email" : "xyz#gmail.com",
"password" : "xyz#123",
"employee_id" : 77
}
]
} ';
$url_send ="http://localhost/cwmsbi/recieve.php";
$str_data = json_encode($data);
function sendPostData($url_send, $post){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($post))
);
$result = curl_exec($ch);
curl_close($ch); // Seems like good practice
return $result;
}
echo " " . sendPostData($url_send, $str_data);
?>
And receive.php
<?php
$json_input_data=json_decode(file_get_contents('php://input'),TRUE);
print_r( $json_input_data);
?>
Now when I am running send.php on my localhost, it displays the data on same page but does not goes to recieve.php.
How this can be achieved? I am curious and in need of this too. How can I run a JSON file and where should i obtain results? Your guidance will be immensely useful to me right now.
First of all i see you are json encoding $data two times (as when it gets defines it is already a json string and then you do $str_data = json_encode($data);).
If you want to achive the change of location with post data too, you can't use curl
(POST data and redirect user by PHP CURL - read this question for further infos) - and i don't think you can do it by php only.
If i was trying to achive what you're trying to achive (and i would never make a page to show login password to users - as it is bad practice to show a password, even in emails), i suggest to set the json string into $_SESSION variable in send.php and redirect with header("Location: http://localhost/cwmsbi/recieve.php") where you get the json data from $_SESSION variable and you print it.
I did not make an example as i think this one perfectly suites you:
https://stackoverflow.com/a/42215249/9606459
Extra hint: even if placing the password in php $_SESSION variable is better than put it in post request, remember you are doing bad practice and at least remember to empty out that json string in $_SESSION variable after you print it.
e.g.:
unset($_SESSION['user_data']);

how to get unknown string in $_GET method through URL

I want to pass a string from one PHP file to another using $_GET method. This string has different value each time it is being passed. As I understand, you pass GET parameters over a URL and you have to explicitly tell what the parameter is. What if you want to return whatever the string value is from providing server to server requesting it? I want to pass in json data format. Additionally how do I send it as Ajax?
Server (get.php):
<?php
$tagID = '123456'; //this is different every time
$tag = array('tagID' => $_GET['tagID']);
echo json_encode($tag);
?>
Server (rec.php):
<?php
$url = "http://192.168.12.169/RFID2/get.php?tagID=".$tagID;
$json = file_get_contents($url);
#var_dump($json);
$data = json_decode($json);
#var_dump($data);
echo $data;
?>
If I understand correctly, you want to get the tagID from the server? You can simply pass a 'request' parameter to the server that tells the server what to return.
EDIT: This really isn't the proper way to implement an API (like, at all), but for the sake of answering your question, this is how:
Server
switch($_GET['request']) {
case 'tagID';
echo json_encode($tag);
break;
}
You can now get the tagID with a URL like 192.168.12.169/get.php?request=tagId
Client (PHP with CURL)
When it comes to the client it gets a bit more complicated. You mention AJAX, but that will only work for JavaScript. Your php file can't use AJAX, you'll have to use cURL.
$request = "?request=tagID";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, '192.168.12.169/get.php' . $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, '3');
$content = trim(curl_exec($ch));
curl_close($ch);
echo $content;
EDIT: added the working cURL example just for completeness.
Included cURL example from: How to switch from POST to GET in PHP CURL
Client (Javascript with AJAX)
$.get("192.168.12.169/get.php?request=tagId", function(data) {
alert(data);
});

URL truncated after ampersand when passed thru curl in PHP (linux) using POST method

PHP code:
$fields_string = "";
foreach ($postingfields as $key=>$value) {
$fields_string .= $key . '=' . urlencode($value) . '&';
}
$fields_string = rtrim($fields_string,'&');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$client_url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$response = curl_getinfo( $ch );
curl_close($ch);
$client_url php variable holds the value: https://pcloudtest.com/Default.aspx?cid=99938
$fields_string php variable holds the value: &sid=30&title=Mr&firstname=Charles&surname=Smith
The destination server has been set up to respond with the following HTML:
When I debug (send info to a separate txt file in linux) the value of $result is:
<URL>https://pcloudtest.com/Default.aspx?cid=99938</URL>
ie this is what the destination server is claiming has been sent to them from my end.
In other words, the $client_url is all that is being posted, and not the rest of it (ie the $fields_string) and the full URL that should've been posted should read:
https://pcloudtest.com/Default.aspx?cid=99938&sid=30&title=Mr&firstname=Charles&surname=Smith
I have tried everything I can to figure out why the php curl functions are apparently sending out a shortened URL, ie up to the first occurrence of an ampersand. The code logic I have above has not changed in months and is working for other destination servers.
I might add that the other destination servers where this logic has no issues are http: sites not https:. But I have been reassured by the tech guys on the other end that it definitely has nothing to do with posting to a https site.
Please help. I hope I have outlined my issue clearly enough, and if not, please advise as to more info I can provide.

How to cURL multiple continuous pages in a "for" loop with PHP?

For example, I want to curl 8 text files from http://example.com/0.txt to http://example.com/7.txt and echo them out, in a loop. The following is my current codes.
for ($i=0; $i < 6; $i++) {
$curl = curl_init();
$post_url = 'http://example.com/' . i . '.txt';
curl_setopt($curl, CURLOPT_URL, $post_url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($curl);
curl_close($curl);
echo '<article>' . $data . '</article>';
}
It seems that traditionally the value of key CURLOPT_URL is supposed to directly written in the 4th line, but the way doesn't meet my demand. I tried separating the string with two dots and inserting the loop-controlling variable i into the two strings, to form the third parameter, but it doesn't work.
Then I tried bring the statement out from the line, and set a variable in advance which combines two strings and one number variable and place the variable in the curl_setopt() function as the third parameter. It doesn't work.
By the time I search "php curl loop" or "curl in loop with parameter" or something else, Google can hardly provide me with helpful information.
So eventually I am seeking help here : (
Thanks in advance if anyone would like to offer solution.
Not sure it can be because of typo but try fixing this & check,
$post_url = 'http://example.com/' . $i . '.txt'; // You miss '$' here
^

Decoding JSON after sending using PHP cUrl

I've researched everywhere and cannot figure this out.
I am writing a test cUrl request to test my REST service:
// initialize curl handler
$ch = curl_init();
$data = array(
"products" => array ("product1"=>"abc","product2"=>"pass"));
$data = json_encode($data);
$postArgs = 'order=new&data=' . $data;
// set curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postArgs);
curl_setopt($ch, CURLOPT_URL, 'http://localhost/store/rest.php');
// execute curl
curl_exec($ch);
This works fine and the request is accepted by my service and $_Post is populated as required, with two variables, order and data. Data has the encoded JSON object. And when I print out $_Post['data'] it shows:
{"products":{"product1":"abc","product2":"pass"}}
Which is exactly what is expected and identical to what was sent in.
When I try to decode this, json_decode() returns nothing!
If I create a new string and manually type that string, json_decode() works fine!
I've tried:
strip_tags() to remove any tags that might have been added in the http post
utf8_encode() to encode the string to the required utf 8
addslashes() to add slashes before the quotes
Nothing works.
Any ideas why json_decode() is not working after a string is received from an http post message?
Below is the relevant part of my processing of the request for reference:
public static function processRequest($requestArrays) {
// get our verb
$request_method = strtolower($requestArrays->server['REQUEST_METHOD']);
$return_obj = new RestRequest();
// we'll store our data here
$data = array();
switch ($request_method) {
case 'post':
$data = $requestArrays->post;
break;
}
// store the method
$return_obj->setMethod($request_method);
// set the raw data, so we can access it if needed (there may be
// other pieces to your requests)
$return_obj->setRequestVars($data);
if (isset($data['data'])) {
// translate the JSON to an Object for use however you want
//$decoded = json_decode(addslashes(utf8_encode($data['data'])));
//print_r(addslashes($data['data']));
//print_r($decoded);
$return_obj->setData(json_decode($data['data']));
}
return $return_obj;
}
Turns out that when JSON is sent by cURL inside the post parameters & quot; replaces the "as part of the message encoding. I'm not sure why the preg_replace() function I tried didn't work, but using html_entity_decode() removed the &quot and made the JSON decode-able.
old:
$return_obj->setData(json_decode($data['data']));
new:
$data = json_decode( urldecode( $data['data'] ), true );
$return_obj->setData($data);
try it im curious if it works.

Categories