I need:
$content = "{\"data1\":90,\"data2\":\"SUKAORU\",\"data3\":7483478334}";
curl_setopt_array($curl, array(CURLOPT_POSTFIELDS => $content);
I did:
$_REQUEST = array("data1"=>90,"data2"=>"SUKAORU,"data3"=>7483478334);
$content1 = '"' . addslashes(json_encode($_REQUEST)) . '"';
curl_setopt_array($curl, array(CURLOPT_POSTFIELDS => $content1);
//or
$content1 = addslashes(json_encode($_REQUEST));
curl_setopt_array($curl, array(CURLOPT_POSTFIELDS => $content1);
//or
$content1 = json_encode($_REQUEST);
curl_setopt_array($curl, array(CURLOPT_POSTFIELDS => $content1);
$content and $content1 looks identically:
But second version returns error from server "unable to decode request".
How can I ecranate array into JSON like in I need example?
Don't use addslashes. Just don't use it.
The slashes here:
$content = "{\"data1\":90,\"data2\":\"SUKAORU\",\"data3\":7483478334}";
… are only part of the PHP source code. They are not part of the data.
If you're generating the JSON using json_encode then you don't need to manually write \" to get quotes into the " delimited string literal. You don't have a string literal and json_encode is generating the quotes.
This should be fine.
$data = array("data1"=>90,"data2"=>"SUKAORU","data3"=>7483478334);
$json = json_encode($data);
curl_setopt_array($curl, array(CURLOPT_POSTFIELDS => $json);
Note addition of missing " after "SUKAORU.
Related
I made a RSS to JSON file
https://www.dannny0117.com/.well-known/api/news2.php
It works, in that it returns the output as JSON from the RSS source. Now, I want to print only a few elements from that with PHP echo.
According to the JSON, I need to grab channel, item, title and guid since those are the things I want to output.
I only need the 1st post title and link, but my code just won't pick it up because I don't fully know how to access the thing.
Here is the code that I'm using that I think should echo but doesn't:
<?php
$url = "https://www.dannny0117.com/.well-known/api/news2.php";
$content = file_get_contents($url);
$json = json_decode($content, true);
$title = $content['channel']['item'][0]['title'];
$link= $content['channel']['item'][0]['guid'];
echo $title , $link;
?>
This is not a problem with encoding or unicode character, the main problem is that my code CAN'T read the items from the JSON needed.
There are 2 mistakes which you made:
1) You have UTF-8 characters in your json string.
2) You have output of json_decode() string in variable $json but you are using $content.
Use the code below.
$url = "https://www.dannny0117.com/.well-known/api/news2.php";
$content = file_get_contents($url);
$enc = mb_detect_encoding($content);
if($enc == 'UTF-8') {
$content = preg_replace('/[^(\x20-\x7F)]*/','', $content);
}
$json = json_decode($content,true);
$title = $json['channel']['item'][0]['title'];
$link = $json['channel']['item'][0]['guid'];
echo "<pre>";
print_r([$title , $link]);
you can check this link here , it about predefined constants, usually when you deal with none latin letters you can have this kind of mess. try use JSON_UNESCAPED_UNICODE
and this will solve your problem.
you can use something like this:
$json_output = json_decode($content, true, JSON_UNESCAPED_UNICODE);
as you said it did not work so would you try to add this :
$options = array('http' => array(
'header' => 'Accept-Charset: UTF-8'
)
); $context = stream_context_create($options);
$url = "https://www.dannny0117.com/.well-known/api/news2.php";
$content= file_get_contents($url, false, $context);
$json = json_decode($content, true,JSON_UNESCAPED_UNICODE);
I'm having an extrange issue when receiving parameters from a POST cURL request. No matter how I encode it (json, url, rawurl, utf8, base64...) before POSTing it, I am not able to perform any decoding operation through the array elements, via loop. I'm giving you the details.
From the consuming controller, in some other php (Yii) app, I build my request like this:
private function callTheApi($options)
{
$url = "http://api.call.com/url/api";
$params = array( 'api_key' => $this->api_key,
'domain' => $this->domain,
'date' => $options['date'],
'keys' => $options['keys'] // This is an array
);
// Following some good advice from Daniel Vandersluis here:
// http://stackoverflow.com/questions/3772096/posting-multidimensional-array-with-php-and-curl
if (is_array($params['keys'])
{
foreach ($params['keys'] as $id => $name)
{
$params['keys[' . $id . ']'] = $name;
}
unset($params['keys']);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data; charset=utf-8'));
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_USERAGENT,
"Mozilla/5.0 (Windows; U; Windows NT 5.0; en; rv:1.9.0.4) "
. "Gecko/2009011913 Firefox/3.0.6");
$output = curl_exec($ch);
$error = curl_errno($ch);
$error_text = curl_error($ch);
curl_close($ch);
if (!$output || $error != 0)
die("<br><hr>Problems...<br>"
. "Line:" . __LINE__ . " dataExtractor.php<br>"
. "Error: " . $error . " - " . $error_text . "<hr>"
. $url . "<hr>");
sleep(1);
return json_decode($output, true);
}
And in the api itself, this is the function:
public function api()
{
$params = $_POST;
foreach($params as $k=>$v){
if($k=='domain') $domain = $v;
if($k=='date') $date = $v;
if($k=='api_key') $api_key = $v;
if($k=='keys') $keys = $v;
}
echo json_encode($keys);
// All my logic would be here, after parsing the array correctly.
}
Ok, now for the problems:
If i leave everything like stated before, it works. I have my $keys array in the api, and I can use it however I want. The "echo json_encode($keys)" sentence returns the array ALMOST as it should be. But the problem is some values of the array are corrupted in the cURL operation. Values such as spanish characters á, é ,í, ó, ú OR ü are simply not present in the array_values.
If some key in the $keys array was spanish word "alimentación" in the original array, once it's been cURLed to the api, it becomes "alimentacin". There, the ó is not there anymore.
So, my chances are encoding each value in the array to a safely transferred value, so that I can decode it later. But what do you know, I can't.
I've tried urlencoding, rawurlencoding, json_encoding, base64_encoding... each value of the array. And if I return the received array from the api, it contains the encoded values all right. BUT.
If I loop the array in the api for decoding, and then try to return it, no matter what decoding function I'm applying to its values, the output is ALWAYS "NULL".
I have no clue what I'm doing wrong here. Not even close.
So any help would be much appreciated. Thanks in advance, community.
When you create cUrl params array you should know that keys cannot be utf8.
And when you add some parameters in foreach loop
$params['keys[' . $id . ']'] = $name;
$id can be utf8 character.
To avoid that I recommend you to use json_encode
$params = array(
'api_key' => $this->api_key,
'domain' => $this->domain,
'date' => $options['date'],
'keys' => json_encode($options['keys']) // This is an array
);
In your api in this case you should change nothing.
This is the function I use to grab a JSON file from Feedbin API.
<?php
error_reporting(E_ALL);
// JSON URL which should be requested
$json_url = 'https://api.feedbin.me/v2/entries.json';
$username = 'my_username'; // authentication
$password = ' my_password'; // authentication
// Initializing curl
$ch = curl_init( $json_url );
// Configuring curl options
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => $username . ":" . $password // authentication
);
// Setting curl options
curl_setopt_array( $ch, $options );
// Getting results
$result = curl_exec($ch); // Getting JSON result string
print_r ($result);
?>
Problem is the JSON I get is a bit.. strange.
It has a lot of chars like \u003E\u003C/a\u003E\u003C/p\u003E\n\u003Cp\u003E ...
You can see the JSON here.
When you call json_decode in PHP on strings that contain these encodings they will be correctly decoded. http://json.org/ lists \ufour-hex-digits as a valid character. There is no issue.
$ echo json_decode('"\u003E\u003C/a\u003E\u003C/p\u003E\n\u003Cp\u003E"');
></a></p>
<p>
They are valid unicode sequence. Here is a simple example
$data = array(
"abc" => 'åbcdéfg'
);
// Encode
$data = json_encode($data) . "\n";
// Output Value
echo $data;
// Output Decoded Value
print_r(json_decode($data));
Output
{"abc":"\u00e5bcd\u00e9fg"}
stdClass Object
(
[abc] => åbcdéfg
)
My question is I want to get acess my fb friends using curl and decode into json then i want to show only those friends whose name starting with letter a such as aman,adam etc pls help me..Following is my code.
<?php
// create a new cURL resource
$json_url="https://graph.facebook.com/100001513782830/friends?access_token=AAACEdEose0cBAPdK62FSjs4RvA21efqc8ZBKyzAesT5r4VSpu0XScAYDtKrCxk4PmcRBVzE2SLiGvs2d5FeXvZAD72ZCShwge3vk4DQqRAb8vLlm1W3";
$ch = curl_init( $json_url );
// Configuring curl options
/* $options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-type: application/json')
);
// Setting curl options
curl_setopt_array( $ch );
*/// Getting results
$result = curl_exec($ch); // Getting jSON result string
$obj = json_decode($result, true);
foreach($obj[data] as $p)
{
echo '
Name: '.$p[name][first].'
Age: '.$p[age].'
';
}
You will offcourse try not to hardcode "a" but for this purpose :
foreach($obj[data] as $p){
if(strtolower(substr(trim($p[name][first]),0,1)) == 'a'){
echo 'Name: '.$p[name][first].'Age: '.$p[age];
}
}
Btw, it is not a good idea to post security tokens (in URL) to public places.
Since the name is string, you can simply iterate over that array and filter by name:
$letter = 'A';
foreach($obj['data'] as $p) {
if ($p['name'][0] == $letter) {
// do something with $p
}
}
But there is a little problem with UTF-8 -- this solution (and that one with substr too) will not work on multibyte characters. So you need to use mb_substr instead of plain substr function:
foreach($obj['data'] as $p) {
if(mb_strtolower(mb_substr($p['name'], 0, 1))) == 'Á'){
echo "Name: ", $p['name'], "\n",
"Age: ", $p['age'], "\n";
}
}
I'm writing a php application that submits via curl data to sign up for an iContact email list. However I keep getting an invalid email address error. I think this may be due to the fact that I'm escaping the # symbol so it looks like %40 instead of #. Also, according to the php documentation for curl_setopt with CURLOPT_POSTFIELDS:
The full data to post in a HTTP
"POST" operation. To post a file,
prepend a filename with # and use the
full path.
So, is there anyway to pass the # symbol as post data through curl in php without running it through urlencode first?
Use http_build_query() on your data-array first before passing it to curl_setopt(), that will lead to it sending the form as application/x-www-form-encoded instead of multipart/form-data (and thus the # is not interpreted).
Also why do you really care about the # in an email-address? It only matters if the # is the first character, not somewhere in the middle.
After search PHP curl manual, I found there is no information to escape the first ‘#’ if the post field is a string instead of a file if post with multipart/form-data encoding.
The way I worked around this problem is prefixing a blank at the beginning of the text. While our backend API will strip blanks so it could remove the blank and restore the original text. I don't know weather Twitter API will trim blanks on user input.
If so, this workaround also works for you.
If any one found the way to escaping the first '#' when using PHP curl with multipart/form-data encoding, please let us know.
I ran into the same issue, though with curl itself and not PHP curl.
When using curl's field option '-F' a leading # symbol will not be sent in the POST but instead will instruct curl to send the file name that immediately succeeds the symbol as part of the POST.
Fortunately, curl offers another option '--form-string', which behaves the same way as '-F', except that the 'form-string' option is not parsed.
As an example, if you want to use curl to POST field1 with value "#value" and file1 with the file "testfile.txt" you can do so as follows:
curl "http://www.url.com" --form-string "field1=#value" -F "file1=#testfile.txt"
This is the true solution that can support both string containing # and files.
Solution for PHP 5.6 or later:
Use CURLFile instead of #.
Solution for PHP 5.5 or later:
Enable CURLOPT_SAFE_UPLOAD.
Use CURLFile instead of #.
Solution for PHP 5.3 or later:
Build up multipart content body by youself.
Change Content-Type header by yourself.
The following snippet will help you :D
<?php
/**
* For safe multipart POST request for PHP5.3 ~ PHP 5.4.
*
* #param resource $ch cURL resource
* #param array $assoc "name => value"
* #param array $files "name => path"
* #return bool
*/
function curl_custom_postfields($ch, array $assoc = array(), array $files = array()) {
// invalid characters for "name" and "filename"
static $disallow = array("\0", "\"", "\r", "\n");
// initialize body
$body = array();
// build normal parameters
foreach ($assoc as $k => $v) {
$k = str_replace($disallow, "_", $k);
$body[] = implode("\r\n", array(
"Content-Disposition: form-data; name=\"{$k}\"",
"",
filter_var($v),
));
}
// build file parameters
foreach ($files as $k => $v) {
switch (true) {
case false === $v = realpath(filter_var($v)):
case !is_file($v):
case !is_readable($v):
continue; // or return false, throw new InvalidArgumentException
}
$data = file_get_contents($v);
$v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v));
list($k, $v) = str_replace($disallow, "_", array($k, $v));
$body[] = implode("\r\n", array(
"Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
"Content-Type: application/octet-stream",
"",
$data,
));
}
// generate safe boundary
do {
$boundary = "---------------------" . md5(mt_rand() . microtime());
} while (preg_grep("/{$boundary}/", $body));
// add boundary for each parameters
array_walk($body, function (&$part) use ($boundary) {
$part = "--{$boundary}\r\n{$part}";
});
// add final boundary
$body[] = "--{$boundary}--";
$body[] = "";
// set options
return curl_setopt_array($ch, array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => implode("\r\n", $body),
CURLOPT_HTTPHEADER => array(
"Expect: 100-continue",
"Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
),
));
}
?>
#PatricDaryll's answer is correct, but I needed to make a bit of researches to understand where to use this http_build_query function.
To clarify and summarise, instead of doing:
curl_setopt($ch, CURLOPT_POSTFIELDS, $array);
You will use:
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array));
Simple but confusing... curl is smart enough to understand if you gave him a string or an array.
In order to escape the # sign in the non-file data, you need to do the following.
Prepend the text string with the NULL character
$postfields = array(
'upload_file' => '#file_to_upload.png',
'upload_text' => sprintf("\0%s", '#text_to_upload')
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://example.com/upload-test');
curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
curl_exec($curl);
curl_close($curl);