When you define a parameter in your route, Symfony requires that parameter to be specified. So, in your case, :state and :city have to both be specified in the url.
If you'd like to make one or both of these parameters optional, you can try to use the * (unnamed wildcard) routing syntax. That would look something like this:
some_route_name:
url: /module/*
param:
module: module
action: search
This route will match urls that look like this:
- /module/city/chicago
- /module/state/illinois
- /module/state/illinois/city/chicago
- /module/city/chicago/state/illinois
I know that's not ideal, because 'city' and 'state' are in the url. But it is the easiest way to do what you want with Symfony's routing system.
Then, in your controller, you'd forward to 404 if the user hasn't specified a city or state:
$this->forward404Unless($this->getRequestParameter('city') || $this->getRequestParameter('state'));
If that's not good enough, you have a few other options. If you're using 1.1 or 1.2, you could subclass the routing object to make it do what you want. Or you could use more than one route to do what you want (one that is /module/:city_or_state and another that is /module/:state/:city).