Using `ENUM`s as class property triggers BC failure
Having a class property of type (Backed)Enum:
class SomeClass
{
protected VisibilityEnum $visibility = VisibilityEnum::Public;
}
triggers backwardCompatibilityCheck error in my CI action:
Running roave-backward-compatibility-check --from=1.0 --install-development-dependencies
[BC] SKIPPED: An enum expression Namespace\VisibilityEnum::Public is not supported in class Namespace\Example in file /src/SomeClass.php (line 20)
Can I disable the BC check on specific files?
Or do I need to switch from using Enums to constants?
Related to https://github.com/laminas/laminas-continuous-integration-action/issues/310
Can I disable the BC check on specific files?
There's a baseline feature for that, but generally, the tool will refuse to evaluate any non-constant expressions. ENUMs are effectively instances of a class, and require evaluating that class at runtime to be instantiated.
Copying from discussion held elsewhere:
Dilemma: I have a piece of code like
class SomeClass { protected VisibilityEnum $visibility = VisibilityEnum::Public; }BetterReflection will categorically refuse to give you the value of
$visibility, since it requires autoloadingVisibilityEnum, and instantiating one of its values.The reasons are multiple, but most notably:
- loading code can lead to a security issue, and BR is designed to analyze code from also potentially malicious parties
VisibilityEnummay exist multiple times, when inspecting multiple codebases (or different versions of the same library), therefore leading to conflictsPHP has multiple of such cases (most notably default values) in which a declaration holds a runtime expression
function foo($time = new DateTimeImmutable()) {I'm wondering if there's a way to sandbox this expression in a way that is:
- safe for the system to evaluate
- does not cause any sort of side-effects (like declaring
VisibilityEnumin the global scope)
Thanks @Ocramius
I understand the reasoning of why BetterReflection is not able to identify the exact value of $visibility just by looking at the property, without its value specified.
I would expect the behaviour you described from this code:
protected VisibilityEnum $visibility;
But when I'm specifying that the property $visibility is of type VisibilityEnum and has this exact value VisibilityEnum::Public.
protected VisibilityEnum $visibility = VisibilityEnum::Public;
In this case I would expect BetterReflection to see that $visibility is not just of type VisibilityEnum, but it is initialized with a specific value of that Enum.
In this case I would expect
BetterReflectionto see that$visibilityis not just of typeVisibilityEnum, but it is initialized with a specific value of that Enum.
The problem is that ReflectionProperty#getDefaultValue() cannot be used.
I'm thinking of designing something like ReflectionProperty#getDefaultValueSnapshot() or such, as an API that "observes" the expression 🤔