PHP SimpleXMLElement: Count isn't counting all public properties of the Object - php

I have the following code:
$b = $br->b;
var_dump($b);
$iCountBlock = count($b);
Where b is a SimpleXMLElement object. The var dump outputs:
object(SimpleXMLElement)[16]
public 'blockID' => string '160999' (length=6)
public 'blockDesc' => string 'Description' (length=37)
public 'moduleID' => string '1' (length=1)
public 'pubID' =>
object(SimpleXMLElement)[18]
public 'contentID' => string '93305' (length=5)
public 'linkToPageID' =>
object(SimpleXMLElement)[19]
public 'moduleFunction' => string 'replaceHTML' (length=11)
public 'moduleVars' =>
object(SimpleXMLElement)[20]
public 'c' =>
object(SimpleXMLElement)[21]
public 'contentID' => string '93305' (length=5)
public 'contentType' => string '1' (length=1)
public 'description' => string 'new.usdish.com index redesign content' (length=37)
public 'content' =>
object(SimpleXMLElement)[22]
However, $iCountBlock gets set to 1... it doesn't appear to be counting all the public properties of the object as it should. I also tried using a foreach loop to loop over each property of b and it didn't even enter the loop.
foreach($b as $key => $val) { ... }
I'm kinda at a loss here, as I'm not sure what's going on. Any thoughts?

Form PHP 5.3 and higher SimpleXMLElement does use a count function for the length!
$count = $b->count();
In PHP before 5.3 you have to use the childern property for getting the count.
$count = count($b->children());
Info at: http://php.net/manual/en/simplexmlelement.count.php

Related

While and foreach different behaviour with fetching PDO::FETCH_OBJECT

While using something like:
$db = new PDO(connection_details)
$query = "SELECT * FROM vservers LIMIT 5";
$result = $db->query($query);
And then try to get records with while f.e.
while ($row = $result->fetchAll(PDO::FETCH_OBJ)) {
var_dump($row);
}
it returns an array with StdObjects like this:
array (size=5)
0 =>
object(stdClass)[3]
public 'vserverid' => string '898' (length=3)
public 'templatename' => string 'Debian' (length=14)
public 'template' => string 'debian-7.0-x86' (length=14)
1 =>
object(stdClass)[4]
public 'vserverid' => string '792' (length=3)
public 'templatename' => string 'Ubuntu' (length=33)
public 'template' => string 'ubuntu-15.04' (length=27)
And with foreach it returns StdObjects
foreach ($result->fetchAll(PDO::FETCH_OBJ) as $key) {
var_dump($key);
}
object(stdClass)[3]
public 'vserverid' => string '898' (length=3)
public 'templatename' => string 'Debian' (length=6)
public 'template' => string 'debian' (length=6)
object(stdClass)[4]
public 'vserverid' => string '792' (length=3)
public 'templatename' => string 'Ubuntu' (length=6)
public 'template' => string 'ubuntu' (length=6)
Can someone please explain this behaviour? Normally, I would like to return Objects like with foreach, but is it a good practice ?
fetchAll() returns all the results as an array, where each element is an object that represents a row from the table.
In your while code, the first iteration sets $row to the entire result set, and dumps it as a single array. There's only one iteration because the next call to fetchAll() returns an empty array, because there's nothing left to fetch.
In your foreach code, fetchAll() returns the array to foreach, which then iterates over it one element at a time, setting $key to each object. Then you dump that one object in your body.
Normally when you're using while you use fetch(), not fetchAll(). This code will be equivalent to the foreach:
while ($key = $result->fetch(PDO::FETCH_OBJ)) {
var_dump($key);
}

How to sort and merge a PHP array by a specific key? [duplicate]

