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
Related
I'm trying to come up with a simple approach for extracting data from a multitude of json data sources where the reference is stored in a string literal. This is easy to do when the object structure is known but is there any way to get php to interpret the string literal as it would directly in code?
$data = json_decode('
{
"foo": 1,
"object": {
"foo": 1.1,
"bar": 1.2
},
"array": [
"foo",
"bar"
]
}
');
// Explicitly coded reference all work, of course
var_dump($data->foo); // int(1)
var_dump($data->object->foo); // float(1.1)
var_dump($data->array[0]); // string(3) "foo"
And I know that I can access an object's property from a string literal like this:
$string = 'foo';
var_dump($data->$string); // int(1)
var_dump($data->object->$string); // float(1.1)
Is there any way to go about achieving this for the second and third references, without having to break up the string and loop through the object recursively until each element is found?
$string = 'object->foo';
var_dump($data->$string);
$string = 'array[0]';
var_dump($data->$string);
If there is nothing native to PHP for handling this, is there a library or anything that I could use to make this process easier?
Edit: To provide some extra clarity, this is an application where a JSON feed can be configured through the UI and an administrator can extract values from the JSON feed. This works fine for simpler JSON structures but breaks down when they're trying to pull a value such as $foo->bar->baz[0]->qux->corge. I'm trying to find an easier way to get values such as this when the structure changes and I can't account for every possibility within the code.
Since you are using JSON, i‘d use JSON Pointers. Here is their official spec
What they do is providing a query language for json objects (similar to XPath for XML). Accessing your foo within object would result in a query like /object/foo.
Now you‘d have your users specify the json pointer queries, and use a json pointer library to perform the actual queries. This has the advantage that if you ever decide to ditch PHP for say Java, you’d only need to use a JSON Pointer implementation for Java and your users won‘t be impacted by the change.
Using PHP, I printed out an array ($result) using print_r. But the format in which the array has been returned is a new one on me. Specifically, how do I retrieve the text found in the field "reviews_review" ("Wow, what a great...") when it's found in this particular format with its multiple values? Example:
stdClass Object
(
[node_reviews_nid] => 5270
[reviews_review] => a:2:{s:5:"value";s:38:"Wow, what a great place. The bestest!";s:6:"format";s:13:"filtered_html";}
Those extra values and curly brackets have got me stumped. If I wanted the node_reviews_nid I could simply use $result->node_reviews_nid" - but doing that to get reviews_review just retrieves too much ie,
a:2:{s:5:"value";s:38:"Wow, what a great place. The bestest!";s:6:"format";s:13:"filtered_html";})
The odd curly brackets you're seeing are the result of PHP's serialize function.
Basically it's intended to convert complex structures like objects, nested arrays and so on into simple strings which are easier and safer to transfer, for example over HTTP. Think of it as JSON representation, but specific to PHP (do not attempt to json_decode() a serialized value).
Also worth noting is that serialize-d string has a maximum length, beyond which it's simply truncated, so avoid using it for very large structures - you'll lose data.
The reverse of that is unserialize. So to read the review's text, you would first have to unserialize the "reviews_review" property, then reference the "value" index of the resulting array.
$review_data = unserialize($result->reviews_review);
$review_text = $review_data['value'];
print($review_text);
The data in reviews_review looks like a serialized array i.e. written using the serialize() function
So you will need to unserialize it using unserialize() before you can use it
$review = unserialize($obj->reviews_review);
print_r($review);
In PHP figured out how to use {name-with-reserved-chars} notation to access object data after JSON decode but I also have index values as well in the path (like [0]). My attempts to add the index value has returned nothing despite all my attempts to vary the pattern. Here is an example based on a big JSON object:
["ops:world-patent-data"]["exchange-documents"]["exchange-document"]
[0]["bibliographic-data"]["publication-reference"]["document-id"][0].date.$
my attempt gets nothing:
print $result->{'ops:world-patent-data'}->{'exchange-documents'}->{'exchange-document'}->
{0}->{'bibliographic-data'}->{'publication-reference'}->{'document-id'}->{0}->date;
wondering how to place the 0 and 1 indexes in the path ...
When deserializing an actual JSON list (i.e, not an object but an actual array with numerical indices; something like [1,2,3,...] or also [{...},{...},...]), PHP's parse_json function builds a corresponding PHP array with numerical indices (while on the other hands, it maps JSON objects to instances of the stdClass class -- unless you use the $assoc parameter of the parse_json function).
So, because you are accessing arrays instead of objects, your code would probably have to look like this:
print $result->{'ops:world-patent-data'}->{'exchange-documents'}->
{'exchange-document'}[0]->{'bibliographic-data'}->{'publication-reference'}->
{'document-id'}[0]->date;
It would probably easier to use the $assoc parameter, forcing json_decode to map the entire JSON object with associative arrays, allowing you to use the square bracket notation for object access also.
I am having trouble understanding the concept of serialize/unserialize in PHP.
Assume I have a very simple PHP object (class someObject) and after setting the attributes of that object I want to serialize it:
So I call: serialize($someObject);
I want to transfer this serialized object into another php skript via a html form so I set it as a hidden value:
<input type="hidden" name="someObject" value="<? print $someObject; ?>"
In the next php script I want to use unserialize to get my object back and transfer it e.g. to a databae.
$unserialize = unserialize($_POST['someObject'])
But this always returns BOOL(false) - so what am I missing here?
Thanks for your help!
A serialized string looks like this:
O:1:"a":1:{s:3:"foo";s:3:"100";}
You have tourlencode/urldecode the serialized string to prevent any characters in the serialized representation from breaking your markup. Have a look at your page source. The first quote likely ended your HTML value attribute. So you got something like:
<input ... value="O:1:"a":1:{s:3:"foo";s:3:"100";}">
So your $_POST will never contain the full serialized string, but only O:1:
If this is not the issue, make sure you got a serialized string from the object in the first place. Also please be aware that there some objects cannot be serialized or have modified behavior when (un)serialized. Please refer to the Notes in PHP Manual for serialize for details.
If you dont need to send objects across different servers running PHP, consider persisting them in a Session instead. It's easier, less error prone and more secure because the object cannot be tampered with while in transit.
You need to have the class defined in your second script before you unserialize() the object
I have a PHP multidimensional array witch i converted to JSON using JSON_encode().
I am using drupal so for those not familiar with it, drupal array often have keys that looks like that :
$some_array['und']['0']['value']
So my JSON object ends up looking like:
some_array.und.0.value
Now the problem is that when use the above syntaxe to retreive the value i the following JS error in the FB console : "missing name after . operator"
Also this data is meant to be used with a Jquery template, so i alos tried accessing this data directly in my template with:
${field_city.und.0.value}
Witch unfortunately didn't work either..
How would i go to fix that issue ? Can i access somehow this proprety with JS? Or is there a way that i have JSON_encode function replace all 0 by let's say "zero"? Or even replacing '0' when parsing the JSON string?
Suggestions much appreicated.
Try accessing it with some_array.und["0"].value. '0' is not a valid name for a javascript object, which is why accessing it via the . notation is not working.
However, if you access it via the square brackets, you can access keys with any name at all.
As well as using the dot notation, you can use regular array notation to access JSON nodes:
some_array.und['0'].value