PHP array comparison with different lengths - php

I need to compare values from 2 arrays that are not always the same size, each containing either a login or a logout time. I need to get the time difference total or time logged in between these values. Where I am getting caught is the logout result is usually smaller then the login. I tried the following but it isn't accurate at all.
$offset = 0;
for($i=0;$i<sizeof($login_ary);$i++){
//unset($time_logged);
$time_logged = Array();
while( (int)$login_ary[$i] > (int)$logout_ary[$i] ) {
$offset++;
}
$time_logged['login'] = $login_ary[$i] + $offset;
$time_logged['logout'] = $logout_ary[$i];
$calc_ary[] = $time_logged;
}
$time_logged_in = "undefined";
End result I need to get either an array with lined up login/logoffs or a calculation of the total time difference between the login time and then logout time. But I have to exclude logins that don't have an associated logout.
EDITS
1) Times inside of the arrays are unix timestamps
2) the arrays aren't static as this is done inside a loop for each user in a result set so the var_dump would look something like the following
login_arr
Array([0] => '1385402632',[1] => '1385763384',[2] => '1387293992')
logout_arr
Array([0] => '1387294012')
** MY SOLUTION **
My solution is out of context of the original question which is why I posted it as an edit instead of an answer. But here is what I did, the simplicity of it makes me feel foolish that I didn't think of it originally. What I did, is write the session timeout into the logout_ary since the data was going to be unrepresented otherwise, we decided that fudging a time was better then completely avoiding it. So I took the login time and fudged a logout time and spliced it into the array at the same point. I still would like to know the true answer to this problem if there is one though.
for($i=0;$i<sizeof($login_ary);$i++){
//unset($time_logged);
$time_logged = Array();
if( (int)$login_ary[$i] > (int)$logout_ary[$i] ) {
array_splice($logout_ary,$i,0,$login_ary[$i]+$session_length);
$time_logged['login'] = $login_ary[$i];
$time_logged['logout'] = $logout_ary[$i];
} else {
$time_logged['login'] = $login_ary[$i];
$time_logged['logout'] = $logout_ary[$i];
}
$calc_ary[] = $time_logged;
}

Just read the comments, I think this might be what you're after comment and I can see if I can help more.
<?php
function calcTime($login_ary, $loutout_ary) {
$login_ary_length = sizeof($login_ary);
$logout_ary_length = sizeof($logout_ary);
if($login_ary_length != $logout_ary_length) {
$diff = $login_ary_length - $logout_ary_length;
//just find the code that suits your format and put it in the function strtotime()
$timestamp = strtotime('TODAYS DATE AND TIME');
//for the amount of diff we add todays date and time to the array so that they are eqal
for(i=0; i<=$diff; i++) {
array_push($logout_ary, $timestamp);
}
//I'm going to leave this for you to do.
return $total_hours;
}
}
?>
I hope this is what you're looking for.

What exactly is stored in the two arrays? Just time variables? How are you to know if say that login_ary[i] is the login time for the log_out[i] time? Also, why not just take the log_out time - the log_in time to get the time differential?

Related

gravity form $_POST issue

