Reputation: 2362
I need to access $layers
from inside the function isOk($layer)
, but everything i tried the outside function variable $layers
is ok, but inside the function, even with global is return null.
Here is the code:
$layers = array();
foreach($pcb['PcbFile'] as $file){
if(!empty($file['layer'])){
$layers[$file['layer']] = 'ok';
}
}
// Prints OK!
var_dump($layers);
function isOk($layer){
global $layers;
// Not OK! prints NULL
var_dump($layers);
if(array_key_exists($layer, $layers))
return ' ok';
return '';
}
// NOT OK
echo isOk('MD');
I always use Object orientation, but this was something so simple that i made with a simple function... Why $layers
is not being 'received' correcly inside the function?
Upvotes: 1
Views: 3476
Reputation: 86505
Watch this...
HalfAssedFramework.php
<?php
class HalfAssedFramework {
public static function run($path) {
include $path;
}
}
HalfAssedFramework::run('example.php');
example.php
<?php
$layers = array();
foreach($pcb['PcbFile'] as $file){
if(!empty($file['layer'])){
$layers[$file['layer']] = 'ok';
}
}
// Prints OK!
var_dump($layers);
function isOk($layer){
global $layers;
// Not OK! prints NULL
var_dump($layers);
if(array_key_exists($layer, $layers))
return ' ok';
return '';
}
// NOT OK
echo isOk('MD');
Run example.php
directly, and it should work. Run HalfAssedFramework.php
, and it won't.
The problem is scope. When example.php
is included inside the run
function, all the code inside it inherits the function's scope. In that scope, $layers
isn't global by default.
To fix this, you have a couple of options:
example.php
will never run directly, you can say global $layers;
at the beginning of the file. I'm not sure whether this will work if the script is run directly, though.$layers
with $GLOBALS['layers']
everywhere.$layers
as an argument to isOk
.Upvotes: 6
Reputation: 4317
Not exactly answering the question, but have you considered not using globals? Globals really aren't that cool: they make your code harder to read, harder to understand and as a consequence, harder to maintain.
Consider something like that:
<?php
class LayerCollection
{
private $layers;
public function __construct($layers)
{
$this->layers = $layers;
}
public static function fromPcbFile($data)
{
$layers = array();
foreach ($data['PcbFile'] as $layer) {
if (!empty($layer)) {
$layers[$layer] = true;
}
}
return new self($layers);
}
public function hasLayer($layer)
{
return array_key_exists($layer, $this->layers);
}
}
$layers = LayerCollection::fromPcbFile($pcb);
var_dump($layers->hasLayer('MD'));
Doesn't it look better? You can then proceed to enrich LayerCollection
as you need more ways of interacting with your layers. This is not perfect, since there's still
a static method lying around (makes testing harder, a factory would be better suited for that job), but that's a good start for a refactoring.
More about why globals are evil: https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil
Upvotes: 2