foreach loop in php get invalid argument supplied - php

I get "Invalid argument supplied" when using the following code. I can successfully parse an ip address and port number but i dont know how to get more than one at a time. My foreach loop is not working. Any ideas?
$dom = new DOMDocument();
$dom->loadHTMLFile($url);
$xml = simplexml_import_dom($dom);
$dom_results = $xml->xpath("/html/body/div[#id='subpagebgtabs']/div[#id='container']/table[#id='listtable']");
$ip_address = $dom_results[0]->tr->td[1]->span;
$ip_post = $dom_results[0]->tr->td[2];
$address_parts = $ip_address.":".$ip_post;
foreach ($address_parts as $address_full){
echo $address_full . "<br>";
}
$Dom_Results Output
["tr"]=>
array(50) {
[0]=>
object(SimpleXMLElement)#5 (3) {
["#attributes"]=>
array(2) {
["class"]=>
string(0) ""
["rel"]=>
string(7) "9054676"
}
["comment"]=>
object(SimpleXMLElement)#56 (0) {
}
["td"]=>
array(8) {
[0]=>
object(SimpleXMLElement)#57 (2) {
["#attributes"]=>
array(2) {
["class"]=>
string(20) "leftborder timestamp"
["rel"]=>
string(10) "1309047901"
}
["span"]=>
string(10) "2 minutes"
}
[1]=>
object(SimpleXMLElement)#58 (1) {
["span"]=>
string(13) "122.72.10.201"
}
[2]=>
string(3) "80"

I think this is what you're looking for:
// If results are found
if ( ! empty($dom_results) )
// Loop through each result. Based on your XPath query, the $dom_results
// contains tables. This loops through the rows of the first table.
foreach ( $dom_results[0]->tr as $row )
{
$ip_address = $row->td[1]->span;
$ip_post = $row->td[2];
// Output the address
echo $ip_address . ":" . $ip_post . "<br />";
}

it seems you want to extract all the ip address and port numbers and concatenate it like
ipaddress:port
So try this
foreach($dom_results as $dom) {
$ip = $dom->tr->td[1]->span;
$port = $dom->tr->td[2];
$address = $ip . ":". $port;
echo $address . "<br />";
}

Related

Update Check with PHP

