Multiplication with a simplexml_load_file() object doesn't work - php

I extract values from an XML with PHP
<?php
$url = 'list.xml';
$xml = simplexml_load_file($url);
$entries = $xml->item;
$i = 0;
$total = 1;
foreach($entries as $entry){
$i++;
$number[$i] = $entry->total;
$total *= $number[$i];
}
echo $total;
?>
How can I build a total based on each $number extracted from the XML? Right now, my total is zero.
So for all loops together something like:
$total = $number[1] * $number[2] * $number[3] * $number[4] ....

This should work for you:
(You have to cast the return of simplexml_load_file() to double)
$url = "list.xml";
$xml = simplexml_load_file($url);
$entries = $xml->results->rate;
$count = 0;
$total = 1;
$number = array();
foreach($entries as $entry){
$count++;
$number[$count] = $entry->Bid;
$total *= (double)$number[$count];
}
echo "Total: " . $total;

Related

I want to echo out a total number per repeat

I have created a small script which gives me random numbers. Now I want to create a list of this random number list with repeating numbers.
It should generate match numbers of this list of random numbers (A match number is a number which repeats)
For instance 4 – 6 – 9 – 32 – 34 – 31 – 5 – 32 (The match number here is 8 because after 8 numbers we have a repeater). I would like all the match numbers to be echo beside each other with a space in between.
Can someone help me?
I have tried creating an if statement but I can't get it working.
for ($rnd=1;$rnd<=50;$rnd++)
{
$random = mt_rand(0,100) . " ";
echo $random;
}
Explanation coming soon.
$numbers = array();
for($i = 1; $i <= 50; $i++) {
$number = mt_rand(0,100);
if(!isset($numbers[$number])) $numbers[$number] = array();
$numbers[$number][] = $i;
}
foreach($numbers as $key => $value) {
$start = '';
foreach($value as $k => $v) {
echo $start . $key . ' (Match Number: ' . $v . ')';
$start = ' - ';
}
echo '<br />';
}
If I don't misunderstood your question then this is what you want. Let's do this way-
<?php
$existing = [];
$repeat_numbers = [];
for ($rnd=1;$rnd<=50;$rnd++)
{
$random = mt_rand(0,100);
if(in_array($random,$existing)){
$repeat_numbers[] = $rnd; // pushing the repeating index
}
$existing[] = $random;
echo $random.PHP_EOL;
}
echo implode('-',$repeat_numbers);
?>
WORKING DEMO: https://3v4l.org/eEhB8
AS PER THE COMMENT
<?php
$existing = [];
$repeat_numbers = [];
for ($rnd=1;$rnd<=50;$rnd++)
{
$randoms[] = mt_rand(0,100);
}
echo implode('-',$randoms).PHP_EOL;
$i = 1;
foreach($randoms as $rnd){
if(in_array($rnd,$existing)){
$repeat_numbers[] = $i;
$i=1;
}
$existing[] = $rnd;
$i++;
}
echo implode('-',$repeat_numbers);
?>
WORKING DEMO https://3v4l.org/Xjc5X
AS PER THE LATEST COMMENT
<?php
$existing = [];
$repeat_numbers = [];
$randoms = explode('-','3-31-34-29-28-5-28-23-31-4-1-31-11-17-23-9-20-24-22-3-11-24-26-4-10');
$i = 1;
foreach($randoms as $rnd){
if(in_array($rnd,$existing)){
$repeat_numbers[] = $i;
$i=1;
$existing = []; // This like will do the magic for you
}
$existing[] = $rnd;
$i++;
}
echo implode('-',$repeat_numbers);
?>
WORKING DEMO: https://3v4l.org/hIT22
FINAL EDIT:
<?php
$existing = [];
$repeat_numbers = [];
$randoms = explode('-','4-9-13-18-19-34-23-9-9-13-44-5-13-13-88-26-29-27-34-67-65-83-26');
$i = 1;
foreach($randoms as $rnd){
if(in_array($rnd,$existing)){
$repeat_numbers[] = $i;
$i=1;
$existing = [];
}else{
$existing[] = $rnd;
$i++;
}
}
echo implode('-',$repeat_numbers);
?>
WORKING DEMO: https://3v4l.org/9j7iq
EDITED AGAIN:
<?php
$existing = [];
$repeat_numbers = [];
$randoms = explode('-','4-9-13-18-19-34-23-9-9-13-44-5-13-13-88-26-29-27-34-67-65-83-26');
//print_r($randoms);
$i = 0;
foreach($randoms as $rnd){
$i++;
if(in_array($rnd,$existing)){
$repeat_numbers[] = $i;
if(count($existing)==1){
$i=1;
}else{
$i=0;
}
$existing = [];
}
$existing[] = $rnd;
//print_r($existing);
}
echo implode('-',$repeat_numbers);
?>
WORKING DEMO: https://3v4l.org/VfIJY

Get max/min value from json file with PHP