I've been wrapping my head around this issue for at least a couple days now, searched online and even broke the code down to make sure I'm not missing anything.
The Goal: I'm simply grabbing the value from the Birthdate field, calculate it, then save it to the hidden field which is called 'Age'.
The Issue: I am able to grab the value and calculate just fine. However I am unable to store/save it to that specific field, which as you will see in the code is field id= 47. Whenever I run the app, fill out the form and checked the Entries, the #47 pops up (it is not related to the id#. I ran some test like saving it into another field and it was the same). I am able to 'echo' out the var $age and it gives me exactly what I want. However when I try to save it, it gives me the aforementioned '47'.
On the line that contains '$_POST['input_47'] = $age', that is where my issue is. I know I can pass integer and strings to the $_POST, but it will not accept the $age.
Please let me know if I haven't made my request clear. Thank you very much to anyone who can provide a hint or two to get this resolved!
Here's the code that I placed on functions.php *edited
add_filter( 'gform_pre_submission_filter_1', 'pre_submission', 10, 4 );
function pre_submission ($form) {
// Calculate the age based on incoming variable $fsmConvert
$ageTime = strtotime($_POST['input_26']);
$t = time(); // current timestamp
$ageConvert = ($ageTime < 0) ? ( $t + ($ageTime * -1) ) : $t - $ageTime;
$year = 60 * 60 * 24 * 365;
$ageYears = $ageConvert / $year; // if you want exact estimate, STOP HERE
$age = floor($ageYears); //this is calculated age
foreach($form['fields'] as $field2) {
if(strpos($field2['id'], 47) === false) {
continue;
$field2['defaultValue'] = $age;
}
}
// return $form;
return $form;
}
Instead of adding your $age variable in $_POST directly, you can try to add it in $value variable.
Note : By default $form contains whole Gravity form inputs and $value contains all the inputs that user passed.
Let me know if I can help you further....

Small scope/huge frustration mystery: buggy array behavior in php

