PHP json_encode($_POST) and mySQL issue - php

I am trying to json_encode($_POST) in PHP, but I have one small problem.
On my $_POST sometimes I get some encoded JSON as example below:
Array
(
[module] => {"media":true}
)
Where module contains a JSON string. My problem is when I use json_encode($POST); I get a result like this:
{"module":"{\"petMedia\":true}"}
Trying to insert into mySQL JSON column, I get this error
Invalid JSON text: "Missing a comma or '}' after an object member.
It's not possible for me to decode the string before because not always I get encoded JSON.
Thanks.

If I had POST variables coming in where sometimes they have json encoded in it, or not... one way to handle it, would be a cleanup loop.
Lets say this is the POST in:
$_POST -> 'var1' = 'some string'
-> 'var2' = '2315'
-> 'var3' = '{"some":"json"}'
Now, I would setup a little cleaner, because you cannot just json_encode($_POST) as you found out. It double encodes the var3.
$clean = array();
foreach($_POST as $key => $val) {
json_decode($val);// test
if (json_last_error() == JSON_ERROR_NONE) {
$clean[$key] = json_decode($val);// $val is json, so pre-decode it
} else {
$clean[$key] = $val;// its not real json, so assign straight
}
}
print_r($clean);
print_r(json_encode($clean));
Results in:
Array (
[var1] => some string
[var2] => 2315
[var3] => stdClass Object
(
[some] => json
)
)
// this then is a json encoded string, which is good:
{"var1":"some string","var2":2315,"var3":{"some":"json"}}
Basically, this then makes a full object which you can now store into the database safely, since all variables and their values are json encodable.
I hope this helps you get started, and you dont actually have normal variables inside json strings, that are not json encoded, and and and and ;)

A variation on a theme perhaps
/* emulate POST */
$_POST=array(
'php'=>'fantastic',
'javascript'=>'awesome',
'asp'=>'awful',
'module'=>json_encode( array( 'media' => true ) )
);
/* process the POST array and decode any json data within */
array_walk( $_POST, function( &$value ){
$tmp=json_decode( $value );
if( json_last_error() == 0 )$value=$tmp;
});
/* encode the POST data */
$encoded=json_encode( $_POST );
Outputs:
{"php":"fantastic","javascript":"awesome","asp":"awful","module":{"media":true}}

Related

PHP delete json array item messes up the JSON itself

