A class constant (Class::NAME) may be private (PHP 7.1), final (8.1) and typed (8.3, Subsection 4.11.11). A static property holds one value per class; a static method has no $this. self:: names the current class, and PHP 8.3 added Class::{$name}.
<?php
class Product {
public const string CURRENCY = 'USD'; // typed constant (PHP 8.3)
final public const int MAX_QTY = 99; // children cannot redefine it
private const TAX_RATE = 0.08;
public const PRICE_WITH_TAX = 1000 * (1 + self::TAX_RATE); // constant expression
private static int $created = 0; // one value for the whole class
public function __construct(public string $sku) { self::$created++; }
public static function created(): int { return self::$created; }
}
new Product('BK-101'); new Product('BK-202');
$name = 'MAX_QTY';
echo Product::created(), ' ', Product::CURRENCY, ' ', Product::{$name}, ' ',
Product::PRICE_WITH_TAX, "\n";
try { echo Product::TAX_RATE; } catch (Error $e) { echo $e->getMessage(), "\n"; }Output
2 USD 99 1080 Cannot access private constant Product::TAX_RATE
Static state lasts one request under PHP-FPM, but in a long-running worker (Asynchronous PHP) it survives between requests and users; prefer injected objects (Subsection 4.9.15).