A strange PHP object - php

I'm using SimpleXML to get some data from an API. Its returning things in this format:
object(SimpleXMLElement)#10 (1) {
[0]=>
string(36) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
My question is, how can I possibly access the string value of this object? If I try to do $myVariable->0 that gives me an error. Doing $zero = '0' and then echo $myVariable->$zero doesn't work either, nor does (array) $myVariable work (that gives a warning).

The trick is that SimpleXMLElement has __toString magic method implemented that would return your string(36) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", so to get this string you just cast (string) on your SimpleXMLElement object:
(string)$myVariable
With PHP you can
print $myVariable;
of course, so explicit (string) here is not necessarily needed.

AFAIR it's like this:
$myVariable->{0}
Edit: That would work in majority of cases, but not this one. It looks like SimpleXML implements not only __toString method like Nemoden pointed out, but also __get, so that accessing object properties in this way results in cloned object being returned.

Related

Multiply float(7.2) for simpleXML with PHP5.6

I am trying to do a simple multiplication in an object-oriented PHP project for an XML file.
In the MariaDB, the data is saved as float(8.2). I get this error:
The object of class ArticlePrice could not be converted to int in [file online...]
$item->addChild('price', $article->getPrice(CountryPublic::getByShortCut('a')));
$item->addChild('newPrice', $productPriceNew*1.8);
Then I tried to convert it to float (instead of minifloat) like this:
$productPrice = $article->getUsualPrice(CountryPublic::getByShortCut('a'));
$productPriceNew = (float)$productPrice*1.8;
The message I get is this:
The object of class ArticlePrice could not be converted to double in
What am I doing wrong?
you actually try to cast an object into a float.
$article->getUsualPrice(CountryPublic::getByShortCut('a'));
Your method getUsualPrice return an object ArticlePrice, you should put a getter on your class ArticlePrice to access your attribut price inside it and then cast it into a float.
It's the straightforward solution but probably not the most beautiful in term of conception.
if you try something like
var_dump($article->getUsualPrice(CountryPublic::getByShortCut('a')) instanceof ArticlePrice)
You see that you cast an object in float.
After your commentary
object(ArticlePrice)#11396 (15) {
["id":protected]=> string(36) "7f01d63a-3f08-480a-b798-c83f6ddbdb94"
["articleID":protected]=> string(36) "65983c99-66e4-43689ba7039dc5e742c0"
["countryID":protected]=> string(36) "31149178-8a2a-4e57-8133-ca12004a59dd"
["price":protected]=> string(5) "13.50"
you see that you got on attribut called price.
you only need to do your operation on that attribut not on your object.
you probably have a getter on your class something called getPrice().
The following code will working:
(float)$article->getPrice(CountryPublic::getByShortCut('a'))->getPrice()
but you probably need to take a moment to think about the name of your method, it is redundant to have two methods called getPrice()

Uncaught Error: Cannot use object of type stdClass as array

Fatal error: Uncaught Error: Cannot use object of type stdClass as array
$code = json_decode($src);
echo $code["items"];
var_dump shows the following (truncated):
object(stdClass)#7 (3) { ... }
I don't know what stdClass is and how to use it.
Edit:
stdClass is a class which creates an instance of simple object. Properties of classes are to be accessed using ->, not [...] notation.
As per documentation for json_decode, simply setting the second argument to true will result in the result being associative array, which can be in turn accessed like an array.
At the time of posting this question, I didn't try searching on how to decode JSON - as that's pretty simple and I got that working. I was just getting another error (above), and had no luck searching on how to fix that. I believe people have similar problems, as this question is getting some views as well.
Use json_decode($src, true) to get associative array.
This is preferred way, as currently you get mixed arrays and objects and you may end up in crazy house, trying to work with these :)
Alternatively use -> operator to get properties of object.
Currently your item is at:
$code->items[0]->pagemap->cse_image[0]->src
The json_decode function has a second parameter dedicated to just that: setting it to true will return an associative array where there is an object (in { "curly": "braces" }) in JSON.
To illustrate that:
$a = json_decode('{ "b": 1 }', false);
var_dump($a->b);
// prints: int(1)
$a = json_decode('{ "b": 1 }', true);
var_dump($a['b']);
// prints: int(1)
Note the difference in how values are accessed.
Further reading: http://php.net/json_decode

Cant get value in PHP array but var_dump shows that it exists