I'm working on an update system that checks a remote file string
$local = simplexml_load_file(root_p.'/version.xml');
$remote = simplexml_load_file("mygithuburltoblob/version.xml");
if($local->build == $remote->build) {
} else {
echo "Version ".$remote->version." Available now";
}
But even if the build numbers match it still returns that the update is available. Does anyone know why that would be?
(Yes root_p is already defined, the problem isn't loading and retrieving the values)
Remote Var Dump
object(SimpleXMLElement)#12 (6) { ["title"]=> string(11) "Loopy Cubix" ["author"]=> string(12) "Morgan Green" ["version"]=> string(3) "1.0" ["build"]=> string(4) "1111" ["type"]=> string(5) "Alpha" ["feed"]=> object(SimpleXMLElement)#15 (0) { } }
Local Var Dump
object(SimpleXMLElement)#11 (6) { ["title"]=> string(24) "Looped Cubix Pre Release" ["author"]=> string(12) "Morgan Green" ["version"]=> string(3) "1.0" ["build"]=> string(4) "1111" ["type"]=> string(6) "Closed" ["feed"]=> object(SimpleXMLElement)#15 (0) { } }
On the top of the page is my output from
<?php
$local = simplexml_load_file(root_p.'/version.xml');
$remote = simplexml_load_file("https://raw.githubusercontent.com/Doxramos/Invontrol/master/version.xml");
echo "Local: ". gettype($local->build);
foreach($local->build as $build) {
echo $build. "<br />";
}
echo "Remote: ". gettype($remote->build);
foreach($remote->build as $build) {
echo $build. "<br />";
}
Shows both as an object with the same value.
As I see that oject is no equal, example of some compared elements:
["title"]=> string(11) "Loopy Cubix"
["title"]=> string(24) "Looped Cubix Pre Release"
The issue had to do with whitespace while parsing the XML data. I ended up fixing it by replacing
if($remote->build == $local->build) {
}
else {
//Output Update Information
}
with
$trimmed_local = trim($local->build);
$trimmed_remote = trim($remote->build);
And using the new variables as my comparison operators
if($trimmed_local == $trimmed_remote) {
}
else {
//Output Update Information
}

Echo status message in php geonames timezone

I'm using following code php to get timezone:
$url = 'http://api.geonames.org/timezone?lat=' . $latitude . '&lng=' . $longitude . '&username=demo';
$xml = simplexml_load_file($url);
foreach($xml->children() as $timezone)
{
echo "TimezoneId: ".$timezone->timezoneId." ";
echo "DstOffset : ".$timezone->dstOffset." ";
echo "GmtOffset : ".$timezone->gmtOffset." ";
}
it work but for latitude and longitude of Antartica for example it give error status message:
<status message="no timezone information found for lat/lng" value="15"/>
How to echo this message?
I'm tryng this:
if ($xml->status) {
echo "error: ".$timezone->status['message']. "";
}
but don't work
You are trying to get an element from object, which doesn't exist. In such a XML element you have attributes and some values like in your case: countryCode, countryName, dstOffset, gmtOffset and etc. If you use var_dump() the result you can see the error message is in these attributes, which is an array.
Here you are an example:
var_dump() on a location without problem:
object(SimpleXMLElement)#4 (12) {
["#attributes"]=>
array(1) {
["tzversion"]=>
string(11) "tzdata2014i"
}
["countryCode"]=>
string(2) "KG"
["countryName"]=>
string(10) "Kyrgyzstan"
["lat"]=>
string(7) "40.4246"
["lng"]=>
string(7) "74.0021"
["timezoneId"]=>
string(12) "Asia/Bishkek"
["dstOffset"]=>
string(3) "6.0"
["gmtOffset"]=>
string(3) "6.0"
["rawOffset"]=>
string(3) "6.0"
["time"]=>
string(16) "2015-07-09 19:53"
["sunrise"]=>
string(16) "2015-07-09 05:41"
["sunset"]=>
string(16) "2015-07-09 20:36"
}
And here a var_dump() of Antartica:
object(SimpleXMLElement)#4 (1) {
["#attributes"]=>
array(2) {
["message"]=>
string(41) "no timezone information found for lat/lng"
["value"]=>
string(2) "15"
}
}
You can easily handle and print this error message like that:
if ($xml->status) {
echo 'error:' . $timezone->attributes()->message;
}
try this,
<?php
$url = 'http://api.geonames.org/timezone?lat=' . $latitude . '&lng=' . $longitude . '&username=demo';
$xml = simplexml_load_file($url);
foreach ($xml->geoname as $o_location){
printf(
'Name %s<br>
lat is %s<br>
lon is %s<br>
geonameId is %s<br>
countryCode is %s<br>
countryName is %s<br>
fcl is %s<br>
fcode is %<br>
',
$o_location->name,
$o_location->lat,
$o_location->lng,
$o_location->geonameId,
$o_location->countryCode,
$o_location->countryName,
$o_location->fcl,
$o_location->fcode
);
}
?>

create php array using simpleXMLobject

