Strictus
Strict Typing for local variables in PHP
#Introduction
Strictus brings strict typing for local variables into PHP.
With Strictus, you can control the types of local variables using different patterns.
💣 The problem:
PHP has no support for strongly typed Local Variables.
Here is an illustrative example of a basic mistake:
<?php
$total = 82.50;
$discount = 0.10;
if ($total >= 50) {
$discount = '25%';
}
$total = $total - ($total * $discount);
In the code above, nothing prevents overriding the float value of $discount a string value, causing a bug.
👍 The solution:
Let's rewrite the previous example using Strictus and strongly typed variables:
<?php
use Strictus\Strictus;
$total = Strictus::float(82.50);
$discount = Strictus::float(0.10);
if ($total() >= 50) {
$discount(0.25);
}
$total($total() - ($total() * $discount()));
echo $total();
In the code above, the variable $discount is an instance of StrictusFloat::class and it only accepts float values.
An Exception StrictusTypeException is thrown when we try to assign anything that is not of type float, like a string for example.
See this example:
<?php
use Strictus\Strictus;
$discount = Strictus::float(0.10);
$discount('25%');
#Installation
You can install the package via composer:
composer require strictus/strictus
Requires: PHP 8.1+
#Usage
There are a few different patterns you can use to work Strictus.
#Creating Your Variables
To create a variable, simply call Strictus::*method*(), replacing the *method* with the type you want to enforce.
For example:
<?php
use Strictus\Strictus;
$name = Strictus::string('Wendell');
$comment = Strictus::nullableString(null);
$score = Strictus::int(100);
$isActive = Strictus::boolean(true);
$authors = Strictus::array(['Wendell', 'Christopher']);
$person = Strictus::object((object) ['name' => 'Wendell', 'country' => 'BR']);
$calculator = Strictus::instance(CalculatorClass::class, new CalculatorClass());
$role = Strictus::enum(Role::class, Role::CONTRIBUTOR);
class CalculatorClass
{
}
enum Role
{
case CONTRIBUTOR;
}
💡 Check out all the available variable methods.
#Getting Variable Value
To retrieve the variable value, just call it like a function:
echo $name();
echo $score() - 10;
if ($isActive()) {
}
echo implode($authors(), ';');
Alternatively, you can use the $variable like a Value Object:
$name = Strictus::string('Christopher');
echo $name->value;
#Update Variable Value
To update the variable value, call it like a function passing the new value as the argument:
$score = Strictus::int(100);
$score($score() - 20);
echo $score();
Alternatively, you can use the $variable like a Value Object:
$score = Strictus::int(100);
$score->value = 0;
echo $score();
#Variable methods
You can use the following methods to create single type variables:
#Union Types
Strictus also supports union types:
use Strictus\Enums\Type;
$unionTypesVariable = Strictus::union([Type::INT, Type::STRING], 'foo');
echo $unionTypesVariable->value;
echo $unionTypesVariable();
$unionTypesVariable->value = 100;
echo $unionTypesVariable->value;
$unionTypesVariable->value = false;
#Immutable Variables
If you want to create immutable variables, you can use the ->immutable() method. If you try to assign a new value
to an Immutable Variable, an Strictus\Exceptions\ImmutableStrictusException exception will be thrown:
$immutableScore = Strictus::int(100)->immutable();
$immutableScore(50);
$immutableScore->value = 50;
#Error Handling
If you try to assign a value that doesn't match the type of the created variable, an
Strictus\Exceptions\StrictusTypeException exception will be thrown:
$score = Strictus::int(100);
$score('one hundred');
$score->value = false;
If you try to assign a new value to an Immutable Variable, an
Strictus\Exceptions\ImmutableStrictusException exception will be thrown:
$immutableScore = Strictus::int(100)->immutable();
$immutableScore(50);
$immutableScore->value = 50;
#Motivation
Following a discussion on Twitter between Christopher Miller and
Wendell Adriel around the lack of strongly typed local variables
for PHP we quickly decided a package was the right approach whilst we could get an RFC into the core.
#Credits
#Contributing
We welcome contributions!
Please visit the Contributing Guide to learn more about contributing to Strictus.