Skip to content

Commit 79d247b

Browse files
committed
refactor: add declare(strict_types=1) to all source files and fix type safety
Add strict_types declaration to all 34 PHP files under src/Klein/. Fix all resulting TypeError failures and resolve all PHPStan errors. strict_types — added to 33 files (Route.php already had it): AbstractResponse, AbstractRouteFactory, App, DataCollection, HeaderDataCollection, ResponseCookieDataCollection, RouteCollection, ServerDataCollection, all Exceptions/*, HttpMethod, HttpStatus, Klein, Request, Response, ResponseCookie, RouteFactory, RouteRegexCompiler, ServiceProvider, IndexInterface, RadixRouteIndex, Validator Type coercion fixes exposed by strict_types: - HeaderDataCollection: cast array key to string before explode() - ResponseCookieDataCollection: use $value->getName() as key instead of relying on implicit int-to-string coercion - ServiceProvider::markdown(): cast $arg to string before htmlentities() - ServiceProvider::validateParam(): explicitly cast mixed param() return to ?string before passing to validate() PHPStan fixes (0 errors remaining): - HeaderDataCollection: add @param array type hint - Klein::filterMatchingRoutes(): narrow $requestMethod to string - Klein catch-all filter: separate setRouteMatchedAgainstUri() from boolean expression (was "always true" right-hand side) - Route::$regex: remove unused nullable type - Route::$regexMatchingParams/$routeMatched: change @type to @var for PHPStan, add default value - Route: remove unnecessary ?? on non-nullable $namespace - Route::validateMethod(): rewrite using HttpMethod::tryFrom() instead of duplicated 9-arm match blocks; validate array elements with is_string() guard (annotated @var mixed) - RouteRegexCompiler::getPathFor(): self:: instead of static:: for private constant - RadixRouteIndex: add PHPDoc types for constructor params and property; handle preg_split false return; suppress recursive array reference and loop-inference edge cases Code quality (incidental, already in working tree): - Rename snake_case properties to camelCase: protocol_version, is_name_prepared, number_of_skips, route_factory, error_callbacks, http_error_callbacks, after_filter_callbacks, output_buffer_level, http_messages - Klein: use InvalidCallableException instead of raw InvalidArgumentException for uncallable callbacks - InvalidCallableException: add constructor with message prefix, use proper imports - RouteFactory/DataCollection: remove stray blank lines after opening brace - Klein: add visibility to class constants - Klein::with(): require_once instead of require - Request: expand @param $files to full array shape - MockRequestFactory: add parameter types and return type - RequestTest: use realistic associative arrays and file structures in test data Tests: 298 passed, 790 assertions. PHPStan: 0 errors.
1 parent 5f626b3 commit 79d247b

38 files changed

Lines changed: 293 additions & 159 deletions

src/Klein/AbstractResponse.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* Klein (klein.php) - A fast & flexible router for PHP
45
*
@@ -10,6 +11,8 @@
1011
* @license MIT
1112
*/
1213

14+
declare(strict_types=1);
15+
1316
namespace Klein;
1417

1518
use Klein\DataCollection\HeaderDataCollection;
@@ -22,7 +25,6 @@
2225
*/
2326
abstract class AbstractResponse
2427
{
25-
2628
/**
2729
* Properties
2830
*/
@@ -32,7 +34,7 @@ abstract class AbstractResponse
3234
*
3335
* @type string
3436
*/
35-
protected string $protocol_version = '1.1';
37+
protected string $protocolVersion = '1.1';
3638

3739
/**
3840
* The response body
@@ -125,12 +127,12 @@ public function protocolVersion(?string $protocol_version = null): AbstractRespo
125127
// Require that the response be unlocked before changing it
126128
$this->requireUnlocked();
127129

128-
$this->protocol_version = $protocol_version;
130+
$this->protocolVersion = $protocol_version;
129131

130132
return $this;
131133
}
132134

133-
return $this->protocol_version;
135+
return $this->protocolVersion;
134136
}
135137

136138
/**
@@ -308,7 +310,7 @@ public function unlock(): static
308310
*/
309311
protected function httpStatusLine(): string
310312
{
311-
return sprintf('HTTP/%s %s', $this->protocol_version, $this->status);
313+
return sprintf('HTTP/%s %s', $this->protocolVersion, $this->status);
312314
}
313315

314316
/**

src/Klein/AbstractRouteFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* @license MIT
1111
*/
1212

13+
declare(strict_types=1);
14+
1315
namespace Klein;
1416

1517
use Klein\Routes\Route;

src/Klein/App.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* @license MIT
1111
*/
1212

13+
declare(strict_types=1);
14+
1315
namespace Klein;
1416

1517
use BadMethodCallException;

src/Klein/DataCollection/DataCollection.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
* @license MIT
1212
*/
1313

14+
declare(strict_types=1);
15+
1416
namespace Klein\DataCollection;
1517

1618
use ArrayAccess;
@@ -133,9 +135,9 @@ public function all(?array $mask = null, bool $fill_with_nulls = true): array
133135
*/
134136

135137
return array_intersect_key(
136-
$this->attributes,
137-
array_flip($mask)
138-
) + $attributes;
138+
$this->attributes,
139+
array_flip($mask)
140+
) + $attributes;
139141
}
140142

