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
## Parameter Renaming ($id → $userId) & Position Shifts
296
296
297
-
PHP permits child classes to rename parameters when implementing an interface or extending a class. TypePHP maps inherited parameter contracts by **index position** (0, 1, 2...) rather than parameter name:
297
+
When a child class or attribute constructor overrides a parent method, parameter positions or parameter names may shift. TypePHP resolves parameter contract inheritance using **Name-First Resolution**:
298
+
299
+
1.**Name Matching:** If a parameter name in the child method matches a parameter name in the parent class (e.g. `$api`), the parent's contract is inherited by that parameter regardless of its position index in the child.
300
+
2.**Position Fallback:** If a parameter is renamed in the child class (e.g., `$id` $\rightarrow$ `$userId`), TypePHP falls back to matching by position index.
298
301
299
302
```php
300
-
interface UserApiInterface
303
+
class BaseField
301
304
{
302
305
/**
303
-
* Interface uses parameter name $id
306
+
* Parent constructor has $api at position #1
304
307
*
305
-
* @param positive-int $id
308
+
* @param string $type
309
+
* @param bool|array{admin-api: bool} $api
306
310
*/
307
-
public function find(int $id): bool;
311
+
public function __construct(string $type, bool|array $api = false) {}
308
312
}
309
313
310
-
class UserApi implements UserApiInterface
314
+
class OneToManyRelation extends BaseField
311
315
{
312
-
// Child renames parameter $id to $userId
313
-
public function find(int $userId): bool
314
-
{
315
-
return true;
316
+
/**
317
+
* Child inserts $entity, $ref, $onDelete BEFORE $api (position shift!)
> **Execution Order Note:** Native PHP type hints (e.g., `int $id`, `string $username`) are evaluated by PHP's C-engine *before* function execution begins. TypePHP's extended PHPDoc contracts (e.g., `positive-int`, `non-empty-string`) execute at the very start of the function/method body. If a native type hint fails, PHP throws its native `TypeError` before TypePHP's guard rails run.
37
37
38
+
---
39
+
## PHP 8.0+ Named Arguments
40
+
41
+
TypePHP natively supports PHP 8.0+ Named Arguments. Because parameter contracts are mapped by parameter name rather than argument position index, you can pass named arguments in any order, and TypePHP will accurately validate each parameter:
42
+
43
+
```php
44
+
<?php
45
+
46
+
declare(strict_types=1);
47
+
48
+
/**
49
+
* @param positive-int $id
50
+
* @param non-empty-string $username
51
+
* @param int<1,100> $age
52
+
*/
53
+
function registerUser(int $id, string $username, int $age): void
54
+
{
55
+
// ...
56
+
}
57
+
58
+
// Valid Call: Arguments passed in completely reversed/swapped order
59
+
registerUser(age: 25, username: 'Alice', id: 42);
60
+
61
+
// Invalid Call: $id (-5) passed as 3rd named argument
62
+
registerUser(age: 25, username: 'Alice', id: -5);
63
+
// Throws: TypeError: registerUser(): Argument $id must be of type positive-int, negative int (-5) given
0 commit comments