I'm trying to get this array ($resdata) with object(SimpleXMLElement) into a php array:
$resdata =
array(59) {
[0]=> ...
[10]=> object(SimpleXMLElement)#294 (28) {
["reservation_id"]=> string(7) "8210614"
["event_id"]=> string(6) "279215"
["space_reservation"]=> array(2) {
[0]=> object(SimpleXMLElement)#344 (9) {
["space_id"]=> string(4) "3760"
["space_name"]=> string(9) "205"
["formal_name"]=> string(33) "Center" }
[1]=> object(SimpleXMLElement)#350 (9) {
["space_id"]=> string(4) "3769"
["space_name"]=> string(9) "207"
["formal_name"]=> string(32) "Right" } } }
}
I've tried:
$res = (array)$resdata;
$reservation = $res['reservation'];
$result = array();
foreach ($reservation as $key => $value){
$res = array($value);
$spid = $res[0]->space_reservation->space_id;
echo $value->event_id."<br />";
echo $spid."<br />";
}
This only outputs the first space_id and I need to get all the space_ids within "space_reservation" array. Not all records will have multiple space_ids. Any help pointing me in the right direction is appreciated. Not sure if I should use xpath but I need to re-write my foreach statement regardless.
I was hoping to be able to literally convert all references to "object(SimpleXMLElement)#_ (#)" to "array(#)"
[10]=> array (28) {
["reservation_id"]=> string(7) "8210614"
["event_id"]=> string(6) "279215"
["space_reservation"]=> array(2) {
[0]=> array (9) {
["space_id"]=> string(4) "3760"
["space_name"]=> string(9) "205"
["formal_name"]=> string(33) "Center" }
[1]=> array (9) {
["space_id"]=> string(4) "3769"
["space_name"]=> string(9) "207"
["formal_name"]=> string(32) "Right" } } }
}
the function in my cakephp 1.3 controller is this:
$xml = simplexml_load_string($string);
$this->data['events']= $xml->children();
$resdata = $this->data['events'];
$this->set('resdata',$resdata);
I think this should do what you are looking for:
foreach ($resdata as $res) {
echo $res->event_id . '<br />';
foreach ($res->space_reservation as $reservation) {
echo $reservation->space_id . '<br />';
}
}
Googled it and found a general solution for any SimpleXMLElement to array conversion:
function xml2array($xml) {
$arr = array();
foreach ($xml as $element) {
$tag = $element->getName();
$e = get_object_vars($element);
if (!empty($e)) {
$arr[$tag] = $element instanceof SimpleXMLElement ? xml2array($element) : $e;
}
else {
$arr[$tag] = trim($element);
}
}
return $arr;
}

Containers listing in Windows Azure SDK for PHP

