I'm writing a native iOS 7 app that requires retrieving data from a JSON api (that I control). Example JSON output looks like:
{
"id" : "544",
"name" : "1900 Green Gables",
"address" : "83 West Main Street",
"city" : "Milford",
"phone" : "(607) 547-1381",
"video_thumb" : null,
"thumbnail" : null,
"s_description" : null
}
I'm using php's json_encode() to convert the associative array returned from my DB query. In the objective-c I use NSJSONSerialization to convert the JSON into an NSMutableArray. The problem is that null values are converted to "<null>". I suspect this is because json_encode() is not double quoting null values. I'd rather keep the value null for consistency's sake (doesn't seem robust to check if a value is "<null>" in my obj-c code)
I know that I could fix the problem by regexing the output of json_encode(), but I'd rather avoid the extra step and I'm worried about the negative impact on performance. Are there any changes I can make to the PHP, Objective-C or even the SQL query to fix this?
<null> is the stringified description of [NSNull null], which is a placeholder for nil in Cocoa collections (which can't contain nil directly).
You should be comparing the value to [NSNull null]:
if (dictFromJson[#"video_thumb"] != [NSNull null]) {
// do stuff with video thumb here
}
Related
i am using
$user = User::find($user_id);
return response()->json(array('user'=>$user),200);
On local server with php5.9 it returns all the keys except id as string.
{
"success": "1",
"message": "success",
"user": {
"id": 75,
"name": "",
"postal_code": "73733",
}
}
But the same code on production server with php7.0 returns other keys as of type integer ex. check this postal_code value.
{
"success": "1",
"message": "success",
"user": {
"id": 75,
"name": "",
"postal_code": 73733,
}
}
So solve this i am using $cast=[] in User.php.
But i have used raw queries also. What is the best way to convert all the values in response json to be of string type.
The difference in the type is most likely due to the fact that your local server is using the php5-mysqld (non-native) driver, whereas your production server is probably using the php-mysqlnd (native) driver. One of the main differences is that the non-native driver reads all fields as strings, whereas the native driver will automatically convert integer fields to PHP integers.
The id shows up as an integer in both cases because Laravel automatically adds the primary key field ('id') to the casts array with the type defined by the $keyType property (default to int).
I would say you have four options:
Attempt to install the non-native mysql driver for PHP 7 on your production server (not recommended).
Don't do anything on the PHP side, and just make sure that whatever is consuming the json can handle strings or integers (probably a good idea either way, but still doesn't solve the real issue).
Add postal_code to your casts array, to ensure it is always casted to a string (not bad; this will work for most cases, but is not exactly the correct solution).
Change the field type of the postal_code field from an integer to a varchar(5), varchar(9), or varchar(10), depending on if you're going to store the +4, and with or without a hyphen (best solution).
Changing the postal_code data type in the database to a varchar really is the best option. The main reason is that, while they are comprised of numbers, postal codes are not actually integers, or numeric in nature. You will never be doing any arithmetic with them. Additionally, there are postal codes that start with a leading 0, and if the value is stored as an integer, this is an extra edge case condition you have to contend with whenever displaying postal codes.
Enabling PDO::ATTR_STRINGIFY_FETCHES setting will solve this problem. You can add this PDO setting under database configurations.
'options' => array(
PDO::ATTR_STRINGIFY_FETCHES => true,
),
You could cast to string like:
$user['postal_code'] = (string) $user['postal_code'];
Further information on variable type casting is in the PHP manual.
Hope this helps :)
PHP
$query = $myCollection->findOne(array("field2.sf2" => "value two"));
echo json_encode($query);
Returned JSON Object
{"_id":{"$id":"5476854783473474578548"},"field1":"value one","field2":{"sf1":["av1","av2","av3"],"sf2":"value two"},"field3":"value three"}
What is happening at:
"_id":{"$id":"5476854783473474578548"}
I can see it is the representation of the Document's "_id" key and value ie:
"_id": ObjectId("5476854783473474578548")
But a few things are happening:
The value becomes a sub document ie it is surrounded in curly braces
ObjectId is being replaced by "$id"
I'm using MongoDB, accessed by a PHP file, via jQuery's getJSON() method.
Are there any gotcha's i need to look out for with this happening?
Any commonly known 'industry knowledge' tips that could be helpful to a MongoDB newbie or further explain what is happening?
The objectId Is not being replaced but merely serialised to string form when you call json_encode.
Its properties are being taken out, placed inside stringified JSON and sent over the wire where then in JQuery the library parses that stringified JSON into the object you see.
No data has been lost.
The only gotcha I can think of is that the constructor for MongoId does not actually take this object back in, it assumes only a hexadecimal ObjectId (i.e. 5476854783473474578548) http://www.php.net/manual/en/mongoid.construct.php
Here's my server side PHP script:
echo json_encode(
array(
"1" => "foo",
"2" => "bar"
)
);
The indexes are strings.
I'm fetching this array through $.ajax() with jQuery, and using Chrome's developer tools I can see that it's interpreting the indexes as numeric values and not strings.
How can I preserve that string type when passing the JSON from the server to the client? Or is the concept of type completely lost when transferring JSON data from a server to a client?
Strings can be numeric and strings, and even booleans, thanks to type coercion and duck typing (if it looks, walks, and quacks like a duck, it is a duck), since both are loosely typed languages. You should be just fine handling it like a string.
In the case of Chrome developer tools, you have a string that consists only of numeric characters. Therefore, it's also a numeric data type (it "looks like a duck").
Perhaps if you explain what, exactly, it is you're doing that isn't working, we could help you with a better way.
This is because in PHP, what javaScript calls an object is an array in php. In JavaScript, array indexes cannot be strings, they must be positive integers.
If you want JavaScript to interpret that as an array, give it a 0 index and make the indexes integers rather than strings.
Your code already does what you want it to do. The keys are strings.
http://jsfiddle.net/XC85h/
var jsonStr = '{"1":"foo","2":"bar"}';
var obj = JSON.parse(jsonStr);
for (key in obj) {
console.log(typeof key, key); // string 1, string 2
}
Edit (per comments)
Never rely on the sort order of a JavaScript object, it may vary between browsers.
I have a database with a "Text" col which contains a javascript object like this:
{
"description" : "",
"title" : " diagramm1",
"xlabel" : "Zeit",
"ylabel" : "",
"ylabel1" : "Anzahl Stabis aufgelegt",
"ylabel2" : "Anzahli.O.",
"tablename" : "edmat1",
"xvaluecol" : "timestamp",
"y1valuecol" : "EDMAT1Q001",
"y2valuecol" : "EDMAT1Q002",
"showRangeSelector" : true,
"divid" : "diagramm1",
"refreshtime" : 30000
}
If I get this out of the database with php it is interpreted as a php array. What can I do to force php to treat this like a string? Afterwards I want to give this javascript object to javascript.
Tried json_encode on php side and JSON.parse at Javascript side, there must be a other solution.
EDIT:
$db=mysql_connect("localhost","root","");
mysql_select_db("visualization");
$anfrage="SELECT options FROM mat1 WHERE id=1";
$a=mysql_query($anfrage);
$b=mysql_fetch_row($a);
echo $b;
only have on row!
If I get this out of the database with php it is interpreted as a php array. What can I do to force php to treat this like a string?
If you store it as a string, then it will stay a string. Even in JavaScript you have to parse it to have an object or an array.
You use mysql_fetch_row, that means you will have your row with your result in an indexed array.
As yoy selected only one column, your array will contain only one column too.
So your solution is (as said in comments) $your_result = $db[0];
Moreover, acording to the php doc I advise you to switch your mysql_ function to mysqli_ functions that are newer, more performant and which support newer version of Mysql SGBD.
The application I am designing consumes JSON objects returned by PHP scripts that select from a SQL Server 2008 database. The problem I am encountering is that when the database is missing a value for a certain field, it returns as a null in JSON. Then when the app parses the JSON (I am using NSJSONSerialization), the dictionary contains a value. When using this dictionary to populate my view, the application crashes when encountering the null value.
What would be the easiest way to bypass this problem? I am thinking I could just replace all nulls with empty string before the PHP returns the data as JSON; however, that might not be the best solution. Is there a simple way to check in iOS?
Thanks for the help.
To check for null values you need to see if the object is [NSNull null].
id object = [dict objectForKey:#"key"];
if(object == [NSNull null])
{
//Handle null value
}