Apache mod_rewrite URL - apache

Hi I need some help with mod_rewrite.
I would like to change this kind of URL
127.0.0.1/app/controller/<anyName1>/<anyName2>.php?firstParam=1&secondParam=text&...&nParam=nSomething
to 127.0.0.1/anyName1/anyName2/1/text/.../nSomething
Could you give me any example how to do that?

You can save yourself a lot of stress by not trying to modify anything beyond /<anyName1>/<anyName2>/ with mod_rewrite. Dynamically mapping path components to query variables requires some very funky recursive voodoo magic.
Instead grab only /<anyName1>/<anyName2>/, append the rest of the path to the redirect, and then use PHP to parse the path:
.htaccess
RewriteCond %{REQUEST_URI} !^/app/controller/[^/]+/[^/]+\.php
RewriteRule ^([^/]+)/([^/]+)/?(.*)$ /app/controller/$1/$2.php/$3 [L]
PHP
$components = array_filter(explode('/', $_SERVER['PATH_INFO']), 'strlen');
echo '<pre>';
print_r($components);
echo '</pre>';
Output:
Array
(
[1] => 1
[2] => text
[3] => ...
[4] => nSomething
)

Related

GET query string parameters from .htaccess rewrite URL in PHP

In my website, I am trying to rewrite few of my URLs as bellow:
This URL
http://example.com/news.php?newstype=newsletter&newsid=1123&newstitle=my news title
int to:
http://example.com/newsletter/1123/my news title
My rewrite rule in .htaccess looks like as shown below:
RewriteEngine On
Options +FollowSymlinks
RewriteBase /
RewriteRule ^(.*)/(.*)/(.*)/?$ news.php?newstype=$1&newsid=$2&newstitle=$3 [L,QSA,NC,B]
My <a> tag is looks this:
$seoUrl = "$urlNewsType/$newsid/$urlNewsTitle/";
$seoUrl = urldecode($seoUrl);
$seoUrl = html_escape($seoUrl, 'UTF-8');
Read More
These every things are working for me. But my question is, I need to get these query string parameters separately from URL into PHP. Problem is I can't get these prameters as I do usually.
In php, This is the output of:
echo '<pre>',print_r($_GET).'</pre>';
Array
(
[newstype] => news/1114
[newsid] => Presentation: Heath+Day+in+2018
[newstitle] =>
)
Can anybody tell me, what is the wrong which I have done in this regard?
The regex pattern (.*) is greedy. It matches the full requested path. Try ([^/]+) instead :
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ news.php?newstype=$1&newsid=$2&newstitle=$3 [L,QSA,NC,B]

.htaccess rewrite rules behaving in a wrong way

