1

I am trying to add the sales of the month and showing it on the table. Everything is working fine but a warning message is showing Undefined offset: 9.

The image is:enter image description heIe

Kindly check the code what I am doing:

$thisyear = $db->query("SELECT total_Price,order_date FROM orderTable WHERE YEAR(order_date) = '{$thisyear}'");

 $current = array();
 $currentTotal = 0;

 while($x = mysqli_fetch_assoc($thisyear)){
 $month = date("m-d-Y",strtotime($x['order_date']));

 //The Below line showing Error
 $current[(int)$month] += $x['grand_total']; // This line showing Error

 $currentTotal += $x['total_Price'];
 }

With this code, I am getting the correct result. It is adding the monthly sales and showing it on the table but a warning message is also showing.

Kindly suggest what I am doing wrong.

Sarah
  • 405
  • 2
  • 7
  • 23
  • add this before: `if(!isset($current[(int)$month])) {$current[(int)$month] = 0;}` when using `+=` it implies that the key exists – ka_lin Sep 20 '18 at 08:11
  • 1
    $Month is a string like `09-20-2018` and you int cast it. That won't work as you expect. Use date and isolate the month if that is what you need – Andreas Sep 20 '18 at 08:12
  • Why you don't do `date('n')` to get 1-12 month number instead of casting `01-12-2045` to integer? – Justinas Sep 20 '18 at 08:13
  • you're open to SQL injection .. this should be addressed asap – treyBake Sep 20 '18 at 08:14
  • 1
    In general, type casting the array indices to `int` is useless. PHP does this on its own anyway, if it is possible. In this code it is completely wrong. Use `$month = date('m', strtotime($x['order_date']));` to extract only the month from the date. – axiac Sep 20 '18 at 08:18

3 Answers3

1

$current[(int)$month] is the array item you're writing to, but since you use the += operating, you're adding to an existing item. That line actually means:

$current[(int)$month] = $current[(int)$month] + $x['grand_total']; 

This means that you're not just writing to month 9, but also reading from it, and apparently that month doesn't exist in $current yet.

Since you don't initialize any items of $current at all, I think the first item the query returns has month 9, so it's the first iteration that fails.

Possible solutions:

  • Initialize $current by adding all months, giving each a default value of 0.
  • Before adding, check if the month exists, and initialize it if it doesn't.
  • Use a ternary expression, or even some warning suppression to try and read the month value, defaulting to 0 if it fails.

I would go for the first one, since it's the most transparent one.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
1

since $month is date("m-d-Y",strtotime($x['order_date'])); as it will end up with a date in 09-20-2018 format, the cast to int would (if not fail) be wrong. instead you can do it like this.

$mm = date("m",strtotime($x['order_date']));
if (!isset($current[$mm])) {         //or !isset($current[(int)$mm])
    $current[$mm] = 0;               //or $current[(int)$mm] = 0;
}
$current[$mm] += $x['grand_total'];  //or $current[(int)$mm] += $x['grand_total'];

this will eliminate the errors as, += operator assumes it was previously set (it was not), thus showing a warning that it wasn't set before.

Cemal
  • 1,469
  • 1
  • 12
  • 19
  • Thanks Cemal, It Works. Great Solution. You are a genius. – Sarah Sep 20 '18 at 08:41
  • Thanks Cemal, It Works. Great Solution. You are a genius. – Sarah Sep 20 '18 at 08:41
  • The cast to int will not fail, and actually not be wrong. PHP takes the number at the start of the string (which is the month number) and cast that to int, ignoring the test. It's not the greatest solution to do it like that, but it won't fail. Your code does solve the issue though, because it checks and sets `$current[$mm]` if necessary, which was the actual issue. – GolezTrol Sep 20 '18 at 09:37
  • @GolezTrol THE OP hasn't posted the PHP version that's why it's written `(if not fail)` . It solves the problem of having an undefined offset, which was the question. – Cemal Sep 20 '18 at 09:39
0

The line throwing warning because initially $current[(int)$month]is not set

Do like below:-

$thisyear = $db->query("SELECT total_Price,order_date FROM orderTable WHERE YEAR(order_date) = '{$thisyear}'");

$current = array();
$currentTotal = 0;

while($x = mysqli_fetch_assoc($thisyear)){
    $month = (int)date("m",strtotime($x['order_date']));

    $current[$month] = isset($current[$month]) ? $current[$month]+$x['grand_total'] : $x['grand_total'];

    $currentTotal += $x['total_Price'];
}

Note:- += operator means to add something in existing, but it your case index 9 is not pre-set there

Alive to die - Anant
  • 70,531
  • 10
  • 51
  • 98
  • 1
    @Alive Thanks for the quick reply again. Now after I have used your edited code, my code worked correctly. It solved my problem. But Still I dont understand how this code is working. I come to know initially $current[(int)$month] was not set but what is the difference between your last code and this code? How this code worked? – Sarah Sep 20 '18 at 08:23
  • @Sarah my code checked first that `$current[$month]` is set or not? if not then set it and put `$x['total_Price']` value in it. If set then add `$x['total_Price']` value to previous available value – Alive to die - Anant Sep 20 '18 at 08:27
  • 1
    @Alive Thank You so much! Now I understand all the concept. And this edited code looks more simpler, using int before date. Thanks, Again! – Sarah Sep 20 '18 at 08:30
  • @Sarah you'r welcome! – Alive to die - Anant Sep 21 '18 at 04:13