This question already has answers here:
Creating one array from another array in php [closed]
(2 answers)
Closed 6 years ago.
I have the following PHP array
array (size=14)
0 =>
object(stdClass)[39]
public 'department' => string 'BOOKS' (length=32)
public 'dep_url' => string 'cheap-books' (length=32)
public 'category' => string 'Sci-fi' (length=23)
public 'cat_url' => string 'sci-fi' (length=23)
1 =>
object(stdClass)[40]
public 'department' => string 'JEWELRY' (length=32)
public 'dep_url' => string 'cheap-jewels' (length=32)
public 'category' => string 'Rings' (length=23)
public 'cat_url' => string 'rings' (length=23)
2 =>
object(stdClass)[41]
public 'department' => string 'JEWELRY' (length=32)
public 'dep_url' => string 'cheap-jewels' (length=32)
public 'category' => string 'Earings' (length=23)
public 'cat_url' => string 'cheap-earings' (length=23)
As you can see its an array of departments with their categories, how can i merge the array to get something like the following:
array (size=14)
0 =>
object(stdClass)[39]
public 'department' => string 'BOOKS' (length=32)
public 'dep_url' => string 'cheap-books' (length=32)
innerarray[0] =
public 'category' => string 'Sci-fi' (length=23)
public 'cat_url' => string 'sci-fi' (length=23)
1 =>
object(stdClass)[40]
public 'department' => string 'JEWELRY' (length=32)
public 'dep_url' => string 'cheap-jewels' (length=32)
innerarray[0] =
public 'category' => string 'Rings' (length=23)
public 'cat_url' => string 'rings' (length=23)
innerarray[1] =
public 'category' => string 'Earings' (length=23)
public 'cat_url' => string 'cheap-earings' (length=23)
I want to merge the array by department with the least amount of loops.
I hope i am clear with my question, thanks for any help you can give!
It would be best if you had a department ID (a primary key) to use to identify duplicates, but in lieu of that you should use the department name and URL together to match them.
Something like this should work:
$output = [];
foreach ($array as $entry) {
// no department ID, so create one for indexing the array instead...
$key = md5($entry->department . $entry->dep_url);
// create a new department entry
if (!array_key_exists($key, $output)) {
$class = new stdClass;
$class->department = $entry->department;
$class->dep_url = $entry->dep_url;
$class->categories = [];
$output[$key] = $class;
}
// add the current entry's category data to the indexed department
$category = new stdClass;
$category->category = $entry->category;
$category->cat_url = $entry->cat_url;
$output[$key]->categories[] = $category;
}
This will give you an array of department objects which contains, each of which contains an array of category objects. It'll be indexed by a hash which you create manually in lieu of a department ID/primary key to use instead.
To remove those keys simply do:
$output = array_values($output);

Displaying data from MaasApi - object

As the title says I'm trying to display data here is my code
$mars_temperature = new MaasApi();
$data=$mars_temperature->getLatest();
var_dump($data);
echo $data['sol'];
error Fatal error: Cannot use object of type stdClass as array on the last line and here is var_dump:
object(stdClass)[3]
public 'terrestrial_date' => string '2015-02-09' (length=10)
public 'sol' => int 893
public 'ls' => float 287
public 'min_temp' => float -72
public 'min_temp_fahrenheit' => float -97.6
public 'max_temp' => float 2
public 'max_temp_fahrenheit' => float 35.6
public 'pressure' => float 890
public 'pressure_string' => string 'Higher' (length=6)
public 'abs_humidity' => null
public 'wind_speed' => null
public 'wind_direction' => string '--' (length=2)
public 'atmo_opacity' => string 'Sunny' (length=5)
public 'season' => string 'Month 10' (length=8)
public 'sunrise' => string '2015-02-09T12:23:00Z' (length=20)
public 'sunset' => string '2015-02-10T00:39:00Z' (length=20)
Update:
Here is also the code for API : https://github.com/dbough/MaasApi/blob/master/MaasApi.php
To access object properties, use the object operator: ->.
echo $data->sol;
To echo the properties that you referenced in your comment, use:
echo $data->max_temp;
echo $data->min_temp;

How do I check an objects property types?

