Hi,
Seems like the route helper is not working properly on commands. I would like to generate a URL to a named route with parameters but it seems to be always missing the hostname and port. It works fine on controllers and route closures but not on commands.
routes.php which returns http://localhost:12345/user/1
<?php
$app->get('user/{id}', ['as' => 'user', function ($id) {
return route('user', ['id' => 1]);
}]);
Same route helper on the command:
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$url = route('user', ['id' => 1]);
$this->info($url);
}
vagrant@homestead:~/Code/lumen_route_helper$ php artisan test:url
http://:/user/1
As a temporary solution to this problem, i added this to my console kernel file:
protected function prepareConsoleUrl()
{
$url = env('APP_URL', 'http://localhost');
$urlParts = parse_url($url);
if (isset($urlParts['path']) && mb_strlen($urlParts['path']) > 1) {
$_SERVER['SCRIPT_NAME'] = $urlParts['path'].DIRECTORY_SEPARATOR.'index.php';
$_SERVER['SCRIPT_FILENAME'] = getenv('PWD').DIRECTORY_SEPARATOR.$urlParts['path'].DIRECTORY_SEPARATOR.'index.php';
}
$this->app->instance('request', Request::create($url, 'GET', [], [], [], $_SERVER));
}
and to the constructor i added $this->prepareConsoleUrl();, but if you don't have the constructor there already, you can do it like this:
public function __construct(Application $app)
{
parent::__construct($app);
$this->prepareConsoleUrl();
}
I fetched the code from this commit: https://github.com/j3j5/framework/commit/920f023e1bd11de1a6a2a0e923a0cce7481110d9
That should do it until a real solution is added to lumen
I have the same problem and it's still not fixed.
We're open to PRs to fix it.
Up. The issue still exists.
Still exists
Still getting this problem anywhere outside of immediate routes..
For some reason the Symfony base request class isn't constructed/configured the same way it is with Laravel. In Laravel, it uses the 'HOST' header to determine the host for the root URL. All of the headers seem to be empty in Lumen while the URLGenerator is interacting with it...
If you try dd'ing inside here you'll notice the following:
// Line: 1258 in vendor/symfony/http-foundation/Request.php
public function getHost()
{
// Laravel: 'foo.bar'
// Lumen: ''
dd($this->headers->get('HOST'));
}
I'll keep digging...
@matthewerskine @lasselehtinen
Here resolved the problem
https://laravel-news.com/using-named-routes-lumen-test
@solofeed this is ugly solution, and didnt work with custom headers
is there any way to route() helper return url with path and port without disturbing request and headers
@urukalo It is not my solution)
If you have better solution, tell us please)
For me, the previous solution did not work.
So I had to write temporary overhead
// TODO: Remove after fix https://github.com/laravel/lumen-framework/issues/513
$uri = str_replace('http://:', 'http://localhost', $uri);
@solofeed
i have similar temp fix
in TestCase i override call method with:
public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
{
$uri = str_replace('http://:', '', $uri);
parent::call($method, $uri, $parameters, $cookies, $files, $server, $content);
}
now waiting for fix .. anyone have idea how to resolve this problem?
This should work (do not forget to provide a proper APP_URL in .env config):
// Assuming $app is an instance of \Laravel\Lumen\Application
$app->make('url')->forceRootUrl(env('APP_URL', 'http://localhost/'));
Or you can enable the AppServiceProvider and put into register method to force the root url only in certain evironment.
In testing environment it might be better to edit the createApplication method in tests/TestCase.php like this:
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make('url')->forceRootUrl(env('APP_URL', 'http://localhost/'));
return $app;
}
In the same way, to fix the issue in console you can place the same code in the constructor of the Console Kernel as shown below:
public function __construct(\Laravel\Lumen\Application $app)
{
parent::__construct($app);
$this->app->make('url')->forceRootUrl(env('APP_URL', 'http://localhost/'));
}
@dvdmarchetti @lasselehtinen I think I found the issue and submitted the fix (#739). Can you guys test it please? Does it fix your problem?
Does not fix the problem
@solofeed @urukalo Have you tried my solution as well?
@dvdmarchetti Yes, your solution works well) thanks
Going to re-open this because it still seems to be a problem.
there is also: https://github.com/vluzrmos/lumen-url-host
@driesvints I鈥檓 currently unable to test, but isn鈥檛 this issue related to PR #805? In that case it might already be fixed.
@JacksonIV I was still able to reproduce this. I think the problem is that it happens when running phpunit.
@driesvints The route helper works in regular commands and queues in my tests. However, it doesn't work in Phpunit because the kernel is never bootstrapped when running tests. If you call this:
app('Illuminate\Contracts\Console\Kernel');
right before you call the route helper in your test, it'll work.
I'm not sure how you'd want to see this fixed, because it can be done in multiple ways. The kernel has to be bootstrapped somewhere within the instantiation of the tests.
Yeah, just like here: https://github.com/laravel/lumen/blob/master/bootstrap/app.php#L46-L49
We'll need a base test class which bootstraps the app with this binding before it'll properly work. This is probably something for a new major release. I'll ask some input from @taylorotwell on this.
@driesvints I took a closer look at this and it seems Lumen will already boot when running tests. However, since the application will boot through the console, it won't have a base url. This issue was fixed in the console kernel for regular commands.
When you run tests in Lumen it will not try to boot Lumen as a console application but as a regular application instead, that's why the fix doesn't work.
I've made a PR where i set the root url of the url generator to the APP_KEY environment value when Lumen boots in the testing environment.
Sweet. Thanks man!
This problem still exists! anyone going to fix it?
This problem still happens
Most helpful comment
As a temporary solution to this problem, i added this to my console kernel file:
and to the constructor i added
$this->prepareConsoleUrl();, but if you don't have the constructor there already, you can do it like this:I fetched the code from this commit: https://github.com/j3j5/framework/commit/920f023e1bd11de1a6a2a0e923a0cce7481110d9
That should do it until a real solution is added to lumen