I have an array, stored in $array, that with
print "<pre>";
print_r($array);
print "</pre>";
gives an output like this:
Array
(
[device] => Array
(
[0] => Array
(
[#attributes] => Array
(
[name] => Low volt light
[id] => 10
[type] => Z-Wave Switch Multilevel
[value] => 0
[address] => 00016922-018
[code] =>
[canDim] => True
[lastChange] => 26-07-2014 17:31:33
[firstLocation] => Kitchen
[secondLocation] => Main
)
)
[1] => Array
(
[#attributes] => Array
(
[name] => Light
[id] => 11
[type] => Z-Wave Switch Multilevel
[value] => 99
[address] => 00016922-019
[code] =>
[canDim] => True
[lastChange] => 31-07-2014 20:01:05
[firstLocation] => Bedroom
[secondLocation] => Main
)
)
I cannot find my way to access/display for example the value (in this case 0) of device with [id]=>10. What syntax would be the right one in php?
There's not an easy way to do this, without looping through the array.
e.g.
foreach ($array['devices'] as $device) {
if ($device['#attributes']['id'] === $idBeingSearchedFor) {
// Do something with $device.
}
}
Due to the #attributes array key, I'm guessing that this came from XML at some point: You might consider using Simple XML to parse it instead, as you could potentially use XPath then, which does support this type of access.
Alternatively again, you could reformat the array so it could be easily accessed by ID.
For example:
$formattedArray = array();
foreach ($array['devices'] as $device) {
$id = $device['#attributes']['id'];
$formattedArray[$id] = $device;
}
You could then access the device by its ID as follows:
$device = $formattedArray[$idBeingSearchedFor];
You could do it like that:
$id = 10;
$device = array();
foreach($array['device'] as $devices) {
if($devices['#attributes']['id'] == $id) {
$device = $devices['#attributes'];
break;
}
}
echo $device['value'];
Looks like SimpleXML, and if that is the case then those arrays are actually objects that, when put through print_r, look just like arrays. To access them, do the following:
Get straight to the data:
$name = $array->device[0]->attributes()->name;
Or loop through each of the attributes in the first device:
foreach ($array->device[0]->attributes() as $key => $value) {
// Do something with the data. $key is the name of the
// attribute, and then you have the $value.
}
Or you could loop through all the devices:
foreach ($array->device as $device) {
foreach ($device->attributes() as $key => $value) {
// Do something
}
}
It's simple ... try below...
print $array['device'][0]['#attributes']['id'];
or
print $array['device']['0']['#attributes']['id'];
Related
So I have an Array set up as follows
Array
(
[0] => App\Model\Entity\Member Object
(
[id] => 20
[fname] => John
// ...
[member_attribute] => Cake\ORM\Entity Object
(
[id] => 13
[membership_status] => Active
[last_payment] => 1541581496
// ...
)
)
I'm using a foreach loop for the first level
foreach ($aArray as $Member => $Value)
However I can't access the [member_attributes] data because it's in its own array.
Any help?
The items in your array are objects, so use object notation to access them:
foreach ($aArray as $Member => $Value) {
$id = $Value->member_attribute->id;
}
There also is no need to use the key => value form of the foreach, you could just access your Members like:
foreach ($aArray as $Member) {
$id = $Member->member_attribute->id;
}
That may be a matter of preference, however, I think it is more clear.
I am trying to use the Hubspot API (http://developers.hubspot.com/docs/overview) to loop through all deals and find only those which are current and then do something with those deals.
No matter what I try to do I cannot get my head around how I access the data I need - below is an example of the output.
In the API there are lots of items like dealstage below and the value field under these is what I need to access - for example in this case the deal is closedlost. Another example would be amount which would also have an entry in value so I can then see the deal value.
I want to loop through all deals and for each deal get the dealstage, amount, last update, owner and so on. Each of these are contained in an array of the same layout as [dealstage] below with a value
I have gotten to where I can print the dealstage value for each deal but it doesn't really help - is there a better way of doing this?
foreach ($list['deals'] as $line) {
foreach ($line['properties'] as $row => $value) {
if ($row=="dealstage") {
$stage=$value['value'];
print $stage."<br>";
}
}
}
Example array:
Array
(
[deals] => Array
(
[0] => Array
(
[portalId] => 12345
[dealId] => 67890
[isDeleted] =>
[associations] => Array
(
[associatedVids] => Array
(
[0] => 4051
)
[associatedCompanyIds] => Array
(
[0] => 23456
)
[associatedDealIds] => Array
(
)
)
[properties] => Array
(
[dealstage] => Array
(
[value] => closedlost
)
[createdate] => Array
(
[value] => 1471334633784
)
[amount] => Array
(
[value] => 1000
)
Would something like this be what you are looking for. Loop through the array picking out the items you are interested in and place them in a nice simple array for you to use later when building your email.
$for_email = array();
foreach ($list['deals'] as $line) {
$t = array();
if (isset($line['properties']['dealstage']['value'])) {
$t['dealstage'] = $line['properties']['dealstage']['value'];
}
if (isset($line['properties']['amount']['value'])) {
$t['amount'] = $line['properties']['amount']['value'];
}
if (isset($line['properties']['createdate']['value'])) {
$t['createdate'] = $line['properties']['createdate']['value'];
}
// any other data you want to capture
// put this data in the new array
$for_email[] = $t;
}
// check what the new array looks like
print_r($for_email);
I have a database query which returns several records, however I would like to append more data to this object by typing the array as an object so that I can for example add more data to the output than the database contains.
I have done some research on this and found some functions such as array_merge but whenever I attempt to use this it gave me issues related to the array's depth and sometimes even created an entirely new array key instead of adding onto the currently existing ones.
This is the data from my database:
Array
(
[Cat] => Array
(
)
[Dog] => Array
(
)
[Rabbit] => Array
(
[0] => stdClass Object
(
[name] => fluffy
[owner] => foobar
)
[1] => stdClass Object
(
[name] => toby
[owner] => foobar
)
[2] => stdClass Object
(
[name] => josie
[owner] => Joseph
)
)
)
I'd like to make it so that every array key which exist have an extra field but other animals remain empty if they do not have any records.
Example:
Array
(
[Cat] => Array
(
[0] => stdClass Object
(
[name] => ralph
[owner] => Joseph
[extra] => some extra data
)
)
[Dog] => Array
(
)
[Rabbit] => Array
(
[0] => stdClass Object
(
[name] => fluffy
[owner] => foobar
[extra] => some extra data
)
[1] => stdClass Object
(
[name] => toby
[owner] => foobar
[extra] => some extra data
)
[2] => stdClass Object
(
[name] => josie
[owner] => Joseph
[extra] => some extra data
)
)
)
The reason I am attempting to merge the two is because I have several helper functions which generate pretty results and I'd like to utilize them rather than output the raw data from the database, the extra data is demonstration of how i'd like to merge onto the current array.
Thanks!
EDIT - Updated code:
function listPets(){
$foo = [];
foreach($pets as $p){
$getPets = $database->Findall("SELECT name, owner, info FROM pets...");
$foo[$p->name] = $getPets;
foreach($foo as $arr){
if(count($arr)){
foreach($arr as $v){
$v->extra = $this->message($getPets->info);
}
}
}
}
return $foo;
}
The solution is:
Loop through the array using foreach loop.
Check if the inner array is empty or not.
If the inner array is not empty then loop through it and append extra property to each of the objects.
So your code should be like this:
// Suppose $array is your original array
foreach($array as $arr){
if(count($arr)){ // check if the array is empty or not
foreach($arr as $v){
$v->extra = 'some extra value'; // append extra property to the object
}
}
}
// display $array
echo '<pre>';
print_r($array);
echo '</pre>';
Here's the demo:
Live Demo
Are you actually trying to merge two arrays or just append some extra information to the non-empty keys in the array of animals?
In the second case, depending on the information you want to add, there's two ways you could go:
Add it to the SELECT statement:
SELECT name, owner, 'extra stuff' as extra FROM ...
Do it like #rajdeep-paul said. Only you can skip the empty array check, if it's empty, foreach will not iterate through it anyway:
foreach ($dbData as $animals) {
foreach ($animals as $animal) {
$animal->extra = 'extra stuff';
}
}
The function below merges arrays & objects:
UPDATE
<?
function fuse_data()
{
$list = func_get_args();
$data = array_shift($list);
$type = gettype($data);
$data = ((array)$data);
foreach ($list as $indx => $item)
{
foreach ($item as $name => $valu)
{
if (!isset($data[$name]) || empty($data[$name]))
{
$data[$name] = $valu;
}
}
}
return (($type == 'object') ? ((object)$data) : $data);
}
?>
Use it like this:
$data = fuse_data($result, $node2, $list3, $foo, $bar);
Edit as you like, it's just a proof of concept.
You can do something like ...
foreach($pets as &$pet) { // passing by reference to manipulate the original array.
if(!empty($pet) && is_array($pet)){ // Checking if the element is an array and not empty
foreach($pet as &$feature){ // Again passing by reference the 2nd dimension
if(is_object($feature)){ // Checking if the element is object to prevent the "Property of non-object" error.
$feature->extra = 'Some value'; // If all is well, we asign the new property to the object.
}
}
}
}
Now even though I think there are better ways to write(optimize) a query than firing it inside a loop!!! but just for the sake of your question, your code should be like..
function listPets(){
$foo = [];
foreach($pets as $p){
$getPets = $database->Findall("SELECT name, owner, info FROM pets...");
$foo[$p->name] = $getPets;
foreach($foo as $arr){
if(is_array($arr) && count($arr)){
foreach($arr as $v){
if(!empty($v) && is_object($v)){
$v->extra = $this->message($getPets->info);
}
}
}
}
}
return $foo;
}
I'm facing a bit of a problem I can't fix myself.
What I'm trying to achieve is sort of a search filter. I have an array which can variate between 1 row to +100 rows.
The array is built like this:
Array
(
[0] => Array
(
[0] => PK customer
[1] => Call number
[2] => Subject of the call
[3] => Date created
[4] => Date changed
)
)
Here is a real version of one of my array's:
stdClass Object ( [ReadOpenCallsResult] => stdClass Object (
[ArrayOfstring] => Array
(
[0] => stdClass Object (
[string] => Array
(
[0] => 180355
[1] => C0000448207
[2] => TESTDOC
[3] => 3-7-2013 14:20:14
[4] => 3-7-2013 14:20:14
)
[1] => stdClass Object (
[string] => Array
(
[0] => 180355
[1] => C0000448209
[2] => TESTDOC
[3] => 2-7-2013 14:20:14
[4] => 2-7-2013 14:20:14
)
)
I have a WCF webservice which generates an array of the result of a function in C# and then sends it to my PHP page.
Now I was testing the in_array function, it works perfectly with an easy array but I can't seem to make it work with a multidimensional array.
I store my array into $_SESSION['searchCalls']
I tested with all kinds of array's but I can't get the 'real' array to work.
I tried it this way:
$key = array_search('180335',$_SESSION['searchCalls']);
And this way
if (in_array('180335',$_SESSION['searchCalls']))
EDIT: I saw some really good examples, but.. is it possible to get all the values in the sub array when someone looks for 'C0000448207' and then get the subject of the call and the datecreated with it?
This is the function which generates the object arrays.
public List<List<string>> ReadOpenCalls(int relation)
{
RidderIQSDK IQSDK = new RidderIQSDK();
SDKRecordset inboundSet = IQSDK.CreateRecordset("R_ACTIONSCOPE", "PK_R_ACTIONSCOPE, DESCRIPTION, DATECREATED, DATECHANGED, CODE", "FK_RELATION = " + relation, "DATECREATED DESC ");
var messages = new List<List<string>>();
List<string> mess = new List<string>();
if (inboundSet != null && inboundSet.RecordCount > 0)
{
inboundSet.MoveFirst();
do
{
List<string> list = new List<string>();
string pkas = inboundSet.Fields["PK_R_ACTIONSCOPE"].Value.ToString();
string code = inboundSet.Fields["CODE"].Value.ToString();
string descr = inboundSet.Fields["DESCRIPTION"].Value.ToString();
string datecreated = inboundSet.Fields["DATECREATED"].Value.ToString();
string datechanged = inboundSet.Fields["DATECREATED"].Value.ToString();
list.Add(pkas);
list.Add(code);
list.Add(descr);
list.Add(datecreated);
list.Add(datechanged);
messages.Add(list);
inboundSet.MoveNext();
}
while (!inboundSet.EOF);
return messages;
}
mess.Add(null);
messages.Add(mess);
IQSDK.Logout();
return messages;
}
I solved it myself already, this is my solution which is kinda nasty but it works.
$roc = array('relation' => $_SESSION['username']);
$rocresponse = $wcfclient->ReadOpenCalls($roc);
$_SESSION['searchCalls'] = $rocresponse;
foreach ($rocresponse->ReadOpenCallsResult as $key => $value){
if (count($value) === 0) {
}
if (count($value) === 1) {
foreach ($value as $key1 => $value1){
if (in_array($searchWord,$value1)){
echo "Value is in it";
}
}
}
else{
foreach($value as $key1 => $value1){
foreach($value1 as $key2 => $value2){
if (array_search($searchWord,$value2)){
print_r($value2);
}
}
}
}
}
I'm always interested in better solutions, and maybe this solution can help someone else out too.
As pointed out by Nisarg this isn't an Array its an Object. Or you need to update your question to show you are accessinng the object.
What if you try something like this
$SearchCalls = $_SESSION['searchCalls'];
if (in_array('180335',$SearchCalls->ReadOpenCallsResult)){
//do some work.
}
I have an array which is generated from an XML file and it shows me like below when printed with print_r
Array
(
[cxname] => Global CX 87 123
[ipaddress] => 66.240.55.87
[slots] => Array
(
[slot] => Array
(
[0] => Array
(
[slotno] => 1
[cardtype] => 0x24
[modelno] => OP3524J
[label1] => OP
[label2] => Module
[severity] => Minor
)
[1] => Array
(
[slotno] => 2
[cardtype] => 0x25
[modelno] => OP3524K
[label1] => OP
[label2] => Module
[severity] => Major
)
)
)
)
When I print like this, it shows nothing
echo $dataArray->cxname;
But following code works and prints "Global CX 87 123 "
echo $dataArray["cxname"];
How can I make it work as above example.
Just do this:
$dataArray = (object)$dataArray;
It'll convert the array in an stdClass object and allow you to use it that way. Please note that this will only convert the first level for the array. You'll have to create a function to recurse through the array if you want to access all levels that way. For example:
<?php
function arrayToObject($array) {
if(!is_array($array)) {
return $array;
}
$object = new stdClass();
if (is_array($array) && count($array) > 0) {
foreach ($array as $name=>$value) {
$name = strtolower(trim($name));
if (!empty($name)) {
$object->$name = arrayToObject($value);
}
}
return $object;
}
else {
return FALSE;
}
}
For more information, have a look at http://www.richardcastera.com/blog/php-convert-array-to-object-with-stdclass. To find out about typecasting, you can also read http://www.php.net/manual/en/language.types.object.php#language.types.object.casting.
This:
echo $dataArray["cxname"];
is the way you access array elements. But this:
echo $dataArray->cxname;
is the way, you access class members.
If you want to access the data as class members, you have to use a xml parser which returns classes (or objects), not arrays.
If you have got the XML string, you can parse it into an object by using simplexml_load_string().