SimpleXMLElement Object
(
[0] => CEM
)
There is a SimpleXMLElement Object like this. I tried accessing it with $object->0 and $object->{0}. But it is giving a php error. How do we access it with out changing it to another format.
From your print_r output it might not be really obvious:
SimpleXMLElement Object
(
[0] => CEM
)
This is just a single XML element containing the string CEM, for example:
<xml>CEM</xml>
You obtain that value by casting to string (see Basic SimpleXML usageDocs):
(string) $object;
When you have a SimpleXMLElement object and you're unsure what it represents, it's easier to use echo $object->asXML(); to output the XML and analyze it than using print_r alone because these elements have a lot of magic that you need to know about to read the print_r output properly.
An example from above:
<?php
$object = new SimpleXMLElement('<xml>CEM</xml>');
print_r($object);
echo "\n", $object->asXML(), "\n";
echo 'Content: ', $object, "\n"; // echo does cast to string automatically
Output:
SimpleXMLElement Object
(
[0] => CEM
)
<?xml version="1.0"?>
<xml>CEM</xml>
Content: CEM
(Online Demo)
In your case, it appears as you do
print_r($object) and $object it's an array
so what you are viewing is not an XML objet but an array enclosed in the display object of print_r()
any way, to access a simpleXML object you can use the {} sytax here it goes:
$xmlString = '<uploads token="vwl3u75llktsdzi">
<attachments>
<attachment myattr="attribute value">123456789</attachment>
</attachments>
</uploads>';
$xml = simplexml_load_string($xmlString);
echo "attachment attribute: " . $xml->{"attachments"}->attributes()["myattr"] " \n";
echo " uploads attribute: " . $xml->{"uploads"}->attributes()["token"] . "\n";
you can replace "attachments" with $myVar or something
remember attributes() returns an associative array so you can access data with square braces or through array_keys() or do a foreach cycle.
In your specific case may be just
echo $object[0]; // returns string "CEM"
Related
I been looking thru the posts here all day but can't figure out what I'm doing wrong. (I'm new to php and json)
Here is my code that work.
$json = '{"id":1234,"img":"1.jpg"}';
$data = json_decode($json, true);
echo $data["img"];
But when the json respond is this
$json = '{"demo1":[{"id":1234,"img":"1.jpg"}],"userId":1}';
it's a big harder for me. then img is a child of demo1? How to get it?
Thx. :)
Figuring out the array indices
As you're new to PHP, I'll explain how to figure out the array indces of the required array value. In PHP, there are many functions for debugging — print_r() and var_dump() are two of them. print_r() gives us a human-readable output of the supplied array, and var_dump() gives us a structured output along with the variable types and values.
In this case, print_r() should suffice:
$json = '{"demo1":[{"id":1234,"img":"1.jpg"}],"userId":1}';
$data = json_decode($json, true);
// wrap the output in <pre> tags to get a prettier output
echo '<pre>';
print_r($data);
echo '</pre>';
This will produce the following output:
Array
(
[demo1] => Array
(
[0] => Array
(
[id] => 1234
[img] => 1.jpg
)
)
[userId] => 1
)
From there, it should be pretty easy for you to figure out how to access the required vaule.
$data['demo1'][0]['img'];
Creating a helper function for ease of use
For ease of use, you can create a helper function to make this process easier. Whenever you want to view the contents of an array, you can simply call dump_array($array); and be done with it. No more messing around with <pre> tags or print_r().
Function code:
function dump_array($array) {
echo '<pre>' . print_r($array, TRUE) . '</pre>';
}
Usage example:
$arr = ['foo' => range('a','i'), 'bar' => range(1,9)];
dump_array($arr);
after decoding :
echo $data->demo[0]->img;
Basically, a { in JSON leads to a -> (it's an object).
And a [ to a [], it's an array.
I have a simple XML structure like, that when parse with simplexml_load_string generates this:
SimpleXMLElement Object
(
[#attributes] => Array
(
[token] => rs2rglql9c8ztem
)
[attachments] => SimpleXMLElement Object
(
[attachment] => 112979696
)
)
the XML structure:
<uploads token="vwl3u75llktsdzi">
<attachments>
<attachment>123456789</attachment>
</attachments>
</uploads>
I can get to the only actually important value "123456789" through iteration but that is a faf. Is there a way I can access it directly, ideally using the names of the elements.
I need to able to get attributes to ideally.
The simplest way to store the textual node value of a SimpleXMLElement in its own variable is to cast the element to a string:
$xml = simplexml_load_string($str);
$var = (string) $xml->attachments->attachment;
echo $var;
UPDATE
In accordance with the further question in your comment, the SimpleXMLElement::attributesdocs method will also return a SimpleXMLElement object which can be accessed in the same manner as the above solution. Consider:
$str = '<uploads token="vwl3u75llktsdzi">
<attachments>
<attachment myattr="attribute value">123456789</attachment>
</attachments>
</uploads>';
$xml = simplexml_load_string($str);
$attr = (string) $xml->attachments->attachment->attributes()->myattr;
echo $attr; // outputs: attribute value
Yes you can through the {} sytax here it goes:
$xmlString = '<uploads token="vwl3u75llktsdzi">
<attachments>
<attachment myattr="attribute value">123456789</attachment>
</attachments>
</uploads>';
$xml = simplexml_load_string($xmlString);
echo "attachment attribute: " . $xml->{"attachments"}->attributes()["myattr"] " \n";
echo " uploads attribute: " . $xml->{"uploads"}->attributes()["token"] . "\n";
you can replace "attachments" with $myVar or something
remember attributes() returns an associative array so you can get the keys with php array_keys() or do a foreach cycle.
I have some code that pulls HTML from an external source:
$doc = new DOMDocument();
#$doc->loadHTML($html);
$xml = #simplexml_import_dom($doc); // just to make xpath more simple
$images = $xml->xpath('//img');
$sources = array();
Then, if I add all of the sources with this code:
foreach ($images as $i) {
array_push($sources, $i['src']);
}
echo "<pre>";
print_r($sources);
die();
I get this result:
Array
(
[0] => SimpleXMLElement Object
(
[0] => /images/someimage.gif
)
[1] => SimpleXMLElement Object
(
[0] => /images/en/someother.jpg
)
....
)
But when I use this code:
foreach ($images as $i) {
$sources[] = (string)$i['src'];
}
I get this result (which is what is desired):
Array
(
[0] => /images/someimage.gif
[1] => /images/en/someother.jpg
...
)
What is causing this difference?
What is so different about array_push()?
Thanks,
EDIT: While I realize the answers match what I am asking (I've awarded), I more wanted to know why whether using array_push or other notation adds the SimpleXMLElement Object and not a string when both arent casted. I knew when explicitly casting to a string I'd get a string. See follow up question here:Why aren't these values being added to my array as strings?
The difference is not caused by array_push() -- but by the type-cast you are using in the second case.
In your first loop, you are using :
array_push($sources, $i['src']);
Which means you are adding SimpleXMLElement objects to your array.
While, in the second loop, you are using :
$sources[] = (string)$i['src'];
Which means (thanks to the cast to string), that you are adding strings to your array -- and not SimpleXMLElement objects anymore.
As a reference : relevant section of the manual : Type Casting.
Sorry, just noticed better answers above, but the regex itself is still valid.
Are you trying to get all images in HTML markup?
I know you are using PHP, but you can convert use this C# example of where to go:
List<string> links = new List<string>();
if (!string.IsNullOrEmpty(htmlSource))
{
string regexImgSrc = #"<img[^>]*?src\s*=\s*[""']?([^'"" >]+?)[ '""][^>]*?>";
MatchCollection matchesImgSrc = Regex.Matches(htmlSource, regexImgSrc, RegexOptions.IgnoreCase | RegexOptions.Singleline);
foreach (Match m in matchesImgSrc)
{
string href = m.Groups[1].Value;
links.Add(href);
}
}
In your first example, you should:
array_push($sources, (string) $i['src']);
Your second example gives an array of strings because you are converting the SimpleXMLElements to strings using the (string) cast. In your first example you are not, so you get an array of SimpleXMLElements instead.
I'm requesting data from an online source which I then decode into json StdClass objects (using php). Once I've done this I have the following (see below). I'm trying to extract the elements in 'otherstuff' by doing echo $response->stuff->WHAT GOES HERE?->otherstuff
However I cant hard code the [2010-12] because its a date, is there any way I can call e.g. $response->stuff->nextsibling->stuff
I hope this makes sense to someone :D Currently i'm bastardising this with a $key => $value for loop and extracting the key value and using it in my $response->stuff->$key->stuff call.
stdClass Object
(
[commentary] =>
[stuff] => stdClass Object
(
**[2010-12]** => stdClass Object
(
[otherstuff] => stdClass Object
(
[otherstuffrate] => 1
[otherstufflevel] => 1
[otherstufftotal] => 1
)
)
)
)
StdClass instances can be used with some Array Functions, among them
current — Return the current element in an array and
key — Fetch a key from an array
So you can do (codepad)
$obj = new StdClass;
$obj->{"2012-10"} = 'foo';
echo current($obj); // foo
echo key($obj); // 2012-10
On a sidenote, object properties should not start with a number and they may not contain dashes, so instead of working with StdClass objects, pass in TRUE as the second argument to json_decode. Returned objects will be converted into associative arrays then.
The date key must be a string, otherwise PHP breaks ;).
echo $response->stuff['2010-12']->otherstuff
Retrieve it using a string.
Edited again: added object code also
json decode it as associative array, and use key fetched through array_keys . See it work here : http://codepad.org/X8HCubIO
<?php
$str = '{
"commentary" : null,
"stuff" : {
"ANYDATE" : {
"otherstuff": {
"otherstuffrate" : 1,
"otherstufflevel" : 1,
"otherstufftotal" : 1
}
}
}
}';
$obj = json_decode($str,true);
$reqKey = array_keys($obj["stuff"]);
$req = $obj["stuff"][$reqKey[0]]["otherstuff"];
print_r($req);
print "====================as object ============\n";
$obj = json_decode($str);
$req = current($obj->stuff)->otherstuff;
print_r($req);
?>
I have some json object that I decoded, and one of the attributes starts with an "#" and I can't access the element with php because it throws an error.
[offers] => stdClass Object
(
[#attributes] => stdClass Object
(
[id] => levaka0B8a
)
)
How would I go about accessing attributes?
You can access it by a string:
echo $obj->{'#attributes'}->id; // levaka0B8a
Or a variable:
$name = '#attributes';
echo $obj->$name->id;
For more information on how variables are defined and used, see the following docs:
Variable Basics - Useful for learning what can be accessed as a variable without needing to use strings.
Variable Variables - How we used the variable to act as the name for another variable. This can be dangerous so tread carefully
You could do this:
$object->{'#attributes'}
Try to use,
$objSimpleXml->attributes()->id
Sample Code to Refer
<?php
$string = <<<XML
<a>
<foo name="one" game="lonely">1</foo>
</a>
XML;
$xml = simplexml_load_string($string);
var_dump( $xml );
foreach($xml->foo[0]->attributes() as $a => $b) {
echo $a,'="',$b,"\"\n";
}
?>
direct access is below from ircmaxwell or Richard Tuin, however you can decode JSON with second param true and recive array insted what could be an easier to access