I am facing a strange issue with my PHP code (I'm a beginner to PHP so apologies for my bad coding skills). Each array item in my JSON has a unique ID associated with it, to delete an array I just pass the unique ID to my code and it deletes the array item associated with it, but all my array items contain an integer field and that doesn't get deleted and it messes up my JSON (parsing fails when I try to do so later).
<?php
$var1 = filter_input(INPUT_POST, 'unique_id', FILTER_UNSAFE_RAW);
if ($var1 === null) {
die('The "unique_id" parameter is not set');
}
$data = file_get_contents('feed.json');
if ($data === false) {
die('An error occurred when opening "feed.json"');
}
$json = json_decode($data, true);
if ( ! isset($json[0]['unique_id'])) {
die("The JSON was not decoded correctly");
}
foreach ($json as $key => $value) {
if ($value['unique_id'] == $var1) {
unset($json[$key]);
}
}
$new_json_string = json_encode($json);
file_put_contents('feed.json', $new_json_string, JSON_UNESCAPED_SLASHES | LOCK_EX);
echo "Success";
?>
Here's the sample JSON:
[
{"student_id":"22222222","unique_id":"862916786a1340afbfdf23caa541963f","status":"Hey yo what's up","image":"none","likes":"0"},
{"student_id":"33333333","unique_id":"d237556a90d44b1397e9290cd8g09349","status":"Message from another student","image":"none","likes":22}
]
after deleting, I'm left with
{"1":{"student_id":"33333333","unique_id":"d237556a90d44b1397e9290cd8g09349","status":"Message from another student","image":"","likes":31}
As you can see {"1": is invalid and shouldn't be there.
Does anyone know what am I doing wrong?
EDIT: Here's my code to create a new array item in my JSON
$json = file_get_contents('feed.json');
$data = json_decode($json);
$data[] = array('student_id' => "$student_id", 'unique_id' => "$unique_id" ,'status' => "$status_txt", 'image' => "$image_link", 'likes' => "0");
file_put_contents('feed.json', json_encode($data), JSON_UNESCAPED_SLASHES | LOCK_EX);
This is a combination of two things:
There is no representation of sparse Arrays in JSON
JSON's arrays with [] can only have a comma-separated list of contiguous elements starting from index 0.
No type information distinguishes JSON arrays and JSON objects in PHP
Both of these things are stored as PHP's array type. JSON objects use the associative keys.
When you unset index 0 from your array, it becomes sparse. Now, the only way to encode something that has a something[1] but no something[0] in JSON is to have an object with a key "1".
PHP's JSON encoder allows this because the array you pass in is of the right type (array) to be serialized as a JSON object. So it does this.
Maybe you wanted to use array_splice to remove the array element instead of unset.
Use array_values() to convert array as notified by Cheery in comments.

Get the value for key in json array in php

How to get the corresponding value for key associated
[{"name":"challenge","properties":[{"name":"mobileNo","value":"aa"},{"name":"challengeT","value":"1Day"},{"name":"emailId","value":"ff#gmail.com"},{"name":"deviceId","value":"9500e297-081b-4f97-93b7-dafddc55db31"}]},{"name":"challenge","properties":[{"name":"emailId","value":"a#b.com"},{"name":"mobileNo","value":"345345"},{"name":"deviceId","value":"435435dfgdfg"}]}]
Your Json is valid. You can validate at following
website: http://jsonlint.com/
You have to use a php "json_decode()" function to decode a json encoded data.
Basically json_decode() function converts JSON data to a PHP array.
Syntax: json_decode( data, dataTypeBoolean, depth, options )
data : - The json data that you want to decode in PHP.
dataTypeBoolean(Optional) :- boolean that makes the function return a PHP Associative Array if set to "true", or return a PHP stdClass object if you omit this parameter or set it to "false". Both data types can be accessed like an array and use array based PHP loops for parsing.
depth :- Optional recursion limit. Use an integer as the value for this parameter.
options :- Optional JSON_BIGINT_AS_STRING parameter.
Now Comes to your Code
$json_string = '[{"name":"challenge","properties":[{"name":"mobileNo","value":"aa"},{"name":"challengeT","value":"1Day"},{"name":"emailId","value":"ff#gmail.com"},{"name":"deviceId","value":"9500e297-081b-4f97-93b7-dafddc55db31"}]},{"name":"challenge","properties":[{"name":"emailId","value":"a#b.com"},{"name":"mobileNo","value":"345345"},{"name":"deviceId","value":"435435dfgdfg"}]}]' ;
Assign a valid json data to a variable $json_string within single quot's ('') as
json string already have double quots.
// here i am decoding a json string by using a php 'json_decode' function, as mentioned above & passing a true parameter to get a PHP associative array otherwise it will bydefault return a PHP std class objecy array.
$json_decoded_data = json_decode($json_string, true);
// just can check here your encoded array data.
// echo '<pre>';
// print_r($json_decoded_data);
// loop to extract data from an array
foreach ($json_decoded_data as $key => $value) {
echo "$key <br/>";
foreach ($value as $key2 => $value2) {
echo "$key2 = $value2 <br />";
}
}
Output :
0
name = challenge
properties = Array
1
name = challenge
properties = Array

PHP json_decode return empty array

I just test this sample from php doc (http://au2.php.net/manual/en/function.json-decode.php)
here is my code:
<?php $json = '{"a":1,"b":2,"c":3,"d":4,"e":5}'; echo json_decode($json, true), '<br />';?>
But it just returns an EMPTY array.
Have no idea why...Been searching around but no solution found.
PLEASE help!
You can validate at following
website: http://jsonlint.com/
You have to use a php "json_decode()" function to decode a json encoded data.
Basically json_decode() function converts JSON data to a PHP array.
Syntax: json_decode( data, dataTypeBoolean, depth, options )
data : - The json data that you want to decode in PHP.
dataTypeBoolean(Optional) :- boolean that makes the function return a PHP Associative Array if set to "true", or return a PHP stdClass object if you omit this parameter or set it to "false". Both data types can be accessed like an array and use array based PHP loops for parsing.
depth :- Optional recursion limit. Use an integer as the value for this parameter.
options :- Optional JSON_BIGINT_AS_STRING parameter.
Now Comes to your Code
$json_string = '{"a":1,"b":2,"c":3,"d":4,"e":5}' ;
Assign a valid json data to a variable $json_string within single quot's ('') as
json string already have double quots.
// here i am decoding a json string by using a php 'json_decode' function, as mentioned above & passing a true parameter to get a PHP associative array otherwise it will bydefault return a PHP std class objecy array.
$json_decoded_data = json_decode($json_string, true);
// just can check here your encoded array data.
// echo '<pre>';
// print_r($json_decoded_data);
// loop to extract data from an array
foreach ($json_decoded_data as $key => $value) {
echo "$key | $value <br/>";
}
you should not use echo because it is an array. use print_r or var_dump .it works fine
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
print_r(json_decode($json, true));
Output:
Array
(
[a] => 1
[b] => 2
[c] => 3
[d] => 4
[e] => 5
)
No, it doesn't return an empty array.
Printing an array with echo just prints a string "Array()".
Use print_r or var_dump to get the structure of the variable.
In newer PHP it will also emit a notice when using echo on an array ("Array to string conversion"), so you shouldn't do it anyway. The manual you've mentioned changed to print_r.
It works fine, but you use wrong method to display array.
To display array you cannot use echo but you need to use var_dump
It works fine as others mention, but when you print the array it is converted to string, which means only the string "Array" will be printed instead of the real array data. You should use print_r(), var_dump(), var_export() or something similar to debug arrays like this.
If you turn on notices you will see:
PHP Notice: Array to string conversion in ...
The example you linked uses also var_dump for the same reason.
var_dump have pretty print in php5.4
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump( json_decode($json));

PHP json_decode thrown an error for validate json string

I have following error
Notice: Trying to get property of non-object in action.php
while posted json has validated (by jsonLint.com validation).
Here is my json string:
[
{
"eTGid": "1",
"eTid": "34",
"evrakGelisTarihi": "12/12/2013",
"evrakKonu": "Sertifika denemesi",
"evrakKurumID": "1047",
"evrakCikisTarihi": "13/12/2013",
"evrakCikisSayisi": "313213213213",
"aciklamaBolumu": "açıklayıcı notlar",
"gelenEvrakTarihi": "30/12/2013",
"gelenEvrakSayisi": "3132321",
"gelenEvrakEtakipNo": "987654",
"bagliIlaclar": "[\"0\",\"[{\\\"ilacID\\\":\\\"744\\\",\\\"ilacPN\\\":\\\"asdasd2132\\\",\\\"ilacSKT\\\":\\\"12/12/2013\\\"}]\"]",
"bagliFirmalar": "[\"0\",\"[{\\\"firmaID\\\":\\\"1047\\\"}]\"]",
"": "[\"0\",\"[{\\\"bankaID\\\":\\\"5\\\",\\\"makbuzNO\\\":\\\"asdasda\\\",\\\"makbuzTARIHI\\\":\\\"12/12/2013\\\",\\\"ihracaatYapilacakUlkeID\\\":\\\"2\\\",\\\"ilacIhracADI\\\":\\\"ABFADER\\\",\\\"makbuzTUTAR\\\":\\\"202,06\\\",\\\"makbuzTipDetayDEGERİ\\\":\\\"10\\\"}]\",\"[{\\\"bankaID\\\":\\\"5\\\",\\\"makbuzNO\\\":\\\"ASDAWW\\\",\\\"makbuzTARIHI\\\":\\\"12/12/2013\\\",\\\"ihracaatYapilacakUlkeID\\\":\\\"191\\\",\\\"ilacIhracADI\\\":\\\"ABFADEX\\\",\\\"makbuzTUTAR\\\":\\\"202,06\\\",\\\"makbuzTipDetayDEGERİ\\\":\\\"9\\\"}]\"]",
"bagliMakbuzlar": "[\"0\",\"987654»12/12/2013»3213213\"]",
"kurumIcimi": "hayir"
}
]
and my php code is:
$gelenJsonVerisi = $_POST['yeniEvrak'];
echo($gelenJsonVerisi);
$yeniEvrakObj = json_decode($gelenJsonVerisi);
exit($yeniEvrakObj->{'eTGid'});
Where did I go wrong?
After suggestions:
My Json string has arrived to the serverside (php) as an array (between brackets).
Array has only one element (member) that it is our json string (object)
Handle the arrays first element and assign it to a php object and deal with it.
$gelenJsonVerisi = $_POST['yeniEvrak'];
$yeniEvrakObjArray = json_decode($gelenJsonVerisi,TRUE);
$yeniEvrakObj = $yeniEvrakObjArray[0];
exit($yeniEvrakObj['eTGid']); // one of sample value
Thank you
The JSON string shows an array, that contains a single object. access the data like so:
$yeniEvrakObj = json_decode($gelenJsonVerisi);
echo $yeniEvrakObj[0]->eTGid;
If you're sure there's but 1 object inside that array, you could try:
$yeniEvrakObj = json_decode(
substr($gelenJsonVerisi,1,-1)
);
Which chops off the leading and terminating brackets. This implies no leading of trailing whitespace, so trim the string first.
check codepad. As you can see, the json_decode call returns the data as an array containing an object:
Array
(
[0] => stdClass Object
(
[eTGid] => 1
[eTid] => 34
[evrakGelisTarihi] => 12/12/2013
[evrakKonu] => Sertifika denemesi
[evrakKurumID] => 1047
[evrakCikisTarihi] => 13/12/2013
[evrakCikisSayisi] => 313213213213
)
)
It's not json_decode throwing the error, it's when you try to access the resulting array. Yes, that's right, array. Your JSON value is this:
[ { ... } ]
^ array ^
So you need to access the result like:
$yeniEvrakObj[0]->eTGid
$gelenJsonVerisi = $_POST['yeniEvrak'];
echo($gelenJsonVerisi);
$yeniEvrakObj = json_decode($gelenJsonVerisi);
exit($yeniEvrakObj[0]->eTGid);
The problem is the way you're trying to access to the decoded object, as it is inside an array.
Your code should be:
$gelenJsonVerisi = $_POST['yeniEvrak'];
echo($gelenJsonVerisi);
$yeniEvrakObj = json_decode($gelenJsonVerisi);
exit($yeniEvrakObj[0]->eTGid);
Edit: Thanks for the comments on this answer that made me see I was mistaken

PHP: Recursive htmlspecialchars on object

I want to establish a generic sanitizer for my data that comes from various sources. With sanitizing I mean (at this stage) applying htmlspecialchars to strings. Now, the data that comes from these sources can be anything from an object to an array to a string, all nested (and complicated), and the format is always a bit different.
So I thought of a recursive htmlspecialchars function that applies itself to arrays and objects, and only applies htmlspecialchars to strings, but how do I walk an object recursively?
Thanks.
EDIT: I think I should have mentioned this - I am actually building a RIA that relies heavily on JS and JSON for client-server communication. The only thing the server does is fetching stuff from the database and returning it to the client via JSON, in the following format:
{"stat":"ok","data":{...}}
Now as I said, data could be anything, not only coming from a DB in the form of strings, but also coming from an XML
The workflow to process the JSON is as follows:
Fetch data from the DB/XML (source encoding is iso-8859-1)
Put them into the "data" array
Recursively convert from iso-8859-1 to utf-8 using
private function utf8_encode_deep(&$input) {
if (is_string($input)) {
$input = $this -> str_encode_utf8($input);
} else if (is_array($input)) {
foreach ($input as &$value) {
$this -> utf8_encode_deep($value);
}
unset($value);
} else if (is_object($input)) {
$vars = array_keys(get_object_vars($input));
foreach ($vars as $var) {
$this -> utf8_encode_deep($input -> $var);
}
}
}
Use PHP's json_encode to convert the data into JSON
Send (echo) the data to the client
Render the data using JS (e.g. putting into a table)
And somewhere in between that, the data should be somehow sanitized (at this stage only htmlspecialchars). Now the question should have been: Where to sanitize, using what method?
You can try the following
class MyClass {
public $var1 = '<b>value 1</b>';
public $var2 = '<b>value 2</b>';
public $var3 = array('<b>value 3</b>');
}
$list = array();
$list[0]['nice'] = range("A", "C");
$list[0]['bad'] = array("<div>A</div>","<div>B</div>","<div>C</div>",new MyClass());
$list["<b>gloo</b>"] = array(new MyClass(),"<b>WOW</b>");
var_dump(__htmlspecialchars($list));
Function Used
function __htmlspecialchars($data) {
if (is_array($data)) {
foreach ( $data as $key => $value ) {
$data[htmlspecialchars($key)] = __htmlspecialchars($value);
}
} else if (is_object($data)) {
$values = get_class_vars(get_class($data));
foreach ( $values as $key => $value ) {
$data->{htmlspecialchars($key)} = __htmlspecialchars($value);
}
} else {
$data = htmlspecialchars($data);
}
return $data;
}
Output Something like
array
0 =>
array
'nice' =>
array
0 => string 'A' (length=1)
1 => string 'B' (length=1)
2 => string 'C' (length=1)
'bad' =>
array
0 => string '<div>A</div>' (length=24)
1 => string '<div>B</div>' (length=24)
2 => string '<div>C</div>' (length=24)
3 =>
object(MyClass)[1]
...
array
0 =>
object(MyClass)[2]
public 'var1' => string '<b>value 1</b>' (length=26)
public 'var2' => string '<b>value 2</b>' (length=26)
public 'var3' =>
array
...
You would only want to escape when outputting into HTML. And you cannot output a complete array or object into HTML, so escaping everything seems invalid.
You have one level of indirection because of your JSON output. So you cannot decide in PHP what context the data is used for - JSON is still plain text, not HTML.
So to decide whether any data inside the JSON must be escaped for HTML we must know how your Javascript is using the JSON data.
Example: If your JSON is seen as plain text, and contains something like <b>BOLD</b>, then the expected outcome when used inside any HTML is exactly this text, including the chars that look like HTML tags, but no bold typesetting. This will only happen if your Javascript client handles this test as plain text, e.g. it DOES NOT use innerHTML() to place it on the page, because that would activate the HTML tags, but only innerText() or textContent() or any other convenience method in e.g. jQuery (.text()).
If on the other hand you expect the JSON to include readymade HTML that is fed into innerHTML(), then you have to escape this string before it is put into JSON. BUT you must escape the whole string only if you do not want to add any formatting to it. Otherwise you are in a situation that uses templates for mixing predefined formatting with user content: The user content has to be escaped when put into HTML context, but the result must not - otherwise Javascript cannot put it into innerHTML() and enable the formatting.
Basically a global escaping for everything inside your array or object most likely is wrong, unless you know for everything that it will be used in a HTML context by your Javascript.
function htmlrecursive($data){
if (is_array($data) && count($data) > 1){
foreach ($data as &$d){
$d = htmlrecursive($d);
}
} else if (!is_array($data)){
return htmlspecialchars($data);
}
else {
return htmlspecialchars($data[0])
}
}
htmlrecursive($array);
For objects you need to implement The ArrayAccess interface then you can do a array walk recursive
Also check this question Getting an object to work with array_walk_recursive in PHP

Categories