6

I'm newer to PHP 8. I'm working in code where there are a number of 'constant' mappings. They are done using a static array in various classe. Example:

public static $mapNamedIds = array(
    "NamedItem1" => 1234, 
    "NamedItem2" => 2345, 
    "NamedItem3" => 3456,
);

Is there a reason it should not be implemented like this? Example:

public const NAMED_IDS_MAP = array(
    "NamedItem1" => 1234, 
    "NamedItem2" => 2345, 
    "NamedItem3" => 3456,
);

Is there a reason why static would be better than using a const array? Other than the 'const' actually being constant. Is there a performance benefit of const over static? Again these are typically defined in classes and are not globals...

3
  • 1
    Constants in classes have evolved with PHP. Before PHP 7.0.33 you could not use constants in classes, before PHP 8.1 you could redefine them in child classes, and, according to the manual you could only use an array since PHP 8.3. Not sure about that, but what this all means is that choosing a static array guarantees greater compatibility with older versions of PHP, simply because they have been around longer. I doubt there will be any noticeable performance differences. You've remained vague about the code you're working in. Commented May 13 at 23:11
  • In your case you may consider using ENUM instead. I personally use CONST only with private visibility to prevent "magic values". I use STATIC anywhere where you know no instance is required, especially in Factory methods or when you want things to happen only ONCE in the application like a singleton. - But as always, it depends :) Commented May 14 at 9:49
  • Other than performance (me thinks it can be neglected), can you explain a bit more what you mean by "better"? Some hints in which direction you're looking for, the use case you present is pretty abstract to me and I could benefit from some grip. Commented May 14 at 10:18

3 Answers 3

5

One benefit of a constant over a static property is, that it can be used to initialize both constants and properties. A property can't:

final class So79620502
{
    public const NAMED_IDS_MAP = array(
        "NamedItem1" => 1234,
        "NamedItem2" => 2345,
        "NamedItem3" => 3456,
    );

    public static $mapNamedIds = So79620502::NAMED_IDS_MAP;
}

Demo: https://3v4l.org/58fQr

Performance? -> Metric yourself, because this depends on the use-case, and there you need to do the metrics. I know of no other noteworthy performance differences otherwise.


There can be also types in PHP where a static property is not available, but a constant. So if you consider specific refactoring pathways, it can be worth to at least have known about it:

/**
 * Enum So79620502
 *
 * @link https://stackoverflow.com/a/79620535/367456
 */
enum So79620502
{
    public const NAMED_IDS_MAP = array(
        "NamedItem1" => 1234,
        "NamedItem2" => 2345,
        "NamedItem3" => 3456,
    );
}

Enumerations (8.1, here with zero enum cases) do not have static properties (and have no implementable properties at all.)

Object interfaces (5.0) show similar runtime behaviour (7.1 for constants: 8.1 final, 8.3 type tagged), but they now (8.4) allow public set readonly properties, so these aspects have differentiated quite a bit.

Demo: https://3v4l.org/7XPqN

Sign up to request clarification or add additional context in comments.

3 Comments

The question was about benefits of a static property over a constant, but your point is correct, of course.
Hmm, good point. But doesn't the answer shows an example/the case of a property over a constant? If that's a benefit, lies in the eye of the beholder, naturally. Ah, there is another one, ... let me edit the answer (but again YMMV material.)
Don't forget that as of 8.3 (I think it was 8.3) class constants can be typed as well (scalar only). They are also supported in Traits but I forget which version introduced that. @KIKOSoftware class constants can still be redefined after 8.1 unless they have a final modifier. And last but not least. Class constants are available to Interfaces, which is probably their most beneficial usage.
1

For Your Information

static $map const MAP
Mutability Mutable at runtime Immutable — you can’t change it once defined
Performance Requires a runtime property lookup Stored in OPcache at compile-time
Late-static binding Yes (static::$map) No
Use case When you intend to modify or override at runtime When the data never changes

1 Comment

Could you elaborate on the performance you mention a bit? E.g. how can the opcache constant lookup (hit and miss) be compared with the property lookup (hit and miss)?
0

In reference to the class const usage. A simple example of how static keyword usage is possible with class constants.

<?php declare(strict_types=1);

interface TestInterface
{
    public const TEST = __CLASS__;
}

class TestClass implements TestInterface
{
    public const TEST = __CLASS__;

    public function test(): string
    {
        return static::TEST;
    }
}

class TestClass2 extends TestClass
{
    public final const TEST = __CLASS__;

    public function test(): string
    {
        return static::TEST;
    }
}

echo (new TestClass())->test() . '<br>'; // Outputs: TestClass
echo (new TestClass2())->test() . '<br>'; // Outputs: TestClass2

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.