I have foreach cycle in PHP. It is going trough json items, and for every item I have value that changes. I set my cycle to run every 20min.
I need my value to be saved and next time foreach runs for that item I need to assign at the beginning old value to variable so I can compare old and new value in foreach cycle.
here is the code:
// Parse results and extract data to display
foreach($json as $quote)
{
//add before value
$state1 = $state2;
// assign object elements to vars
$q_change = $quote->c;
$q_price = $quote->l;
$q_name = $quote->t;
$q_changep = $quote->cp;
$q_symbol = $quote->t;
$q_ltrade = $quote->lt;
$q_exch = $quote->e;
$state2 = $q_change;
$parametar = $q_change - $state1;
// Define class based on change
if ( $parametar < -0.3 ) { $chclass = "minus"; }
else if ( $parametar > 0.3 ) { $chclass = "plus"; }
else if ( $q_change < 0 ) { $chclass = "minus"; }
else if ( $q_change > 0 ) { $chclass = "plus"; }
else { $chclass = "zero"; $q_change = "0.00"; }
}
Any idea how that might work?
You will have to save the JSON on the file system to retrieve the values on subsequent runs:
$oldJsonFile = '/path/to/data.json';
if (is_file($file)) {
$oldJson = file_get_contents($oldJsonFile);
}
// Do the work, and then store it back to the file system
file_put_contents($cacheFile, $newJson);
I'd imagine you are looking to do something like the following. Sessions will store your data for the next foreach execution.
session_start();
$previousData = $_SESSION['PreviousData'];
foreach($array as $key => $value){
//... all your foreach calculations
//end of foreach
}
$_SESSION['PreviousData'] = $thisData;
Alternatively you could store the data into a database, that's what they are for. Then you'll be free to do all kinds of interesting queries on past records etc.
Related
this is my sample array data from bio-metrics
I just want to collect data that has the same bio_id and date
temp:[
0:{
bio_id:"1"
date:"2017-10-05"
date_time:"2017-10-05 08:00:22"
device_name:"biometrics"
time:"08:00:22"
}
1:{
bio_id:"1"
date:"2017-10-05"
date_time:"2017-10-05 08:00:23"
device_name:"biometrics"
time:"08:00:23"
}
2:{
bio_id:"2"
date:"2017-10-05"
date_time:"2017-10-05 08:06:29"
device_name:"biometrics"
time:"08:06:29"
}
3:{
bio_id:"1"
date:"2017-10-05"
date_time:"2017-10-05 15:06:47"
device_name:"biometrics"
time:"15:06:47"
}
4:{
bio_id:"2"
date:"2017-10-05"
date_time:"2017-10-05 16:01:50"
device_name:"biometrics"
time:"16:01:50"
}
]
I been stuck with this code that I made, and don't know how I should manipulate it, or how I will store it properly, I have try some array function but it gives different result to my data
$len = count($temp);
for ($i=0; $i <$len ; $i++) {
$id = $temp[$i]['bio_id'];
$date = $temp[$i]['date'];
for ($x=0; $x < $len; $x++) {
if ($id == $temp[$x]['bio_id'] && $date == $temp[$x]['date']) {
$data[] = $temp[$x];
$int[] = $x;
}
}
}
I don't know how I should manipulate it, or how I will store it properly, I have try some array function but it gives different result to my data
This code will work to collect duplicate in the array on the basis of id and date
$newTemp = array();
foreach($temp as $value){
$newTemp[$value['id'].'_'.$value['date']][] = $value;
}
$newTemp = array();
for($temp as $value){
$key = $value->id." ".$value->date;
if(isset($newTemp[$key])){
$newTemp[$key] = array_merge($newTemp[$key],$value);
}else{
$newTemp[$key] = $value;
}
}
I just want to collect data that has the same bio_id and date
The easiest way is to iterate over the input array and aggregate the data into a new array, indexed by key generated using the bio_id and date fields. This way, a duplicate entry can be easily identified because the key already exists in the output array.
$input = array(/* the big input array here */);
// Build the output here
$output = array();
foreach ($input as $item) {
$key = $item['bio_id'].':'.$item['date'];
if (array_key_exists($key, $output)) {
// This is a duplicate
// Ignore the data, update only the count
$output[$key]['count'] ++;
} else {
// This is the first time this combination is processed
// Copy the input
$output[$key] = $item;
// Keep in 'count' how many times this combination exists in the input
$output[$key]['count'] = 1;
}
}
Each entry of $output is the first entry of $input that has the same combination of bio_id and date. Additional, the value of count is the number of entries of $input that share that pair of bio_id and date.
Work on this example if you need to aggregate the data in a different way (keep all duplicates, instead of their number, f.e.).
Another example that keeps the duplicates:
// Build the output here
$output = array();
foreach ($input as $item) {
$key = $item['bio_id'].':'.$item['date'];
if (array_key_exists($key, $output)) {
// This is a duplicate; add it to the list
$output[$key]['all'][] = $item;
} else {
// This is the first time this combination is processed
// Copy important values (bio_id and date) from the input
$output[$key] = array(
'bio_id' => $item['bio_id'],
'date' => $item['date'],
// Store the entire $item into a list
'all' => array($item),
);
}
}
Read about PHP arrays how to access their elements using the square brackets syntax and how to create or modify their values.
Since i have many diffrent workers on my workkey and i just want to print every work once. I Though of doin a check like this.
At the end of the loop i wanna save the value from workkey. So before every print i will check, If the new workkey is diffrent from the last one = Dont print.
$counter = 0;
while(db2_fetch_row($queryexe)) {
$work = db2_result($queryexe, 'workkey');
$fname = db2_result($queryexe, 'fname');
$lname = db2_result($queryexe, 'lname');
if ($workkey != $saveworkkey){
$counter = 0;
}
if ($counter < 1){
print ( some stuff)
print ( some stuff)
print ( some stuff)
}
$workkey = $saveworkkey;
$counter++;
}
What I do to solve the issue is to add all values to an array with the key as array key. This way, even if there are duplicates they will overwrite eachother.
$workers = array()
while ($record = db2_fetch_row($queryexe)) {
$workers[$record['workkey']] = $record;
}
To print your values you can simply foreach
foreach ($workers as $worker) {
// print worker
}
I'm working on a project in which I pull various statistics about the NHL and inserting them into an SQL table. Presently, I'm working on the scraping phase, and have found an XML parser that I've implemented, but I cannot for the life of me figure out how to pull information from it. The table can be found here -> http://www.tsn.ca/datafiles/XML/NHL/standings.xml.
The parser supposedly generates a multi-dimmensional array, and I'm simply trying to pull all the stats from the "info-teams" section, but I have no idea how to pull that information from the array. How would I go about pulling the number of wins Montreal has? (Solely as an example for the rest of the stats)
This is what the page currently looks like -> http://mattegener.me/school/standings.php
here's the code:
<?php
$strYourXML = "http://www.tsn.ca/datafiles/XML/NHL/standings.xml";
$fh = fopen($strYourXML, 'r');
$dummy = fgets($fh);
$contents = '';
while ($line = fgets($fh)) $contents.=$line;
fclose($fh);
$objXML = new xml2Array();
$arrOutput = $objXML->parse($contents);
print_r($arrOutput[0]); //This print outs the array.
class xml2Array {
var $arrOutput = array();
var $resParser;
var $strXmlData;
function parse($strInputXML) {
$this->resParser = xml_parser_create ();
xml_set_object($this->resParser,$this);
xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");
xml_set_character_data_handler($this->resParser, "tagData");
$this->strXmlData = xml_parse($this->resParser,$strInputXML );
if(!$this->strXmlData) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($this->resParser)),
xml_get_current_line_number($this->resParser)));
}
xml_parser_free($this->resParser);
return $this->arrOutput;
}
function tagOpen($parser, $name, $attrs) {
$tag=array("name"=>$name,"attrs"=>$attrs);
array_push($this->arrOutput,$tag);
}
function tagData($parser, $tagData) {
if(trim($tagData)) {
if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) {
$this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $tagData;
}
else {
$this->arrOutput[count($this->arrOutput)-1]['tagData'] = $tagData;
}
}
}
function tagClosed($parser, $name) {
$this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this- >arrOutput)-1];
array_pop($this->arrOutput);
}
}
?>
add this search function to your class and play with this code
$objXML = new xml2Array();
$arrOutput = $objXML->parse($contents);
// first param is always 0
// second is 'children' unless you need info like last updated date
// third is which statistics category you want for example
// 6 => the array you want that has wins and losses
print_r($arrOutput[0]['children'][6]);
//using the search function if key NAME is Montreal in the whole array
//result will be montreals array
$search_result = $objXML->search($arrOutput, 'NAME', 'Montreal');
//first param is always 0
//second is key name
echo $search_result[0]['WINS'];
function search($array, $key, $value)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value)
$results[] = $array;
foreach ($array as $subarray)
$results = array_merge($results, $this->search($subarray, $key, $value));
}
return $results;
}
Beware
this search function is case sensitive it needs modifications like match to
a percentage the key or value changing capital M in montreal to lowercase will be empty
Here is the code I sent you working in action. Pulling the data from the same link you are using also
http://sjsharktank.com/standings.php
I have actually used the same exact XML file for my own school project. I used DOM Document. The foreach loop would get the value of each attribute of team-standing and store the values. The code will clear the contents of the table standings and then re-insert the data. I guess you could do an update statement, but this assumes you never did any data entry into the table.
try {
$db = new PDO('sqlite:../../SharksDB/SharksDB');
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
echo "Error: Could not connect to database. Please try again later.";
exit;
}
$query = "DELETE FROM standings";
$result = $db->query($query);
$xmlDoc = new DOMDocument();
$xmlDoc->load('http://www.tsn.ca/datafiles/XML/NHL/standings.xml');
$searchNode = $xmlDoc->getElementsByTagName( "team-standing" );
foreach ($searchNode as $searchNode) {
$teamID = $searchNode->getAttribute('id');
$name = $searchNode->getAttribute('name');
$wins = $searchNode->getAttribute('wins');
$losses = $searchNode->getAttribute('losses');
$ot = $searchNode->getAttribute('overtime');
$points = $searchNode->getAttribute('points');
$goalsFor = $searchNode->getAttribute('goalsFor');
$goalsAgainst = $searchNode->getAttribute('goalsAgainst');
$confID = $searchNode->getAttribute('conf-id');
$divID = $searchNode->getAttribute('division-id');
$query = "INSERT INTO standings ('teamid','confid','divid','name','wins','losses','otl','pts','gf','ga')
VALUES ('$teamID','$confID','$divID','$name','$wins','$losses','$ot','$points','$goalsFor','$goalsAgainst')";
$result= $db->query($query);
}
I am using this function to redirect to a random post. I am trying to find a mechanism to prevent the same random post to appear twice in a row. Can anyone give a hint?
function sofa_view_random_post() {
// make array of all posts IDs
$q = get_posts('numberposts=-1');
$array = array();
foreach($q as $p) {
$array[] = $p->ID;
}
// randomize array to get random post
$k = array_rand($array);
$v = $array[$k];
wp_redirect( get_permalink( $v ) ); exit;
}
I get all posts IDs first and put them to array. I randomize the array to get a value. But not sure how to prevent same value from being triggered.
Store the previous result in the session, and make sure you don't pick that one again:
if( !isset( $_SESSION['last_random_post'])) {
$_SESSION['last_random_post'] = -1;
}
do {
$k = array_rand( $array);
} while( $k == $_SESSION['last_random_post']);
$_SESSION['last_random_post'] = $k;
I'm not sure how this applies to wordpress specifically, but it should be easily adaptable:
For completeness, here is the function incorporating the above code:
function sofa_view_random_post() {
if( !isset( $_SESSION['last_random_post'])) {
$_SESSION['last_random_post'] = -1; // Or null, as long as its an invalid ID
}
// make array of all posts IDs
$q = get_posts('numberposts=-1');
$array = array();
foreach($q as $p) {
$array[] = $p->ID;
}
// randomize array to get random post
do {
$k = array_rand( $array);
} while( $k == $_SESSION['last_random_post']);
$_SESSION['last_random_post'] = $k;
$v = $array[$k];
wp_redirect( get_permalink( $v ) ); exit;
}
Use sessions. Store the last used ID in the session data, and when constructing the list of possible posts, omit that post from the list.
Like this:
function sofa_view_random_post() {
// Initialise last post value as NULL if missing
if (!isset($_SESSION['last_post'])) {
$_SESSION['last_post'] = NULL;
}
// Make array of all posts IDs except last viewed
$q = get_posts('numberposts=-1');
$array = array();
foreach ($q as $p) {
if ($p->ID !== $_SESSION['last_post']) {
// Only add this ID if it's not the last viewed post
$array[] = $p->ID;
}
}
// Get random post ID and store it in the session
$k = array_rand($array);
$_SESSION['last_post'] = $v = $array[$k];
// Redirect user
wp_redirect( get_permalink( $v ) );
exit;
}
I have a set of structured data, that I'm trying to merge together, based on a set of conditions.
There is a set of rows, returned from the db. Each row has a course id, and a discipline id. There's an equal amount of disciplines in each course, but some disciplines are repeated in both courses.
I want to build a data structure where if the discipline is in both courses, then it only appears once on a line in a new data structure, and nothing else, but if there are two unmatched disciplines, then they are both included in a new course.
The code I'm using so far, is filtering and removing the keys that are duplicated, and adding them to a new array. This works fine.
However, because I can't control the order in which the data comes (don't ask) I'm having troubles making sure that each line has either a discipline that appears in both courses, or one of each.
I think I need some techniques to help deal with this, and was wondering if anyone had come across this before. I want to avoid making many consecutive loops, if possible.
Thanks.
edit: messy and horrible code below:
function buildDisciplineMap(){
$sql = "SELECT [idcurso]
,[idversao]
,[ordem]
,[bloco]
,[obsbloco]
,[iddisciplina] as idd
,cast([iddisciplina] as TEXT) as iddisciplina
,[descdisciplina]
,[iddepartamento]
,[descdepartamento]
,[ects]
,[horas]
,[idregente]
,[regente]
,[idregente1]
,[regente1]
,[idregente2]
,[regente2]
,[idregente3]
,[regente3]
,cast([objectivos] as TEXT) as objectivos
,cast([programa] as TEXT) as programa
,[descdisciplina_en]
,cast([objectivos_en] as TEXT) as objectivos_en
,cast([programa_en] as TEXT) as programa_en
FROM [proffile2].[dbo].[vw_site_CursosDisciplinas_FEG]
where idcurso = '3512 GE' or idcurso = '3513 ECON' order by idcurso desc ";
$discs = $this->returnObject($sql);
$map = new stdClass();
// find blocos, and titles
foreach ($discs as $key => $value) {
if (isset($map->bloco[$value->bloco])) {
// block already exists
} else {
#echo "making new block";
$map->bloco[$value->bloco] = new stdClass();
}
if (strlen($value->obsbloco)>1) {
$map->bloco[$value->bloco]->title = $value->obsbloco;
}
}
foreach ($map->bloco as $keybloco => $value) {
$map->bloco[$keybloco]->lines = array();
$processed_ids = array();
foreach ($discs as $kd => $vd) {
if ($vd->bloco == $keybloco) {
// check if this discipline occurs more than once in this block
foreach ($discs as $kdd => $vdd) {
if ($vdd->iddisciplina == $vd->iddisciplina && $kdd != $kd && !in_array($kd,$processed_ids) && !in_array($kdd,$processed_ids)) {
// this discipline is for both courses
$details = array();
$details['both'] = $vd;
$map->bloco[$keybloco]->lines[] = $details;
array_push($processed_ids, $kd, $kdd);
unset($discs[$kdd]);
unset($discs[$kd]);
break;
}
}
}
}
}
$processed_ids = array();
foreach ($discs as $key => $value) {
echo $value->idcurso."\n";
}
foreach ($discs as $kd => $vd) {
$bloco = $vd->bloco;
$lastidx =sizeof($map->bloco[$bloco]->lines)-1;
$line = $map->bloco[$bloco]->lines[$lastidx];
echo sizeof($map->bloco[$bloco]->lines);
#pr($line);
if (isset($line['both'])) {
echo "omog - \n ";
$map->bloco[$bloco]->lines[][$vd->idcurso] = $vd;
unset($discs[$kd]);
continue;
}
#pr($line['both']->idcurso);
foreach ($map->bloco[$bloco]->lines as $k => $v) {
echo $k."-";
#echo $v['3513 ECON']->idcurso;
}
if ($line[$vd->idcurso]) {
echo 'add';
$map->bloco[$bloco]->lines[][$vd->idcurso] = $vd;
} else {
echo 'fill';
$map->bloco[$bloco]->lines[sizeof($map->bloco[$bloco]->lines)-1][$vd->idcurso] = $vd;
}
}
echo sizeof($discs);
return $map;
}
You said "don't ask", but I've got to: why can't you control the order of the rows? Aren't you the one writing the database query?
If you think fixing the order of the rows will help you parse and build a new data structure better, why not make sorting the rows the first step in your process? Or, is the data set too large?
You might find some of PHP's array set manipulations to be of use. i.e. array_diff, array_intersect_key etc.