Late Static Bindings
PHP version 5.3
was a significant improvement: namespace support, closures, the intl
library,
and late static bindings.
Here is a practical example: making a static call to a __construct()
method.
Sample code
- The
__construct()
method returns$this
, the class instance. - The
new()
static method makes a static call possible.
namespace Nevvix\Helper;
class L10n {
protected $locale;
public function __construct($locale) {
$this->locale = $locale;
return $this;
}
static public function new($locale) {
return new static($locale);
}
public function currency($value, $currency = NULL) {
$fmt = numfmt_create($this->locale, NumberFormatter::CURRENCY);
$currency = $currency ?: numfmt_get_symbol($fmt, NumberFormatter::INTL_CURRENCY_SYMBOL);
return numfmt_format_currency($fmt, $value, $currency);
}
}
Object Oriented usage
$L10n = new L10n('en_US');
echo $L10n->currency(1000), PHP_EOL;
echo (new L10n('en_US'))->currency(1000), PHP_EOL;
Results:
$1,000.00
$1,000.00
Static call usage
$L10n = L10n::new('en_US');
echo $L10n->currency(1000), PHP_EOL;
echo L10n::new('en_US')->currency(1000), PHP_EOL;
Same results.
Difference
- The
__construct()
returns$this
, so you can chain methods from it if you wrap thenew
call in parentheses.(new L10n($html))->currency()
- When you call the static
new()
method, you can chain directly after it without parentheses.L10n::new($html)->currency()
Practicality
A static call is useful when you have a helper library that is available globally: in your application code, but also embedded in an HTML template.
Dependency injection
I want the object-oriented functionality to be able to inject in other class methods:
namespace Nevvix\ProjectManager\App;
use Nevvix\Helper\L10n;
class Invoice {
public function __construct(...) {
...
return $this;
}
public function currency(L10n $L10n, $locale, $number) {
return $L10n->currency($number);
}
}
$invoice = new Invoice();
echo $invoice->currency('en_US', 1000);
$1,000.00
Templates
I want to call L10n
methods on demand in a template from another part of the application.
<!DOCTYPE html>
<html>
<head>
<title><?= _('Market Prices'); ?></title>
</head>
<body>
<table>
<tr>
<th><?= _('USD'); ?></th>
<th><?= _('GBP'); ?></th>
</tr>
<tr>
<td><?= L10n::new('en_US')->currency($number); ?></td>
<td><?= L10n::new('en_GB')->currency($number); ?></td>
</tr>
</table>
</body>
</html>