Skip to content

Instantly share code, notes, and snippets.

@brzuchal
Last active August 9, 2016 10:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brzuchal/04a324d4a2a3306ac5dece4ce1665375 to your computer and use it in GitHub Desktop.
Save brzuchal/04a324d4a2a3306ac5dece4ce1665375 to your computer and use it in GitHub Desktop.
PHP Immutable class/property
<?php
immutable class Currency
{
/** @var string */
public $code; // this will change to readonly after constructor execution
/** @var string */
public $name; // this will change to readonly after constructor execution
/** @var int */
public $fractionDigits;
public function __constructor(string $code, string $name, int $fractionDigits = 2)
{
$this->code = $code;
$this->name = $name;
$this->fractionDigits = $fractionDigits;
} // after constructor execution all properties are marked as readonly
}
immutable class Money
{
/** @var float */
public $amount = 0; // this will change to readonly after constructor execution
/** @var Currency */
public $currency; // this will change to readonly after constructor execution
public function __constructor(float $amount, Currency $currency)
{
$this->amount = $amount;
$this->currency = $currency;
} // after constructor execution all properties are marked as readonly also
public function addAmount(float $amount) : static
{
return new static($this->amount + $amount, $this->currency);
}
}
$currency = new Currency('PLN', 'Polish złoty');
$money = new Money(150, $currency);
<?php
class Invoice
{
/** @var Money */
public readonly $totalAmount; // this will change to readonly after assign
public function __constructor(array $products)
{
$totalAmount = new Money(0, new Currency('PLN'));
foreach ($products as $product) {
$totalAmount = $totalAmount->addAmount($product->getPrice($totalAmount->currency));
}
$this->totalAmount = $totalAmount;
}
}
$invoice = new Invoice($products);
$invoice->totalAmount; // this property is public but set as readonly and there is no way to change it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment