Is it possible to send JSON data from the client side using ajax (with jQuery), to a PHP page and use json_decode with all the variables exactly the same data type? I thought JSON was suppose to preserve this but it seems it doesn't work if you send it to PHP. If it doesn't do this then I'm not sure why I should ever be using JSON. I might as well just use a standard POST request.
My problem is that I need to send data to PHP for it to be inserted into MySQL which requires the right variable types being inserted, but when the data arrives from JSON it is all converted to a string. I think I'm misunderstanding what JSON is suppose to be used for. Most likely, and if so can anyone explain this to me?
Does this mean I need to manually convert everything on the PHP side all the time throughout my entire web application? That would be a real pain.
// JavaScript:
$.ajax({
type: "POST",
url: "program.php",
data: {
posting: true,
json: JSON.stringify({
posting: true,
id: 6, // should remain an integer
})
},
success: function(data) {
console.log(data);
}
});
// PHP:
if (array_key_exists("posting", $_POST)) {
$result = json_decode($_POST["json"]);
echo gettype($result->id); // string (all values in $result are strings still)
exit();
}
EDIT: The reason I'm worried about variable types is because I am trying to use prepared statements with MySQL and the bind_param function requires you to enter the variable types. This is a PHP function I created to handle this for me:
public static function insert($query, $params) {
$statement = mysqli_prepare(self::$connection, $query);
foreach ($params as $value) {
switch (gettype($value)) {
case "boolean":
$value = (int) $value;
case "integer":
$statement->bind_param("i", $value);
break;
case "double":
$statement->bind_param("d", $value);
break;
case "string":
// it is ALWAYS a string even though some as suppose to be integers
$statement->bind_param("s", $value);
break;
default:
echo "error type: " . gettype($value);
return;
}
}
$statement->execute();
$statement->fetch();
$result = $statement->get_result();
$statement->close();
return $result;
}
If you're still getting stuck with this I have done a basic example that covers the HTML/JavaScript using Jquery and the PHP page (logging data to a text file)
JavaScript Code - Index.html
<a href="#" class="button">Submit</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(".button").on("click", function(){
ajaxSubmit();
});
var ajaxSubmit = function(){
var obj = {};
obj['foo'] = {};
obj['foo']['type'] = 'integer';
obj['foo']['value'] = 1;
obj['bar'] = {};
obj['bar']['type'] = 'string';
obj['bar']['value'] = 'hello';
sendData = JSON.stringify(obj);
$.ajax({
type: "POST",
url: "program.php",
data: {'json': sendData},
success: function(data) {
console.log(data);
}
});
};
</script>
PHP Code - program.php
<?php
$data = $_REQUEST;
$obj = json_decode($data['json']);
foreach ($obj as $var) {
switch ($var->type) {
case 'integer':
fileWrite('Integer: '.$var->value);
break;
case 'string':
fileWrite('String: '.$var->value);
break;
}
}
function fileWrite ($string) {
if (is_array($string)){
$string = 'Array: '.print_r($string, true);
}
if(is_object($string)) {
$string = 'Object: '.print_r($string, true);
}
$fp = fopen('output.txt', 'a');
fwrite($fp, $string."
");
fclose($fp);
}
?>
Let's start with what the JSON developers failed to mention in their specification: JSON is actually JSON when it's used in a string context.
Think logically with me here. How are you going to transfer the data type information? The rational thing would be to mark it somehow. Well, JavaScript does that while it holds your not-so-JSON-yet as an object. But since $_POST
uses only application/x-www-form-urlencoded or multipart/form-data, you end up with the string or binary data anyway.
But at this state it's not possible to save and transfer data types inside your string json, not until you specify data types directly in your JSON as this:
{"name": "Food", "value": "Banana", "type": "string"},
{"name": "Drink", "value": "Beer", "type": "string"},
{"name": "Count", "value": "42", "type": "int"}
And then parse it in PHP. Or punch in the required data types for bind_param
directly and just use it after decoding JSON.
Oh, and yeah, stringify
somehow speaks for itself:
The JSON.stringify() method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified, or optionally including only the specified properties if a replacer array is specified.
Further reading: