URL rewriting in PHP without htaccess - php

Website is running on a web host where we don't have access to a .htaccess file. However, I want to do URL rewriting for user friendly URLs.
e.g. Original URL
www.example.com/file?q=name
expected URL
www.example.com/file/name

As other people said, just use links like /index.php/nice/looking/url.
The "index.php" in the middle of the URL might look a little strange, but I don't think it's possible to have it look better without .htaccess
Else, you could ask your hoster to redirect any URL to /index.php so that you can handle URL rewriting without having /index.php in your URL.
Then you can just use a regex match to detect what file to include.
preg_match('#[/]{1}([a-zA-Z0-9]+)#', $_SERVER["PATH_INFO"], $matches) ($matches will contain all "parts" of the url in an array)
Be careful with including the files, use a whitelist so you're sure nobody would be able to load internal files.

as Alix Axel suggested you can use
www.example.com/index.php/file/name
then you will use $_SERVER['REQUEST_URI'] to process the URL.

Your best bet will be to have URLs such as this:
www.example.com/index.php/file/name
You'll to rewrite your PHP code though.

If you have an Apache server and AcceptPathInfo is enabled, then you can use the URL you wrote. A request of /file/name will then be automatically rewritten to /file with the PATH_INFO value of /name if /file is a regular file.

This is possible solely using language/content negotiation in the Apache configuration (httpd.conf or apache2.conf) along with rewrite rules. Use of an .htaccess file is not required.
In apache2.conf file (or httpd.conf) add the Multiviews directive, MultiviewsMatch directive, and rewrite rules:
<Directory /var/www/html>
Options Indexes FollowSymLinks Multiviews
AllowOverride None
Require all granted
RewriteEngine On
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
<Files "*.php">
MultiviewsMatch Any
</Files>
</Directory>
Then save the file and restart Apache sudo systemctl restart apache2
If you specify the Options directive later in httpd.conf, you have to repeat the Multiviews directive for each site:
<Directory /var/www/html/chocolate.com/>
Options FollowSymLinks Multiviews
AllowOverride All
Require all granted
</Directory>
<Directory /var/www/html/vanilla.com/>
Options FollowSymLinks Multiviews
AllowOverride All
Require all granted
</Directory>
This will not adversely affect content negotiation if you are already serving in multiple languages. For example, replacing example.com/home.php with
home.en.php
home.fr.php
home.de.php
Then in apache2.conf:
AddLanguage fr .fr
AddLanguage de .de
AddLanguage en .en
LanguagePriority fr de en
ForceLanguagePriority Fallback
Your language will still be negotiated but the php extension will not appear in the URL.

or can create a routing switch in the index.php file:
$request = $_SERVER['REQUEST_URI'];
switch ($request) {
case '/file' :
require __DIR__ . '/file';
break;
case '' :
require __DIR__ . '/file';
break;
case '/file/name' :
require __DIR__ . '/file?q=name';
break;
default:
http_response_code(404);
require __DIR__ . '/404.php';
break;
}

Try this
www.example.com/file?q=name
to
www.example.com/name (better than www.example.com/file/name)
Open your .htaccess from your project root folder and add this code
Options +FollowSymLinks
RewriteEngine On
RewriteRule \.(js|css|jpe?g|png|gif)$ - [L]
RewriteRule "^([ \w-]+)/?$" /file?q=$1 [L,QSA]
This solves your problem. See the post how to rewrite URL in .htaccess

Related

why a rewrite_rule works only when the folder exist?

