I am trying to get a currency rate from this XML file:
http://www.bank.lv/vk/xml.xml
I am getting a currency ID from a HTML form, after that I have to find it according currency rate.
I am using SimpleXML and XPath, my selection is as follow:
$current_rate = $rates->xpath("/CRates/Currencies/Currency[ID='" .$source_currency ."']/Rate");
$source_currency is tested and valid, however, when casting $current_rate to (string), I get the word Array.
Do I have a mistake in the XPath node selection or somewhere else?
$current_rate = $rates->xpath("/CRates/Currencies/Currency[ID='" .$source_currency ."']/Rate");
Will return an array even if just 1 result is returned, if you use print_r you can see what is returned:
print_r($current_rate);
To access it you will have to use:
if (isset($current_rate))
{
echo $current_rate[0];
}
Or if there is the possibility of having more than 1 result for that given $source_currency:
foreach ($current_rate as $rate)
{
echo $rate, "\n";
}
Related
I need to get the value one one particular value in my json string
the json string comes from an api url http://url:port/api.php?action=reg_user&sub=list and outputs like so
[{"id":"1","username":"username1","credits":"0","group_id":"1","group_name":"Administrators","last_login":"1511883014","date_registered":"1421604973","email":"test1#my-email.com","ip":"8.8.8.8","status":"1"},{"id":"31","username":"username2","credits":"0","group_id":"1","group_name":"Administrators","last_login":"1539813642","date_registered":"1473632400","email":"test2#my-email.com","ip":"8.8.8.8","status":"1"},
i would like to check the value of credits where username = username1
then if credits > 30 do x, else do y
I presume first of all I need to decode this jason string
so i tried to do
$api_result = file_get_contents( 'http://url:port/api.php?action=reg_user&sub=list' );
$json_decode = json_decode($api_result);
echo $json_decode;
expecting this to echo the array in a nicely formatted structure, instead it just outputs the word Array. Where do I go from here?
Thanks
UPDATE 1...
SO i checked again and I defo can echo $api_result so I know that the file_get_contents is working fine i tried the two comments suggestions however both didn't work...
one of the suggestions was to make my php
$api_result = file_get_contents( 'http://url:port/api.php?action=reg_user&sub=list' );
$json_decode = json_decode($api_result);
echo $json_decode['username'];
here is a screenshot of how the echo $api_result is formatted in case this isnt a propper json string
so to me this looks like it opens with (and is all contained in a pair of [] and then each result is enclosed in {} as I'd expect with a json string right? however i thought json strings used {} and arrays used {} so to me this looks like a string inside an array???
I looked at php.net's resource on JSON DECODE and tried var_dump(json_decode($json)); which did print me this
UPDATE 2
I just tried https://www.functions-online.com/json_decode.html and pasted the data in, it was able to decode the data absolutely fine,
It then gave me a copy if the json_decode sample at the bottom but this didn't work either, returning a null value like json_decode doesn't work on my server?
From your second screenshot (please cut & paste the text instead!) you can see the decoded JSON is an array of objects with properties id, username etc. So you can access them using object notation. This code uses the snippet of your api_result from your original question to demonstrate how to do what you want:
$api_result = '[{"id":"1","username":"username1","credits":"0","group_id":"1","group_name":"Administrators","last_login":"1511883014","date_registered":"1421604973","email":"test1#my-email.com","ip":"8.8.8.8","status":"1"},{"id":"31","username":"username2","credits":"0","group_id":"1","group_name":"Administrators","last_login":"1539813642","date_registered":"1473632400","email":"test2#my-email.com","ip":"8.8.8.8","status":"1"}]';
$json = json_decode($api_result);
foreach ($json as $user) {
if ($user->username == 'username1') {
if ($user->credits > 30) {
// do x
echo "user $user->username has more than 30 credits ($user->credits)";
}
else {
// do y
echo "user $user->username has less than or equal to 30 credits ($user->credits)";
}
}
}
Output:
user username1 has less than or equal to 30 credits (0)
Like the title says, I'm importing an external XML file into a site. It's actually weather data from observation sites around the world. I can parse and display the data no problem. My problem is I'm trying to sum up a specific set of data.
Here's the basic code:
<?php
$xml = simplexml_load_file('https://aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=kbwi&hoursBeforeNow=65');
for($i=0;$i<=60;$i++)
{
$precip[$i] = $xml->data->METAR[$i]->precip_in;
echo $precip[$i];
}
?>
This will echo all the values from 'precip_in' from the XML file, and it does work. But if I try to sum up the data in $precip or in 'precip_in' by using array_sum, I get a blank page. Using var_dump returns "NULL" a bunch of times.
Now, I could manually sum the values by doing something like:
$rainTotal = $precip[0]+$precip[1]+$precip[2];
But one thing I want to do with this is a 24 hour rainfall total. The observations aren't always updated at regular or hourly intervals; meaning that if I were to do something like this:
$rainTotal = $precip[0]+$precip[1]+$precip[2]...+$precip[23];
It would not necessarily give me the 24 hour rain total. So, I need a way to sum all the rainfall values contained within 'precip_in' or $precip.
Any ideas on how I should proceed?
EDIT: Some clarifications based on the comments below:
Echoing and var_dump-ing $precip[$i] work fine. But if I try the following:
<?php
$xml = simplexml_load_file('https://aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=kbwi&hoursBeforeNow=65');
for($i=0;$i<=60;$i++)
{
$precip[$i] = $xml->data->METAR[$i]->precip_in;
echo array_sum($precip[$i]);
}
?>
I get a blank page. Doing a var_dump of array_sum($precip[$i]) results in "NULL" a bunch of times in a row.
I have tried casting the XML string as either a float or a string, but I get the same results.
the value of $xml->data->METAR[$i]->precip_in is an object ((SimpleXMLElement)#12 (1) { [0]=> string(5) "0.005" }). It's not numeric, so it has no numeric value. You can cast this to a float however and get the numeric value your were expecting.
for($i=0;$i<=60;$i++)
{
$precip[$i] = (float)$xml->data->METAR[$i]->precip_in;
echo $precip[$i];
}
These float values can be summed.
Consider an array_sum on an XPath array return:
$xml = simplexml_load_file('https://aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=kbwi&hoursBeforeNow=65');
$result = array_sum(array_map("floatval", $xml->xpath('//METAR/precip_in')));
echo $result;
// 10.065
Alternatively you can use XPath's sum() which requires using DOMDocument and not SimpleXML, specifically DOMXPath::evaluate:
$dom = new DOMDocument;
$dom->load('https://aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=kbwi&hoursBeforeNow=65');
$xpath = new DOMXPath($dom);
$sum = (float)$xpath->evaluate('sum(//METAR/precip_in)');
echo $sum;
// 10.065
I have a serialized array that I need to access:-
a:5:{s:5:"width";i:750;s:6:"height";i:330;s:4:"file";s:25:"2017/12/Sophrologie-1.jpg";s:5:"sizes";a:21:{s:20:"listingpro-blog-grid";a:4:{s:4:"file";s:25:"Sophrologie-1-372x240.jpg";s:5:"width";i:372;s:6:"height";i:240;s:9:"mime-type";s:10:"image/jpeg";}s:21:"listingpro-blog-grid2";a:4:{s:4:"file";s:25:"Sophrologie-1-372x330.jpg";s:5:"width";i:372;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:21:"listingpro-blog-grid3";a:4:{s:4:"file";s:25:"Sophrologie-1-672x330.jpg";s:5:"width";i:672;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:23:"listingpro-listing-grid";a:4:{s:4:"file";s:25:"Sophrologie-1-272x231.jpg";s:5:"width";i:272;s:6:"height";i:231;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro-listing-gallery";a:4:{s:4:"file";s:25:"Sophrologie-1-580x330.jpg";s:5:"width";i:580;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:21:"listingpro-list-thumb";a:4:{s:4:"file";s:25:"Sophrologie-1-287x190.jpg";s:5:"width";i:287;s:6:"height";i:190;s:9:"mime-type";s:10:"image/jpeg";}s:23:"listingpro-author-thumb";a:4:{s:4:"file";s:23:"Sophrologie-1-63x63.jpg";s:5:"width";i:63;s:6:"height";i:63;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-gallery-thumb1";a:4:{s:4:"file";s:25:"Sophrologie-1-458x330.jpg";s:5:"width";i:458;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-gallery-thumb2";a:4:{s:4:"file";s:25:"Sophrologie-1-360x198.jpg";s:5:"width";i:360;s:6:"height";i:198;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-gallery-thumb3";a:4:{s:4:"file";s:25:"Sophrologie-1-263x198.jpg";s:5:"width";i:263;s:6:"height";i:198;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-gallery-thumb4";a:4:{s:4:"file";s:25:"Sophrologie-1-653x199.jpg";s:5:"width";i:653;s:6:"height";i:199;s:9:"mime-type";s:10:"image/jpeg";}s:25:"listingpro-detail_gallery";a:4:{s:4:"file";s:25:"Sophrologie-1-383x330.jpg";s:5:"width";i:383;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:33:"listingpro-checkout-listing-thumb";a:4:{s:4:"file";s:24:"Sophrologie-1-220x80.jpg";s:5:"width";i:220;s:6:"height";i:80;s:9:"mime-type";s:10:"image/jpeg";}s:31:"listingpro-review-gallery-thumb";a:4:{s:4:"file";s:25:"Sophrologie-1-184x135.jpg";s:5:"width";i:184;s:6:"height";i:135;s:9:"mime-type";s:10:"image/jpeg";}s:17:"listingpro-thumb4";a:4:{s:4:"file";s:25:"Sophrologie-1-272x300.jpg";s:5:"width";i:272;s:6:"height";i:300;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro_location270_400";a:4:{s:4:"file";s:25:"Sophrologie-1-270x330.jpg";s:5:"width";i:270;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro_location570_455";a:4:{s:4:"file";s:25:"Sophrologie-1-570x330.jpg";s:5:"width";i:570;s:6:"height";i:330;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro_location570_228";a:4:{s:4:"file";s:25:"Sophrologie-1-570x228.jpg";s:5:"width";i:570;s:6:"height";i:228;s:9:"mime-type";s:10:"image/jpeg";}s:26:"listingpro_location270_197";a:4:{s:4:"file";s:25:"Sophrologie-1-270x197.jpg";s:5:"width";i:270;s:6:"height";i:197;s:9:"mime-type";s:10:"image/jpeg";}s:22:"listingpro_cats270_213";a:4:{s:4:"file";s:25:"Sophrologie-1-270x213.jpg";s:5:"width";i:270;s:6:"height";i:213;s:9:"mime-type";s:10:"image/jpeg";}s:22:"Sophrologie-1-1170x400";a:5:{s:4:"file";s:25:"Sophrologie-1-1170x400jpg";s:5:"width";s:4:"1170";s:6:"height";s:3:"400";s:9:"mime-type";s:10:"image/jpeg";s:7:"nova-wp";b:1;}}s:10:"image_meta";a:12:{s:8:"aperture";s:1:"0";s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";s:1:"0";s:9:"copyright";s:19:"Maygutyak - Fotolia";s:12:"focal_length";s:1:"0";s:3:"iso";s:1:"0";s:13:"shutter_speed";s:1:"0";s:5:"title";s:0:"";s:11:"orientation";s:1:"0";s:8:"keywords";a:0:{}}}
I want to retrieve the Sophrologie-1-1170x400jpg filename from it (at the bottom of the array).
I can't figure out how to retrieve this filename into this array. The clue is that there is a nova-wp value in that row.
This array comes fromwp-postmeta table in an wordpress installation.
If you could bring me to the direction, I'll be very thankful.
The data you show has been produced through serialization. Use the unserialize function in order to bring it back to its original state:
$data = unserialize($text);
Then, traverse the deserialized data it in order to retrieve the value you are looking for:
echo $data["sizes"]["Sophrologie-1-1170x400"]["file"];
// Output: Sophrologie-1-1170x400jpg
A working demo can be found here.
If you need to scan your data in order to find the correct value, you can use the following code:
$data = unserialize($text);
if (array_key_exists("Sophrologie-1-1170x400", $data["sizes"])) {
echo $data["sizes"]["Sophrologie-1-1170x400"]["file"];
} else {
echo "File not found!";
}
I am trying to process an XML item into a PHP array and simply return it.
However, I am getting "Array to string conversion" as an error on line 3.
PHP Code
function processPlayers($players) { // paramater is the XML item
$playerGUIDS = array();
$playerGUIDArray = explode(";", $players); // CREATE ARRAY FROM STRING WHICH HAVE A ; DELIMINATER
foreach($playerGUIDArray as $player) {
$playerGUIDS[] = $player;
}
return $playerGUIDS;
}
XML Item
<playguid>DC242003;BY523643</playguid>
I am using WP ALL Import as a plugin so I specify my custom field data value as
[processPlayers({playguid[1]})]
See here:
http://www.wpallimport.com/2015/10/wp-all-export-1-1-1-function-editor/
http://www.wpallimport.com/documentation/advanced/execute-php/
My ideal output is below (this is the form of metadata in a WordPress DB).
a:2:{i:0;s:8:"JC745819";i:1;s:8:"JB705789";}
You got error, because WPAllImport try insert this value into database. So, you must return in function string value, not array. In your case, serialized:
function processPlayers($players) {
return serialize(explode(";", $players));
}
I just encountered a closely related case in parsing multiple XML items as an array. As this is one of the highest ranking search results on the topic, I thought the following might help someone else:
WP All Import does not pass an array value to your custom PHP function. If your input element is not a string, but e.g. a list of XML child elements, then WP All Import will pass an empty string if you try to do the following:
<parents>
<parent>...</parent>
<parent>...</parent>
<parent>...</parent>
...
</parents>
[IF(has_special_children({parents[1]}))]
<h2>My Conditional Header</h2>
{parents[1]/parent[8]}
{parents[1]/parent[12]}
{parents[1]/parent[13]}
[ENDIF]
<?php
function has_special_children($parent) {
var_dump(gettype($parent)); // outputs: string
var_dump($parent); // outputs: string ""
return $parent[8] || $parent[12] || $parent[13];
}
?>
In the PHP function, $parent is always an empty string when passing an XML element that has children.
Solution
You can use a variadic function in PHP to pass the elements of interest and check them individually instead:
[IF(wpai_has_any_value({parents[1]/parent[8]}, {parents[1]/parent[12]}, {parents[1]/parent[13]}))]
<h2>My Conditional Header</h2>
{parents[1]/parent[8]}
{parents[1]/parent[12]}
{parents[1]/parent[13]}
[ENDIF]
<?php
function wpai_has_any_value(...$values) {
return (bool) array_filter($values);
}
?>
I want go get the adress details from a JSON return like:
http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false
But the Array always differs in the amount of elements. So any Idea how to get the adress details like postal code with php?
This should work for you if you want to retrieve the postal_code. It should give you the idea of how to access the other data you require:
// Decode json
$decoded_json = json_decode($json);
foreach($decoded_json->results as $results)
{
foreach($results->address_components as $address_components)
{
// Check types is set then get first element (may want to loop through this to be safe,
// rather than getting the first element all the time)
if(isset($address_components->types) && $address_components->types[0] == 'postal_code')
{
// Do what you want with data here
echo $address_components->long_name;
}
}
}
Just a little addition to the answer provided by Springie. If you want to loop through the whole array, you'll need to add another condition, because you might end up with getting only prefix of the post code.
if ( isset($address_components->types)
&& $address_components->types[0] === 'postal_code'
&& !in_array('postal_code_prefix', $address_components->types) ) { }