Sorry for the title, I couldn't find a better way to write it =/
I am receiving a error object called ErrorBase.
If there is only one error it will return me the following:
public 'ErrorBase' =>
public 'CODIGO_ERRO' => string '1' (length=1)
public 'MENSAGEM_ERRO' => string 'Autenticação Inválida' (length=24)
public 'TIPO_ERRO' => string 'Usuario' (length=7)
But if there is more than one error, it will return me a array of objects like this:
public 'ErrorBase' =>
array
0 =>
object(stdClass)[30]
public 'CODIGO_ERRO' => string '1' (length=1)
public 'MENSAGEM_ERRO' => string 'Autenticação Inválida' (length=24)
public 'TIPO_ERRO' => string 'Usuario' (length=7)
1 =>
object(stdClass)[31]
public 'CODIGO_ERRO' => string '002' (length=3)
public 'MENSAGEM_ERRO' => string 'teste 002' (length=9)
public 'TIPO_ERRO' => string 'tipo 002' (length=8)
2 =>
object(stdClass)[32]
public 'CODIGO_ERRO' => string '003' (length=3)
public 'MENSAGEM_ERRO' => string 'teste 003' (length=9)
public 'TIPO_ERRO' => string 'tipo 003' (length=8)
3 =>
object(stdClass)[33]
public 'CODIGO_ERRO' => string '004' (length=3)
public 'MENSAGEM_ERRO' => string 'teste 004' (length=9)
public 'TIPO_ERRO' => string 'tipo 004' (length=8)
How can I work with these situations?
How do I check if there is a array of objects or only a object?
Thanks in advance for any help.
Try... is_object() and is_array()
is_array($variable) returns true if $variable contains an array, and false otherwise.
Use is_array() :
if (is_array($this->ERROR_BASE))
To test the class of an object :
if ($var instanceof ErrorBase) {
To test if it is an array :
if (is_array($var)) {
use gettype() to returns the vars type.
or use is_array/is_object to test for each

what's wrong with this php code?

Ok, the idea here is to have code that will append SF_ to all key names in an array.
I took my array (which is part of an object), flipped it, added the SF_, and flipped it back.
Somewhere in the process I lost some fields...
here's what I started with:
object(stdClass)[12]
public 'Affiliate_Code__c' => string 'XX-TXUJC3' (length=9)
public 'AltEmail__c' => string 'benny#oxpublishing.com' (length=22)
public 'City' => string 'Mobile' (length=6)
public 'Email' => string 'benny#oxpublishing.com' (length=22)
public 'Fax__c' => string '251-300-1234' (length=12)
public 'FirstName' => string 'Benny' (length=5)
public 'LastName' => string 'Butler' (length=6)
public 'Phone' => string '251-300-3530' (length=12)
public 'PostalCode' => string '36606' (length=5)
public 'State' => string 'AL' (length=2)
public 'Street' => string '851 E I-65 Service Rd' (length=21)
public 'test1__c' => float 1
array
'SF_Affiliate_Code__c' => string 'XX-TXUJC3' (length=9)
'SF_Email' => string 'benny#oxpublishing.com' (length=22)
'SF_City' => string 'Mobile' (length=6)
'SF_Fax__c' => string '251-300-1234' (length=12)
'SF_FirstName' => string 'Benny' (length=5)
'SF_LastName' => string 'Butler' (length=6)
'SF_Phone' => string '251-300-3530' (length=12)
'SF_PostalCode' => int 36606
'SF_State' => string 'AL' (length=2)
'SF_Street' => string '851 E I-65 Service Rd' (length=21)
And here's my code:
$response = $mySforceConnection->query(($query));
foreach ($response->records as $SF) {
}
var_dump($SF);
$SF = array_flip($SF);
foreach ($SF as $key => $value){
$SF[$key] = 'SF_'.$value;
}
$SF = array_flip($SF);
echo "<pre>";
var_dump($SF);
echo "</pre>";
extract($SF);
Any idea?
I'm new to OO programming of any sort, and I'm sure this has something to do with it.
I'm so stupid I have to do:
foreach ($response->records as $SF) { }
because I don't know how to get to that array any other way.
Help!
Thanks!
When you do the flip, you end up with duplicate keys - the values become the keys, and your values are not unique (e.g. Email and AltEmail__c both have the same value).
Rather than doing a flip then flipping back, just create a new array and copy the values in with the new keys:
$SF_new = array();
foreach($SF as $key => $value ) {
$SF_new['SF_' . $key] = $value;
}
// And if you want to continue using the $SF name...
$SF = $SF_new;
array_flip will flip the values and keys, as you said. A PHP array cannot have multiple keys with the same name. Try something like this to avoid flipping:
<?php
$SF = array();
foreach($response->records as $key => $value)
{
$SF['SF_' . $key] = $value;
}
About the way you get to the array in the object, this is the proper way to do it.
$SF = get_object_vars($response);
Will transform your object into an array.
flip swaps keys and values. because you have values that share the same value, you lose them in the flip.

Categories