141143
return $this->attributes;

src/Klein/DataCollection/HeaderDataCollection.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* @license MIT
1111
*/
1212

13+
declare(strict_types=1);
14+
1315
namespace Klein\DataCollection;
1416

1517
/**
@@ -20,7 +22,7 @@
2022
class HeaderDataCollection extends DataCollection
2123
{
2224
/**
23-
* @param array<string, string> $headers
25+
* @param array<string, mixed> $headers
2426
*/
2527
public function __construct(array $headers = [])
2628
{

src/Klein/DataCollection/ResponseCookieDataCollection.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* @license MIT
1111
*/
1212

13+
declare(strict_types=1);
14+
1315
namespace Klein\DataCollection;
1416

1517
use Klein\ResponseCookie;
@@ -31,13 +33,13 @@ class ResponseCookieDataCollection extends DataCollection
3133
* Constructor
3234
*
3335
* @override DataCollection::__construct()
34-
* @param array<string, ResponseCookie> $cookies The cookies of this collection
36+
* @param list<ResponseCookie> $cookies The cookies of this collection
3537
*/
3638
public function __construct(array $cookies = [])
3739
{
3840
parent::__construct();
39-
foreach ($cookies as $key => $value) {
40-
$this->set($key, $value);
41+
foreach ($cookies as $value) {
42+
$this->set($value->getName(), $value);
4143
}
4244
}
4345

src/Klein/DataCollection/RouteCollection.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* @license MIT
1111
*/
1212

13+
declare(strict_types=1);
14+
1315
namespace Klein\DataCollection;
1416

1517
use Klein\Routes\Route;
@@ -23,9 +25,9 @@ class RouteCollection extends DataCollection
2325
{
2426

2527
/**
26-
* @var bool $is_name_prepared Whether the named routes have been prepared
28+
* @var bool $isNamePrepared Whether the named routes have been prepared
2729
*/
28-
protected bool $is_name_prepared = false;
30+
protected bool $isNamePrepared = false;
2931

3032
/**
3133
* Methods
@@ -86,7 +88,7 @@ public function addRoute(Route $route): static
8688
{
8789
// Adding a new route invalidates any previously prepared name index/cache.
8890
// Mark as not prepared so that prepareNamed() can rebuild the name mapping on next access.
89-
$this->is_name_prepared = false;
91+
$this->isNamePrepared = false;
9092

9193
/**
9294
* Auto-generate a name from the object's hash
@@ -131,7 +133,7 @@ public function add(callable|Route $route): static
131133
*/
132134
public function prepareNamed(): static
133135
{
134-
if ($this->is_name_prepared) {
136+
if ($this->isNamePrepared) {
135137
return $this;
136138
}
137139

@@ -154,7 +156,7 @@ public function prepareNamed(): static
154156

155157
// Mark the collection as having processed/normalized named routes so we don't
156158
// repeat the preparation work on further calls to prepareNamed()
157-
$this->is_name_prepared = true;
159+
$this->isNamePrepared = true;
158160

159161
return $this;
160162
}

src/Klein/DataCollection/ServerDataCollection.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* @license MIT
1111
*/
1212

13+
declare(strict_types=1);
14+
1315
namespace Klein\DataCollection;
1416

1517
/**

src/Klein/Exceptions/DispatchHaltedException.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
* @license MIT
1212
*/
1313

14+
declare(strict_types=1);
15+
1416
namespace Klein\Exceptions;
1517

1618
use RuntimeException;
@@ -58,7 +60,7 @@ class DispatchHaltedException extends RuntimeException implements KleinException
5860
*
5961
* @type int
6062
*/
61-
protected int $number_of_skips = 1;
63+
protected int $numberOfSkips = 1;
6264

6365

6466
/**
@@ -72,19 +74,19 @@ class DispatchHaltedException extends RuntimeException implements KleinException
7274
*/
7375
public function getNumberOfSkips(): int
7476
{
75-
return $this->number_of_skips;
77+
return $this->numberOfSkips;
7678
}
7779

7880
/**
7981
* Sets the number of matches to skip on a "next" skip
8082
*
81-
* @param int $number_of_skips
83+
* @param int $numberOfSkips
8284
*
8385
* @return DispatchHaltedException
8486
*/
85-
public function setNumberOfSkips(int $number_of_skips): DispatchHaltedException
87+
public function setNumberOfSkips(int $numberOfSkips): DispatchHaltedException
8688
{
87-
$this->number_of_skips = $number_of_skips;
89+
$this->numberOfSkips = $numberOfSkips;
8890

8991
return $this;
9092
}

src/Klein/Exceptions/DuplicateServiceException.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* @license MIT
1010
*/
1111

12+
declare(strict_types=1);
13+
1214
namespace Klein\Exceptions;
1315

1416
use OverflowException;

0 commit comments

Comments
 (0)