I've this piece of code, it retrieves a node from my node type 'Student'.
I try different things to, save all values in '$node' into an array. But $node is a object.
My question is how doe I store 'all' values in $node into a array. In Java an C# it's simpler to do that.
$results = db_query(db_rewrite_sql("SELECT nid FROM {node} WHERE type =
'student'"));
while($nid = db_result($results)) {
$node = node_load($nid);
// Do something with $node
}
in java or c# you can say in a for/foreach/while 'loop'
String item[] = null;
for(int i = 0; i<=myNode; i++) {
item.add(myNode[i]); // the item and value UgentID, name student, location student are been stored in item array.
}
I don't know if PHP has that too. "yourObject.Add(otherObject)"
The following let's your object behave (access-wise) as an array:
$result = new ArrayObject( $node );
If you truly want an array, simply cast it afterwards:
$result = (array) $result;
Heck, come to think of it, you could even simply do:
$result = (array) $node;
:-)
Both methods of casting to array will actually expose protected/private properties as well, I just found out. :-S Horrible.
edit:
// initiate array
$nodes = array();
while($nid = db_result($results)) {
// either do one of the following, to push
$nodes[] = node_load($nid);
// or:
array_push( $nodes, node_load($nid) );
// Do something with $node
}
Related
I have a json file which I read in. I want to first filter the json data to return the object defined by the datasetID, then get out the datasetName. I have filtered in javascript, but would prefer to stay in php but I can't figure it out, any ideas?
note: foreach is not required as only a single record is returned when filtered using the datasetID. So rather than using a foreach method how would you swelect a single record, first for instance?
$datasetID = '5fd4058e5c8d2'; // unique 13 character string
$data = json_decode(file_get_contents(path/to/file), True);
So I need to first filter for the unique object with $datasetID = '5fd4058e5c8d2';
$filtered_data =
Then I need to return the attribute datasetName from that object
$datasetName =
pointers to the best ways to do this is welcomed.
Sample json data:
[
[
{
"datasetID":"5fd4124900827",
"institutionCode":"None",
"collectionCode":"None",
"datasetName":"None"
}
],
[
{
"datasetID":"5fd4058e5c8d2",
"institutionCode":"None",
"collectionCode":"None",
"datasetName":"None",
}
]
]
I don't know how you got that JSON but it is nested deeper than needed. You can merge the top level arrays to flatten it, then index on datasetID:
$data = array_merge(...$data);
$filtered_data = array_column($data, null, 'datasetID')[$datasetID];
$datasetName = $filtered_data['datasetName'];
Shorter:
$filtered_data = array_column(array_merge(...$data), null, 'datasetID')[$datasetID];
$datasetName = $filtered_data['datasetName'];
Or to keep them all to use:
$data = array_column(array_merge(...$data), null, 'datasetID');
$datasetName = $data[$datasetID]['datasetName'];
I tried with your sample JSON.
First, json_decode will return a PHP array to use foreach on it. I wrote a simple foreach and checked your searching ID is equal to element's datasetID. If it is equal this is the datasetName you are searching for.
<?php
$json = '[[{"datasetID":"5fd4124900827","institutionCode":"None","collectionCode":"None","datasetName":"None"}],[{"datasetID":"5fd4058e5c8d2","institutionCode":"None","collectionCode":"None","datasetName":"None"}]]';
$elements = json_decode($json,TRUE);
$searchingID = "5fd4058e5c8d2";
foreach ($elements as $element) {
if(isset($element[0]['datasetID']) && $element[0]['datasetID'] == $searchingID){
$filtered_data = $element[0];
break;
}
}
echo $filtered_data['datasetName']; // or return $filtered_data['datasetName'];
?>
I receive a JSON stream from an iphone that contains some simple strings and numbers as well as an array of dictionaries. I would like to work with these dictionaries, in essence, storing the data in each of them in a separate MYSQL record.
To get access to the strings as well as the array from the JSON stream, I am using the following:
$jsonString = file_get_contents('php://input');
$jsonArray = json_decode($jsonString, true);
$authString = jsonArray['authstring'];
$itemsArray = $jsonArray['itemsArray'];
This is what itemsArray looks like before being sent to the server:
itemsArray = (
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 6;
iid = 0;
title = "test";
complete = 1;
userid = 99;
whenaddedstr = "2018-06-21 14:10:23";
},
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 37;
iid = 0;
title = "how about this";
userid = 88;
whenaddedstr = "2018-07-07 16:58:31";
},
{
lasttouchedstr = "2018-07-09 17:24:56";
localiid = 38;
iid = 0;
title = reggiano;
userid = 1;
whenaddedstr = "2018-07-07 17:28:55";
}
etc.
I guess I should probably put these dictionaries into an Associative Array in order to save them.
I am struggling, however, with how to reference and get the objects. From what I can tell the following code is returning empty values in so far as $message comes back as empty.
$anitem = $jsonArray['itemsArray'][0];
$message=$anitem;
$title = $jsonArray['itemsArray'][0].[item];
$message.=$title;
Can anyone suggest proper syntax to grab these items and their properties?
Thanks in advance for any suggestions.
I find it strange that people associate things with a dictionary, while it is nothing more then a multidimensional array.
If you can read JSON, you see that the variable will have an index containing each entry.
For PHP:
foreach($jsonArray as $array){
// note that $array is still an array:
foreach($array as $v){
echo "Hurray!: '$v'";
}
}
If it really was an object (or cast to an object), the only thing you need to change is how you access the variable (as in any other language). In PHP it would be:
echo $jsonArray[0]->lasttouchedstr;
Or of it was the same loop:
foreach($jsonArray as $v){
echo $v->lasttouchedstr;
}
Multidimensional?
echo $jsonArray['itemsArray'][0][item]; // array
echo $jsonArray->itemsArray[0][item]; // if items array is an actual array and jsonArray an object.
Most languages associate things written as a . that the left side is an object. In PHP it's written as ->.
Just so you know I'm working in WordPress. I have an array and want to create an object with only certain values from that array.
Then I have another separate array, I'd like to add to this new object. I might be over complicating things. If I am, please let me know.
Here's what I have so far:
$custom = get_post_custom(); //Gets array of values
$picObject = (object)$custom; //Creates object
$picCount = $custom['picturecount'][0];
for ($x = 1; $x <= $picCount; $x++) {
// This assembles a URL that I want to add to the array.
$finalUrl = $picUrl.$gsi.'&picfilename='.$vin.'_00'.$x.'.jpg';
}
Let me know if you need anything else. Thanks in advance everyone!
If you want to create an object with only some values from your array, you shouldn't cast the array because you'll end up with all of its values. Instead, create a new object and set the values you want:
$array = array(
'foo' => 'bar',
'bar' => 'baz'
);
$object = new stdClass();
$object->bar = $array['bar'];
$object->something_else = 'w00t!';
Casting an array to object (i.e. (object)$array) will get you the same type of object, so you can still use $object->new_property = 'foo'; to add stuff to it.
When attempting to use SimpleXML's addChild() method towards the end of the code block below and printing the feed, the output is not the required result. When tested with a string value, addChild() correctly outputs both the name of the node and the value, however I'm not sure if the array or the object inside it are actually within the scope of the first foreach loop.
I want to access the 'name' and 'type' properties of the $nameType object and output them to my main feed with addChild().
//Turns base feed into SimpleXML object.
$feed = simplexml_load_string($xml);
foreach($feed->property as $property) {
//Gets latitude and longitude from each property.
$latitude = $property->latitude;
$longitude = $property->longitude;
//Adds latitude and longitude values into Google Places API URL.
$googleURL = 'https://maps.googleapis.com/maps/api/place/nearbysearch/xml?location='.$latitude.','.$longitude.'&radius=1000&types=train_station&key=my-google-key';
//Gets XML from Google Places and parses into SimpleXML Object.
$googleXMLfile = file_get_contents($googleURL);
$googleXMLdata = simplexml_load_string($googleXMLfile);
//Array for limiting number of results.
$googleStoredXMLDataArray = array();
foreach ($googleXMLdata->result as $result) {
//Assigns result 'name' and 'type' to variables.
$name = $result->name;
$type = $result->type;
//Creates object to store name and type together.
$nameType = new StdClass();
$nameType->name = $name;
$nameType->type = $type;
//Pushes object to array and outputs results limiting feed to 3 results.
array_push($googleStoredXMLDataArray, $nameType);
$output = array_slice($googleStoredXMLDataArray, 0, 3);
}
//Adding proximityTo destination to property nodes in the feed parser.
//Error - needs to pull properties from object inside the array.
$property->addChild('proximityTo_name', '$googleStoredXMLDataArray->$nameType->name');
$property->addChild('proximityTo_type', '$googleStoredXMLDataArray->$nameType->type');
}
print_r($feed);
Do not forget, $googleStoredXMLDataArrayis an indexed array of stdClass objects. Getting the value of these objects in the array is done with an index like this:
$googleStoredXMLDataArray[$index]->name;
$googleStoredXMLDataArray[$index]->type;
where $index is between 0 and count($googleStoredXMLDataArray)-1. I believe 0 is the most accurate hit and the last value the most inaccurate. To get the last value (most inaccurate), use this:
$i = count( $googleStoredXMLDataArray ) - 1;
$property->addChild('proximityTo_name', $googleStoredXMLDataArray[$i]->name);
$property->addChild('proximityTo_type', $googleStoredXMLDataArray[$i]->type);
Rewrite the last part should do the trick of adding ALL proximity values:
foreach( $googleStoredXMLDataArray as $prox ) {
$property->addChild('proximityTo_name', $prox->name);
$property->addChild('proximityTo_type', $prox->type);
}
If you want to skip the XML parsing, and just parse an array of data you can always use JSON instead:
$googleURL = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json'
. '?location='.$latitude.',' . $longitude
. '&radius=1000&types=train_station&key=my-google-key';
$googleObject = json_decode( file_get_contents($googleURL), true );
I want to compare 2 big xml files and retrieve the differences. Like ExamXML and DiffDog do. The solution I found was cycling through all child nodes of each file simultaneously and check if they are equal. But I have no idea how to achieve that... How can I loop through all child nodes and their properties? How can I check if the first element of the first file is equal to the first element of the second file, the second element of the first file is equal to the second element of the second file and so on?
Do yo have a better idea to compare 2 xml files?
I was looking for something to compare two XML like you, and I found this solution that works very well.
http://www.jevon.org/wiki/Comparing_Two_SimpleXML_Documents
I hope that helps to someone.
Have you looked at using XPath at all? Seems like an easy way to grab all of the child nodes. Then you'd be able to loop through the nodes and compare the attributes/textContent.
This might be a very alternative solution for you but this is how I would do it.
First, I'd try to get the format into something much more manageable like an array so I would convert the XML to an array.
http://www.bytemycode.com/snippets/snippet/445/
This is some simple code to do just that.
Then PHP has an array_diff() function that can show you the differences.
http://www.php.net/manual/en/function.array-diff.php
This may or may not work for you considering what you need to do with the differences but if you're looking to just identify and act upon them this might be a very quick solution to your problem.
Try the xmldiff extension
http://pecl.php.net/xmldiff
It's based on the same library as the perl module DifferenceMarkup, you'll get a diff XML document and can even merge then.
//Child by Child XML files comparison in PHP
//Returns an array of non matched children in variable &$reasons
$reasons = array();
$xml1 = new SimpleXMLElement(file_get_contents($xmlFile1));
$xml2 = new SimpleXMLElement(file_get_contents($xmlFile2));
$result = XMLFileComparison($xml1, $xml2, $reasons);
/**
* XMLFileComparison
* Discription :- This function compares XML files. Returns array
* of nodes do not match in pass by reference parameter
* #param $xml1 Object Node Object
* #param $xml2 Object Node Object
* #param &$reasons Array pass by reference
* returns array of nodes do not match
* #param $strict_comparison Bool default False
* #return bool <b>TRUE</b> on success or array of strings on failure.
*/
function XMLFileComparison(SimpleXMLElement $xml1, SimpleXMLElement $xml2, &$reasons, $strict_comparison = false)
{
static $str;
// compare text content
if ($strict_comparison) {
if ("$xml1" != "$xml2") return "Values are not equal (strict)";
} else {
if (trim("$xml1") != trim("$xml2"))
{
return " Values are not equal";
}
}
// get all children
$XML1ChildArray = array();
$XML2ChildArray = array();
foreach ($xml1->children() as $b) {
if (!isset($XML1ChildArray[$b->getName()]))
$XML1ChildArray[$b->getName()] = array();
$XML1ChildArray[$b->getName()][] = $b;
}
foreach ($xml2->children() as $b) {
if (!isset($XML2ChildArray[$b->getName()]))
$XML2ChildArray[$b->getName()] = array();
$XML2ChildArray[$b->getName()][] = $b;
}
//print_r($XML1ChildArray);
//print_r($XML2ChildArray);
// cycle over children
if (count($XML1ChildArray) != count($XML2ChildArray)) return "mismatched children count";// Second File has less or more children names (we don't have to search through Second File's children too)
foreach ($XML1ChildArray as $child_name => $children) {
if (!isset($XML2ChildArray[$child_name])) return "Second file does not have child $child_name"; // Second file has none of this child
if (count($XML1ChildArray[$child_name]) != count($XML2ChildArray[$child_name])) return "mismatched $child_name children count"; // Second file has less or more children
print_r($child_name);
foreach ($children as $child) {
// do any of search2 children match?
$found_match = false;
//$reasons = array();
foreach ($XML2ChildArray[$child_name] as $id => $second_child) {
$str = $str.$child_name.($id+1)."/"; // Adding 1 to $id to match with XML data nodes numbers
//print_r($child, $second_child);
// recursive function call until reach to the end of node
if (($r = XMLFileComparison($child, $second_child, $reasons, $strict_comparison)) === true) {
// found a match: delete second
$found_match = true;
unset($XML2ChildArray[$child_name][$id]);
$str = str_replace($child_name.($id+1)."/", "", $str);
break;
}
else {
unset($XML2ChildArray[$child_name][$id]);
$reasons[$str] = $r;
$str = str_replace($child_name.($id+1)."/", "", $str);
break;
}
}
}
}
return True;
}