Your PHP starts like this:
<html>
<body>
Whatever else it outputs after that, it isn't going to be valid JSON.
I did some debugging in chrome and under the network tab verified the response preview
Look at the raw preview. You seem to be looking at the rendered HTML preview.
Answer from Quentin on Stack Overflowphp - Why would json_encode return an empty string - Stack Overflow
json_encode shows empty objects
javascript - JSON encoding with Services_JSON and json_encode in PHP returning empty object with jQuery ajax call - Stack Overflow
php - Why json_encode returns empty brackets? - Stack Overflow
Your PHP starts like this:
<html>
<body>
Whatever else it outputs after that, it isn't going to be valid JSON.
I did some debugging in chrome and under the network tab verified the response preview
Look at the raw preview. You seem to be looking at the rendered HTML preview.
You don't need to parseJSON when you have added dataType as JSON option in the AJAX.
The data you are getting after ajax is completed is already in JSON format.
"json": Evaluates the response as JSON and returns a JavaScript object. The JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected; the server should return a response of null or {} instead. (See json.org for more information on proper JSON formatting.)
Docs: http://api.jquery.com/jQuery.ajax/
The data inside fail method is not what you've passed from server. It is the information related to the request.
Well after 2 hours of digging (cf Edits)
I found out following :
- In my case it's a encoding problem
mb_detect_encodingreturns probably a faulty response, some strings were probably not UTF-8- using
utf8_encode()on those string solved my problem, but see note below
Here is a recursive function that can force convert to UTF-8 all the strings contained in an array:
function utf8ize($d) {
if (is_array($d)) {
foreach ($d as $k => $v) {
$d[$k] = utf8ize($v);
}
} else if (is_string ($d)) {
return utf8_encode($d);
}
return $d;
}
Use it simply like this:
echo json_encode(utf8ize($data));
Note: utf8_encode() encodes ISO-8859-1 string to UTF-8 as per the docs so if you are unsure of the input encoding iconv() or mb_convert_encoding() may be better options as noted in comments and other solutions.
For me, the answer to this problem was setting charset=utf8 in my PDO connection.
$dbo = new PDO('mysql:host=localhost;dbname=yourdb;charset=utf8', $username, $password);
use the JSON_FORCE_OBJECT option of json_encode:
json_encode($status, JSON_FORCE_OBJECT);
Documentation
JSON_FORCE_OBJECT (integer) Outputs an object rather than an array when a non-associative array is used. Especially useful when the recipient of the output is expecting an object and the array is empty. Available since PHP 5.3.0.
Or, if you want to preserve your "other" arrays inside your object, don't use the previous answer, just use this:
$status = array(
"message"=>"error",
"club_id"=>$_club_id,
"status"=>"1",
"membership_info"=> new stdClass()
);
$status = array(
"message"=>"error",
"club_id"=>$_club_id,
"status"=>"1",
"membership_info"=>(object) array(),
);
By casting the array into an object, json_encode will always use braces instead of brackets for the value (even when empty).
This is useful when can't use JSON_FORCE_OBJECT and when you can't (or don't want) to use an actual object for the value.
Recommended method
json_decode ("{}") will return a stdClass per default, using the below should therefor be considered safe/portable and correct.
json_encode (new stdClass);
Your solution could work..
The documentation specifies that (object) null will result in an empty object, some might therefor say that your code is valid and that it's the method to use.
PHP: Objects - Manual
If a value of any other type is converted to an object, a new instance of the stdClass built-in class is created. If the value was NULL, the new instance will be empty.
.. but, try to keep it safe!
Though you never know when/if the above will change, so if you'd like to be 100% certain that you will always will end up with a {} in your encoded data you could use a hack such as:
$empty = json_decode ("{}");
$result = json_encode($empty); // "{}"
Even though it's tedious and ugly I do assume/hope that json_encode/json_decode is compatible with one another and always will evaluate the following to true:
$a = <something>;
$a === json_decode (json_encode ($a));
If you use objects as dynamic dictionaries (and I guess you do), then I think you want to use an ArrayObject.
It maps into JSON dictionary even when it's empty. It is great if you need to distinguish between lists (arrays) and dictionaries (associative arrays):
$complex = array('list' => array(), 'dict' => new ArrayObject());
print json_encode($complex); // -> {"list":[],"dict":{}}
You can also manipulate it seamlessly (as you would do with an associative array), and it will keep rendering properly into a dictionary:
$complex['dict']['a'] = 123;
print json_encode($complex); // -> {"list":[],"dict":{"a":123}}
unset($complex['dict']['a']);
print json_encode($complex); // -> {"list":[],"dict":{}}
If you need this to be 100% compatible both ways, you can also wrap json_decode so that it returns ArrayObjects instead of stdClass objects (you'll need to walk the result tree and recursively replace all the objects, which is a fairly easy task).
Gotchas. Only one I've found so far: is_array(new ArrayObject()) evaluates to false. You need to find and replace is_array occurrences with is_iterable.
I have a function written like this in my Laravel controller:
/**
* @param Request $request
*
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Throwable
*/
public function saveFreshBatch(Request $request)
{
Log::info("Received a new fresh batch... " . json_encode($request));
...
On my local, I get the following in my logs: "Received a new fresh batch... ", so a string followed by an empty array, with no text afterward, which means the result of json_encode($request) was blank. However, the object is full of data. I ran the debugger and it returned this:
> json_encode($request)
< {"attributes":{},"request":{},"query":{},"server":{},"files":{},"cookies":{},"headers":{}}
However, json_encode($request->all()) returns the correct string as if doing the whole thing, even on local.
On the production (Dev) server, I get a full JSON output, so a gigantic PHP array. In both cases I notice $request->all() gives full code.
Any ideas why the same code would result in different output, for the same object? The only thing I can think of is the headers are different, or the subclassed request is different.
Why does json_encode($request) return different outputs for the same HTTP request?
Problem is that your output has three Objects with private and protected attributes.
See this example
<?php
class sampleClass
{
private $hello = 25;
}
$class = new sampleClass();
echo json_encode($class);
?>
Output will be {}
In your case you have array [] of three {} objects, and they are empty because all their attributes are private or protected.
But if you will change object attributes to be public, public $hello = 25; then output will be
{"hello":25}
You have protected and private attributes, so you can not use any functions, including json_encode() to access directly to your object's property.
Use JSONSerialize
With that line of code
var x = <?php echo $obj ?>;
...the server application echoes back the data that was submitted to it via the "js" key. It will be client that sent it that will receive it, so if in some way it is malicious, it will be that same client dealing with the consequences.
The actual sending to the server is in fact the irrelevant part of the chain: if one has the data to submit, one can also assign it to the variable x directly without the server's interference (e.g. through browser's dev tools).
It would be a different story if in PHP you would use the data to manipulate a server database, call a service, or otherwise change the application's state, and you would not first validate that data.
As to the use of json_encode: if indeed you verify that the argument is valid JSON (by checking that the return value is not false), it will produce a valid JavaScript object literal. The known cases of incompatibility (characters U+2028 and U+2029) will not occur, as by default json_encode escapes these characters.
It is correct as per coding. However you have to validate the variable x should not be empty or the posted value.
<script>var x = "<?php if(isset($_POST['js']))
{
echo json_encode($_POST["js"]);
}";
</script>
Try this one, it will definitely works
function utf8ize($d) {
if (is_array($d)) {
foreach ($d as $k => $v) {
$d[$k] = utf8ize($v);
}
} else if (is_string ($d)) {
return utf8_encode($d);
}
return $d;
}
and then call
echo json_encode( utf8ize( $array ) );
Your json_encode seems to be failing, you would have gotten the notice if you had it enabled in your PHP config. There is other way of deciding is your json_encode failed, try getting the value of json_last_error
This error message might be helpful to decide what went wrong with the encoding.
EDIT
Questions like this has already been answered:
Here