Typed Class Constants

Since PHP 8.3 a class, interface, trait or enum constant can declare a type, checked at compile time. The type is a contract: redeclaring an inherited int constant as string is fatal ("Type of BigCheckout::MAX_ITEMS must be compatible with Checkout::MAX_ITEMS of type int"). Since 8.2, constant expressions may also read an enum case's ->value.

Typed constants on an interface, a class and an enum casePHP
<?php
enum OrderStatus: string { case Pending = 'pending'; case Paid = 'paid'; }   // trimmed
interface Storefront { const string CURRENCY = 'USD'; }
class Checkout implements Storefront {
  const int MAX_ITEMS = 50;
  const OrderStatus INITIAL = OrderStatus::Pending;    // a class or enum type works
  const string INITIAL_COLUMN = self::INITIAL->value;  // enum property in a constant (8.2)
}
class EuroCheckout extends Checkout { const string CURRENCY = 'EUR'; }
echo Checkout::MAX_ITEMS, ' ', EuroCheckout::CURRENCY, ' ', Checkout::INITIAL_COLUMN, "\n";
Output
50 EUR pending

Type every public constant, and add final (Subsection 4.9.5) when no subclass should redefine it.