Im am trying to get the min and max temp value from a json src. I'm not getting the desired result that I am looking for. This is what i have so far.
Any help is greatly appreciated
<?php
$url = 'https://samples.openweathermap.org/data/2.5/forecast?id=524901&appid=b6907d289e10d714a6e88b30761fae22';
$data = file_get_contents($url);
$forecasts = json_decode($data);
$length = count($forecasts->list);
for ($i = 0; $i < $length; $i++) {
$val = round($forecasts->list[$i]->main->temp, 0);
}
$min = min($val);
$max = max($val);
echo "max: ". $max ." - min: ". $max;
?>
You are overwriting the value of $val in each pass through your for loop. What you actually want to do is push each value into an array that you can then take the min and max of:
$val = array();
for ($i = 0; $i < $length; $i++) {
$val[] = round($forecasts->list[$i]->main->temp, 0);
}
$min = min($val);
$max = max($val);
Ok so I'm assuming that "temp" is the attribute where you want to get min/max:
<?php
function max($list){
$highest = $list[0]->main->temp;
foreach($list as $l){
$highest = $l->main->temp > $highest ? $l->main->temp : $highest;
}
return $highest;
}
function min($list){
$lowest = $list[0]->main->temp;
foreach($list as $l){
$lowest = $l->main->temp < $lowest ? $l->main->temp : $highest;
}
return $lowest;
}
$url = 'https://samples.openweathermap.org/data/2.5/forecast?id=524901&appid=b6907d289e10d714a6e88b30761fae22';
$data = file_get_contents($url);
$forecasts = json_decode($data);
$length = count($forecasts->list);
$min = min($forecasts->list);
$max = max($forecasts->list);
echo "max: ". $max ." - min: ". $max;
?>
should be copy-pastable for your case...

how to read only part of an xml file with php xmlreader

I have an RSS xml file that is pretty large, with more than 700 nodes.
I am using XMLReader Iterator library to parse it and display the results as 10 per page.
This is my sample code for parsing xml:
<?php
require('xmlreader-iterators.php');
$xmlFile = 'http://www.example.com/rss.xml';
$reader = new XMLReader();
$reader->open($xmlFile);
$itemIterator = new XMLElementIterator($reader, 'item');
$items = array();
foreach ($itemIterator as $item) {
$xml = $item->asSimpleXML();
$items[] = array(
'title' => (string)$xml->title,
'link' => (string)$xml->link
);
}
// Logic for displaying the array values, based on the current page.
// page = 1 means $items[0] to $items[9]
for($i = 0; $i <= 9; $i++)
{
echo ''.$items[$i]['title'].'<br>';
}
?>
But the problem is that, for every page, i am parsing the entire xml file and then just displaying the corresponding page results, like: if the page is 1, displaying the 1 to 10 nodes, and if the page is 5, displaying 41 to 50 nodes.
It is causing delay in displaying data. Is it possible to read just the nodes corresponding to the requested page? So for the first page, i can read nodes from 1 to 10 positions, instead of parsing all the xml file and then display first 10 nodes. In other words, can i apply a limit while parsing an xml file?
I came across this answer of Gordon that addresses a similar question, but it is using SimpleXML, which is not recommended for parsing large xml files.
use array_splice to extract the portion of array
require ('xmlreader-iterators.php');
$xmlFile = 'http://www.example.com/rss.xml';
$reader = new XMLReader();
$reader->open($xmlFile);
$itemIterator = new XMLElementIterator($reader, 'item');
$items = array();
$curr_page = (0 === (int) $_GET['page']) ? 1 : $_GET['page'];
$pages = 0;
$max = 10;
foreach ($itemIterator as $item) {
$xml = $item->asSimpleXML();
$items[] = array(
'title' => (string) $xml->title,
'link' => (string) $xml->link
);
}
// Take the length of the array
$len = count($items);
// Get the number of pages
$pages = ceil($len / $max);
// Calculate the starting point
$start = ceil(($curr_page - 1) * $max);
// return the portion of results
$arrayItem = array_slice($items, $start, $max);
for ($i = 0; $i <= 9; $i ++) {
echo '' . $arrayItem[$i]['title'] . '<br>';
}
// pagining stuff
for ($i = 1; $i <= $pages; $i ++) {
if ($i === (int) $page) {
// current page
$str[] = sprintf('<span style="color:red">%d</span>', $i);
} else {
$str[] = sprintf('%d', $i, $i);
}
}
echo implode('', $str);
Use cache in this case, since you cannot parse partially an XML.
Check this
<?php
if($_GET['page']!=""){
$startPagenew = $_GET['page'];
$startPage = $startPagenew-1;
}
else{
$startPage = 0;
}
$perPage = 10;
$currentRecord = 0;
$xml = new SimpleXMLElement('http://sports.yahoo.com/mlb/teams/bos/rss.xml', 0, true);
echo $startPage * $perPage;
foreach($xml->channel->item as $key => $value)
{
$currentRecord += 1;
if($currentRecord > ($startPage * $perPage) && $currentRecord < ($startPage * $perPage + $perPage)){
echo "$value->title";
echo "<br>";
}
}
//and the pagination:
//echo $currentRecord;
for ($i = 1; $i <= ($currentRecord / $perPage); $i++) {
echo("<a href='xmlpagination.php?page=".$i."'>".$i."</a>");
} ?>
Updated
Check this Link
http://www.phpclasses.org/package/5667-PHP-Parse-XML-documents-and-return-arrays-of-elements.html
You can use Dom and Xpath. It should be much faster, since Xpath allows you to select nodes by their position in a list.
<?php
$string = file_get_contents("http://oar.icrisat.org/cgi/exportview/subjects/s1=2E2/RSS2/s1=2E2.xml");
$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadXML($string);
$string = "";
$xpath = new DOMXPath($dom);
$channel = $dom->getElementsByTagName('channel')->item(0);
$numItems = $xpath->evaluate("count(item)", $channel);
// get your paging logic
$start = 10;
$end = 20;
$items = $xpath->evaluate("item[position() >= $start and not(position() > $end)]", $channel);
$count = $start;
foreach($items as $item) {
print_r("\r\n_____Node number $count ");
print_r( $item->nodeName);
$childNodes = $item->childNodes;
foreach($childNodes as $childNode) {
print_r($childNode->nodeValue);
}
$count ++;
}