So crazy! I have a bug that's 100% reproducible, it happens in only a few lines of code, yet I cannot for the life of me determine what the problem is.
My project is a workout maker, and the mystery involves two functions:
get_pairings: It makes a set of $together_pairs (easy) and $mixed_pairs (annoying), and combines them into $all_pairs, used to make the workout.
make_mixed_pairs: this has different logic depending on whether it's a partner vs solo workout. Both cases return a set of $mixed_pairs (in the same exact format), called by the function above.
The symptoms/clues:
The case of the solo workout is fine, $all_pairs will only contain $mixed_pairs (because as it's defined, $together_pairs are only for partner workouts)
In the case of the a partner workout, when I combine the two sets in get_pairings(), $all_pairs only successfully gets the first set I give it! (If I swap those lines at step 2 and add $together_pairs first, $all_pairs contains only those. If I do $mixed_pairs first, $all_pairs contains only that).
Then if I uncomment that second-to-last line in make_mixed_pairs() just for troubleshooting to see what happens, then $all_pairs does successfully include exercises from both sets!
That suggests the problem is something I'm doing wrong in making the arrays in make_mixed_pairs(), but I confirmed that the resulting format is identical in both cases.
Anyone see what else I could be missing? I've been narrowing down this bug for 4 hours so far- I can't make it any smaller, and I can't see what's wrong :(
Update: I updated the for loop in make_mixed_pairs() to stop at $mixed_pair_count - 1 (instead of just $mixed_pair_count), and now I sometimes get one single 'together_pair' mixed in the $all_pairs results; the same damn one each time, weirdly. Though it's not 'fixed', because again when I change the order that I add the two sets in get_pairings, when I add $together_pairs first, then $all_pairs is ENTIRELY those- it's so strange...
Here are the functions: first get_pairings (relevant part is right before and after step 2):
/**
* Used in make_workout.php: take the user's available resources, and return valid exercises
*/
function get_pairings($exercises, $count, $outdoor_partner_workout)
{
// 1. Prep our variables, and put exercises into the appropriate buckets
$mixed_exercises = array();
$together_pairs = array();
$mixed_pairs = array();
$all_pairs = array();
$selected_pairs = array();
// Sort the valid exercises: self_pairing exercises go as they are, with extra
// array for consistent formatting. Mixed ones go into $mixed_exercises array
// for more specialized pairing in make_mixed_pairs
foreach($exercises as $exercise)
{
if ($exercise['self_pairing'])
{
$pair = array($exercise);
array_push($together_pairs, [$pair]);
}
else
{
$this_exercise = array($exercise);
array_push($mixed_exercises, $this_exercise);
}
}
// Now get the mixed_pairs
$mixed_pairs = make_mixed_pairs($mixed_exercises, $outdoor_partner_workout);
// 2. combine together into one set, and select random pairs for the workout
// Add both sets to the array of all pairs (to pick from afterward)
$all_pairs += $mixed_pairs;
$all_pairs += $together_pairs;
// Now let's choose at random our desired # of pairs, and save them in $selected_pairs
$pairing_keys = array_rand($all_pairs, $count);
foreach($pairing_keys as $key)
{
array_push($selected_pairs, $all_pairs[$key]);
}
// Finally, shuffle it so we don't always see the self-pairs first
shuffle($selected_pairs);
return $selected_pairs;
}
And the other one- make_mixed_pairs: there are two cases, the first is complicated (and shows the bug) and the second is simple (and works):
/**
* Used by get_pairings: in case of a partner workout that has open space (where
* one person can travel to a point while the other does an exercise til they return)
* we'll pair exercises in a special way. (If not, fine to grab random pairs)
*/
function make_mixed_pairs($mixed_exercises, $outdoor_partner_workout)
{
$mixed_pairs = array();
// When it's an outdoor partner workout, we want to pair travelling with stationary
// put them into arrays and then we'll make pairs using one from each
if ($outdoor_partner_workout)
{
$mixed_travelling = array();
$mixed_stationary = array();
foreach($mixed_exercises as $exercise)
{
if ($exercise[0]['travelling'])
{
array_push($mixed_travelling, $exercise);
}
else
{
array_push($mixed_stationary, $exercise);
}
}
shuffle($mixed_travelling);
shuffle($mixed_stationary);
// determine the smaller set, and pair exercises that many times
$mixed_pair_count = min(count($mixed_travelling), count($mixed_stationary));
for ($i=0; $i < $mixed_pair_count; $i++)
{
$this_pair = array($mixed_travelling[$i], $mixed_stationary[$i]);
array_push($mixed_pairs, $this_pair); // problem is adding them here- we get only self_pairs
}
}
// Otherwise we can just grab pairs from mixed_exercises
else
{
// shuffle the array so it's in random order, then chunk it into pairs
shuffle($mixed_exercises);
$mixed_pairs = array_chunk($mixed_exercises, 2);
}
// $mixed_pairs = array_chunk($mixed_exercises, 2); // when I replace it with this, it works
return $mixed_pairs;
}
Oh for Pete's sake: I mentioned this to a friend, who told me that union is flukey in php, and that I should use array_merge instead.
I replaced these lines:
$all_pairs += $together_pairs;
$all_pairs += $mixed_pairs;
with this:
$all_pairs = array_merge($together_pairs, $mixed_pairs);
And now it all works

Can I retry file_get_contents() until it opens a stream?

I am using PHP to get the contents of an API. The problem is, sometimes that API just sends back a 502 Bad Gateway error and the PHP code can’t parse the JSON and set the variables correctly. Is there some way I can keep trying until it works?
This is not an easy question because PHP is a synchronous language by default.
You could do this:
$a = false;
$i = 0;
while($a == false && $i < 10)
{
$a = file_get_contents($path);
$i++;
usleep(10);
}
$result = json_decode($a);
Adding usleep(10) allows your server not to get on his knees each time the API will be unavailable. And your function will give up after 10 attempts, which prevents it to freeze completely in case of long unavailability.
Since you didn't provide any code it's kind of hard to help you. But here is one way to do it.
$data = null;
while(!$data) {
$json = file_get_contents($url);
$data = json_decode($json); // Will return false if not valid JSON
}
// While loop won't stop until JSON was valid and $data contains an object
var_dump($data);
I suggest you throw some sort of increment variable in there to stop attempting after X scripts.
Based on your comment, here is what I would do:
You have a PHP script that makes the API call and, if successful, records the price and when that price was acquired
You put that script in a cronjob/scheduled task that runs every 10 minutes.
Your PHP view pulls the most recent price from the database and uses that for whatever display/calculations it needs. If pertinent, also show the date/time that price was captured
The other answers suggest doing a loop. A combo approach probably works best here: in your script, put in a few loops just in case the interface is down for a short blip. If it's not up after say a minute, use the old value until your next try.
A loop can solve this problem, but so can a recursive function like this one:
function file_get_contents_retry($url, $attemptsRemaining=3) {
$content = file_get_contents($url);
$attemptsRemaining--;
if( empty($content) && $attemptsRemaining > 0 ) {
return file_get_contents_retry($url, $attemptsRemaining);
}
return $content;
}
// Usage:
$retryAttempts = 6; // Default is 3.
echo file_get_contents_retry("http://google.com", $retryAttempts);

PHP/MySQL - How to adjust query based on the length (characters) within database

I've had excellent support here, so I figured I'd try again, as I have no clue where to even begin looking for this answer.
I have a simple MySQL database, named "testimonials", which contains 3 tables, "id", "name", "content"
What I want to do, is display testimonials within a fixed size block. Just simply displaying the content is no problem at all, however where I'm stuck is the (somewhat) unique way I'm trying to make it work. I would like to display a random item on each page load, and then to check the character length of the "content" within the testimonial, and if it's equal to or greater than XX length, then just display the one testimonial, otherwise if it's less than XX in length to display a second testimonial (assuming it combined with the first doesn't break the container box).
The box in question is 362px in width and 353px in height using 14px font with Verdana. An example of how the testimonial will appear on the page is like this:
"This is the testimonial content, some nice message from a client."
-- Billy Bob, Owner, Crazy Joe's Tavern
The "name" table in the database holds everything in bold (minus the -- of course), in case someone felt the need to ask.
As I typed that, I felt as if I was asking for a miracle, however I'll still post the question, hoping someone might just know the answer. As always, thanks for any help I may get, if this is just simply asking too much, I'm not totally against the idea of only displaying one testimonial at a time making a ground rule saying they have to contain a minimum of XX characters.
Thanks!
Quick Update: I didn't expect to get answers so quickly, I'm not at my desk at the moment, so as soon as I sit back down I'll go through and see which answer fits best. However, do you guys get together and try to make your answer more complex than the previous answer? lol, thanks though, for anyone who's offering help, you guys rock!
Final edit: I decided against this whole idea, as it just way over complicated everything. For the time being, I'm just going to display all testimonials, and make them scroll, while I work on a jQuery snippet to make it prettier. Thanks everyone for your help though! Should I decide again to do this, I'll be trying my chosen answer.
You just need a loop. Pseudo-code:
$length = 0;
$target = 200; // or whatever
while( $length < $target ) {
$comment = getOneComment();
displayComment($comment);
$length += strlen( $comment['content'] ); // assuming getOneComment() returns an associative array
}
To make it pretty, if the display box is going to a be a fixed height, you could use some jQuery to toggle whether to show the second comment on not.
Assuming you have testimonials in an array:
$testimonials = array(
't1' => array(
'content' => 'testimonials 1 content..',
'author' => 'the author'
),
't2' => array(
'content' => 'testimonials 2 content..',
'author' => 'the author 2'
),
);
You could have an maxLengthTestimonialsContent and maxLenthAllTestimonnials variable :
$maxLengthTestimonialsContent = 120;
$maxLenthAllTestimonnials = 240;
And now with a simple loop you build the array testimonials that you will use to show:
$testimonialsToShow = array();
$i = 1; $totalLength = 0
foreach($testimonials as $t) {
if( $i > 1 && strlen( $t['content']) < $maxLengthTestimonialsContent
&& $totalLength < $maxLenthAllTestimonnials )
break; // basically here you test that testimonials less first
// and with less length than maxLengthTestimonial, and also
// total length less than maxLengthAll to be stored
//in $testimonialsToShow
else {
$testimonialsToShow[] = $t;
$totalLength = $t['content'];
}
}
Something like this is what you would need.
<?php
$str = $res["testimonial"];
if (strlen($str) > 50) {
// Logic to retrieve and display second testimonial
}
?>
Obviously there's some more processing you'll have to come up with to determine if the second testimonial is short enough to fit or not. But that should get you started.
EDIT:
For the randomization, I use this on my own site:
$referrals = mysql_query("SELECT id FROM ts_testimonials");
$referralView = array();
$i = 0;
while ($newReferral = mysql_fetch_array($referrals)) {
$referralView[$i] = $newReferral['id'];
$i++;
}
if (sizeof($referralView) >= 1){
$referralTop = rand(0,sizeof($referralView)-1);
$newReferralTop = mysql_fetch_array(mysql_query("SELECT * FROM ts_testimonials WHERE id = '".$referralView[$referralTop]."'"));
if (sizeof($referralView) >=2){
$referralBottom = rand(0,sizeof($referralView)-1);
while ($referralBottom == $referralTop) {
$referralBottom = rand(0,sizeof($referralView)-1);
}
$newReferralBottom = mysql_fetch_array(mysql_query("SELECT * FROM ts_testimonials WHERE id = '".$referralView[$referralBottom]."'"));
}
}

Creating a different array related to different times a loop happens php

there. I'm having a problem with creating arrays in certain conditions in php, i'll try to explain. Here's my code:
for ($i = 1; $i < $tamanho_array_afundamento; $i++) {
if ($array_afundamento[$i] - $array_afundamento[$i - 1] > 1) {
$a = $array_afundamento[$i - 1];
$con->query('CREATE TABLE IF NOT EXISTS afunda_$a
SELECT (L1_forma_tensao_max + L1_forma_tensao_min)/2 as L1_forma_tensao, (L2_forma_tensao_max + L2_forma_tensao_min)/2 as L2_forma_tensao, (L3_forma_tensao_max + L3_forma_tensao_min)/2 as L3_forma_tensao
FROM afundamento
WHERE id > $prevNum AND id < $a');
$tabelas_intervalos_afunda1 = ($con->query("SELECT * FROM afunda_$a");
while ($row = $tabelas_intervalos_afunda->fetch(PDO::FETCH_ASSOC)) {
$array_forma_onda_fase1_afund[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund[] = $row['L3_forma_tensao'];
}
$prevNum = $a;
}
}
So as u can see, i have an if statement in a for loop, what i'm wishing to do is to create
one set of:
{
$array_forma_onda_fase1_afund[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund[] = $row['L3_forma_tensao'];
}
every time the if statement is runned. I was trying replacing this in the original code:
{
$array_forma_onda_fase1_afund_$a[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund_$a[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund_$a[] = $row['L3_forma_tensao'];
}
so as $a is changed everytime the if statement is accessed, i could have a different set of these arrays for everytime the if statement is accessed, but php doesn't accept this and i wouldn't have a very good result, though if i can reach it i would be pleased.
But my goal is to get:
{
$array_forma_onda_fase1_afund_1[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund_1[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund_1[] = $row['L3_forma_tensao'];
}
{
$array_forma_onda_fase1_afund_2[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund_2[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund_2[] = $row['L3_forma_tensao'];
}
...
where the last number represents the array retrieved for the n-th time the if statement runned. Does someone have a tip for it?
Thanks in advance! Would appreciate any help.
EDIT
As asked, my real world terms is as follows:
I have a table from which i need to take all the data that is inside a given interval. BUT, there's a problem, my data is a sine function whose amplitude may change indefinite times (the data bank is entered by the user) and, when the amplitude goes inside that interval, i need to make some operations like getting the least value achieved while the data was inside that interval and some other parameters, for each interval separately, (That's why i created all those tables.) and count how many times it happpened.
So, in order to make one of the operations, i need an array with the data for each time the databank entered by the user goes in that interval (given by the limits of the create query.).
If i were not clear, just tell me please!
EDIT 2
Here's the image of part of the table i'm working with:
http://postimg.org/image/5vegnk043/
so, when the sine gets inside the interval i need, it can be seen by the L1_RMS column, who accuses it, so it's when i need to get the interval data until it gets outside the interval. But it may happens as many times as this table entered by the user brings it on and we need to bear in mind that i need all the intervals separately to deal with the data of each one.
Physics uh?
You can do what you wanted with the arrays, it's not pretty, but it's possible.
You can dynamically name your arrays with the _$a in the end, Variables variables, such as:
${"array_forma_onda_fase3_afund_" . $a}[] = "fisica é medo";

Categories