Array Loop Assuming Nil Data?

本小妞迷上赌 提交于 2019-12-25 07:38:43

问题


I've created an auto-populating array in a counted loop for each month using timestamps, e.g 2016-06-11 00:00:00 - the database layout that the loop is fetching from is:

TimeRecord          | Views 
2016-06-11 00:00:00 | 22
2016-08-11 00:00:00 | 44

Now, the above example skips the 07 (July) month, there is NO DATA for this month, and so when the loop goes through this month, it should return either null or 0, but it returns the previously known number (which is 22 in this case).

For 2016-09, there is no specified data, so the array will give "44".

The code for the loop and fetching from the database to generate the array is like so:

$startMonth = date("y-m-d");
$endMonth = date("y-m-d");

while ($Month <= 12){

$ViewsThisMonth = mysqli_fetch_object(mysqli_query($db, "SELECT    SUM(Views) AS NumberFinalViews, EXTRACT(YEAR_MONTH FROM TimeRecord) AS YearMonth FROM BlogViews WHERE TimeRecord > '$startMonth' AND TimeRecord < '$endMonth' GROUP BY YearMonth"));

if (is_null($ViewsThisMonth->NumberFinalViews)){
$ViewsThisMonth->NumberFinalViews = 0;
}

$ArrayTimeStamp[] = $ViewsThisMonth->NumberFinalViews;
$Month = $Month + 1;
$startMonth = date("y-m-d",strtotime("-$Month month"));
}

An example returned JSON Encoded Array is:

[0,"29392","333","4000","4000","99","99","99","99","99","99","99"]

A screenshot of the database values that caused the above array can be found here. As you can see, 4000 repeats itself twice as there is no record for the 5th month, causing it to use the 4th month's data. 99 is also repeated, as there are no values for the 6th-12th month, therefore it uses the 6th month's value instead of returning a 0.

If there is no TimeRecord for that month when the loop goes through, I want it to return 0, not assume that the view number is the same as the previous month.


回答1:


The problem is that you perform the same query multiple times, albeit with a changing date. The query is designed to give a result for several months, yet you only use one of the result rows. As there is no order by clause, it could be that you get the rows in an unexpected order. Also the way you change the start date in the loop is strange: it moves backwards in time.

It would be better to execute the query only once, and then store the results into a prepared array that is keyed by month-year.

Note that you can perform the null check in the SQL query itself with COALESCE.

The code becomes something like this:

$startYearMonth = date('Ym', strtotime("2015-01-01")); // set this date as you wish
$endYearMonth = date('Ym', strtotime("now"));

// Prepare result array: one entry per month, with all values set to 0
for ($yearMonth = $startYearMonth; $yearMonth <= $endYearMonth; 
                                   $yearMonth += ($yearMonth % 100 == 12 ? 89 : 1)) {
    $months[$yearMonth] = 0;
}

// improved query
$result = mysqli_query($db, "
    SELECT   COALESCE(SUM(Views), 0) AS NumberFinalViews, 
             EXTRACT(YEAR_MONTH FROM TimeRecord) AS YearMonth 
    FROM     BlogViews 
    WHERE    EXTRACT(YEAR_MONTH FROM TimeRecord) 
                   BETWEEN '$startYearMonth' AND '$endYearMonth'
    GROUP BY YearMonth");

// Featch and store each result in their proper year-month slot
while ($ViewsThisMonth = mysqli_fetch_object($result)) {
    $months[$ViewsThisMonth->YearMonth] = $ViewsThisMonth->NumberFinalViews;
}

// output the result
print_r($months);


来源:https://stackoverflow.com/questions/39348799/array-loop-assuming-nil-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!