Using key function without overwritting the same keys in PHP

I'd like to extract the data from an array within an array. But the problem is, when I use the key function it overwrites the first entry. I'm expecting to have a result of 135 rows, but it only gives me back 114.
Below is the code where I'm getting a problem..
while($row1 = mssql_fetch_array($result1)) {
$mycount = $mycount + 1;
$boskey = $row1["EAN11"]."^".$row1["AUART"];
$boskey1 = $row1["ORDNUM"]."^".$row1["ERDAT"]."^".$row1["KUNAG"]."^".$row1["NAME1"]."^".$row1["PERNR"]."^".$row1["FKIMG"]."^".$row1["BASEPRICE"]."^".$row1["NETPRICE"]."^".$row1["ZZMAXDISC"]."^".$row1["MVGR1"]."^".$row1["KDGRP"];
$bos[$boskey][$boskey1] = $bos[$boskey][$boskey1];
}
for ($i = 0; $i < count($bos); $i++) {
$abc = key($bos);
$arr = explode("^",$abc);
$ean11 = $arr[0];
$auart = $arr[1];
echo $ean11 . " - " . $auart;
for ($j = 0; $j < count($bos[$abc]); $j++) { //total count of $bos[$abc] is 114.
$xxx = key($bos[$abc]);
$arr1 = explode("^",$xxx);
$ordnum = $arr1[0];
$docdate = $arr1[1];
$customer = $arr1[2];
$name1 = $arr1[3];
$ae = $arr1[4];
$qty = $arr1[5];
$baseprice = $arr1[6];
$netprice = $arr1[7];
//$discount = $arr1[8];
$booktype = $arr1[9];
$kdgrp = $arr1[10];
$discount = 100 - (100 * ( $netprice / $baseprice));

String as calculation in php

I've got field in my database which contain strings like 21;48;33;22;31. Then I'd like to convert it to mathematical calculation 21+48+33+22+31.
$points = "21;48;33;22;31";
$points = str_replace(";","+",$points );
$points = preg_replace('/[^0-9\+\-\*\/\s]+/', '', $points);
echo $points;
But that simply does not work. I've got the same string "21+48+33+22+31" instead of the sum.
$points = "21;48;33;22;31";
$points = explode(';',$points );
$points = array_sum($points);
echo $points;
$points = "21;48;33;22;31";
$arr = explode(";", $points);
$points = 0;
foreach($arr as $key => $rows){
$points += $rows[$key];
}
echo $points;
Try above code it will give you proper result.
or you can try it also:
$points = "21;48;33;22;31";
$arr = explode(";", $points);
echo $points = array_sum($arr);
The easiest way is to explode the string.
Then you can iterate with foreach over the resulting array and calculate them.
$points = "21;48;33;22;31";
$points = explode(";", $points);
$calc = 0;
forearch($points as $point) {
$calc += $point;
}
Or your can use array_sum:
$points = "21;48;33;22;31";
$points = explode(";", $points);
$calc = array_sum($points);
Something like that. Perhaps there are some shorter ways.
$string = "21;48;33;22;31";
$string = explode(";" , "21;48;33;22;31");
$point = 0;
foreach($string as $num)
{ // by using (int) you can convert string to int.
$point = (int)$num + $point;
}
print($point);
// output
155
explode it then loop for sum...
<?php
$total = 0; // for getting the total
$points = "21;48;33;22;31";
$points = explode(';',$points);
for($i=0;$i<count($points);$i++){
$total+= $points[$i];
}
echo $total;
?>
<?php
eval('$sum = ' . str_replace(';','+','21;48;33;22;31').';');
echo $sum;

Categories