In PHP true , false and null are constants, which are protected from being overwritten in namespaces. As such the following is invalid code:

namespace Foo; const true = false; // Cannot redeclare constant 'true'

It is still possible to overwrite such a constant using ''define()'':

namespace Foo; define('Foo\true', false); var_dump(true); // bool(false)

However this isn't supported functionality (it might be called a bug) and PHP is free to assume that true cannot be overwritten. For example usage of true in a constexpr context will not be affected by the above definition:

// Note: This uses eval() to make sure the define() runs before the constexpr // constant resolution happens namespace Foo; define('Foo\true', false); var_dump(eval('namespace Foo; static $t = true; return $t;')); // bool(true)

The reason why the substitution happens in the constexpr case, but not in the "normal" case is a bug in the implementation. For constexprs the substitution happens before name resolution, whereas for normal code it happens after name resolution.