I understand the scope problems in PHP that arise from use of constants (as well as the global
keyword with normal variables) in functions and classes. I understand Singletons and that I don't have (and will never have) any use for them in PHP. What I don't understand is if use of class constants creates the same or similar issues.
Here's a snippet of code, similar to what I'm writing but much simpler (for brevity's sake I'll treat everything as if it's in one file, no typechecking or initialization, etc.):
<?php
class Environment
{
private $var1;
private $var2;
private $var3;
public const CONST_VAR = "ThisIsConstant";
public __construct($dependency1, $dependency2)
{
$this->var1 = $dependency;
$this->var2 = new SomeOtherObject($dependency2);
if ($this->var1 == self::CONST_VAR) // Situation 1
{
$var3 = true;
}
}
public getStuff()
{
return $this->var1 . " and " . $this->var2->getOtherStuff();
}
}
class SomeOtherObject
{
private $stuff;
public __construct($dependency)
{
if ($dependency == Environment::CONST_VAR) // Situation 2
{
$this->stuff = strtolower($dependency);
}
else
{
$this->stuff = $dependency;
}
}
public getOtherStuff()
{
return $stuff;
}
}
$env = new Environment("TestName", "OtherStuff");
echo $env->getStuff();
echo $env::CONST_VAR; // Situation 3
echo Environment::CONST_VAR // Situation 4
?>
Four situations are present:
- Accessing a class constant in the same class using
self
, which clearly presents no scope issue since I'm really just accessing a property. - Accessing a class constant in another class using the class name, which seems to present a global scope issue since SomeOtherObject requires the Environment class to exist and have that constant. The Environment class is therefore not self-contained and harder to unit test.
- Accessing a class constant in the global space using a variable name, which requires that variable to be an Environment object but seems to not create any scope issue since the Environment class itself does not depend on anything outside of it, rather the other way around.
- Accessing a class constant in the global space using the class name, which also seems to not create any scope issue for the same reason as Situation 3.
From my understanding of these concepts it looks like Situation 2 is the only one that needs to be avoided...but are there global scope/unit testing/code smell issues I'm missing with Situations 1, 3, and 4?
Edit: This question was closed as opinion-based so I'll try to make this more direct. I'm not asking about whether or not using the global space in classes is okay, or whether or not singletons are an antipattern, or any of that. What I'm asking is if the scoping and self-containment issues that do arise from use of the global space within a class (this is not an opinion) work the same way in the opposite direction, i.e. using class constants in the global space. Does it make the code less testable? Does it introduce dependencies where there shouldn't be any? I'm not asking if the behavior is dogmatically right or wrong, I just want to be aware of measurable problems that can arise from doing this. Thanks to everyone for the comments so far!