Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate absolute URL with specific scheme in Symfony2

Tags:

php

symfony

I want to generate an absolute URL with a specific scheme (https) in a Symfony2 controller. All the solutions I found point me to configure the targeted route so that it requires that scheme. But I need the route to remain accessible in http, so I can't set it to require https (in which case http requests are redirected to the corresponding https URL).

Is there a way to generate an URL with, in the scope of that URL generation only, a specific scheme?

I saw that using the 'network' keyword generates a "network path"-style URL, which looks like "//example.com/dir/file"; so maybe I can simply do

'https:' . $this->generateUrl($routeName, $parameters, 'network')

But I don't know if this will be robust enough to any route or request context.

UPDATE: after investigation in the URL generation code, this "network path" workaround seems fully robust. A network path is generated exactly as an absolute URL, without a scheme before the "//".

like image 504
Socce Avatar asked Aug 27 '15 12:08

Socce


3 Answers

According to the code or documentation, currently you cannot do that within the generateUrl method. So your "hackish" solution is still the best, but as @RaymondNijland commented you are better off with str_replace:

$url = str_replace('http:', 'https:', $this->generateUrl($routeName, $parameters));

If you want to make sure it's changed only at the beginning of the string, you can write:

$url = preg_replace('/^http:/', 'https:', $this->generateUrl($routeName, $parameters));

No, the colon (:) has no special meaning in the regex so you don't have to escape it.

like image 162
Francesco Abeni Avatar answered Sep 28 '22 23:09

Francesco Abeni


Best way to go with this

$url = 'https:'.$this->generateUrl($routeName, $parameters, UrlGeneratorInterface::NETWORK_PATH)
like image 37
Basit Avatar answered Sep 28 '22 22:09

Basit


With default UrlGenerator, I don't think that is possible, if you don't want to mess with strings.

You could make your own HttpsUrlGenerator extends UrlGenerator introducting one slight change:

Within method generate(), instead of:

return $this->doGenerate(
    $compiledRoute->getVariables(), 
    $route->getDefaults(), 
    $route->getRequirements(), 
    $compiledRoute->getTokens(), 
    $parameters, 
    $name, 
    $referenceType, 
    $compiledRoute->getHostTokens(), 
    $route->getSchemes() 
);

You could do:

return $this->doGenerate(
    $compiledRoute->getVariables(), 
    $route->getDefaults(), 
    $route->getRequirements(), 
    $compiledRoute->getTokens(), 
    $parameters, 
    $name, 
    $referenceType, 
    $compiledRoute->getHostTokens(), 
    ['https']
);

As you can see, $route->getSchemes() gets pumped into doGenerate() based on the route settings (the tutorial link you provided above).

You could even go further and externalize this schema array and supply it via __construct.

Hope this helps a bit ;)

like image 45
Jovan Perovic Avatar answered Sep 29 '22 00:09

Jovan Perovic