Yii2 htaccess - How to hide frontend/web and backend/web COMPLETELY
Like @deacs said just move the files from frontend/web to yii2app (root folder) and create a folder in yii2app "admin" and move files from backend/web to yii2app/admin and then create .htaccess files in both admin and yii2app with following code :
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
Then add/modify the urlManager component in config file main.php in both frontend/config/main.php and backend/config/main.php with following code :
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
],
],
Then change the index.php in yii2app with following code :
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/vendor/autoload.php');
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/common/config/bootstrap.php');
require(__DIR__ . '/frontend/config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/common/config/main.php'),
require(__DIR__ . '/common/config/main-local.php'),
require(__DIR__ . '/frontend/config/main.php'),
require(__DIR__ . '/frontend/config/main-local.php')
);
$application = new yii\web\Application($config);
$application->run();
Also change the index.php in yii2app/admin with following code :
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../common/config/bootstrap.php');
require(__DIR__ . '/../backend/config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../common/config/main.php'),
require(__DIR__ . '/../common/config/main-local.php'),
require(__DIR__ . '/../backend/config/main.php'),
require(__DIR__ . '/../backend/config/main-local.php')
);
$application = new yii\web\Application($config);
$application->run();
Thats all you need to complete the SEO friendly URLs in yii2. I was struggling myself and then I got help from @deacs answer and I though maybe this will help someone.
If your only goal is to achieve not ever seeing /frontend/web
or /backend/web
, even without using .htaccess rules, you could go for the following:
Why not just pull out the contents of the web
folders and place them in the root? Just adjust the path referring to the framework and config files in the entry scripts index.php
.
Your dir structure would look like:
- yii2app/
- frontend/
- backend/
- common/
- .. other folders..
- admin/
- assets/
- css/
- index.php
- assets/
- css/
- index.php
Your yii2app/index.php
would then look like:
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/vendor/autoload.php');
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/common/config/bootstrap.php');
require(__DIR__ . '/frontend/config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/common/config/main.php'),
require(__DIR__ . '/common/config/main-local.php'),
require(__DIR__ . '/frontend/config/main.php'),
require(__DIR__ . '/frontend/config/main-local.php')
);
$application = new yii\web\Application($config);
$application->run();
and your yii2app/admin/index.php
would look like:
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../common/config/bootstrap.php');
require(__DIR__ . '/../backend/config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../common/config/main.php'),
require(__DIR__ . '/../common/config/main-local.php'),
require(__DIR__ . '/../backend/config/main.php'),
require(__DIR__ . '/../backend/config/main-local.php')
);
$application = new yii\web\Application($config);
$application->run();
EDIT: your entry scripts could look different to mine, but you should get the idea of changing the paths to find the framework files with these examples.
Try this with .htaccess Method-
Step 1
Create .htaccess file in root folder, i.e advanced/.htaccess
and write below code.
Options +FollowSymlinks
RewriteEngine On
# deal with admin first
RewriteCond %{REQUEST_URI} ^/(admin) <------
RewriteRule ^admin/assets/(.*)$ backend/web/assets/$1 [L]
RewriteRule ^admin/css/(.*)$ backend/web/css/$1 [L]
RewriteCond %{REQUEST_URI} !^/backend/web/(assets|css)/ <------
RewriteCond %{REQUEST_URI} ^/(admin) <------
RewriteRule ^.*$ backend/web/index.php [L]
RewriteCond %{REQUEST_URI} ^/(assets|css) <------
RewriteRule ^assets/(.*)$ frontend/web/assets/$1 [L]
RewriteRule ^css/(.*)$ frontend/web/css/$1 [L]
RewriteRule ^js/(.*)$ frontend/web/js/$1 [L]
RewriteRule ^images/(.*)$ frontend/web/images/$1 [L]
RewriteCond %{REQUEST_URI} !^/(frontend|backend)/web/(assets|css)/ <------
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ frontend/web/index.php
Note : if you are trying in local server then replace ^/
with ^/project_name/
where you see arrow sign. Remove those arrow sign <------
after setup is done.
Step 2
Now create a components/Request.php
file in common directory and write below code in this file.
namespace common\components;
class Request extends \yii\web\Request {
public $web;
public $adminUrl;
public function getBaseUrl(){
return str_replace($this->web, "", parent::getBaseUrl()) . $this->adminUrl;
}
/*
If you don't have this function, the admin site will 404 if you leave off
the trailing slash.
E.g.:
Wouldn't work:
site.com/admin
Would work:
site.com/admin/
Using this function, both will work.
*/
public function resolvePathInfo(){
if($this->getUrl() === $this->adminUrl){
return "";
}else{
return parent::resolvePathInfo();
}
}
}
Step 3
Installing component. Write below code in frontend/config/main.php
and backend/config/main.php
files respectively.
//frontend, under components array
'request'=>[
'class' => 'common\components\Request',
'web'=> '/frontend/web'
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
],
// backend, under components array
'request'=>[
'class' => 'common\components\Request',
'web'=> '/backend/web',
'adminUrl' => '/admin'
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
],
Step 4 (Optional, if doesn't work till step three)
create .htaccess file in web directory
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
Note: make sure you have enabled your mod rewrite in apache
Thats it! You can try your project with www.project.com/admin
, www.project.com
in local serverlocalhost/project_name/admin
, localhost/project_name