yii2 urlManager enablePrettyUrl not working - .htaccess

In Yii2, I cannot enable pretty url's.
My config:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
],
My .htaccess:
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
My script:
echo 'enablePrettyUrl: ';
echo Yii::$app->urlManager->enablePrettyUrl ? 'true ' : 'false';
echo '<br>';
echo 'enableStrictParsing: ';
echo Yii::$app->urlManager->enableStrictParsing ? 'true ' : 'false';
echo '<br>';
echo 'showScriptName: ';
echo Yii::$app->urlManager->showScriptName ? 'true ' : 'false';
echo Url::to(['/book/read', 't' => 'booktitle', 'c'=>'chaptertitle']);
The output from the script:
enablePrettyUrl: true
enableStrictParsing: false
showScriptName: false
/book/read?t=booktitle&c=chaptertitle
Clearly, I am not getting pretty Url's. Why not?
We know enablePrettyUrl=== true
I do not believe there is anything wrong with my .htaccess

You are getting pretty URLs. This is a pretty url
/book/read?t=booktitle&c=chaptertitle
An ugly URL is
index.php?r=book/read&t=booktitle&c=chaptertitle
So everything works as expected in yii2. Now you may want to make them prettier still, in this case you can add to your rule section something like
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'book/read/<t>/<c>' => 'book/read',
]
This would generate a link that will look like
book/read/booktitle/chaptertitle
Change it to suit your needs. No need to change anything in the controller, it will still receive the t and c parameters.

you are already getting pretty URL
/book/read?t=booktitle&c=chaptertitle
is a pretty url. you can also hit it like this
/book/read/t/booktitle/c/chaptertitle
if you want in browser it will result in same, if you are confusing yourself with ? in URL.

Related

.htaccess Pretty URL with languages

I have a php website, loading the pages as below.
if ( $secretfile && file_exists( $moddir . $name . "/" . $secretfile . ".php" ) ) {
include_once( $moddir . $name . "/" . $secretfile . ".php" );
} else {
if ( isset( $_GET[ 'mod' ] ) ? $_GET[ 'mod' ] : '' ) {
$secretmodule = isset( $_GET[ 'mod' ] ) ? $_GET[ 'mod' ] : '';
if ( $secretmodule && file_exists( $moddir . $name . "/page.php" ) ) {
include_once( $moddir . $name . "/page.php" );
} else {
include_once( $moddir . "404.php" );
}
} else {
include_once( $moddir . "homepage.php" );
}
}
I am using htaccess to beautify the url as below.
RewriteRule ^([^/]*)/$ /index.php?mod=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/$ /index.php?mod=$1&file=$2 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/$ /index.php?mod=$1&file=$2&proid=$3 [L]
I want to add languages in session but i dont want to change the url of the main language (already indexed). only the other languages will be added an extra variable.
eg:
main language(de) : www.site.com/module/file/ /index.php?mod=$1&file=$2 [L]
other lang (en) : www.site.com/en/module/file/ /index.php?lang=$1mod=$2&file=$3 [L]
other lang (fr) : www.site.com/fr/module/file/ /index.php?lang=$1mod=$2&file=$3 [L]
I am just not sure how to setup the htaccess for these configurations.
You can have these set of rules in .htaccess:
RewriteEngine On
# ignore all files are directories from rules below
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# rules with any lang component
RewriteRule ^(en|fr)/([^/]*)/$ index.php?lang=$1&mod=$2 [L,QSA]
RewriteRule ^(en|fr)/([^/]*)/([^/]*)/$ index.php?lang=$1&mod=$2&file=$3 [L,QSA]
RewriteRule ^(en|fr)/([^/]*)/([^/]*)/([^/]*)/$ index.php?lang=$1&mod=$2&file=$3&proid=$4 [L,QSA]
# rules without any lang component
RewriteRule ^([^/]*)/$ index.php?lang=de&mod=$1 [L,QSA]
RewriteRule ^([^/]*)/([^/]*)/$ index.php?lang=de&mod=$1&file=$2 [L,QSA]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/$ index.php?lang=de&mod=$1&file=$2&proid=$3 [L,QSA]
With your shown attempts, please try following. Make sure your index.php file and htaccess both files are present in same folder(root) in your case.
Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##Rules for en OR fr languages URLs to be rewritten in backend.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(en|fr)/([^/]*)/([^/]*)/?$ /index.php?lang=$1mod=$2&file=$3 [QSA,NC,L]
##Rules for links which are not started with en OR fr links.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)/?$ /index.php?lang=$1mod=$2&file=$3 [QSA,NC,L]

