You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// callable typefunctionmyFunction(): void {
echo"This is callable";
}
$callableVar = 'myFunction';
$callableVar();
classCallableClass {
publicfunction__invoke() {
echo"This is callable from a class";
}
}
$callableInstance = newCallableClass();
$callableInstance();
Composite Types and Type Aliases
// Intersection typesinterfaceInterfaceA {}
interfaceInterfaceB {}
classMyClassimplementsInterfaceA, InterfaceB {}
functionacceptsIntersection(InterfaceA&InterfaceB$obj) {
// Function body
}
$instance = newMyClass();
acceptsIntersection($instance);
// Union typesfunctionacceptsUnion(int|string$value) {
// Function body
}
acceptsUnion(42);
acceptsUnion("Hello");
// Type AliasesfunctionacceptsMixed(mixed$value) {
// Function body
}
acceptsMixed(42);
acceptsMixed("Hello");
acceptsMixed([1, 2, 3]);
functionacceptsIterable(iterable$iterableVar) {
// Function body
}
acceptsIterable([1, 2, 3]);
acceptsIterable(newArrayObject([1, 2, 3]));
PHP has a "strict types" mode that ensures type declarations are strictly enforced. This mode is activated on a per-file basis and affects type declarations for parameters, return values, and class properties. To enable strict types, add declare(strict_types=1); at the top of the PHP file.
Enabling Strict Types
<?phpdeclare(strict_types=1);
Strict Types with Function Parameters and Return Types
<?phpdeclare(strict_types=1);
functionadd(int$a, int$b): int {
return$a + $b;
}
// Usageechoadd(5, 3); // 8echoadd(5.5, 3.2); // TypeError: Argument 1 passed to add() must be of the type integer, float given
Strict Types with Class Properties
<?phpdeclare(strict_types=1);
classUser {
privatestring$name;
privateint$age;
publicfunction__construct(string$name, int$age) {
$this->name = $name;
$this->age = $age;
}
publicfunctiongetName(): string {
return$this->name;
}
publicfunctiongetAge(): int {
return$this->age;
}
}
// Usage$user = newUser("Alice", 30);
echo$user->getName(); // Aliceecho$user->getAge(); // 30$newUser = newUser("Bob", "thirty"); // TypeError: Argument 2 passed to User::__construct() must be of the type integer, string given
Strict Types with Return Types in Methods
<?phpdeclare(strict_types=1);
classCalculator {
publicfunctionmultiply(float$a, float$b): float {
return$a * $b;
}
}
// Usage$calculator = newCalculator();
echo$calculator->multiply(2.5, 4.0); // 10.0echo$calculator->multiply(2, "3"); // TypeError: Argument 2 passed to Calculator::multiply() must be of the type float, string given
In PHP, generics are not natively supported in the same way they are in some other languages like Java or TypeScript. However, with the release of PHP 8, some limited support for generics can be achieved using a combination of docblock annotations and runtime checks. Here are some examples of how you might use generic types in PHP along with explanations.
PHPStan is a static analysis tool for PHP that helps detect errors in your code without executing it. It ensures type safety, catches potential bugs, and enforces best practices, making your code more robust and maintainable.
Key Features of PHPStan
Detects Type Errors: Ensures type correctness across your codebase.
Catches Potential Bugs: Finds issues that could lead to runtime errors.
Supports Generics: Provides support for generic types through annotations.
Integrates with CI/CD: Seamlessly integrates with continuous integration pipelines.
Installation via Composer
To install PHPStan, add it as a development dependency using Composer:
composer require --dev phpstan/phpstan
Basic Configuration
Create a phpstan.neon configuration file in your project root:
<?phpclassExample {
publicfunctionrun() {
$this->unknownMethod();
// Fails because unknownMethod() does not exist
}
}
functionadd($a, $b) {
return$a + $b;
}
echoadd(1);
// Fails because add() is called with the wrong number of arguments
Level 1: Possibly Undefined Variables
<?phpfunctionmaybeUndefined() {
if (rand(0, 1)) {
$a = 1;
}
echo$a;
// Fails because $a might be undefined
}
echo$undefinedVariable;
// Fails because $undefinedVariable is not defined
Level 2: Unknown Methods Checked on All Expressions
<?phpclassAnotherClass {
publicfunctionexistingMethod() {}
}
$object = newAnotherClass();
$object->nonExistentMethod();
// Fails because nonExistentMethod() does not exist
Level 3: Return Types, Types Assigned to Properties
<?phpclassReturnType {
publicfunctiongetString(): string {
return123;
// Fails because the return type should be a string
}
}
classPropertyType {
/** @var int */private$value;
publicfunctionsetValue(string$value) {
$this->value = $value;
// Fails because $value should be an integer
}
}
Level 4: Basic Dead Code Checking
<?phpif ($object instanceof NonExistentClass) {
echo'This will never be true';
// Fails because NonExistentClass does not exist
} else {
echo'This will always execute';
}
functiontest() {
return;
echo'This will never be executed';
// Fails because this is unreachable code
}
Level 5: Checking Types of Arguments Passed to Methods and Functions
<?phpfunctionaddNumbers(int$a, int$b) {
return$a + $b;
}
echoaddNumbers(1, 'two');
// Fails because 'two' is not an integer
Level 6: Report Missing Typehints
<?phpclassTypehintExample {
private$value;
// Fails because the typehint is missingpublicfunctionsetValue($value) {
$this->value = $value;
// Fails because the typehint is missing
}
publicfunctiongetValue() {
return$this->value;
// Fails because the typehint is missing
}
}
Level 7: Report Partially Wrong Union Types
<?phpclassA {
publicfunctionmethodA():void {}
}
classB {
publicfunctionmethodB():void {}
}
functionprocess(A|B|null$object): void {
if ($object instanceof A || $object instanceof B) {
$object->methodA();
// Fails because $object might be an instance of B, which does not have methodA
}
}
Level 8: Report Calling Methods and Accessing Properties on Nullable Types
<?phpfunctiongetLength(?string$str): int {
returnstrlen($str);
// Fails because $str can be null, and strlen() does not accept null
}
Level 9: Be Strict About the mixed Type
<?phpfunctionhandleMixed(mixed$value):void {
echo$value;
// Fails because operations on mixed are not allowed
}
These examples illustrate specific issues that PHPStan detects at each level, aligned with the detailed checks you provided.