Long time, my PHP-application ran on a linux server with apache and PHP.
Now I've set up a windows server with apache and php and simple PHP-Programs have problems.
var_dump($data);
die(var_dump($data['a']));
results in
object(stdClass)#1 (1) { ["a"]=> string(1) "b" }
Fatal error: Cannot use object of type stdClass as array in BLUB.php on line 14
var_dump says there is an index a. Why does $data['a'] throw an exception?
EDIT: $data is json_decode($something);
Because its an object, not an array. You cant access it like that. This would be correct:
$data->a;
The error contains your answer - $data is actually an object of type stdClass. You could either:
a) access the property 'a' with $data->a
or
b) typecast $data as an array using (array)$data
You should use:
$data = json_decode($something, true);
To get array from json
As the error says $data is an object, not an array. As such, you want to use object access, rather than array access. In this case, that would be var_dump($data->a)
since $data in an object you have to access it this way:
$data->a;
Otherwise, you can typecast it to an array and access it actually like an array
$dataArr = (array) $data;
$dataArr['a'];
NOTE
This is possible only whether your object attributes are public

Can I change the variable type from object to string? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to convert object into string in php
I have a variable that contain some object (SimpleXML).
Can I change the type of this variable, and to assing it to this variable itself?
Like this:
$test = (string)$test;
var_dump($test);
The above code does not work, so the output is still object(SimpleXMLElement) and not a string.
But when I assign it another variable, like $new_test = (string)$test it works well, and the var_dump output is string]
If you want the string content, use asXML method.
var_dump($test->asXML());
It depends on how SimpleXML implements the magic function __toString(). Its different from class to class. But if its not implemented, PHP will throw a fatal error.
So, typecasting directly from object to string does not work unless the __toString() method is implemented.
You can't convert an object to string just like adding a declaration, it might work but it wont behave like desired there's a greate article though written before here in stack on how you should do it the optimal way which is by adding a tostring method read more here...
how to convert object into string in php
It depends on the object being converted. For SimpleXML you probably want its asXML method: http://www.php.net/manual/en/simplexmlelement.asxml.php. For general objects, you can typecast to string if the objects implements the __toString() method. Another option would be var_export(...,true), but that is rarely useful except for debugging.
Typecast the SimpleXMLObject to a string
$foo = array( (string) $xml->parent->child );
<?php
$xmlstring = "<parent><child> hello world </child></parent>";
$xml = simplexml_load_string($xmlstring);
$foo = array( (string) $xml->child );
var_dump($xml).PHP_EOL;
var_dump($foo);
?>
Output
object(SimpleXMLElement)#1 (1) {
["child"]=>
string(13) " hello world "
}
array(1) {
[0]=>
string(13) " hello world "
}
http://codepad.org/Bss1rndd

getting items from a SimpleXMLElement object

From what I can tell, a SimpleXMLElement is just an array of other SimpleXMLElements, plus some regular array values if there wasn't a tag nested in another tag.
I have a SimpleXMLElement in a variable $data, and var_dump($data) gives me this:
object(SimpleXMLElement)#1 (33) {
["buyer-accepts-marketing"]=>
string(4) "true"
...
...
but calling var_dump($data->buyer-accepts-marketing) gives me an error, and var_dump($data["buyer-accepts-marketing"]) gives me NULL. Calling var_dump($data->shipping-address->children()) gives me an error.
going like this:
foreach($data as $item) {
var_dump($item);
}
gives a whole bunch of SimpleXMLElement objects, but oddly enough, no strings or ints.
What am I missing here? I want to take specific portions of it and pass them to a function, so for example, I don't have to go
$data->billing-address->postal-code;
...
$data->shipping-address->postal-code;
...
and can just go
address($data->billing-address);
address($data->shipping-address);
etc.
SimpleXMLElement is not just an array. To access child elements, you must use object notation ($a->b) and to access attributes you must use array notation ($a['b']).
Problem is, with object notation, valid tag names can be illegal PHP code.
You need to do this:
$data->{'buyer-accepts-marketing'};
Note that this returns a SimpleXMLElement! The reason for this is that it can contain either just text, more child elements, or both. The output of var_dump() is very misleading for SimpleXMLElements. If you want to the text content of a single <buyer-accepts-marketing> tag, you have to do this:
(string)$data->{'buyer-accepts-marketing'};
Of course it is also perfectly legal to do this:
(int)$data->{'buyer-accepts-marketing'};
The reason this appears to work in some cases (such as echoing a SimpleXMLElement) is that the type conversions are implicit and automatic. You can't echo an object, so PHP automatically converts it to a string.
I have a love/hate relationship with SimpleXML. It makes things very easy only after you understand how complex the actual API is.
Read up on the so-called "basic" examples to get a good handle on it.

Categories