CakePHP Images in webroot not displaying in Production

I have pushed my website to Production yesterday, all is working fine with the 3 .htaccess files I created. The only issue is that the images from my webroot folder are not displayed.
I am calling them with $this->Url->image('pages/' . $page->image)
Link rendered in html :
background-image:url(/app/img/pages/home.jpg);
'App' => [
'namespace' => 'App',
'encoding' => env('APP_ENCODING', 'UTF-8'),
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'fr_FR'),
'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'Europe/Brussels'),
'base' => false,
'dir' => 'src',
'webroot' => 'webroot',
'wwwRoot' => WWW_ROOT,
//'baseUrl' => env('SCRIPT_NAME'),
'fullBaseUrl' => false,
'imageBaseUrl' => 'img/',
'cssBaseUrl' => 'css/',
'jsBaseUrl' => 'js/',
'paths' => [
'plugins' => [ROOT . DS . 'plugins' . DS],
'templates' => [ROOT . DS . 'templates' . DS],
'locales' => [RESOURCES . 'locales' . DS],
],
],
/var/htdocs/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
/app/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>
/app/webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Thank you.
Here is my error Log
2021-10-21 13:18:34 Error: [Cake\Http\Exception\MissingControllerException] Controller class Img could not be found. in /homepages/20/d887310999/htdocs/app/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php on line 226
Stack Trace:
/homepages/20/d887310999/htdocs/app/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php:65
/homepages/20/d887310999/htdocs/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php:311
Request URL: /img/pages/home.jpg

How to configure the .htaccess file for ErrorDocument working?

Good day! I'm doing the website on PHP. It will be a static site with limited count of pages. These pages have idential styles and scripts, so I wrote the viewpage.php script, which get the page name by URL and show it by PHP instruction include if such page is setted or put error 404 otherwise.
It is a structure of my website files:
admin/
auth.php
exit.php
index.php
pages/
index.php
contacts.php
...
err/
err404.php
.htaccess
viewpage.php
and part of viewpage.php
$pages = [
"index/" => [
"page" => "index.php"
],
"contacts/" => [
"page" => "contacts.php"
],
];
...
$requestPage = $_GET[ "page" ] . "/";
if ( !array_key_exists( $requestPage, $pages ) ) {
http_response_code( 404 );
include "pages/err/err404.php";
exit();
}
...
include "pages/$pageFile"; ?>
I want to allow the direct access to site/admin/[index|auth|exit].php and get such redirections:
site/admin/ => site/admin/index.php
site/ => site/viewpage.php?page=index
site/contacts => site/viewpage.php?page=contacts
site/contacts/ => site/viewpage.php?page=contacts
otherwise => site/pages/err/err404.php
I have tried this variant of .htaccess:
ErrorDocument 404 /pages/err/err404.php
RewriteEngine On
RewriteRule ^admin$ admin/index.php [L]
RewriteRule ^admin/$ admin/index.php [L]
RewriteRule ^([a-z\-]+)$ viewpage.php?page=$1 [L]
RewriteRule ^([a-z\-]+)/$ viewpage.php?page=$1 [L]
but I have problems: I can't open main page by site/, only by site/index/
How me to configure the .htaccess file?

how to create htacess to rewrite the route in yii2

I use yii2 to develop a website, and I use the Virtual host.
The question is in yii2 the source code is put in the web folder, and I have to visit the website like this "http://www.mydoname.com/web/index.php", if I want to visit like "http://www.mydoname.com/index.php" ,how to create the .htaccess in the root, what should I write?
Lets try this:
1- Create .htaccess file on the root directory(yii2-app) with this content
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} /(uploads)
RewriteRule ^uploads/(.*)$ uploads/$1 [L]
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, open the frontend/config/main.php file and set $baseUrl for \yii\web\Request and \yii\web\urlManager.
<?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,
];
Visit: localhost/yii2-app/
Original reference

