R.Damasinoro R.Damasinoro - 8 months ago 109
Apache Configuration Question

URL Rewriting from .htaccess with Symfony Routing

I have some trouble RewritingUrl with Symfony (2.8)
My objective is to redirect some URL without having them changing in the browser bar.

I need this so the URL may have a custom, human-readable form, and being shareable.

The URL is also used in a Form thus why the data are sent in the

?param=data
shape

Homewever, Symfony internal routing seems to not quite work with it ( or maybe have I overlooked some stuff but I've seeking up and down all day for this without finding the right answer )

Without the framework, in a .htaccess
If a user went to

www.website.com/search/London/15


I would redirect them to

www.website.com/searchEngine?search_action[city]=London&search_action[radius]=15


Without changing the browser URL so searchEngine nevers shows up , with a simple RewriteRule

RewriteRule ^search/(.*)/(.*)$ /searchEngine?search_action[city]=$1&search_action[radius]=$2 [L]


But once I try to use this same rule with Symfony ( in the .htaccess in the /web forlder, right ?),

www.website.com/search/London/15 land on a Symfony 404 Error Page

My guess is that Symfony tries to look for an internal /Search route, which does not exist as the URL is intended to silently redirect to SearchEngin through the .htaccess

SearchEngine route does exist and
www.website.com/SearchEngine?search_action[city]=London&search_action[radius]=15
works very fine

So far, .htaccess and Symfony works together if I add the R flag to the RewriteRule

RewriteRule ^search/(.*)/(.*)$ /searchEngine?search_action[city]=$1&search_action[radius]=$2 [R,L]


But that's because the URL changes in the browser as it is redirected to SearchEngine.

Is there a way so that Symfony knows that
/search/London/15
leads to
SearchEngine?search_action[city]=London&search_action[radius]=15
, and works without the Url changing ?

Anyone have an idea as to what I should tweak for that ?

Routing



Quite really basic , a single Route just for that URL readable feature and Search, nothing too fancy.

routing.yml



research_action:
path: /SearchEngine
defaults: { _controller: "MySearchBundle:Search:search" }


SearchController:searchAction



public function searchAction(Request $request)
{
/*
expect search_action[city]=London and search_action[radius]=15
*/
$form = $this->createForm('MySearchBundle\Form\Type\SearchType',null);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid())
{
//Get here without problem when from SearchEngine?search_action[city]=London&search_action[radius]=15
/*
This is where Zhuli do the thing
*/

}
return $this->render('SomeDefaultPage.html.twig');
}


.htaccess



...
//Basic Symfony Routing stuff
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
#Doesn't work without that R tag
RewriteRule search/(.*)/(.*)$ /SearchEngine?search_action[city]=$1&search_action[radius]=$2 [R=301,L]
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/app.php [L]
.....

Answer Source

So I found something which is quite longer than just a rule in .htaccess, but I could not find another workaround.

I created a new Route which will forward the /search/London/15 query toward the SearchEngine

forward_action:
path:     /search/{city}/{radius}
defaults: { _controller: "MySearchBundle:Search:searchForward" }

Controller

In the Controller Action I retrieve the URL Attribute (city and radius ) that I pass to the Request:ParameterBag; which I then forward to the SearchEngineAction

  public function searchForwardAction(Request $request,$city,$radius)
  {
        //Putting the attribute in an array
        $query['city']=$city;
        $query['radius']=$radius;
        /*
           Which I pass to the request as a parameter
           The forward will treat this like a Get Query
           ?search_action[city]=$city&search_action[radius]=$radius
         */
        $request->query->set('search_action',$query);
        //Forwarding !
        return $this->forward('MySearchBundle:Search:search',  array('request' => $request));
}

Since I use forward() the URL on the browser stays like /Search/Kyoto/25 but return the result of /SearchEngine?search_action[city]=Kyoto&search_action[radius]=25

It works quite fine but the amount of code and work for just this URL rewriting becomes quite heavy if one compares it to normally a single rule in an .htaccess ( which still does not work properly)

And I will have to modify where the Search Form direct to

I doubt it to be THE best solution since it is quite ..complicated for a such simple task.

Anyone got better ?

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download