I'm building an events website, in all my websites i do the following logic:
RewriteEngine On
Options +FollowSymLinks
RewriteBase /
RewriteRule ^new/event?(/)?$ controller.php?page_name=new-event [QSA,L]
RewriteRule ^get-event/([^/]+)?(/)?$ controller.php?page_name=get-event&event_id=$1 [QSA,L]
RewriteRule ^event/([^/]+)/([^/]+)?(/)?$ controller.php?page_name=event&event_id=$1 [QSA,L]
RewriteRule ^event-edit/([^/]+)?(/)?$ controller.php?page_name=event-edit&event_id=$1 [QSA,L]
// this below line to handle all links that do not apply to the above rules, is this wrong?
RewriteRule ^([^/]+)?(/)?$ controller.php?page_name=$1 [QSA,L]
The last line is to handle all URLs that don't have anything other than the page name, like those:
www.example.com/event-submit/
www.example.com/about/
www.example.com/contact/
Because I made a controller.php file that handles all the requests depending on the page_name value.
But this is not working with this new site, here's what i get:
when I request any URL belonging to this site, the browser just hangs and takes forever, sometimes the page loads but after like 5 minutes.
I have no idea why! (It works on all my other websites!)
Am I doing anything wrong? I have searched a lot and nothing is working.
EDIT
This is controller.php: (it just checks for page_name if it's allowed and then includes it)
<?php
session_start();
define('__SITE_ROOT__', dirname(__FILE__));
define('__HELPERS__', __SITE_ROOT__ . '/' . 'helpers');
define('__APP__', __SITE_ROOT__ . '/' . 'app');
$page_name = strip_tags($_GET['page_name']);
$allowed_pages = array(
'index',
'about',
'contact',
'new-event',
'event-edit',
'get-event',,
'404'
);
class Controller{
public $page_name = 'index';
public $allowed_names = array();
}
$controller = new Controller();
$controller->allowed_names = $allowed_pages;
$controller->page_name = $page_name;
if(in_array($controller->page_name, $controller->allowed_names))
{
$page_real_name = $controller->page_name . ".php";
}else{
$page_real_name = "404.php";
}
include(__APP__ . '/' . $page_real_name);
// this below line to handle all links that do not apply to the above rules, is this wrong?
RewriteRule ^([^/]+)?(/)?$ controller.php?page_name=$1 [QSA,L]
This rule would create a rewrite-loop (500 error), since the regex ^([^/]+)?(/)?$ would also match controller.php (the URL being written to) and you don't appear to have anything that would otherwise prevent this?
You could resolve this my adding a dot to the character class, so it won't match the dot in .php. For example:
RewriteRule ^([^/.]+)?/?$ controller.php?page_name=$1 [QSA,L]
You don't need to surround the last / in parentheses.
(I'm assuming the // comment is just in your question, since that is syntactically invalid. Comments are delimited with #.)
the browser just hangs and takes forever, sometimes the page loads but after like 5 minutes.
However, the above doesn't quite explain this behaviour, unless maybe LimitInternalRecursion is set very high in your server config?! (Default is 10)

Routing with regex in CakePHP#

I'm looking for help on setting up routes in CakePHP3.4.6 where
urls are variable. For instance, I want the following urls:
/California/Posts/view/Skateboard/Jan2nd/10
/Texas/Posts/view/Truck/Feb10th/35
to connect to
/Posts/view/10
/Posts/view/35
respectively. When doing so, I need the URLs preserved in the browser.
(i.e. browser URL shows /California/Posts/view/Skateboard/Jan2nd/10 while content is served for /Posts/view/10)
Can this be done through configuring routes.php?
Any advice will be most appreciated.
I tried using rewrite rules in webroot/.htaccess such as:
RewriteRule ^[^/]+/Posts/view/[^/]+/[^/]+/(\d+)$ /Posts/view/$1 [L]
But this just ends up in 404 errors. The pattern match seems to be correct as the following rule works:
RewriteRule ^[^/]+/Posts/view/[^/]+/[^/]+/(\d+)$ http://www.google.com [L]
Thanks,
Managed to figure this out.
$routes->connect('/:state/Posts/view/:title/:date/:id',
['controller' => 'Posts', 'action' => 'view'],
['id' => '\d+', 'pass' => ['id']]
Did the job

.htaccess rewrite url - convert from nice URL back to GET parameter

How can I rewrite url from this:
https://www.domain.com/blog/category/sub-category-name
to this:
https://www.domain.com/blog/category/?category=sub-category-name
also it must work with others parameters like:
https://www.domain.com/blog/category/sub-category-name?param=value => https://www.domain.com/blog/category/?category=sub-category-name&param=value
or
https://www.domain.com/blog/category/sub-category-name#hash => https://www.domain.com/blog/category/?category=sub-category-name#hash
I don't understand this rewrite syntax so any advice is valuable.
Thanks
You can use this rule :
RewriteEngine on
RewriteRule ^blog/([^/]+)/([^/]+)/?$ /blog/$1/?$1=$2 [QSA,NC,L]
Additional Query perameters are automatically appended to the target path by QSA flag.

htaccess and multilanguage URL

I am trying to translate my URL, depending on the language selected by the user, e.g.:
www.example.com/en/discover or
www.example.com/fr/decouvrir
Obviously I want the two URL to point to the same page (where PHP handles the translation with a dictionary). I was wondering if there was a smart way in the htaccess file to do this "automatically" without having the write the rule for all the pages? For the moment I would do
RewriteRule ^en/discover$ discover.php?lang=en [NC,L]
RewriteRule ^fr/decouvrir$ discover.php?lang=fr [NC,L]
but this solution is not really the easiest if there are a lot of pages and if I want to add another language.
Thanks a lot for your help
You should pass all arguments to single php file (dispatcher), whitch would translate route and then include needed file. Something like:
.htaccess
RewriteRule ^(.*)/(.*)$ index.php?lang=$1&include=$2 [NC,L]
PHP
// This is really bad code, just an example
$dictionary = array(
'en' => array(
'discover' => 'discover'
),
'fr' => array(
'decouvrir' => 'discover'
)
);
echo $dictionary[$_GET['lang']][$_GET['include']];