1

Getting an Undefined Offset error here -- apparently from the $newval array.

Note that the {exp} tag is not PHP, and is simply a sql query by my CMS system which creates the $bags array for me.

<?php

$bags = array();
$newval = array();
$pattern = "[^0-9]";

{exp:query sql="SELECT m_field_id_1 as bags FROM exp_member_data WHERE m_field_id_1 IS NOT NULL"}
$bags[] = "{bags}";
{/exp:query}

foreach ($bags as $key => $value) {
for ( $i = 0, $s = strlen($value); $i < $s; $i++) {
    if ( is_numeric($value[$i]) ) {
        $newval[$key] .= $value[$i];
    }
}
}

$sum = array_sum($newval);
$format = number_format($sum);

echo $format;

?>
3
  • Which line are you getting the error in exactly? Commented Aug 17, 2011 at 19:46
  • 2
    Remember you are starting from 0. So you need to substract 1 from $s. For example your string is 10 characters long that would be indexes 0-9 but not 10. Commented Aug 17, 2011 at 19:48
  • Wild guess: $value[$i] is probably at some point not defined. offset is concerned if the array key exists - not if the array is defined at all. Commented Aug 17, 2011 at 19:49

3 Answers 3

2

Before you can concatenate to a variable, that variable must exist (to avoid a Notice). Simply declare $newval[$key] as an empty string before the for loop:

foreach ($bags as $key => $value) {
    $newval[$key] = '';
    for ($i = 0, $s = strlen($value); $i < $s; $i++) {
        if ( is_numeric($value[$i]) ) {
            $newval[$key] .= $value[$i];
        }
    }
}

By the way, there's nothing wrong with your starting value of $i. It is correct to have it at 0 and not 1 as others are suggesting.

However, if you're trying to remove non-number characters from a string and avoid empty array elements (as your original code does), you can remove the inner for loop and simply:

foreach ($bags as $key => $value) {
    $digits = preg_replace('/[^0-9]/', '', $value);
    if (strlen($digits)) {
        $newval[$key] = $digits;
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Absolutely, stereofrog. I just felt I was doing a little too much refactoring at that point :)
Defining $newval[$key] did the trick -- The reason I used a loop instead of preg_replace was that I've read it parses quicker. Truth to this?
1

As Jrod said you're walking through the characters in $value but you start at 0. strlen() returns the absolute amount of chars in $value so in your for loop you should start at 1 instead of 0.

This is the code you should use:

<?php

$bags = array();
$newval = array();
$pattern = "[^0-9]";

{exp:query sql="SELECT m_field_id_1 as bags FROM exp_member_data WHERE m_field_id_1 IS NOT NULL"}
$bags[] = "{bags}";
{/exp:query}

foreach ($bags as $key => $value) {
    $newval[$key] = '';
for ( $i = 1, $s = strlen($value); $i < $s; $i++) {
    if ( is_numeric($value[$i]) ) {
        $newval[$key] .= $value[$i];
    }
}
}

$sum = array_sum($newval);
$format = number_format($sum);

echo $format;

?>

Comments

1

Instead of this

foreach ($bags as $key => $value) {
for ( $i = 0, $s = strlen($value); $i < $s; $i++) {
    if ( is_numeric($value[$i]) ) {
        $newval[$key] .= $value[$i];
    }
}
}

you can write

 $newval = preg_replace('~\D+~', '', $bags);

one line is easier to debug than six, isn't it.

Comments

Your Answer

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