I am trying to list the containers and so far having no luck at all... i already tried
$aBlobContainer = $blobRestProxy->listContainers();
for($i = 0;$i<= count($aBlobContainer); $i++)
{
echo 'Blob Container name is: '.$aBlobContainer[$i]->Name."\n";
}
but i am having error
Cannot use object of type WindowsAzure\Blob\Models\ListContainersResult as array
Been trying to work around it all day just can't seem to make any progress... let me know if i am doing something silly or if there is a better way to find out if the container already exist? Thanks!
EDIT:
var_dump of the variable $aBlobContainer came up as
object(WindowsAzure\Blob\Models\ListContainersResult)#42 (5) {
["_containers":"WindowsAzure\Blob\Models\ListContainersResult":private]=>
array(2) {
[0]=>
object(WindowsAzure\Blob\Models\Container)#48 (4) {
["_name":"WindowsAzure\Blob\Models\Container":private]=>
string(6) "abc123"
["_url":"WindowsAzure\Blob\Models\Container":private]=>
string(48) "http://orig.blob.core.windows.net/abc123"
["_metadata":"WindowsAzure\Blob\Models\Container":private]=>
array(0) {
}
["_properties":"WindowsAzure\Blob\Models\Container":private]=>
object(WindowsAzure\Blob\Models\ContainerProperties)#47 (2) {
["_lastModified":"WindowsAzure\Blob\Models\ContainerProperties":private]=>
object(DateTime)#49 (3) {
["date"]=>
string(19) "2012-11-29 01:32:20"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "GMT"
}
["_etag":"WindowsAzure\Blob\Models\ContainerProperties":private]=>
string(19) ""0x8CF9BE88256926F""
}
}
[1]=>
object(WindowsAzure\Blob\Models\Container)#46 (4) {
["_name":"WindowsAzure\Blob\Models\Container":private]=>
string(8) "multi123"
["_url":"WindowsAzure\Blob\Models\Container":private]=>
string(50) "http://orig.blob.core.windows.net/multi123"
["_metadata":"WindowsAzure\Blob\Models\Container":private]=>
array(0) {
}
["_properties":"WindowsAzure\Blob\Models\Container":private]=>
object(WindowsAzure\Blob\Models\ContainerProperties)#45 (2) {
["_lastModified":"WindowsAzure\Blob\Models\ContainerProperties":private]=>
object(DateTime)#53 (3) {
["date"]=>
string(19) "2012-11-29 03:13:16"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "GMT"
}
["_etag":"WindowsAzure\Blob\Models\ContainerProperties":private]=>
string(19) ""0x8CF9BF69C25759F""
}
}
}
["_prefix":"WindowsAzure\Blob\Models\ListContainersResult":private]=>
NULL
["_marker":"WindowsAzure\Blob\Models\ListContainersResult":private]=>
NULL
["_nextMarker":"WindowsAzure\Blob\Models\ListContainersResult":private]=>
NULL
["_maxResults":"WindowsAzure\Blob\Models\ListContainersResult":private]=>
NULL
}
Looking at the Source Code:
$blobContainers = $blobRestProxy->listContainers(); //returns ListContainersResult
in order to get the listing of containers you'd have to do a subsequent call of:
$blobContainerArray = $blobContainers->getContainers(); //exposes the array of containers
Then you should be able to use that array in either a foreach or for statement. This workflow matches that of returning a list of blobs from within a container as seen in the README.md file:
try {
// List blobs.
$blob_list = $blobRestProxy->listBlobs("mycontainer");
$blobs = $blob_list->getBlobs();
foreach($blobs as $blob)
{
echo $blob->getName().": ".$blob->getUrl()."<br />";
}
} catch(ServiceException $e){
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code.": ".$error_message."<br />";
}
$options = new ListContainersOptions();
$options->setPrefix("prefixxxx");
$blobContainers = $blobRestProxy->listContainers($options);
$blobContainerArray = $blobContainers->getContainers();
foreach ($blobContainerArray as $container)
{
Trace("Container: " . $container->getName());
}
From the error message, it looks like $blobRestProxy->listContainers() is returning an object. Try the code below.
$aBlobContainer = $blobRestProxy->listContainers();
foreach($aBlobContainer as $row) {
echo 'Blob Container name is: '.$row->Name."\n";
}
When accessing $aBlobContainer as an array (i.e. $aBlobContainer[$i]), it was probably giving the error.
* Edit *
foreach($aBlobContainer as $key => $row) {
echo $row->Name . "\n";
}

php - how to check if there is text within XML element

:) Let's say that i have that code:
<sample number="1">TEXT</sample>
but sometimes it could be
<sample number"1"/>
Q: How to check if it's self closed or not ? Or I want to check if it's there TEXT within element sample
Note: I'm using that way to retrieve XML doc:
$content = #file_get_contents($url);
$xml = new SimpleXMLElement($content);
You need to type cast the element to string, then check if it's empty or not.
Here's a quick example:
$test = simplexml_load_string("<test><elem test='12'><sub /><sub /></elem><elem test='12'>hi</elem><elem test='9' /><elem /></test>");
foreach($test as $elem){
echo "\n";
var_dump($elem);
if((string)$elem == '' && $elem->count() == 0)
echo 'Empty';
else
echo 'Full';
}
Will return:
object(SimpleXMLElement)#3 (2) {
["#attributes"]=>
array(1) {
["test"]=>
string(2) "12"
}
["sub"]=>
array(2) {
[0]=>
object(SimpleXMLElement)#4 (0) {
}
[1]=>
object(SimpleXMLElement)#5 (0) {
}
}
}
Full
object(SimpleXMLElement)#5 (2) {
["#attributes"]=>
array(1) {
["test"]=>
string(2) "12"
}
[0]=>
string(2) "hi"
}
Full
object(SimpleXMLElement)#3 (1) {
["#attributes"]=>
array(1) {
["test"]=>
string(1) "9"
}
}
Empty
object(SimpleXMLElement)#5 (0) {
}
Empty

Categories