Skip to content

Commit

Permalink
Ensure caching config is compatible with v1
Browse files Browse the repository at this point in the history
Signed-off-by: Luís Cobucci <[email protected]>
  • Loading branch information
lcobucci committed Jan 31, 2024
1 parent 822ea0e commit 87321b0
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 17 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ $r->addRoute('POST', '/test', 'handler');
$r->addRoute(['GET', 'POST'], '/test', 'handler');
```

By default the `$routePattern` uses a syntax where `{foo}` specifies a placeholder with name `foo`
By default, the `$routePattern` uses a syntax where `{foo}` specifies a placeholder with name `foo`
and matching the regex `[^/]+`. To adjust the pattern the placeholder matches, you can specify
a custom pattern by writing `{bar:[0-9]+}`. Some examples:

Expand Down Expand Up @@ -142,7 +142,7 @@ $r->addRoute('POST', '/post-route', 'post_handler');

#### Route Groups

Additionally, you can specify routes inside of a group. All routes defined inside a group will have a common prefix.
Additionally, you can specify routes inside a group. All routes defined inside a group will have a common prefix.

For example, defining your routes as:

Expand Down Expand Up @@ -178,13 +178,15 @@ $dispatcher = FastRoute\cachedDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
$r->addRoute('GET', '/user/{name}', 'handler2');
}, [
'cacheFile' => __DIR__ . '/route.cache', /* required */
'cacheKey' => __DIR__ . '/route.cache', /* required */
// 'cacheFile' => __DIR__ . '/route.cache', /* will still work for v1 compatibility */
'cacheDisabled' => IS_DEBUG_ENABLED, /* optional, enabled by default */
'cacheDriver' => FastRoute\Cache\FileCache::class, /* optional, class name or instance of the cache driver - defaults to file cache */
]);
```

The second parameter to the function is an options array, which can be used to specify the cache
file location, among other things.
key (e.g. file location when using files for caching), caching driver, among other things.

### Dispatching a URI

Expand Down
11 changes: 6 additions & 5 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
use FastRoute\Cache\FileCache;
use LogicException;

use function array_key_exists;
use function function_exists;
use function is_string;

if (! function_exists('FastRoute\simpleDispatcher')) {
/** @param array{routeParser?: class-string<RouteParser>, dataGenerator?: class-string<DataGenerator>, dispatcher?: class-string<Dispatcher>, routeCollector?: class-string<RouteCollector>, cacheDisabled?: bool, cacheKey?: string, cacheDriver?: class-string<Cache>|Cache} $options */
/** @param array{routeParser?: class-string<RouteParser>, dataGenerator?: class-string<DataGenerator>, dispatcher?: class-string<Dispatcher>, routeCollector?: class-string<RouteCollector>, cacheDisabled?: bool, cacheKey?: string, cacheFile?: string, cacheDriver?: class-string<Cache>|Cache} $options */
function simpleDispatcher(callable $routeDefinitionCallback, array $options = []): Dispatcher
{
return \FastRoute\cachedDispatcher(
Expand All @@ -20,7 +19,7 @@ function simpleDispatcher(callable $routeDefinitionCallback, array $options = []
);
}

/** @param array{routeParser?: class-string<RouteParser>, dataGenerator?: class-string<DataGenerator>, dispatcher?: class-string<Dispatcher>, routeCollector?: class-string<RouteCollector>, cacheDisabled?: bool, cacheKey?: string, cacheDriver?: class-string<Cache>|Cache} $options */
/** @param array{routeParser?: class-string<RouteParser>, dataGenerator?: class-string<DataGenerator>, dispatcher?: class-string<Dispatcher>, routeCollector?: class-string<RouteCollector>, cacheDisabled?: bool, cacheKey?: string, cacheFile?: string, cacheDriver?: class-string<Cache>|Cache} $options */
function cachedDispatcher(callable $routeDefinitionCallback, array $options = []): Dispatcher
{
$options += [
Expand All @@ -47,7 +46,9 @@ function cachedDispatcher(callable $routeDefinitionCallback, array $options = []
return new $options['dispatcher']($loader());
}

if (! array_key_exists('cacheKey', $options)) {
$cacheKey = $options['cacheKey'] ?? $options['cacheFile'] ?? null;

if ($cacheKey === null) {
throw new LogicException('Must specify "cacheKey" option');
}

Expand All @@ -57,6 +58,6 @@ function cachedDispatcher(callable $routeDefinitionCallback, array $options = []
$cache = new $cache();
}

return new $options['dispatcher']($cache->get($options['cacheKey'], $loader));
return new $options['dispatcher']($cache->get($cacheKey, $loader));
}
}
27 changes: 19 additions & 8 deletions test/Dispatcher/CachingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,23 @@ public function warmUpCache(): void
$this->createDispatcher();
}

public function createDispatcher(): Dispatcher
public function createDispatcher(string $optionName = 'cacheKey'): Dispatcher
{
return cachedDispatcher(
static function (RouteCollector $collector): void {
$collector->get('/testing', ['test']);
$collector->get('/admin/{page}', ['admin-page']);
},
['cacheKey' => self::CACHE_FILE],
// @phpstan-ignore-next-line we're doing dynamic configuration...
[$optionName => self::CACHE_FILE],
);
}

#[PHPUnit\Test]
public function dynamicRouteShouldMatch(): void
#[PHPUnit\DataProvider('possiblePropertyNames')]
public function dynamicRouteShouldMatch(string $propertyName): void
{
$dispatcher = $this->createDispatcher();
$dispatcher = $this->createDispatcher($propertyName);
$result = $dispatcher->dispatch('GET', '/admin/1234');

self::assertSame(Dispatcher::FOUND, $result[0]);
Expand All @@ -50,21 +52,30 @@ public function dynamicRouteShouldMatch(): void
}

#[PHPUnit\Test]
public function staticRouteShouldMatch(): void
#[PHPUnit\DataProvider('possiblePropertyNames')]
public function staticRouteShouldMatch(string $propertyName): void
{
$dispatcher = $this->createDispatcher();
$dispatcher = $this->createDispatcher($propertyName);
$result = $dispatcher->dispatch('GET', '/testing');

self::assertSame(Dispatcher::FOUND, $result[0]);
self::assertSame(['test'], $result[1]);
}

#[PHPUnit\Test]
public function missingRoutShouldNotBeFound(): void
#[PHPUnit\DataProvider('possiblePropertyNames')]
public function missingRoutShouldNotBeFound(string $propertyName): void
{
$dispatcher = $this->createDispatcher();
$dispatcher = $this->createDispatcher($propertyName);
$result = $dispatcher->dispatch('GET', '/testing2');

self::assertSame(Dispatcher::NOT_FOUND, $result[0]);
}

/** @return iterable<string, array{string}> */
public static function possiblePropertyNames(): iterable
{
yield 'v1' => ['cacheFile'];
yield 'v2' => ['cacheKey'];
}
}

0 comments on commit 87321b0

Please sign in to comment.