The objective is to input an url like
https://www.mywebsite/expert/188/name-of-the-expert
and return it to the server in the form
expert.php?exp=188
Like if the user typed in https://www.mywebsite/expert.php?exp=188
WHAT DOES NOT WORK:
simple rules like RewriteRule ^expert-([0-9]*)$ expert.php?exp=$1 [L,NC,QSA]
WHAT WORK
I have the following rewrite_rule that works only when I physically create the folder expert/ in my tree, i.e. /www/expert/
# FRIENDLY URL FOR EXPERTS PROFILE
Rewriterule ^(.*)expert\/([0-9]*)(\/[a-z0-9\-\']*)?\/?$ expert.php?exp=$2 [L,NC,QSA]
Also, for this rule to work, I had to put the <base href="/"> in the page expert.php to avoid errors with all my linked resources:
Failed to load resource: the server responded with a status of 404 ()
The server is APACHE on a shared web hosting platform named OVH.
The full code of the issue:
<IfModule mod_rewrite.c>
RewriteEngine On
Options +FollowSymlinks
RewriteBase /
# FRIENDLY URL FOR EXPERTS PROFILE
Rewriterule ^(.*)expert\/([0-9]*)(\/[a-z0-9\-\']*)?\/?$ expert.php?exp=$2 [L,NC,QSA]
</IfModule>
Have it like this with MultiViews turned off:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
# FRIENDLY URL FOR EXPERTS PROFILE
Rewriterule ^/?expert/(\d+)/?$ expert.php?exp=$1 [L,NC,QSA]
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.
I changed from using rewrite rules to using Apaches FallbackResource after reading https://www.adayinthelifeof.nl/2012/01/21/apaches-fallbackresource-your-new-htaccess-command/. It's more of a 'if page not found, then run this page instead'
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
FallbackResource /root.php
</Directory>
The only thing I have found is that if the URL is for page that does exist - then it serves that instead of your base new base page 'root.php' in my case.

Codeigniter routing is not working with following procedure

I want to do routing in code-igniter and i have done the below steps also
but it is not working.I have done all the required settings also but then also
its not working.Please let me know is i am missing any thing or not.
Step 1
Add This in .htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
#RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
Step 2:
Remove index.php in codeigniter config
$config['index_page'] = '';
Step 3
Add this in route.php
$route['Viewsignup'] = 'Login/index/Viewsignup';
My url is like that:
http://localhost/machinetest/index.php/Login/Viewsignup
I want this url:
http://localhost/machinetest/index.php/Viewsignup
Please help me,
Thanks in Advance
.htaccess should not be issue here. Try this
$route['Viewsignup'] = 'Login/Viewsignup';
This will take you into Login controller's Viewsignup method when your URL looks like http://localhost/machinetest/index.php/Viewsignup
And for removing index.php from URL just update your .htaccess with following
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Now http://localhost/machinetest/Viewsignup URL will work too
On some servers, Apache is configured to ignore some or all directives in .htaccess files. This is for security reasons. The AllowOverride directive controls which features will be allowed in .htaccess files. For example AllowOverride None can turn off htaccess files for a folder and its subfolders.
Check your Apache configuration file for which AllowOverride directive is applied to the directory containing your problem htaccess file.
If you’re not sure which configuration file to look in, start with the main Apache configuration file httpd.conf or apache2.conf. If your website is configured in a file included by httpd.conf (e.g. a virtual hosts configuration file), you will need to look in that file. See Location of httpd.conf on CentOS, Ubuntu, Mac and others to locate your httpd.conf.
To enable using a .htaccess file, change AllowOverride None to AllowOverride All.
For example, for a CentOS 5.3 server, I needed to change the AllowOverride setting in the file /etc/httpd/conf.d/virtualhosts.conf.
httpd.conf before:
Options FollowSymLinks
AllowOverride None
httpd.conf after:
Options FollowSymLinks
AllowOverride All
Be aware that enabling htaccess files has security implications, as htaccess files override your Apache configuration. For example, if your site provides uploads, a hacker could potentially upload a .htaccess file to your server and use it to gain access to your server. There are options to AllowOverride that restrict the directives that will be used from a .htaccess file. See the documentation for AllowOverride.
refer http://smartwebdeveloper.com/apache/htaccess-problems

How to make an alias in .htaccess to change a local URL

I'm pretty sure this is a duplicate but I just don't know how to find the answer to this simple problem.
So I have a local page like this:
http://example.com/mypage.php
And all I want to do is to have anyone who tries to access http://example.com/subfolder/mypage.php to actually load the page at the above location.
I don't want a redirect. http://example.com/subfolder/mypage.php does not exist as an actual path on my server, but I want to make it available via rule in .htaccess
Try this:
RewriteEngine on
RewriteRule ^subfolder/(.*) /$1
This rule rewrites every request that starts with /subfolder/ to /. Or if you need only for a specific URL-path:
RewriteEngine on
RewriteRule ^subfolder/mypage.php /mypage.php
You can add it in .htaccess
RewriteEngine On
RewriteRule ^([^/]+)/(.*) /$2
or use directly in httpd.conf like
<Directory /var/www/>
Options Indexes FollowSymLinks ExecCGI
AllowOverride None
Order deny,allow
Allow from all
RewriteEngine On
RewriteRule ^([^/]+)/(.*) /$2
</Directory>
use $1 to get subfolder and $2 to get mypage.php :)

RewriteRule working on http but breaks on https

I have some RewriteRule in htaccess to have some pretty urls for my landing page. The url can look like www.site.com/new-document and my RewriteRule will make that www.site.com/index.php?page=new-document
This way I can leave the pretty url and use index.php to change the text depending on the page variable.
Everything works perfectly well on http but once I add https to the url I get a Not Found error as in the RewriteRule is not triggering.
Here is a copy of my htaccess code
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^new-document$ index.php?page=new-document
RewriteRule ^old-document$ index.php?page=old-document
</IfModule>
Grasshopper and anubhava pointed me in the right direction!
My problem was that the https virtual host did not have the AllowOverride All directive.
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
Can you get to the HTTPS URL without the RewriteRule? It sounds like Apache may be using a different virtual host or not accepting HTTPS at all.

.htaccess. deny root, allow specific subfolder. Possible?

How can I deny access to http://sub.mydomain.com/, but allow for (completely) http://sub.mydomain.com/test (or http://sub.mydomain.com/test/)
There is a magento back-end behind http://sub.mydomain.com/test/
.htaccess directives apply to that directory, and all subdirectories thereof, so you should disallow access in your DocumentRoot,
http://sub.mydomain.com/.htaccess:
Order deny,allow
Deny from all
And override that in any specific subdirectories you would like to allow access to,
http://sub.mydomain.com/test/.htaccess:
Order allow,deny
Allow from all
How about a .htaccess at the root directory, with the following lines?
RewriteEngine On
# check if request is for subdomain
RewriteCond %{HTTP_HOST} ^sub.mydomain.com$ [NC]
# check if 'test' isnt part of request
RewriteCond %{REQUEST_URI} !^/test/?(.*)$ [NC]
# if subdomain and no 'test' part, redirect to main domain...
RewriteRule ^(.*)$ http://www.mydomain.com/$1 [R,L]
So if the '/test/' section is present, no redirect takes place...
Try create .htaccess file in sub.mydomain.com for deny, and in sub.mydomain.com/test for allow.
Or you can redirect from http://sub.mydomain.com/ to deny subdir.
I know this is a very old thread, but I've been struceling with exactly this scenario for several days and finally got it to work, thus I thought I'd share my solution for further reference.
As of Apache version 2.4 (I guess), it's possible to use directive <RequireAll> and <RequireAny>.
This can be used to allow access to specific subfolders.
My solution for .htaccess (inspired from this site: https://www.the-art-of-web.com/system/apache-authorization/):
SetEnvIf REQUEST_URI "^/test/.*" PUBLICACCESS
# Use for multiple subfolders:
# SetEnvIf REQUEST_URI "^/(?:test|test2|test3|test4)/.*" PUBLICACCESS
<RequireAny>
<RequireAll>
# Public access
Require env PUBLICACCESS
Require all granted
</RequireAll>
<RequireAll>
# Require user and password
AuthType Basic
AuthName "Secured"
AuthUserFile /var/www/example.com/.htpasswd
Require valid-user
</RequireAll>
</RequireAny>
I'm using a cpanel powered server which will add .htaccess entries like the following:
#----------------------------------------------------------------cp:ppd
# Section managed by cPanel: Password Protected Directories -cp:ppd
# - Do not edit this section of the htaccess file! -cp:ppd
#----------------------------------------------------------------cp:ppd
AuthType Basic
AuthName "Protected"
AuthUserFile "/home/****/.htpasswds/sites/****/passwd"
Require valid-user
#----------------------------------------------------------------cp:ppd
# End section managed by cPanel: Password Protected Directories -cp:ppd
#----------------------------------------------------------------cp:ppd
I wanted to allow access to a specific subfolder, and the solution was creating an .htaccess file within that subfolder and placing the following inside:
Satisfy any
If you have protected your DocumentRoot by Auth, then you can allow your Subfolder by follow:
http://sub.mydomain.com/test/.htaccess:
require all granted
Order allow,deny
Allow from all

Categories