22

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
MrWhite
  • 43,179
  • 8
  • 60
  • 84
Vivart
  • 14,900
  • 6
  • 36
  • 74
  • just take an example of article section of website.user submits a article and dynamic url is generated like www.domain-name/articles?cat=3&id=34 but i want like this www.domain-name/articles/cat-name/article-name – Vivart Jan 24 '10 at 11:29

6 Answers6

16

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.

Daan
  • 1,879
  • 17
  • 18
5

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.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
Pentium10
  • 204,586
  • 122
  • 423
  • 502
  • 1
    Better use `$_SERVER['PATH_INFO']` instead of `$_SERVER['REQUEST_URI']` in this case. – Mathias Bynens Jan 24 '10 at 11:34
  • This workaround looks good. one problem when i am using www.domain-name.com/index.php/filename it looks like current directory changes and all css formating lost and relative navigation is also not working. any suggestions. – Vivart Jan 24 '10 at 12:12
  • 1
    add / base reference for your each file reference like ` ` also link your CSS by using base reference `src="/media/css.css"` – Pentium10 Jan 24 '10 at 12:37
4

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.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
Alix Axel
  • 151,645
  • 95
  • 393
  • 500
3

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.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
1

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.

J.Dubbs
  • 11
  • 3
1

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;
}
phemmytesh
  • 11
  • 1