php json_decode() giving null - php

I have a json string like below
{"cv_url":"http://localhost/kaj/wp-content/uploads/2017/03/Mir-Ruhul-Amin.doc","cv_path":"C:\wamp\www\kaj/wp-content/uploads/2017/03/Mir-Ruhul-Amin.doc"}
while trying to decode by php json_decode() it giving me null value.
Any help is appreciated.
Thanks

That is because your JSON in invalid.
You need to escape it like so:
{
"cv_url": "http://localhost/kaj/wp-content/uploads/2017/03/Mir-Ruhul-Amin.doc",
"cv_path": "C:\\wamp\\www\\kaj/wp-content/uploads/2017/03/Mir-Ruhul-Amin.doc"
}
So your variable should actually be:
'{"cv_url": "http://localhost/kaj/wp-content/uploads/2017/03/Mir-Ruhul-Amin.doc","cv_path": "C:\\wamp\\www\\kaj/wp-content/uploads/2017/03/Mir-Ruhul-Amin.doc"}'
for PHP to decode it.
To escape JSON you can simply encode the array in php first or if that does not suit you you can use the following function:
/**
* #param $value
* #return mixed
*/
function escapeJsonString($value) {
$escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
$replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
$result = str_replace($escapers, $replacements, $value);
return $result;
}
TIP:
You can always test the validity of your json on online tools like:
http://jsonlint.com
and
http://www.jsoneditoronline.org/

Related

php: wanted to replace '\\\/' from string

I wanted to replace en/us with es/es:
<?php
$str = array('url'=>'www.domain.com\/data\/en\/us\/data.gif');
$json = json_encode($str);
$str = str_replace('en\/us', 'es\/es', $json);
echo $str;
You need to 'double escape' the backslash, like so:
<?php
$str = array('url'=>'www.domain.com/data/en/us/data.gif');
$json = json_encode($str);
$str = str_replace('en\\/us', 'es\\/es', $json);
echo $str;
See http://php.net/manual/en/language.types.string.php (section 'Single quoted').
Would be easier to escape the string BEFORE feeding it to json_encode, but I'm assuming this is a test case and the data you want to replace in is already JSON.
JSON is a useful format for moving data between systems. Converting data to JSON and then trying to manipulate it without parsing it first is almost always a terrible (overly complicated and error prone) idea.
Do the replacement before you convert it to JSON.
<?php
function replace_country($value) {
echo $value;
echo "\n";
return str_replace('en\/us', 'es\/es', $value);
}
$str = array('url'=>'www.domain.com\/data\/en\/us\/data.gif');
$str = array_map("replace_country", $str);
$json = json_encode($str);
echo $json;
Try this
$str = array('url'=>'www.domain.com\/data\/en\/us\/data.gif');
$str['url']=str_replace('en\/us', 'es\/es', $str['url']);
$json = json_encode($str);
It produce out put as
It will work for you.

Replacing characters in MIME encoded emails

I am looking for a way to simply replace characters with their ASCII counterparts in MIME encoded emails. I've written preliminary code below, but it seems like the str_replace commands I'm using will keep on going forever to catch all possible combinations. Is there a more efficient way to do this?
<?php
$strings = "=?utf-8?Q?UK=20Defence=20=2D=20Yes=2C=20Both=20Labour=20and=20Tory=20Need=20To=20Be=20Very=20Much=20Clearer=20On=20Defence?=";
function decodeString($input){
$space = array("=?utf-8?Q?","=?UTF-8?Q?", "=20","?=");
$hyphen = array("=E2=80=93","=2D");
$dotdotdot = "=E2=80=A6";
$pound = "=C2=A3";
$comma = "=2C";
$decode = str_replace($space, ' ', $input);
$decode = str_replace($hyphen, '-', $decode);
$decode = str_replace($pound, '£', $decode);
$decode = str_replace($comma, ',', $decode);
$decode = str_replace($dotdotdot, '...', $decode);
return $decode;
}
echo decodeString($strings);
?>
I figured it out - I have to pass $strings to the mb_decode_mimeheader() function.

PHP: json_decode not working

