I have created an API and i get all my data with a specific url, and by 'id' like this :
'myfolder.php/1'
So now i try to get my url with a string :
myfolder.php/mystring
in a Htacess for the id i do like this :
RewriteRule ^[^/]+/(\d+)$ myfolder.php?id=$1
but i don't find the good regex for characters i have try like this :
RewriteRule ^[^/]+/([a-z]+)$ myfolder.php?string
Edit :
If i call url 'myurl.com', my function getProducts is called.
If i call 'myurl.com/1', getProduct($id) is called
But if i call 'myurl.com/string', $_GET is empty, and getProducts is called.
switch($request_method) {
case 'GET':
// HERE $_GET is empty if i called a string
if(!empty($_GET["id"])) {
$id= $_GET["id"];
getProduct($id);
}
else {
getProducts();
}
break;
default:
header("HTTP/1.0 405 Method Not Allowed");
break;
}
With your shown samples, please try following. Please make sure to clear your browser cache before testing your URLs. Also make sure your php file is residing in same folder where you are keeping your htaccess rules file.
##Enabling RewriteEngine here.
RewriteEngine ON
##Placing conditions for non-existing requests with rewriterule to php file.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w-]+)/?$ myfolder.php/$1 [NC,QSA,L]
Related
I am having an issue with mod rewrite. I am also a total beginner to it. I am using CodeIgniter and trying to rewrite the following:
http://url.dev/news/news_selection?item=59
to look like this:
http://url.dev/news/news_selection/59/
I have followed a tutorial on: https://www.addedbytes.com/articles/for-beginners/url-rewriting-for-beginners/ (more specifically the : "Patterns and Replacements" section)
The issue is I write my RewriteRule as below and it still does not rewrite the url after going to the page (eg. http://url.dev/news/news_selection?item=59)
RewriteRule ^news/news_selection/([0-9]+)/?$ news_selection?item=$1 [NC,L]
Any advice on where I am going wrong? Thank you.
I am not sure if the routes and controller affect this issue but I added them for reference below.
In my routes for codeIgniter I have
//_News Folder
$route['news/(:any)'] = 'pages/view2/_news/$1';
1: _news is the folder
2: news_selection is the php file
3: pages is the controller
My controller has the following function for view2:
public function view2($sub ='', $page='')
{
if ( ! file_exists(APPPATH.'/views/pages/'.$sub.'/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$sub.'/'.$page.'.php', $data);
$this->load->view('templates/footer', $data);
}
The rest of my .htaccess:
Options -Indexes
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
#Removes access to the system folder by users.
#Additionally this will allow you to create a System.php controller,
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ index.php?/$1 [L]
#When your application folder isn't in the system folder
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
# Submitted by: ElliotHaughin
ErrorDocument 404 /index.php
You just need this to use url as above:
RewriteEngine on
RewriteCond $1 !^(index\.php|images|captcha|css|js|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
You can use this for all controller. This file .htaccess is in application folder.
I figured it out after about 10 hours of trying everything today.
I decided that it may be a routing issue with CI and decided to try passing my variable from the url in the cleaned up format. So...
If I enter: http://url.dev/news/news_selection/59
It will work with the following route:
//_News Folder
$route['news/news_selection/(:num)'] = 'pages/view_test/_news/news_selection/$1';
and controller:
public function view_test($sub='', $page='', $var1='')
{
if ( ! file_exists(APPPATH.'/views/pages/'.$sub.'/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
$data['item'] = $var1;
$this->load->view('templates/header');
$this->load->view('pages/'.$sub.'/'.$page.'.php', $data);
$this->load->view('templates/footer');
}
By using these I can pass the page number as $var1 and then pass it on to my view via $data. Then I picked up $data['item'] as $item in my news_selection.php page and passed it to my model for processing. Reference to CI Manual for this.
After that the page processes like it normally would have.
I have a few URLs such as
http://sitename.com/recipes/234
//sitename.com/recipes/235
//sitename.com/recipes/236
The URL routes are set in this way :
//sitename.com/controller/action/ID
I need to write an htaccess rule that will do a 301 redirect to http://sitename.com/recipes if the item does not exist and cake throws a 404 error .
I have tried this in core PHP and it works fine . But I am finding it difficult to do the same in an MVC environment . I want to implement it on cakephp framework .
I tried using the following code
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?request=$1 [L]
For MVC, in your Recipes controller view method, for example, you could use following code:
public function view($id = null)
{
// ....
$recipe = $this->Recipe->findById($id);
if (!$recipe) {
// Not found flash error message
return $this->redirect(
array('action' => 'index'),// -> Recipes index page
301
);
}
// ....
}
See docs here.
My present url structure :
domain.com/items/view/5
domain.com/user/view/5
domain.com/user/edit/5
Now i don't want users to directly know the 'id' in the url, as they can directly fire a query from the address bar.
Hence i want to mask the url to :
domain.com
i.e. domain.com/anything will come as it is but the url will not change.
Thanks in advance.
Also note that i have already made .htaccess file with following code to remove 'index.php' from the url and that is working perfect.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
Can't be done. The only way to hide the id is to pass it outside the url - i.e. as POST data; but .htaccess doesn't have access to that, only the url.
Your code should instead handle the fact that users could enter the url directly and either act correctly or use a http-redirect header to send the user back to the main page.
I have a url http://domain.com/module/controller/action/get1/value1/?get2=value2&get3=value3 I want to use Mod_Rewrite to change the ?&= to appropriate / slashes inline with the first GET variable.
I also need to avoid conflicts with my current Mod_Rewrite rules:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ zend.php [NC,L]
If you don't need the GET parameters in their native $_GET container, you could leave the htaccess file as is, and have the front controller (I assume you are using PHP) do the parsing and not mod_rewrite.
You would have to access the $_SERVER["REQUEST_URI"] and parse out the parameters before any other URL parsing (I think you are using the Zend Frameworks') kicks in.
This works only if you can modify the part of your program that needs value1 value2 value3 etc. If it's some Zend component that needs the parameters, and that component fetches them directly from $_GET, this will not work for you and you may in fact have to build mod_rewrite instructions.
Btw, you are aware by the way that with the method in your .htaccess, invalid links to images, CSS files and other media types will all be routed to zend.php?
Try putting these rules in front of yours:
RewriteCond %{QUERY_STRING} ^([^&=]+)=([^&]+)&(.+)
RewriteRule ^ %{REQUEST_URI}%1/%2/?%3 [N]
RewriteCond %{QUERY_STRING} ^([^&=]+)=([^&]+)$
RewriteRule ^ %{REQUEST_URI}%1/%2/? [L,R]
I could not find a nice way to do this... so I resolved to write some minimised PHP code at the top of my zend.php.
list($sURL, $sQuery) = explode('?', $_SERVER['REQUEST_URI']);
$sOriginalURL = $sURL;
if ('/' !== substr($sURL, -1)) $sURL .= '/';
if (isset($sQuery)) {
foreach (explode('&', $sQuery) as $sPair) {
if (empty($sPair)) continue;
list($sKey, $sValue) = explode('=', $sPair);
$sURL .= $sKey . '/' . $sValue . '/';
}
}
if (isset($sQuery) || $sOriginalURL !== $sURL) header(sprintf('Location: %s', $sURL));
If anyone can improve on this please comment below.
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.