Danny Englander
Danny Englander

Reputation: 2044

Undefined variable outside a foreach loop

I've written code that grabs google fonts and adds them as an HTML body class. The code works fine but in my IDE, I am getting an undefined variable message. I can see why as the variable is outside the foreach loop.

 $fontstring = implode(' ', $families);
    foreach ($families as $fontstring) {
      $font = preg_replace('#[^a-zA-Z0-9]+#', '-', $fontstring);
    $vars['classes_array'][] = strtolower($font);
    }

For the code above, $fontstring before the loop appears to be undefined.

This code takes strings from Google's api and strips out the characters to make them pretty strings.

<body class="Pathway+Gothic+One:regular">

becomes:

<body class="pathway-gothic-one-regular">

I can then use it within my Sass code for fine tuned theming, e.g.

.pathway-gothic-one-regular {
@include headings(uppercase, .02em, 60px, 9px);
// etc...
}

I've tried things like $fontstring = array(); but that did not seem to help. I also tried the implode function within the foreach but that did not work either. So I am at a bit of a loss here.

Upvotes: 0

Views: 1153

Answers (2)

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76405

Given that you're using PHPStorm, I suspect you've not declared $vars (correctly) up front:

foreach ($anArray as $foo)
{
    //PHPStorm (rightfully) complains
    $newVar['array_vals'][] = $foo;
}
return $newVar;//<-- again, PHPStorm will complain, with good reason

Because $newVar isn't declared up front, there is no real guarantee that $newVar will exist outside of the loop: if $anArray is empty, the loop will not be executed, and $newVar is not created.
In addition to that, writing $newVar[] = $foo; is bad practice: you're accessing a variable that doesn't exist as if it were an array. PHP will create an array for you, but it will emit a notice if it has to access a key of an array that does not exist (undefined index error). This is the case if $vars in your code was not declared up front, because you're accessing a non-existent variable as an array with the key classes_array. In short: initialize the $vars array:

$vars = array(
    'classes_array' => array()
);

That should fix those warnings/errors. On to $fontString: PHPStorm also warns you if you're assigning a variable, and immediately re-assign it, which you do:

$fontString = implode(' ', $families);//assigning
foreach ($families as $fontString)
{//re-assigning in the loop!
    //more on the code here later
}

If you want PHPStorm to give you the green light, then you'll have to write something like:

$vars = array('classes_array' => array());//initialize
if ($families)
{
    foreach ($families as $fontString)
    {//a one-liner
        $vars['classes_array'][] = preg_replace(
            '/[^\d\w]+/',//\d == [0-9], \w == [a-z]
            '-',
            strtolower($fontString)//tolower here, so you don't need [A-Z]
        );
    }
}
else
{
    $vars['classes_array'][] = '';//empty string
}

I've pasted this code in PHPStorm, and got no warnings or errors whatsoever: all variables are used, and all of them are initialized when and where they should be. The way code I pasted in PHPStorm was:

protected function test(array $families = null)
{
    $vars = array(
        'classes_array' => array()
    );
    if ($families)
    {
        foreach ($families as $fontString)
        {
            $vars['classes_array'][] = preg_replace(
                '/[^\d\w]+/',
                '-',
                strtolower($fontString)
            );
        }
    }
    else
    {
        $vars['classes_array'][] = '';
    }
    return $vars;
}

Upvotes: 2

jems
jems

Reputation: 93

try this...

if(isset($families) && $families != null)
{
    $fontstring = array();
    $fontstring = implode(' ', $families);
    foreach ($families as $fontstring) 
    {
        $font = preg_replace('#[^a-zA-Z0-9]+#', '-', $fontstring);
        $vars['classes_array'][] = strtolower($font);
    }
}

Upvotes: 0

Related Questions