This does not work:
$jsonDecode = json_decode($jsonData, TRUE);
However if I copy the string from $jsonData and put it inside the decode function manually it does work.
This works:
$jsonDecode = json_decode('{"id":"0","bid":"918","url":"http:\/\/www.google.com","md5":"6361fbfbee69f444c394f3d2fa062f79","time":"2014-06-02 14:20:21"}', TRUE);
I did output $jsonData copied it and put in like above in the decode function. Then it worked. However if I put $jsonData directly in the decode function it does not.
var_dump($jsonData) shows:
string(144) "{"id":"0","bid":"918","url":"http:\/\/www.google.com","md5":"6361fbfbee69f444c394f3d2fa062f79","time":"2014-06-02 14:20:21"}"
The $jsonData comes from a encrypted $_GET variable. To encrypt it I use this:
$key = "SOME KEY";
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$enc = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_ECB, $iv);
$iv = rawurlencode(base64_encode($iv));
$enc = rawurlencode(base64_encode($enc));
//To Decrypt
$iv = base64_decode(rawurldecode($_GET['i']));
$enc = base64_decode(rawurldecode($_GET['e']));
$data = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $enc, MCRYPT_MODE_ECB, $iv);
some time there is issue of html entities, for example \" it will represent like this \&quot, so you must need to parse the html entites to real text, that you can do using
html_entity_decode()
method of php.
$jsonData = stripslashes(html_entity_decode($jsonData));
$k=json_decode($jsonData,true);
print_r($k);
You have to use preg_replace for avoiding the null results from json_decode
here is the example code
$json_string = stripslashes(html_entity_decode($json_string));
$bookingdata = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );
Most likely you need to strip off the padding from your decrypted data. There are 124 visible characters in your string but var_dump reports 144. Which means 20 characters of padding needs to be removed (a series of "\0" bytes at the end of your string).
Probably that's 4 "\0" bytes at the end of a block + an empty 16-bytes block (to mark the end of the data).
How are you currently decrypting/encrypting your string?
Edit:
You need to add this to trim the zero bytes at the end of the string:
$jsonData = rtrim($jsonData, "\0");
Judging from the other comments, you could use,
$jsonDecode = json_decode(trim($jsonData), TRUE);
While moving on php 7.1 I encountered with json_decode error number 4 (json syntex error). None of the above solution on this page worked for me.
After doing some more searching i found solution at https://stackoverflow.com/a/15423899/1545384 and its working for me.
//Remove UTF8 Bom
function remove_utf8_bom($text)
{
$bom = pack('H*','EFBBBF');
$text = preg_replace("/^$bom/", '', $text);
return $text;
}
Be sure to set header to JSON
header('Content-type: application/json;');
str_replace("\t", " ", str_replace("\n", " ", $string))
because json_decode does not work with special characters. And no error will be displayed. Make sure you remove tab spaces and new lines.
Depending on the source you get your data, you might need also:
stripslashes(html_entity_decode($string))
Works for me:
<?php
$sql = <<<EOT
SELECT *
FROM `students`;
EOT;
$string = '{ "query" : "' . str_replace("\t", " ", str_replace("\n", " ", $sql)).'" }';
print_r(json_decode($string));
?>
output:
stdClass Object
(
[query] => SELECT * FROM `students`;
)
I had problem that json_decode did not work, solution was to change string encoding to utf-8. This is important in case you have non-latin characters.
Interestingly mcrypt_decrypt seem to add control characters other than \0 at the end of the resulting text because of its padding algorithm. Therefore instead of rtrim($jsonData, "\0")
it is recommended to use
preg_replace( "/\p{Cc}*$/u", "", $data)
on the result $data of mcrypt_decrypt. json_decode will work if all trailing control characters are removed. Pl refer to the comment by Peter Bailey at http://php.net/manual/en/function.mdecrypt-generic.php .
USE THIS CODE
<?php
$json = preg_replace('/[[:cntrl:]]/', '', $json_data);
$json_array = json_decode($json, true);
echo json_last_error();
echo json_last_error_msg();
print_r($json_array);
?>
Make sure your JSON is actually valid. For some reason I was convinced that this was valid JSON:
{ type: "block" }
While it is not. Point being, make sure to validate your string with a linter if you find json_decode not te be working.
Try the JSON validator.
The problem in my case was it used ' not ", so I had to replace it to make it working.
In notepad+ I changed encoding of json file on: "UTF-8 without BOM".
JSON started to work
TL;DR Be sure that your JSON not containing comments :)
I've taken a JSON structure from API reference and tested request using Postman. I've just copy-pasted the JSON and didn't pay attention that there was a comment inside it:
...
"payMethod": {
"type": "PBL" //or "CARD_TOKEN", "INSTALLMENTS"
},
...
Of course after deletion the comment json_decode() started working like a charm :)
Use following function:
If JSON_ERROR_UTF8 occurred :
$encoded = json_encode( utf_convert( $responseForJS ) );
Below function is used to encode Array data recursively
/* Use it for json_encode some corrupt UTF-8 chars
* useful for = malformed utf-8 characters possibly incorrectly encoded by json_encode
*/
function utf_convert( $mixed ) {
if (is_array($mixed)) {
foreach ($mixed as $key => $value) {
$mixed[$key] = utf8ize($value);
}
} elseif (is_string($mixed)) {
return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
}
return $mixed;
}
Maybe it helps someone, check in your json string if you have any NULL values, json_decode will not work if a NULL is present as a value.
This super basic function may help you. I made the NULL in an array just in case I need to add more stuff in the future.
function jsonValueFix($json){
$json = str_replace( array('NULL'),'""',$json );
return $json;
}
I just used json_decode twice and it worked for me
$response = json_decode($apiResponse, true);
$response = json_decode($response, true);

Decoding base64 strings in PHP

