My codebase is located in url.com/ with /public housing index.php and .htaccess, which the servers configured to point at for url.com
My .htaccess looks like this:
RewriteEngine on
ServerSignature On
Options +Indexes +FollowSymlinks +MultiViews
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(js|ico|gif|jpg|png|css)$ /index.php
RewriteRule ^([-A-Za-z0-9]+)/([-A-Za-z0-9]+).([-A-Za-z0-9]+)$ index.php?module=$1&action=$2&return=$3
RewriteRule ^([-A-Za-z0-9]+).([-A-Za-z0-9]+)$ index.php?module=$1&action=index&return=$3
What I would like is the following URLS to get the following:
url.com/users/list.json equal = module = users, action = list, return = json
url.com/users/list.json?from=0&to=15 equal = module = users, action = list, return = json, from = 0, to = 15
Is this possible? I've been banging my head against a wall for a long time trying to get this work so I'm putting a bounty on it
You could try:
RewriteRule ([-A-Za-z0-9]+)/([-A-Za-z0-9]+)\.(json|xml)$ /testrewrite.php?module=$1&return=$3&action=$2 [L,QSA]
The QSA option will keep the query strings in tact.
The RewriteRule pattern simply does not match the requested URL path as the pattern for the third path segment [0-9]+ does not match List.
Apache's %{QUERY_STRING} will maintain the GET variables in your rules. For example:
RewriteRule ^([-A-Za-z0-9]+)/([-A-Za-z0-9]+).([-A-Za-z0-9]+)$ index.php?module=$1&action=$2&return=$3?%{QUERY_STRING}
Related
Hello I have a "protected" folder on my server. In its .htaccess file for conditional redirect of some users I use the following rules:
RewriteCond %{REMOTE_ADDR} ^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} !^/special
RewriteRule ^$ /special [R,NE,NC]
In the /special folder I have a .htaccess file with the following rules:
RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4$
RewriteRule ^(.*)$ / [R=301,NE,NC,L]
The application in the folder will be laravel based so my content will have to be served from index.php file residing in /special/laravel/public/index.php
I want the URL to look like /special/.
What rules should I put and where for this to happen?
This is a follow up to my previous question:
https://stackoverflow.com/questions/24487012/redirecting-specific-ip-to-special-content-htaccess-vs-php
Simply rewrite the URL with .htaccess: (goes in /)
DirectoryIndex index.php
#Redirect to /special/laravel/public if you haven't already and the IP is okay
RewriteCond %{REMOTE_ADDR} ^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} !^/special/laravel/public
RewriteRule ^(/special)(/laravel)?(.+) /special/laravel/public$2 [L]
#if IP does not match and you ARE in the folder, then Redirect to root
RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} ^/special/laravel/public
RewriteRule .? / [R=301,L]
I think that'll work. I didn't test it though. I can add to it if you need me to. And of course for your use case you may need to add some more RewriteConds in there for validating the REMOTE_ADDR.
The way I handle it:
.htaccess:
RewriteCond %{REQUEST_URI} !^/load_page.php$
RewriteRule ^(.+)$ /load_page.php [QSA, L]
That causes the server to redirect internally to load_page.php if the requested URL is not load_page. Without the RewriteCond, I believe it would cause an infinite redirect. This should work, but I didn't test it because it's different from my implementation, since mine also handles rewriting URLS to have trailing slashes and never show .php which makes it a bit more complex and quite different.
load_page.php:
$SITE_ROOT = $_SERVER['DOCUMENT_ROOT'];
$URL = $_SERVER['REQUEST_URI'];
ob_start();
if (conditionOne){
//change $URL here if you need to or do nothing
} else if (conditionTwo){ //check the IP or whatever you want to here
if (aCondition){//if $URL starts with '/special'
$URL = str_ireplace('/special/','/special/laravel/public/',$URL,1);
}
if (is_dir($SITE_ROOT.$URL))$URL .='index.php';
}
if (!file_exists($SITE_ROOT.$URL))$URL = '/error/404.php';
include($SITE_ROOT.$URL);
$content = ob_get_clean();
echo $content;
It's something to that affect. The user doesn't see load_page.php and they don't see that you changed the URL to special/laravel/public, but you include the correct file.
im trying to beautify my urls, my urls are like that
http://www.mysite.com/details.php?id=19&object=1
object=1 (videos) or object=0 (articles)
i want change this url to
http://www.mysite.com/videos/19
of course i make videos because i mentioned that when object =1 means videos
and when object =0
i want this
http://www.mysite.com/articles/19
I tried using this from some tutorials , but didnt work.nothing happen.
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^videos/([a-zA-Z]+)/([0-9]+)/$ details.php?object=$1&id=$2
and also how do i do the if condition with RewriteCond to check if object is 1 or 0 , if 1 then print videos else articles.
any help would be much apreciated.
It is better to use RewriteMap for your case here. Here is a sample how to use it:
Add following line to your httpd.conf file:
RewriteMap objMap txt://path/to/objectMap.txt
Create a text file as /path/to/objectMap.txt like this:
articles 0
videos 1
Add these line in your .htaccess file under DOCUMENT_ROOT:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteRule ^([^/]+)/([0-9]+)/?$ /details.php?object=${objMap:$1}&id=$2 [L,QSA]
Advantage: With this setup in place, you can edit or recreate the file /path/to/objectMap.txt anytime you have a new object id mapping without any need to add new rules.
UPDATE: If you have no control over Apache config you will have to deal with multiple rewrite rules (one each of each object id mapping) like this:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+details\.php\?id=([^&]+)&object=1\s [NC]
RewriteRule ^ /videos/%1? [R=302,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+details\.php\?id=([^&]+)&object=0\s [NC]
RewriteRule ^ /articles/%1? [R=302,L]
RewriteRule ^videos/([0-9]+)/?$ /details.php?object=1&id=$1 [L,QSA,NC]
RewriteRule ^articles/([0-9]+)/?$ /details.php?object=0&id=$1 [L,QSA,NC]
I have a url like this:
http://domain.com/index.php?id=223
And this .htaccess code:
RewriteEngine On
RewriteRule ^([^/]*)\.html$ /index.php?id=$1 [L]
From what I understand this should output:
http://domain.com/223.html
But its not doing anything, can someone please explain how this works and what I'm doing wrong?
Your original rule takes any file that does not include a slash and ends with ".html" at the root level (including a file called ".html") and redirects the request to a file called index.php and it takes the first part of the filename from the request (before the dot) and passes it as a query called "id."
RewriteRule ^([^/]*)\.html$ /index.php?id=$1 [L]
Since this is .htaccess you should take the slash off
You should do this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)\.html$ /index.php?id=$1 [L]
In your html itself in the links, you'll need to call filename.html.
<a href='/223.html'>Some page with an id of 223</a>
For SEO you can take the start match off
RewriteRule ([^/]+)\.html$ /index.php?id=$1 [L]
This would make it so you could reference a file like:
/somedirectory/someseotitle/223.html
Additionally you should then create 301 redirects from all of the id=$id links and make them go to their intended targets with the full URL. The code below would go into the index.php file at the top before any cookies are set or sessions started. As an example of what you could do... I'm only guessing about table structure:
<?php
if ($_SERVER['REQUEST_URI']=='/index.php' && !empty($_GET['id']){
if (is_numeric($_GET['id'])){
$id = $_GET['id'];
$cquery = "select count(*) from table where id = $id";
$count = mysqli_result(mysqli_query($cquery),0);
if($count == 1){
$tquery = "select title from table where id = $id";
$result = mysqli_query($tquery);
while ($row=mysqli_fetch_array($result)){
$title = urlencode($row['title']);
$headerString = "Location: /$title/$id.html";
header( "HTTP/1.1 301 Moved Permanently" );
header($headerString);
}
}
}
}
?>
In addition to what you already have in .htaccess you will need a rule for external redirection of /index.php?id=223 to /223.html. This should be your complete .htaccess:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(?:index\.php|)\?id=([^&\s]+) [NC]
RewriteRule ^ /%1.html? [R=302,L]
RewriteRule ^([^.]+)\.html$ /index.php?id=$1 [L,QSA,NC]
Once you verify it is working fine, replace R=302 to R=301. Avoid using R=301 (Permanent Redirect) while testing your mod_rewrite rules.
I'm trying to rewrite urls like http://www.url.com/blog/?p=123 to http://www.url.com/#blog/123. I've read up on things and found that you can only parse the query string in the RewriteCond so I tried something like:
RewriteCond %{QUERY_STRING} ^p=([0-9]*)$
RewriteRule ^.*$ /#blog/%0 [NE,R]
When I try this the urls end up being rewritten to:
http://www.url.com/#blog/p=213?p=213
Any ideas how to do this properly? Also, is there a way to add an additional RewriteCond that checks that the REQUEST_URI contains blog?
You can do this by removing the query string entirely:
RewriteCond %{QUERY_STRING} ^p=([0-9]*)$
RewriteRule ^.*$ /#blog/%1? [NE,R]
This should give you:
http://www.url.com/#blog/213
If you want to check if the URL contains the term "blog" then simply check:
RewriteCond %{REQUEST_URI} .*/blog/.*
It is important to note that you will not be able to check for "blog" in links like http://www.url.com/#blog because, as noted by Patrick, everything after the # is not sent to the server.
See the Apache wiki on mod_rewrite for more information.
That may not work because browsers do not send the fragment of the url after the hash (#) with the request, so any request for http://www.url.com/#blog/p=213?p=213 will be a request for http://www.url.com/
The hash fragment is supposed to be used for anchor tags on pages, and is never sent to the server.
Try this rule in your .htaccess file:
Options +FollowSymlinks -MultiViews
RewriteEngine on
RewriteCond %{QUERY_STRING} ^p=(.*)$ [NC]
RewriteRule ^blog/?$ /#blog/%1? [NC,NE,L,R]
With above a URL of http://localhost/blog/?p=1234 will become http://localhost/#blog/1234
In my present project I've got several directories: application (my MVC files, which mustn't be accessed), images, css, and js. Effectively I want all requests to images/css/js to proceed unchanged, but all others I wish to call index.php/my/path.
My .htaccess currently looks like this, and is wreaking havoc with my routing.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php|images|js|css|robots\.txt)
RewriteRule ^(.*)$ http://example.com/index.php/$1 [L]
</IfModule>
This isn't working as relative URLs start stacking up, such as: example.com/blog/view/1/blog/view/2.
When I attempt something like,--
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/(index\.php|images|js|css|robots\.txt)
RewriteRule ^ index.php%{REQUEST_URI} [PT]
</IfModule>
I get this error with any request: No input file specified.
How can I force all requests not to my whitelisted directories to call, not redirect to (redirection murders posting, I found), index.php/path? IE, when /blog/view/1 is requested by the browser, .htaccess calls index.php/blog/view/1. The reference files at Apache's site aren't too clear about how to do this sort of thing—that, or, I am just missing the point of what I'm reading about RewriteRule.
And, I really want to understand this. Why will your answer work? Why are my attempts failing?
This is what I have in my .htaccess for my framework:
<IfModule mod_rewrite.c>
RewriteEngine on
#This will stop processing if it's images
RewriteRule \.(css|jpe?g|gif|png|js)$ - [L]
#Redirect everything to apache
#If the requested filename isn’t a file….
RewriteCond %{REQUEST_FILENAME} !-f
#and it isn’t a folder…
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
#L = (last - stop processing rules)
#QSA = (append query string from requeste to substring URL)
</IfModule>
Hope this helps.
PS: Maybe you want to remove the lines to stop redirecting if it's a file or folder ;)
Antonio helped me get on the right track, so here's the resulting .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
# skip if whitelisted directory
RewriteRule ^(images|css|js|robots\.txt|index\.php) - [L]
# rewrite everything else to index.php/uri
RewriteRule . index.php%{ENV:REQUEST_URI} [NE,L]
</IfModule>
You're going to have to do that using PHP. For example, if you wanted to split your URI into something like domain.tld/controller/action/param, then you could use the following PHP code as a start:
<?php
// Filter URI data from full path
$uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['REQUEST_URI']);
$uri_string = trim($uri_string, '/'); // Make sure we don't get empty array elements
// Retrieve URI data
$uri_data = explode('/', $uri_string);
In that case, $uri_data[0] is the controller, $uri_data[1] is the action, and beyond that are parameters. Note that this isn't a foolproof method, and it's never a great idea to trust user-entered input like this, so you should whitelist those controllers and actions which can be used.
From here, knowing the controller and having a consistent directory structure, you can require_once the proper controller and call the action using variable variables.
This is what I use in my .htaccess file for my CMS:
Options -Indexes
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php/$1 [NC,L]
And then in my index.php file I have:
$path_info = '';
$path_info = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : $path_info;
$path_info = isset($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : $path_info;
$request = explode('/', trim($path_info, '/'));
// if $request[0] is set, it's the controller
// if $request[1] is set, it's the action
// all other $request indexes are parameters
Hope this helps.