I am trying out an alternative approach to beautiful URLs with PHP:
$request = explode("/", substr(#$_SERVER['PATH_INFO'], 1));
The above snippet will let me use URLs that are something like "www.example.com/index.php/article/how-to-diy" where "/article/how-to-diy" is the URL parameter.
I'd really like to lose the "index.php", though, and I am in no way a .htaccess-wiz, so I could use some help on making a rewriterule that will change my URLs into "www.example.com/article/how-to-diy".
I've looked around on SO and the examples I found were all related to a classic parameter syntax (i.e. "index.php?page=12"), which is not the solution I am after.
I'm accustomed to the typical MVC/Wordpress way of handling urls...less work in htaccess and all the work in the url router. I'll give an example:
.htaccess
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
</IfModule>
Then, within index.php call a routing mechanism that parses your urls and produces the appropriate page. But don't use PATH_INFO, you need to know what is being requested:
$request = explode("/", #$_SERVER['REQUEST_URI']);
EDIT:
If the script (index.php) and .htaccess are not located in the document root, the RewriteRule should reflect this:
RewriteRule . /path/to/index.php
And then the routing mechanism should simply loop through $request, in order to find the parts it needs.
Related
The URL I want to achieve: https://example.com/VdnbzeHfua/ep1_mp4
Note : My page (index.php) is located in root folder
when I access this URL https://example.com/VdnbzeHfua/ep1_mp4 it should not look forward for sub folders
i will get and use the values in the URL with PHP (index.php in root folder) like this
<?php
$url = $_SERVER['REQUEST_URI'];
................
...........
?>
How to achieve this with php and .htaccess?
Please anyone help me solving this.
You require a standard front-controller pattern, which can be achieved with a single directive in .htaccess:
FallbackResource /index.php
Any request that would otherwise trigger a 404 is passed to /index.php instead.
An alternative method (which is perhaps more commonly seen) is to use mod_rewrite instead. For example:
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
Although this alone doesn't do anything more than the FallbackResource directive does above.
Both methods would require the DirectoryIndex to be set correctly, if not already (this will usually be set to index.php in the server config). For example, at the top of your .htaccess, before the existing directives:
DirectoryIndex /index.php
You seem to already have the PHP part resolved. ie. check the value of $_SERVER['REQUEST_URI'] in order to examine the requested URL, which incidentally will also contain the query string.
You can then include the necessary PHP files as required. For example, this could be something simple like:
if ($url == '/about') {
include('content/about.php');
}
But can be made as complex as you like. Obviously an if construct won't scale to 1000s of pages.
I'm currently writing a PHP app and am about to create various controllers. Currently I have one controller with certain method, so the URL looks like this:
http://somewebsite.com/index.php?c=controller&a=action
It's being rewritten to this:
http://somewebsite.com/controller/action
With this .htaccess file:
RewriteEngine On
RewriteRule ^([a-z]+)/([a-z]+)$ index.php?c=$1&a=$2 [NC]
What I want to achieve is the ability to rewrite URL with more than one controller (the more, the better), possibly in random order. Is there a more convenient way than rewriting every possible combination of URL parameters?
Many frameworks (Codeigniter, WordPress, Laravel, etc.) use an .htaccess file similar to the following:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
This rewrites all incoming URLs to be handled by the index.php file. You can then use $_SERVER['REQUEST_URI'] variable to get the exact request URI, parse it, and then handle it how you want.
if you're going for an arbitrary routing scheme, probably your best bet is to just pass the entire url string e.g. ^(.+)$ to index.php and let your php application split the string based on '/' and handle the array however makes sense for your application
I'm trying to convert a query string;
http://atwd/books/course?course_id=CC100&format=XML&submit=Submit
Into a segment URI;
http://atwd/books/course/CC100/XML
I'm working in CodeIgniter.
I was looking at a stackoverflow answer that said to check CodeIgniter's URL segment guide, but I don't think there's any information on how to convert a query string into a segment URI. There is, however a way to convert a segment URI into a query string, which is bringing up a load of results from Google too.
Following another stackoverflow answer, I tried this in my .htaccess file but nothing seemed to work
RewriteCond %{QUERY_STRING} ^course_id\=([^&]+)\&format\=([^&]+)$
RewriteRule ^$ /course/%1/format/%2 [R,L]
In my entire .htaccess file I have this;
<IfModule mod_rewrite.c>
RewriteEngine on
#Source: http://codeigniter.com/user_guide/general/urls.html
#Removal of index.php
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php?route/$1 [L]
#Source: https://stackoverflow.com/questions/3420204/htaccess-get-url-to-uri-segments
#Format Course function requests
RewriteBase /
RewriteCond %{QUERY_STRING} ^course_id\=([^&]+)\&format\=([^&]+)$
RewriteRule ^$ /course/%1/format/%2 [R,L]
</IfModule>
This is in my root directory of Codeigniter screenshot
My code in the .htaccess file isn't working, I refresh the page and nothing happens. The code to hide the index.php is working though. Does anyone know why?
The notion of "converting URLs" from one thing to another is completely ambiguous, see the top part of this answer for an explanation of what happens to URLs when redirecting or rewriting: https://stackoverflow.com/a/11711948/851273
There's 2 things that happen, and I'm going to take a wild stab and guess that you want the 2nd thing, since you're complaining that refreshing the page doesn't do anything.
When you type http://atwd/books/course?course_id=CC100&format=XML&submit=Submit into your browser, this is the request URI that gets sent through mod_rewrite: /books/course. In your rule, you are matching against a blank URI: RewriteRule ^$ /course/%1/format/%2 [R,L]. That's the first reason your rule doesn't work. The second reason why it doesn't work is because above that, everything except images and index.php and robots.txt is being routed through index.php. So even if you were matching against the right URI, it gets routed before your rule even gets to do anything.
You need to correct the pattern in your rule to match the URI that you expect to redirect, and you need to place this rule before the routing rule that you have. So everything should look roughly like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^course_id\=([^&]+)\&format\=([^&]+)$
RewriteRule ^/?books/course$ /course/%1/format/%2 [R,L]
#Source: http://codeigniter.com/user_guide/general/urls.html
#Removal of index.php
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php?route/$1 [L]
</IfModule>
You'll need to tweak the paths to make sure they match what you are actually looking for.
To both redirect the browser and internally rewrite back to your original URL, you need to do something different.
First, you need to make sure all of your links look like this: /course/CC100/format/XML. Change your CMS or static HTML so all the links show up that way.
Then, you need to change the rules around (all before your codeigniter routing rule) to be something liek this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# redirect browser to a URI without the query string
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /books/course/?\?course_id=([^&]+)&format=([^&]+)
RewriteRule ^/?books/course$ /course/%2/format/%3? [R,L]
# internally rewrite query string-less request back to one with query strings
RewriteRule ^/?course/([^/]+)/format/([^/]+)$ /books/course?course_id=$1&format=$2&submit=Submit [L]
#Source: http://codeigniter.com/user_guide/general/urls.html
#Removal of index.php
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php?route/$1 [L]
</IfModule>
I'm not going to address the misunderstanding already addressed pretty well in the other answer and comments, and I can't speak for CodeIgniter specifically, but having given their URL routing docs a quick skim, it seems pretty similar to most web frameworks:
You probably just want to direct all traffic (that doesn't match physical files) to the frontend web controller (index.php) and handle the URL management in CodeIgniter's routing, not a htaccess file.
To do that, your htaccess could be as simple as:
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php [QSA,L]
</IfModule>
This, as I said, will redirect any traffic that doesn't match an physical file such as robots.txt or an image to your index.php.
Then, using the routing as described in the docs (http://ellislab.com/codeigniter/user-guide/general/routing.html) you can take in parameters and pass them to your controllers as you see fit, there is no need to 'convert' or 'map' anything, your URL's don't need to resolve to /?yada=yada internally, based on your routing rules CodeIgniter can work it out.
You'll need wildcard routes such as this from the docs:
$route['product/:id'] = "catalog/product_lookup";
A rough example of what yours might end up looking like would be something like:
$route['course/:id/format/:format'] = "course/something_or_other_action";
If I'm understanding you correctly, you might be over-thinking it. I have something similar in my own code.
I have a controller named Source. In that controller, I have the following method:
public function edit($source_id, $year)
{
# Code relevant to this method here
}
This produces: http://localhost/source/edit/12/2013, where 12 refers to $source_id and 2013 refers to $year. Each parameter that you add is automatically translated into its own URI segment. It required no .htaccess trickery or custom routes either.
I am relatively new at php coding and am working to write my own MVC stuff. I'd rather do this than use a framework b/c I'll understand it much better this way :).
Currently, I have my site setup as follows:
domain.com/services
Will rewrite into index.php?page=services
Inside of index.php I have code that will load the correct template based on the URI string. However, I want to make my site a bit more complex than this...
I would like the server to load the appropriate php file based on the uri string. What is the best way to do this? Perhaps have the index.php actually read an execute another php file?
Thanks!
Edit: My current htaccess that handles what I'm doing now is:
# Turn on URL rewriting
RewriteEngine On
# Installation directory
#RewriteBase
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
RewriteCond %{HTTP_HOST} ^domain.net$
RewriteRule (.*) http://www.domain.net$1 [R=301]
#remove trailing slash
RewriteRule ^(.+)/$ /$1 [R=301,L]
# Protect application and system files from being viewed
RewriteRule ^(?:templates|configs|templates_c)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule ^([^/\.]+)/?$ index.php?page=$1
What should I change to achive what i want? I was thinking just:
RewriteRule ^(.*)$ index.php [L,NS]
And then:
list( $controller, $function, $params ) = explode( '/', $uri, 3 );
$params = explode( '/', $uri );
What would be a good php methodology to execute the right code at this point? just include the file?
You can create multiple rewrite rules based on the URIs. Here's a simple example - you can make more complex ones using RewriteCond.
# Rewrite all URIs beginning with 'a' to index1.php
RewriteRule ^(a[^/\.]+)/?$ index1.php?page=$1
# Rewrite all URIs beginning with 'b' to index2.php
RewriteRule ^(b[^/\.]+)/?$ index2.php?page=$1
If you really want different files to handle different types of URIs this is probably the way to go, unless you have dozens of such items. Otherwise you can figure out dispatching from within index.php
Best way is to use .htaccess ModRewrite for URL changes, so that you compact readable URLs will be correctly translated to your script paths
My own way to work in such situation:
RewriteRule ^/([^/]*)/([^/]*)/?$ engine.php?prmtrs=$1/$2 [L]
<?php
list($url_part, $url_page) = explode('/', $_GET['prmtrs']);
?>
Of cource you need to clean data from you $_GET befor use it, just simplified example to show idea more clear.
I want to have a PHP file catch and manage what's going to happen when users visit:
http://profiles.mywebsite.com/sometext
sometext is varying.
E.g. It can be someuser it can be john, etc. then I want a PHP file to handle requests from that structure.
My main goal is to have that certain PHP file to redirect my site users to their corresponding profiles but their profiles are different from that URL structure. I'm aiming for giving my users a sort of easy-to-remember profile URLs.
Thanks to those who'd answer!
Either in Apache configuration files [VirtualHost or Directory directives], or in .htaccess file put following line:
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,NC,QSA]
</IfModule>
It will silently redirect all incoming requests that do not correspond to valid filename or directory (RewriteCond's in the code above make sure of that), to index.php file. Additionally, as you see, MultiViews option also needs to be disabled for redirection to work - it generally conflicts with these two RewriteCond's I put there.
Inside index.php you can access the REQUEST_URI data via $_SERVER['REQUEST_URI'] variable. You shouldn't pass any URIs via GET, as it may pollute your Query-String data in an undesired way, since [QSA] parameter in our RewriteRule is active.
You should use a rewrite rule..
In apache (.htaccess), something like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [QSA,L]
</IfModule>
Then in your index.php you can read $_GET['url'] in your php code.
You can use a .htaccess file (http://httpd.apache.org/docs/1.3/howto/htaccess.html) to rewrite your url to something like profiles.websites.com/index.php?page=sometext . Then you can do what you want with sometext in index.php.
An obvious way to do this would be via the 404 errorDocument - saves all that messing about with mod_rewrite.
If you have not heard about MVC, its time you hear it, start with CodeIgniter, its simplest and is quite fast, use default controller and you can have URLs like
domain.com/usernam/profiledomain.com/usernam/profile/editdomain.com/usernam/inboxdomain.com/usernam/inbox/read/messageid Or use .htaccess wisely