I am trying to decode base64 string in PHP.
For example, I can do this in a python script by doing:
s = "0CC0QFjAA"
base64.b64decode(str(s)+'=====', '_-');
How can I decode base64 strings in PHP?
I think this would do it:
$decoded = base64_decode(str_replace(array('_', '-'), array('+', '/'), $s));
If you need the more general form:
function b64decode($str, $altchars = null) {
if ($altchars) {
$altarray = array($altchars[0], $altchars[1]);
$str = str_replace($altarray, array('+', '/'), $str);
}
return base64_decode($str);
}
The PHP function is called base64_decode. You could call it like base64_decode($s);

CakePHP 1.3 warning array_merge sanitize

I'm using CakePHP 1.3.7 and ran into a very specific issue.
The Sanitize core class method used in my application is the one of version 1.2. When I want to save particular data, it gives me a warning :
Warning: array_merge(): Argument #2 is not an array in
/usr/share/php/cake/libs/sanitize.php on line 113
but it does save, and with the right encoding/format.
Here's the method who causes this warning (version 1.2, which is NOT on line 113, but I'll come to that later)
function html($string, $remove = false) {
if ($remove) {
$string = strip_tags($string);
} else {
$patterns = array("/\&/", "/%/", "/</", "/>/", '/"/', "/'/", "/\(/", "/\)/", "/\+/", "/-/");
$replacements = array("&", "%", "<", ">", """, "'", "(", ")", "+", "-");
$string = preg_replace($patterns, $replacements, $string);
}
return $string;
}
And here's how this method is called
$value = Sanitize::html($value,true);
Now as you can see, array_merge() is not called in this method, but if I replace the html() method by the 1.3 version
function html($string, $options = array()) {
static $defaultCharset = false;
if ($defaultCharset === false) {
$defaultCharset = Configure::read('App.encoding');
if ($defaultCharset === null) {
$defaultCharset = 'UTF-8';
}
}
$default = array(
'remove' => false,
'charset' => $defaultCharset,
'quotes' => ENT_QUOTES
);
$options = array_merge($default, $options);
if ($options['remove']) {
$string = strip_tags($string);
}
return htmlentities($string, $options['quotes'], $options['charset']);
}
array_merge() falls exactly on line 113.
If I now call html() this way
$value = Sanitize::html($value,array('remove' => true));
I don't get the warning anymore. However, my data doesn't save with the right encoding/format anymore.
Here's an example of text I need to save (it is french and needs UTF-8 encoding)
L'envoi d'une communication & à la fenêtre
I can't overcome this doing
$value = Sanitize::html($value,array('remove' => true, 'quotes' => ENT_HTML401));
because I'm using PHP 5.3.6 thus I can't use the constant ENT_HTML401
If I use another constant like ENT_NOQUOTES, it ignores the quotes (obviously) but not the french accents and other special chars, which is intented to work this way but I want to save the text exactly like I quoted (or at least read it).
I'm guessing I wouldn't need to use htmlentities, but I think it is safer to and updating the core method is the only way I found to not get the warning. I also suppose I should not really modify these files other than for updating them?
So, briefly, I want to :
Get rid of the warning
Save/read data in the right format
I might have forgotten some infos, thanks
I ended up updating the html() method of the Sanitize class to match version 1.3 as follow
function html($string, $options = array()) {
static $defaultCharset = false;
if ($defaultCharset === false) {
$defaultCharset = Configure::read('App.encoding');
if ($defaultCharset === null) {
$defaultCharset = 'UTF-8';
}
}
$default = array(
'remove' => false,
'charset' => $defaultCharset,
'quotes' => ENT_QUOTES
);
$options = array_merge($default, $options);
if ($options['remove']) {
$string = strip_tags($string);
}
return htmlentities($string, $options['quotes'], $options['charset']);
}
I call it like this
$value = Sanitize::html($value, array('remove'=>true,'quotes'=>ENT_NOQUOTES));
And I simply decode the text fields this way whenever I read their value from database
$data['Model']['field'] = html_entity_decode($data['Model']['field'], ENT_NOQUOTES, "UTF-8");
EDIT : I had to undo what I described above because the way data was encoded in the 1.3 version of the function made it so we had to decode the data in the whole application when reading it.
Also, I am NOT using CakePHP 1.3.7 (got confused with cake console); I'm using 1.2.4 so updating the function was not appropriate afterall.
I kept the version 1.2 and this time I simply changed the second parameter to an array as follow and it seemed to do the trick as I'm not getting the warning anymore.
function html($string, $options = array()) {
if ($options['remove']) {
$string = strip_tags($string);
} else {
$patterns = array("/\&/", "/%/", "/</", "/>/", '/"/', "/'/", "/\(/", "/\)/", "/\+/", "/-/");
$replacements = array("&", "%", "<", ">", """, "'", "(", ")", "+", "-");
$string = preg_replace($patterns, $replacements, $string);
}
return $string;
}

Categories