0

I have a piece of code which will select x number of days into the future and print it out.

I'm then trying to select data from those timestamps, and print out accordingly:

Below I am selecting the number of days in the future it should loop ($max) and how many rows/data there is ($data["cnt"])

    $stmt=$dbh->prepare("select round((expire - unix_timestamp()) / 86400) as days, count(*) as cnt from xeon_users_rented WHERE user_by=:username group by days;");
    $stmt->bindParam(":username",$userdata['username']);
    $stmt->execute();
    $data=$stmt->fetchAll();
    $max = max(array_map(function($d){
        return $d['days'];
    }, $data));

    $expireData = array();

I then loop through x number of days in the future and print it out: (Let's say that $x is = 10)

for($x = 0; $x <= $max; $x++){
  if ($data[$x]["cnt"] > 0){
    $expireData[]  = $data[$x]["cnt"];
  }else{
    $expireData[] = 0;
  }

    $stamp = strtotime('+'.$x.' day', time());
    $expireDays[] = date("Y/m/d", $stamp);

}

I then print out the days data and the data:

<?php echo implode("', '", $expireDays); ?>
<?php echo implode("', '", $expireData); ?>

Which gives me:

'2014/11/05', '2014/11/06', '2014/11/07', '2014/11/08', '2014/11/09', '2014/11/10', '2014/11/11', '2014/11/12', '2014/11/13', '2014/11/14', '2014/11/15'

and (where each digit represent a value for that specific date)

2,8,0,0,0,0,0,0,0,0

So far so good. The only problem here is, that the data (2,8,0,0etc.) is not correct. It should for example be:

0,0,2,0,0,0,8,0,0,0

My question is: How can I print out the data, where it matches the timestamp (xeon_users_rented.expire)?

2 Answers 2

1

To simplify my answer from before and to answer your question directly "How can I print out the data, where it matches the timestamp"?

You need to first put the unix timestamp of "strtotime('+'.$x.' day', time());" into an array from your original loop. Remove the expiredays[] stuff from that loop.

Then loop through that array and then use array_search for finding any matching indexes in the $data array.

if (found in $data array)
    $expireDays[] = $data[array_search position]['cnt'];
else
    $expireDays[] = 0;
Sign up to request clarification or add additional context in comments.

Comments

1

From what I have gathered in what you are trying to establish, the sql query (for example) returns an array such as:

$data = array(
    array("days"=>232975857, "cnt"=> 4),
    array("days"=>232975867, "cnt"=> 10),
    array("days"=>232976689, "cnt"=> 0),
    array("days"=>232976688, "cnt"=> 2)
);

The max in your case is 10. However, please note that your code (below):

$max = max(array_map(function($d){
    return $d['days'];
}, $data));

could return a lot of PHP E_NOTICE errors and be slow because you are working out a maximum from the unix_timestamp at that stage which is for example 232975867 (far too many loops I suspect that you need). The max should be worked out in the following way I suspect:

$max = count($data);

In my case (from my data example example) this will return something like 4 for which your for loop code will need to reference "<" not "<=". To optimise this I would actually put straight into the for loop "...; $x < count($data); ...;" unless of course you need the $max later.

Here is a big issue for me. I don't see where currently you have any correlation between the $stamp variable and the "days" column from your sql statement. Perhaps I have not seen enough information from you to fully understand or I am interpreting your question incorrectly but your sql for one will not necessarily return the same dates as the stamp variable will calculate and will not certainly return a cnt of 0 for any dates that do not exist in that table. This is why:

if ($data[$x]["cnt"] > 0){

part of the section is unnecessary and possibly incorrect.

To answer your question why do you get "2,8,0,0,0,0...." instead of the order you expected is because the sql does not return 0 cnt values as quite simply the date does not exist in it's table and your implode still returns '0's appended as you forcibly added the 0's afterwords with the line:

$expireData[] = 0;

First of all, you need to fill your data (or re-write your data to contain cnt of '0's in the correct array places). You can achieve this from the sql level with a subquery that ensures missing dates are contained and then a cnt value of 0 is enforced. I'll leave this to you to work out however another way (via PHP) is to do the following (pseudo code):

place each 'stamps' (in unix format) in array from previous loop
forloop $i through $stamps
    array_search $stamps against $data['days']
    if (found)
        $expireDays[] = $data[array_search position]['cnt'];
    else
        $expireDays[] = 0;

This means that you remove the $expireDays from your first loop.

Finally, perhaps I have misunderstood and that your 'days' column shouldn't match your $stamp dates as those dates are in the future and your 'days' columns are in the past. In this case, your only option is to adjust your sql statement to forcibly include dates that are missing (between a certain date range)

Good luck.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.