Search code examples
zend-frameworkmezzio

Zend Expressive Route with optional parameter


I want use a route to get the complete collection and, if available, a filtered collection.

so my route:

$app->get("/companies", \App\Handler\CompanyPageHandler::class, 'companies');

My Handler for this route:

use App\Entity\Company;
use App\Entity\ExposeableCollection;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class CompanyPageHandler extends AbstractHandler
{
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $categories = new ExposeableCollection();
        foreach (['test', 'test1', 'test3'] as $name) {
            $category = new Company();
            $category->setName($name);

            $categories->addToCollection($category);
        }

        return $this->publish($categories);
    }
}

When getting this route /companies, i get the expected collection

[{"name":"test"},{"name":"test1"},{"name":"test3"}]

So now i change the route

$app->get("/companies[/:search]", \App\Handler\CompanyPageHandler::class, 'companies');

It's all fine when i'm browsing to /companies. But if i try the optional parameter /companies/test1 then i got an error

Cannot GET http://localhost:8080/companies/test1

my composer require section:

"require": {
    "php": "^7.1",
    "zendframework/zend-component-installer": "^2.1.1",
    "zendframework/zend-config-aggregator": "^1.0",
    "zendframework/zend-diactoros": "^1.7.1 || ^2.0",
    "zendframework/zend-expressive": "^3.0.1",
    "zendframework/zend-expressive-helpers": "^5.0",
    "zendframework/zend-stdlib": "^3.1",
    "zendframework/zend-servicemanager": "^3.3",
    "zendframework/zend-expressive-fastroute": "^3.0"
},

In Zend Framework 2 and Symfony4 this route definition works fine. So im confused. Why my optional parameter doesn't work?


Solution

  • That's because you are using https://github.com/nikic/FastRoute router and correct syntax would be:

    $app->get("/companies[/{search}]", \App\Handler\CompanyPageHandler::class, 'companies');
    

    or be more strict and validate search param something like this:

    $app->get("/companies[/{search:[\w\d]+}]", \App\Handler\CompanyPageHandler::class, 'companies');