arnapou / ensure
Library - Simple library to make safer php code for SA tools.
Installs: 1 118
Dependents: 6
Suggesters: 0
Security: 0
Stars: 1
Forks: 0
pkg:composer/arnapou/ensure
Requires
- php: ~8.3.0 || ~8.4.0 || ~8.5.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.52
- phpstan/extension-installer: ^1.3
- phpstan/phpstan: ^2.0
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/php-code-coverage: ^12.0
- phpunit/phpunit: ^12.0
README
This library is a simple tool to have a safer php code.
We want to 'ensure' or 'enforce' the type check for quality reasons and/or for Static Analysis tools like PHPStan or Psalm.
Installation
composer require arnapou/ensure
packagist đī¸ arnapou/ensure
Ensure
In the example below, we guarantee the fact that a non-constrained int or string are constrained into the class.
use Arnapou\Ensure\Ensure;
use Arnapou\Ensure\Expected;
class MyObject
{
/** @var positive-int */
public int $id;
/** @var non-empty-string */
public string $name;
/**
* @throws Expected
*/
public function __construct(int $id, string $name)
{
$this->id = Ensure::positiveInt($id);
$this->name = Ensure::nonEmptyString($name);
}
}
Enforce
In the example below, which can be from a legacy code, we have a phpdoc type-hinting in the construct.
But it is not "hard" enough from a php point of view, and it may be too risky to change the mixed type-hinting.
You can guaranty the type hinting inside the class while staying lax on type-check by using Enforce.
It will cast the value when it is enough "safe" to do it :
- Examples of valid/auto-casted
int:"1234","1.2e3",3.0,true - Examples of invalid
int:"foo","1.234e2",3.14,[]
use Arnapou\Ensure\Enforce;
use Arnapou\Ensure\Expected;
class MyObject
{
/** @var positive-int */
public int $id;
/** @var non-empty-string */
public string $name;
/**
* @param int $id
* @param string $name
*
* @throws Expected
*/
public function __construct(mixed $id, mixed $name)
{
$this->id = Enforce::positiveInt($id);
$this->name = Enforce::nonEmptyString($name);
}
}
Message customization or translation
You can do that implementing your own MessageFactoryInterface
and then set it as default for Expected class.
class MyMessageFactory implements MessageFactoryInterface
{
public function createExpectedMessage(string $expected, int $code, mixed $value, string $propertyName, mixed ...$parameters): string
{
// Build the message here.
}
}
// Change the default message factory.
\Arnapou\Ensure\Expected::setMessageFactory(new MyMessageFactory());
âšī¸ The default MessageFactory implementation is final,
you cannot extend it, but you can reuse it with composition if necessary :
class MyMessageFactory implements MessageFactoryInterface
{
private \Arnapou\Ensure\MessageFactory\MessageFactory $internal;
public function __construct(){
$this->internal = new \Arnapou\Ensure\MessageFactory\MessageFactory();
}
public function createExpectedMessage(string $expected, int $code, mixed $value, string $propertyName, mixed ...$parameters): string
{
if (/* any logic you need */) {
// Your customization here
}
// Default on the default message factory
return $this->internal->createExpectedMessage($expected, $code, $value, $propertyName, ...$parameters);
}
}
// Change the default message factory.
\Arnapou\Ensure\Expected::setMessageFactory(new MyMessageFactory());
Php versions
| Date | Ref | 8.5 | 8.4 | 8.3 | 8.2 |
|---|---|---|---|---|---|
| 25/10/2025 | 2.8.x, main | Ã | Ã | Ã | |
| 24/11/2024 | 2.7.x | Ã | Ã | ||
| 25/11/2023 | 2.0 - 2.6 | Ã | |||
| 17/05/2024 | 1.4.x | Ã | Ã | ||
| 23/08/2023 | 1.x | Ã |