There is an issue on Yii2 to redirecting / urls to /frontend/web.
In other words we need a way to hidden /frontend/web from addresses.
We will do this without changing Apache configuration and creating virtual host or setting document root (It's good for share hostings that we have not access to apache.conf)
Let's do it:
1- Create .htaccess file on the root directory with this content
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ frontend/web/$1 [L]
</IfModule>
# Deny accessing below extensions
<Files ~ "(.json|.lock|.git)">
Order allow,deny
Deny from all
</Files>
# Deny accessing dot files
RewriteRule (^\.|/\.) - [F]
2- Create .htaccess file in frontend/web with the below contents
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
3- Now, we should play a little with frontend config of framework
You must open the frontend/config/main.php file and set $baseUrl for \yii\web\Request and \yii\web\urlManager.
$baseUrl is the url your application point to. if you host your application in the root directory of www you may set the $baseUrl to '/'
For another example if you are developing a blog system and your application hosted in www/blog you must set the baseUrl to '/blog'
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);
return [
'id' => 'app-frontend',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'frontend\controllers',
'components' => [
'request' => [
'baseUrl' => '/',
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'urlManager' => [
'baseUrl' => '/',
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => []
]
],
'params' => $params,
];
Soft Way ¶
If you not sure where your application will host, you must do it in pragmatically way. for this purpose we change the config file as below
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);
use \yii\web\Request;
$baseUrl = str_replace('/frontend/web', '', (new Request)->getBaseUrl());
return [
'id' => 'app-frontend',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'frontend\controllers',
'components' => [
'request' => [
'baseUrl' => $baseUrl,
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'urlManager' => [
'baseUrl' => $baseUrl,
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => []
]
],
'params' => $params,
];
As you see above we use \yii\web\Request to find $baseUrl of application. but because the returned $baseUrl contains /frontend/web we remove it
use \yii\web\Request;
$baseUrl = str_replace('/frontend/web', '', (new Request)->getBaseUrl());
enjoy !
And for backend?
I'm going to hide frontend/www and change backend/www to something else, eg. http://domain.com/admin<br>
Your solution is fine to hide frontend/www.
Just let me know what did you do for backend?
Thank you
I was really looking exactly for this. Best solution (in my case) I've seen so far.
Thank you :)
Create VirtualHost
is it not better to create its virtual host , instead of all this code ?
Reply To: Create VirtualHost
If you have access to Apahce configurations, it's better to use Virtual Host instead my solution. but if you are working on shared hostings, or assume that the end user of your application host your application on shared hostings, its better for you to use the demonstrated solution.
Reply To: And for backend?
hiding /backend/web/index.php is same as the frontend.
but you could play with root .htaccess file and add new rules and condition to .htaccess file
Anymore I think redirecting /backend/web is less important than /frontend and not include this section in my article.
Thanks for sharing
It's a nice article.... thanks for the sharing this :)..
vendor, common, etc folders
As I understand, with this method you should also keep in mind, that vendor/, common/ and other folders are at root level, that means it would be possible to open let's say http://your.domain/vendor/bin/yii file. Probably should put a lot of restrictions in .htaccess file.
EDIT: I'm sorry, i was wrong. jtag05 is right.
Re: vendor, common, etc folders
I'm pretty sure that the following prevents all requests that aren't directed at the public directory to be routed to /frontend/web/
RewriteCond %{REQUEST_URI} !^public RewriteRule ^(.*)$ frontend/web/$1 [L]
Images folder at root
This works great. Thanks for this article.
But images won't display if the "Images" folder is located at webroot in order to be shared by both Frontend and Backend.
Thanks, but I've this problem
At the end someone explaing us exactly how to make usable shared hosting and pretty url at same time !!!!
you're my hero !
COMMENT EDITED: no problem with debug toolbar
Re: Thanks, but I've this problem
I didn't see any problem with Debug toolbar and I need more info to solve your problem
Thank You!
Could you extend this tutorial to enable /something to point to backend?
In this situation, we've also backend/web to use.
Can you please extend this example to be abale to use domain.tld/something to open /backend/www/index.php ?
Thank you in advance
Page not found error while getting backend
i implement this code on my localhost. it works fine on frontend, no problem in debug toolbar as well, my project name is yii2test but when i go to
it shows page not found error
Please help
common folder library reference error AppAsset.php
i got an error accessing libraries in the common folder
so i had to put the lib folder in frontend and backend..
cool solution
Clean the URL up after redirecting on shared host.
Thanks!
The soft version was the simplest solution after redirecting using .htaccess.
It's nice not to have to move directories and file around.
I think a similar article show be written to achieve it on Nginx.
after create new htaccess in route directory problme resolve but. i am not able to access backend/web please kindaly help me
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.