How to access a controller with pretty url in Yii2 [duplicate]

Simple question. I use Yii2 advanced template. In apache I have DocumentRoot "{$path}/www/yii-application1/frontend/web". How can I access /www/yii-application1/uploads in order to show image to user?
Following code does not work:
<?php echo Html::img('../../uploads/ring.jpg') ?>
It works with DocumentRoot "{$path}/www/yii-application1/". But in this case an index page of website looks like domain.com/frontend/web. But I need just domain.com.
Step : 1
First create .htaccess file in here yii-application1/.htaccess
Options +FollowSymlinks
RewriteEngine On
# deal with backend first
RewriteCond %{REQUEST_URI} /(backend)
RewriteRule ^backend/assets/(.*)$ backend/web/assets/$1 [L]
RewriteRule ^backend/css/(.*)$ backend/web/css/$1 [L]
RewriteRule ^backend/image/(.*)$ backend/web/image/$1 [L]
RewriteCond %{REQUEST_URI} !/backend/web/(assets|css|image)/
RewriteCond %{REQUEST_URI} /(backend)
RewriteRule ^.*$ backend/web/index.php [L]
RewriteCond %{REQUEST_URI} /(assets|css|js|img|font)
RewriteRule ^assets/(.*)$ frontend/web/assets/$1 [L]
RewriteRule ^css/(.*)$ frontend/web/css/$1 [L]
RewriteRule ^js/(.*)$ frontend/web/js/$1 [L]
RewriteRule ^image/(.*)$ frontend/web/image/$1 [L]
RewriteCond %{REQUEST_URI} !/(frontend|backend)/web/(assets|css|js|image|font)/
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ frontend/web/index.php
Step : 2
Now create a components/Request.php file in common directory and write below code in this file.
Request.php file
<?php
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;
}
public function resolvePathInfo(){
if($this->getUrl() === $this->adminUrl){
return "";
}else{
return parent::resolvePathInfo();
}
}
}
?>
Step : 3
Now Installing component. Write below code in frontend/config/main.php and backend/config/main.php files respectively.
//Frontend
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => [
'name' => '_frontendUser', // unique for frontend
]
],
'session' => [
'name' => 'PHPFRONTSESSID',
'savePath' => sys_get_temp_dir(),
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<alias:>' => 'site/<alias>',
],
],
'request'=>[
'cookieValidationKey' => '[gfhjghsdjks44fdf4fgf4fgfg5645ggxcvvc]',
'csrfParam' => '_frontendCSRF',
'class' => 'common\components\Request',
'web'=> '/frontend/web'
],
]
//Backend
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => false,
'identityCookie' => [
'name' => '_backendUser', // unique for backend
]
],
'session' => [
'name' => 'PHPBACKSESSID',
'savePath' => sys_get_temp_dir(),
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
'request'=>[
'cookieValidationKey' => '[ruiqwybnddiogj786789hzcassdas9dasdjufi]',
'csrfParam' => '_backendCSRF',
'class' => 'common\components\Request',
'web'=> '/backend/web',
'adminUrl' => '/backend'
],
]
Your domain.com/frontend/web problem solved to follow the above steps.
and you can access the index page for domain.com/frontend/web using domain.com.
Now You can access you image using
<?php echo Html::img('uploads/ring.jpg') ?>
Also you can access the domain.com/frontend/web/image using below code
<?= Html::img(Yii::getAlias('#web').'/image/xyz.png', ['class' => 'retina']); ?>
also you get webroot path using this Yii::getAlias('#webroot')
You can also use alise inside config array on web.php file of config folder like
'aliases' => [
'#uploads' => '#app/web/upload',
],
and use it in any where you want like
<?= Html::img("#uploads/image/xyz.png", ['class' => 'retina']); ?>

Resources