URL parameter in Codeigniter separated by slashes - php

In my project, I am passing parameters through URL like,
http://site.org/project/controllername/function?id=1&type=free
What I want is to change the URL to
http://site.org/project/controllername/function/1/free
Actually I am creating the URLs dynamically like
<a href="<?php echo base_url()?>controllername/function?id=<?php echo $defaultrow->id;?>&type=free">
Controller Code :
// Inside VideoController
function search()
{
$userid=$this->tank_auth->get_user_id();
$data['userid']=$userid;
$time=time();
$data['defaultvideoquery']=$this->db->query("select cv.videotitle,cv.video,cv.thumbnail,
cv.added_on,cp.description,cv.id,cv.likes,cv.dislikes,cv.views from channel_programmes as cp INNER JOIN channel_videos as cv
ON cp.programme_source=cv.id and cp.channel_id=0 and $time>=cp.starttime and $time>=cp.endtime and cp.status=1");
$data['videonum']=$data['defaultvideoquery']->num_rows();
$data['page']='video/search';
$this->load->view('layout/template',$data);
}
// Inside ChannelsController
function playchannel()
{
if (!$this->tank_auth->is_logged_in())
{ // not logged in
redirect('auth/login');
}
$data['id']=$userid;
$id=$this->input->get('id');
if($this->input->get('type'))
{
if($this->input->get('type')=="free")
{
$time=time();
$data['currentdate']=$time;
$pgmquery=$this->db->query("select cp.channel_id,cp.title,cp.programme_source,cp.url,cp.description,cv.status,cv.video,cp.starttime,cp.endtime from
channel_videos as cv INNER JOIN channel_programmes as cp ON cv.id=cp.programme_source where cp.status=1 and cv.id=$id");
}
else
{
$query=$this->db->query("select id,title,thumbnail,channel_type,created_on,status,channel_type,description from videochannel
where created_for=$userid and id=$id");
$data['queryresult']=$query->row();
$data['channeldata']=$query->result();
}
$data['pgmnum']=$pgmquery->num_rows();
$data['pgmresult']=$pgmquery->result();
}
$data['page']='channels/playchannel';
$this->load->view('layout/template',$data);
}
View Code:
if(isset($videonum))
{
if($videonum>0)
{
foreach($defaultvideoquery->result() as $defaultrow)
{?>
<a href="<?php echo base_url()?>channels/playchannel?id=<?php echo $defaultrow->id;?>&type=free">
<?php if($defaultrow->thumbnail=="")
{ ?>
<img src="<?php echo base_url();?>images/No_image.png" class="videothumb" alt="Video thumbnail <?php echo $defaultrow->videotitle;?>">
<?php }
else
{ ?>
<img src="<?php echo base_url();?>channel/<?php echo $defaultrow->id;?>/<?php echo $defaultrow->thumbnail;?>" class="videothumb" alt="Video thumbnail <?php echo $defaultrow->videotitle;?>">
<?php } ?>
</a>
}
}
}
Htaccess Code :
RewriteEngine On
RewriteBase /projectname/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule \.htaccess - [F]
RewriteRule (.*)(css\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(css\/smoothness\/images\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(js\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(js\/user\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(js\/user\/timeslots\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(channel_data\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(images\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(sliders\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(secure\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(userdata\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(channel\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(css\/admin\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(css\/screen\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(css\/skins\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(css\/fonts\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(css\/images\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(css\/smoothness\/)(.*)$ $2$3 [QSA,L]
RewriteRule (.*)(fonts\/)(.*)$ $2$3 [QSA,L]
RewriteCond %{request_uri} !^index\.php
RewriteRule ^(.*)$ index.php?/$1 [QSA,L]
Is there any method to do this in Codeigniter without using htaccess. I tried adding
//$route['(:any)'] = 'controllername/function/$1';
$routes['channels/playchannel/(:any)'] = 'channels/playchannel/$1';
in application/config/routes.php file. But it returned 404 (Page Not Found) Error.
Can anyone help me to achieve this. Thanks in advance.

Isn't this already built in?
The segments in the URL, in following with the Model-View-Controller approach, usually represent:
example.com/class/function/ID
The first segment represents the controller class that should be invoked.
The second segment represents the class function, or method, that should be called.
The third, and any additional segments, represent the ID and any variables that will be passed to the controller.
The URI Class and the URL Helper contain functions that make it easy to work with your URI data. In addition, your URLs can be remapped using the URI Routing feature for more flexibility.
source: http://ellislab.com/codeigniter/user-guide/general/urls.html
Your URL should be like: example.com/Controllername/Functionname/ID/OtherID
In your class you get the ID like this:
class Controllername
{
function Functionname($ID = FALSE, $OtherID = FALSE)
{
$ID_from_url = $ID;
$OtherID_from_url = $OtherID;
}
}
To create such an URL like that you can do multiple things.
$this->load->helper('url');
echo site_url("news/local/123"); // http://example.com/index.php/news/local/123
echo base_url("blog/post/123"); // http://example.com/blog/post/123
New code based on your application:
// function
function playchannel($id = false, $condition = false)
{
if (!$this->tank_auth->is_logged_in())
{ // not logged in
redirect('auth/login');
}
$data['id']=$userid;
if($condition)
{
if($condition=="free")
{
$time=time();
$data['currentdate']=$time;
$pgmquery=$this->db->query("select cp.channel_id,cp.title,cp.programme_source,cp.url,cp.description,cv.status,cv.video,cp.starttime,cp.endtime from
channel_videos as cv INNER JOIN channel_programmes as cp ON cv.id=cp.programme_source where cp.status=1 and cv.id=$id");
}
else
{
$query=$this->db->query("select id,title,thumbnail,channel_type,created_on,status,channel_type,description from videochannel
where created_for=$userid and id=$id");
$data['queryresult']=$query->row();
$data['channeldata']=$query->result();
}
$data['pgmnum']=$pgmquery->num_rows();
$data['pgmresult']=$pgmquery->result();
}
$data['page']='channels/playchannel';
$this->load->view('layout/template',$data);
}
//view
if(isset($videonum))
{
if($videonum>0)
{
foreach($defaultvideoquery->result() as $defaultrow)
{?>
<a href="<?php echo base_url()?>channels/playchannel/<?php echo $defaultrow->id;?>/free">
<?php if($defaultrow->thumbnail=="")
{ ?>
<img src="<?php echo base_url();?>images/No_image.png" class="videothumb" alt="Video thumbnail <?php echo $defaultrow->videotitle;?>">
<?php }
else
{ ?>
<img src="<?php echo base_url();?>channel/<?php echo $defaultrow->id;?>/<?php echo $defaultrow->thumbnail;?>" class="videothumb" alt="Video thumbnail <?php echo $defaultrow->videotitle;?>">
<?php } ?>
</a>
}
}
}
This should work.

In CodeIgniter, you can do this through your routes.php.
In your routes.php,
$routes['controller/method/param1/param2'] = 'controller/method/$1/$2';
for example, you want to have a URL something like this:
http://example.com/video/playchannel/13/free
You can rewrite it via your routes.php like this:
$routes['video/playchannel/(:any)/(:any)'] = 'video/playchannel/$1/$2';
And then on your video.php controller,
Class Video {
function __construct() {
}
public function playchannel( $id, $type ) {
// do process
if (!$this->tank_auth->is_logged_in()) {
// not logged in
redirect('auth/login');
}
$data['id'] = $userid;
if( $type == 'free' ) {
// do something here
}
}
}
So the URL should look like this:
http://example.com/video/playchannel/13/free
Don't use $this->input->get('something') when you are not using a query string on your URL.
Hope this helps!

In Codeigniter you can get segments using $this->uri->segment(n); // n=1 for controller, n=2 for method, etc
This provides you to retrieve information from your URI strings
consider this example http://example.com/index.php/controller/action/1stsegment/2ndsegment
it will return
$this->uri->segment(1); // controller
$this->uri->segment(2); // action
$this->uri->segment(3); // 1stsegment
$this->uri->segment(4); // 2ndsegment

For the below link you can get the values using input->post
http://site.org/project/controllername?id=1&type=free
example: to get the id & type
//add this in controller function.
$this->input->post('id');
or for the other link http://site.org/project/controllername/function/1/free
generally for every name from controller seperated with '/' are segments of URL
$this->uri->segment(n);
<a href="<?php echo site_url();?>controllername/function?id=<?php echo $defaultrow->id;?>&type=free">
for more information visit this link

Related

Using php GET after mod rewrite [duplicate]

I have a index.php which handle all the routing index.php?page=controller (simplified) just to split up the logic with the view.
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w\d~%.:_\-]+)$ index.php?page=$1 [NC]
Which basically:
http://localhost/index.php?page=controller
To
http://localhost/controller/
Can anyone help me add the Rewrite for
http://localhost/controller/param/value/param/value (And soforth)
That would be:
http://localhost/controller/?param=value&param=value
I can't get it to work with the Rewriterule.
A controller could look like this:
<?php
if (isset($_GET['action'])) {
if ($_GET['action'] == 'delete') {
do_Delete_stuff_here();
}
}
?>
And also:
<?php
if (isset($_GET['action']) && isset($_GET['x'])) {
if ($_GET['action'] == 'delete') {
do_Delete_stuff_here();
}
}
?>
Basically what people try to say is, you can make a rewrite rule like so:
RewriteRule ^(.*)$ index.php?params=$1 [NC, QSA]
This will make your actual php file like so:
index.php?params=param/value/param/value
And your actual URL would be like so:
http://url.com/params/param/value/param/value
And in your PHP file you could access your params by exploding this like so:
<?php
$params = explode( "/", $_GET['params'] );
for($i = 0; $i < count($params); $i+=2) {
echo $params[$i] ." has value: ". $params[$i+1] ."<br />";
}
?>
I think it's better if you redirect all requests to the index.php file and then extract the controller name and any other parameters using php. Same as any other frameworks such as Zend Framework.
Here is simple class that can do what you are after.
class HttpRequest
{
/**
* default controller class
*/
const CONTROLLER_CLASSNAME = 'Index';
/**
* position of controller
*/
protected $controllerkey = 0;
/**
* site base url
*/
protected $baseUrl;
/**
* current controller class name
*/
protected $controllerClassName;
/**
* list of all parameters $_GET and $_POST
*/
protected $parameters;
public function __construct()
{
// set defaults
$this->controllerClassName = self::CONTROLLER_CLASSNAME;
}
public function setBaseUrl($url)
{
$this->baseUrl = $url;
return $this;
}
public function setParameters($params)
{
$this->parameters = $params;
return $this;
}
public function getParameters()
{
if ($this->parameters == null) {
$this->parameters = array();
}
return $this->parameters;
}
public function getControllerClassName()
{
return $this->controllerClassName;
}
/**
* get value of $_GET or $_POST. $_POST override the same parameter in $_GET
*
* #param type $name
* #param type $default
* #param type $filter
* #return type
*/
public function getParam($name, $default = null)
{
if (isset($this->parameters[$name])) {
return $this->parameters[$name];
}
return $default;
}
public function getRequestUri()
{
if (!isset($_SERVER['REQUEST_URI'])) {
return '';
}
$uri = $_SERVER['REQUEST_URI'];
$uri = trim(str_replace($this->baseUrl, '', $uri), '/');
return $uri;
}
public function createRequest()
{
$uri = $this->getRequestUri();
// Uri parts
$uriParts = explode('/', $uri);
// if we are in index page
if (!isset($uriParts[$this->controllerkey])) {
return $this;
}
// format the controller class name
$this->controllerClassName = $this->formatControllerName($uriParts[$this->controllerkey]);
// remove controller name from uri
unset($uriParts[$this->controllerkey]);
// if there are no parameters left
if (empty($uriParts)) {
return $this;
}
// find and setup parameters starting from $_GET to $_POST
$i = 0;
$keyName = '';
foreach ($uriParts as $key => $value) {
if ($i == 0) {
$this->parameters[$value] = '';
$keyName = $value;
$i = 1;
} else {
$this->parameters[$keyName] = $value;
$i = 0;
}
}
// now add $_POST data
if ($_POST) {
foreach ($_POST as $postKey => $postData) {
$this->parameters[$postKey] = $postData;
}
}
return $this;
}
/**
* word seperator is '-'
* convert the string from dash seperator to camel case
*
* #param type $unformatted
* #return type
*/
protected function formatControllerName($unformatted)
{
if (strpos($unformatted, '-') !== false) {
$formattedName = array_map('ucwords', explode('-', $unformatted));
$formattedName = join('', $formattedName);
} else {
// string is one word
$formattedName = ucwords($unformatted);
}
// if the string starts with number
if (is_numeric(substr($formattedName, 0, 1))) {
$part = $part == $this->controllerkey ? 'controller' : 'action';
throw new Exception('Incorrect ' . $part . ' name "' . $formattedName . '".');
}
return ltrim($formattedName, '_');
}
}
How to use it:
$request = new HttpRequest();
$request->setBaseUrl('/your/base/url/');
$request->createRequest();
echo $request->getControllerClassName(); // return controller name. Controller name separated by '-' is going to be converted to camel case.
var_dump ($request->getParameters()); // print all other parameters $_GET & $_POST
.htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Your rewrite rule would pass the entire URL:
RewriteRule ^(.*)$ index.php?params=$1 [NC]
Your index.php would interpret that full path as controller/param/value/param/value for you (my PHP is a little rusty):
$params = explode("/", $_GET['params']);
if (count($params) % 2 != 1) die("Invalid path length!");
$controller = $params[0];
$my_params = array();
for ($i = 1; $i < count($params); $i += 2) {
$my_params[$params[$i]] = $params[$i + 1];
}
How about redirect to index.php?params=param/value/param/value, and let php split the whole $_GET['params']? I think this is the way wordpress handling it.
For some reason, the selected solution did not work for me. It would constantly only return "index.php" as value of params.
After some trial and error, I found the following rules to work well. Assuming you want yoursite.com/somewhere/var1/var2/var3 to point to yoursite.com/somewhere/index.php?params=var1/var2/var3, then place the following rule in a .htaccess file in the "somewhere" directory:
Options +FollowSymLinks
RewriteEngine On
# The first 2 conditions may or may not be relevant for your needs
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-f
# This rule converts your flat link to a query
RewriteRule ^(.*)$ index.php?params=$1 [L,NC,NE]
Then, in PHP or whichever language of your choice, simply separate the values using the explode command as pointed out by #Wesso.
For testing purposes, this should suffice in your index.php file:
if (isset($_GET['params']))
{
$params = explode( "/", $_GET['params'] );
print_r($params);
exit("YUP!");
}
Is this what your looking for?
This example demonstrates how to easily hide query string parameters using loop flag. Suppose you have URL like http://www.mysite.com/foo.asp?a=A&b=B&c=C and you want to access it as http://www.myhost.com/foo.asp/a/A/b/B/c/C
Try the following rule to achieve desired result:
RewriteRule ^(.*?\.php)/([^/]*)/([^/]*)(/.+)? $1$4?$2=$3 [NC,N,QSA]
Are you sure you are using apache server,.htaccess works only on apache server. If you are using IIS then web.config is reqired. In that case:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Homepage">
<match url="Homepage"/>
<action type="Rewrite" url="index.php" appendQueryString="true"/>
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"/>
<handlers>
<add name="php" path="*.php" verb="*" modules="IsapiModule" scriptProcessor="C:\Program Files\Parallels\Plesk\Additional\PleskPHP5\php5isapi.dll" resourceType="Unspecified"/>
</handlers>
</system.webServer>
</configuration>

404 on http request

When I try to make an ajax request to a codeigniter route I get an 404 error
The root folder of the project is http://localhost/control_cuotas/
this is the controller(index works):
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Control_cuotas_controller extends CI_Controller {
public function index()
{
$data = array();
$tables = $this->getTables();
$data['tables'] = $tables;
$this->load->view('main/main_view', $data);
}
public function getData($data){
var_dump($data);
}
private function getTables(){
$sql = "SELECT TABLE_NAME "
."FROM INFORMATION_SCHEMA.TABLES "
."WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME LIKE 'datos_%'";
$query = $this->db->query($sql);
$tables = array();
foreach ($query->result() as $row){
$name = substr($row->TABLE_NAME,0,-2);
if(!in_array($name,$tables)){
array_push($tables, $name);
}
}
return $tables;
}
and this is the javascript:
$(document).ready(function(){
$('#tables').change(function(){
var selected = $(this).val();
$.ajax({
url:'getData/'+selected
});
});
});
}
an this is the route
$route['getData/(:any)']['GET'] = 'control_cuotas_controller/getData/$1';
The request is done on the following url
http://localhost/control_cuotas/getData/selected_value
Please Check .htaccess file
and Try this code;
RewriteEngine on
RewriteCond $1 !^(index\.php|public|\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1
OR
$(document).ready(function(){
$('#tables').change(function(){
var selected = $(this).val();
$.ajax({
url:'http://localhost/control_cuotas/getData/'+selected
});
});
});
}
You haven't added .htaccess code to remove index.php from the URL. Either do that or in your JavaScript change the URL as http(:)//localhost/control_cuotas/index.php/getData

codeigniter routing wont route correctly

I'm new to codeigniter and i'm doing a project now..
I have a home controller which controlls all the pages and it is working fine.
The website contains an article page where it displays all the articles and if some one clicks on the read more it will redirect to article details page
The problem is if i click the read more link (eg : http://example.com/articles_details/2/sample-slug) on the articles page, it automatically redirects to http://example.com/articles_details/2 .... can somebody help me to fix this.
below is the details of my project files
Folder structure
website_folder/
–––– application/
---------- controllers/
---------------- admin/
---------------- home.php
---------- views/
---------------- templates/
--------------------- articles.php
--------------------- article_details.php
---------------- _main_layout.php
–––– assets/
–––– system/
---- .htaccess
–––– index.php
home controller
class Home extends Frontend_Controller
{
function __construct()
{
parent::__construct();
}
public function index()
{
$slug = $this->uri->segment(1) ? $this->uri->segment(1) : 'home';
$this->data['page'] = $slug;
$method = '_'.$slug;
if(method_exists($this,$method))
{
$this->$method();
}
else
{
show_error('Could not load template '.$method);
}
$this->data['subview'] = $slug;
$this->load->view('components/page_head');
$this->load->view($layout,$this->data);
$this->load->view('components/page_tail');
$this->load->view('components/'.$script);
}
private function _home()
{
//fetch datas to be shown in homepage
}
private function _articles()
{
//fetch datas to be shown in article page
}
private function _article_details()
{
//fetch datas to be shown in article detail page
$aid = $this->uri->segment(2);
$query = $this->db->query("select * from articles where id = ".$aid);
$this->data['articledetails'] = $query->row();
count($this->data['v']) || show_404(uri_string());
$rslug = $this->uri->segment(3);
$sslug = $articledetails->slug;
if($rslug != $sslug)
{
redirect('article_details/'.$aid.'/'.$sslug,'location','301');
}
}
}
routes.php
$default_controller = "home";
$controller_exceptions = array('admin');
$route['default_controller'] = $default_controller;
$route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/index/$1';
$route['404_override'] = '';
Htaccess File
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
</IfModule>
articles.php (views file)
<div id="articles">
<?php if($pagination) echo $pagination; ?>
<ul class="articles">
<?php
if(count($articles))
{
foreach($articles as $val)
{
?>
<li>
<h2><?php echo $val->heading; ?></h2>
<p><?php echo truncate(strip_tags($val->details),200); ?></p>
[ Read More ]
</li>
<?php
}
}
else
{
echo '<li><strong>No records found..</strong></li>';
}
?>
</ul>
</div>
articles_details.php (views file)
var_dump($articledetails);
You should have a controller named article_details or in your main controller , define a function as article_details and index(as exist) . but Do Not control everything by a function , while you can have lots of it.
So the right way is that you should have a index function , and fetch rows then pass it to the view to show it.
in your view :
foreach($articles as $i){
echo '[ Read More ]';
}
And in your controller , define a function named : article_details . It will be public and you can handle the article ID and fetch details and pass it to the view.
As CI 2.2.0 , method or functions that starts with an underscore _
"..will not be served via a URL request.."
.
have a look here, and find PRIVATE FUNCTIONS.
The logical question here is why would you want to redirect a VISIBLE controller/method to a HIDDEN one?. you will not be able to access anything since you want in Hidden the first place.
Remove the underscores and change the property to public. If you want int to be accessed correctly.
Or maybe you have a typo or forgot to type something from the tutorial you were following.

.htaccess or something adds additional stuff to the URL. PHP

I just recently started to work with .htaccess on a website i'm working on. Everything works just fine, but when I try to acces the user.php file which is located on the index, I keep getting this url:
http://lifeline.andornagy.info/user/?url=user
on every other file and place, it works just great.
This is the function with what I call different pages depending on the URL :
public function lifeline() {
global $templatePath;
if ( isset($_GET['url']) && $_GET['url'] !== 'user' ) {
$url = $_GET['url'];
$result = mysql_query("SELECT * FROM posts WHERE url='$url' ");
if ( !mysql_num_rows($result) ) {
if ( file_exists($templatePath.'404.php') ) {
include_once($templatePath.'404.php');
} else {
include_once('404.php');
}
}
while($row = mysql_fetch_assoc($result)){
if ( $row['type'] === 'post' ) {
include_once($templatePath.'post.php');
} elseif ( $row['type'] === 'page' ) {
include_once($templatePath.'page.php');
}
}
} elseif ($_GET['url'] === 'user') {
include_once($templatePath.'user.php');
} else {
include_once($templatePath.'index.php');
}
}
And this is my .htaccess file.
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?url=$1
RewriteRule ^([a-zA-Z0-9_-]+)/$ index.php?url=$1
RewriteRule ^(.+)(\s|%20)(.+)$ /$1-$3 [R=301,QSA,L,NE]
ErrorDocument 404 /404.php
And I would like if my URL would look like this:
http://lifeline.andornagy.info/user
Without the /?url=user
Sorry If I sound noobish. :(
Without examining this too closely, the last RewriteRule in your .htaccess includes [R=301], making it the only rule capable of "adding" (i.e. redirecting you to) the /?user=x. I'd take a closer look at that last rule.

.htaccess rewrite GET variables

I have a index.php which handle all the routing index.php?page=controller (simplified) just to split up the logic with the view.
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w\d~%.:_\-]+)$ index.php?page=$1 [NC]
Which basically:
http://localhost/index.php?page=controller
To
http://localhost/controller/
Can anyone help me add the Rewrite for
http://localhost/controller/param/value/param/value (And soforth)
That would be:
http://localhost/controller/?param=value&param=value
I can't get it to work with the Rewriterule.
A controller could look like this:
<?php
if (isset($_GET['action'])) {
if ($_GET['action'] == 'delete') {
do_Delete_stuff_here();
}
}
?>
And also:
<?php
if (isset($_GET['action']) && isset($_GET['x'])) {
if ($_GET['action'] == 'delete') {
do_Delete_stuff_here();
}
}
?>
Basically what people try to say is, you can make a rewrite rule like so:
RewriteRule ^(.*)$ index.php?params=$1 [NC, QSA]
This will make your actual php file like so:
index.php?params=param/value/param/value
And your actual URL would be like so:
http://url.com/params/param/value/param/value
And in your PHP file you could access your params by exploding this like so:
<?php
$params = explode( "/", $_GET['params'] );
for($i = 0; $i < count($params); $i+=2) {
echo $params[$i] ." has value: ". $params[$i+1] ."<br />";
}
?>
I think it's better if you redirect all requests to the index.php file and then extract the controller name and any other parameters using php. Same as any other frameworks such as Zend Framework.
Here is simple class that can do what you are after.
class HttpRequest
{
/**
* default controller class
*/
const CONTROLLER_CLASSNAME = 'Index';
/**
* position of controller
*/
protected $controllerkey = 0;
/**
* site base url
*/
protected $baseUrl;
/**
* current controller class name
*/
protected $controllerClassName;
/**
* list of all parameters $_GET and $_POST
*/
protected $parameters;
public function __construct()
{
// set defaults
$this->controllerClassName = self::CONTROLLER_CLASSNAME;
}
public function setBaseUrl($url)
{
$this->baseUrl = $url;
return $this;
}
public function setParameters($params)
{
$this->parameters = $params;
return $this;
}
public function getParameters()
{
if ($this->parameters == null) {
$this->parameters = array();
}
return $this->parameters;
}
public function getControllerClassName()
{
return $this->controllerClassName;
}
/**
* get value of $_GET or $_POST. $_POST override the same parameter in $_GET
*
* #param type $name
* #param type $default
* #param type $filter
* #return type
*/
public function getParam($name, $default = null)
{
if (isset($this->parameters[$name])) {
return $this->parameters[$name];
}
return $default;
}
public function getRequestUri()
{
if (!isset($_SERVER['REQUEST_URI'])) {
return '';
}
$uri = $_SERVER['REQUEST_URI'];
$uri = trim(str_replace($this->baseUrl, '', $uri), '/');
return $uri;
}
public function createRequest()
{
$uri = $this->getRequestUri();
// Uri parts
$uriParts = explode('/', $uri);
// if we are in index page
if (!isset($uriParts[$this->controllerkey])) {
return $this;
}
// format the controller class name
$this->controllerClassName = $this->formatControllerName($uriParts[$this->controllerkey]);
// remove controller name from uri
unset($uriParts[$this->controllerkey]);
// if there are no parameters left
if (empty($uriParts)) {
return $this;
}
// find and setup parameters starting from $_GET to $_POST
$i = 0;
$keyName = '';
foreach ($uriParts as $key => $value) {
if ($i == 0) {
$this->parameters[$value] = '';
$keyName = $value;
$i = 1;
} else {
$this->parameters[$keyName] = $value;
$i = 0;
}
}
// now add $_POST data
if ($_POST) {
foreach ($_POST as $postKey => $postData) {
$this->parameters[$postKey] = $postData;
}
}
return $this;
}
/**
* word seperator is '-'
* convert the string from dash seperator to camel case
*
* #param type $unformatted
* #return type
*/
protected function formatControllerName($unformatted)
{
if (strpos($unformatted, '-') !== false) {
$formattedName = array_map('ucwords', explode('-', $unformatted));
$formattedName = join('', $formattedName);
} else {
// string is one word
$formattedName = ucwords($unformatted);
}
// if the string starts with number
if (is_numeric(substr($formattedName, 0, 1))) {
$part = $part == $this->controllerkey ? 'controller' : 'action';
throw new Exception('Incorrect ' . $part . ' name "' . $formattedName . '".');
}
return ltrim($formattedName, '_');
}
}
How to use it:
$request = new HttpRequest();
$request->setBaseUrl('/your/base/url/');
$request->createRequest();
echo $request->getControllerClassName(); // return controller name. Controller name separated by '-' is going to be converted to camel case.
var_dump ($request->getParameters()); // print all other parameters $_GET & $_POST
.htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Your rewrite rule would pass the entire URL:
RewriteRule ^(.*)$ index.php?params=$1 [NC]
Your index.php would interpret that full path as controller/param/value/param/value for you (my PHP is a little rusty):
$params = explode("/", $_GET['params']);
if (count($params) % 2 != 1) die("Invalid path length!");
$controller = $params[0];
$my_params = array();
for ($i = 1; $i < count($params); $i += 2) {
$my_params[$params[$i]] = $params[$i + 1];
}
How about redirect to index.php?params=param/value/param/value, and let php split the whole $_GET['params']? I think this is the way wordpress handling it.
For some reason, the selected solution did not work for me. It would constantly only return "index.php" as value of params.
After some trial and error, I found the following rules to work well. Assuming you want yoursite.com/somewhere/var1/var2/var3 to point to yoursite.com/somewhere/index.php?params=var1/var2/var3, then place the following rule in a .htaccess file in the "somewhere" directory:
Options +FollowSymLinks
RewriteEngine On
# The first 2 conditions may or may not be relevant for your needs
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-f
# This rule converts your flat link to a query
RewriteRule ^(.*)$ index.php?params=$1 [L,NC,NE]
Then, in PHP or whichever language of your choice, simply separate the values using the explode command as pointed out by #Wesso.
For testing purposes, this should suffice in your index.php file:
if (isset($_GET['params']))
{
$params = explode( "/", $_GET['params'] );
print_r($params);
exit("YUP!");
}
Is this what your looking for?
This example demonstrates how to easily hide query string parameters using loop flag. Suppose you have URL like http://www.mysite.com/foo.asp?a=A&b=B&c=C and you want to access it as http://www.myhost.com/foo.asp/a/A/b/B/c/C
Try the following rule to achieve desired result:
RewriteRule ^(.*?\.php)/([^/]*)/([^/]*)(/.+)? $1$4?$2=$3 [NC,N,QSA]
Are you sure you are using apache server,.htaccess works only on apache server. If you are using IIS then web.config is reqired. In that case:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Homepage">
<match url="Homepage"/>
<action type="Rewrite" url="index.php" appendQueryString="true"/>
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"/>
<handlers>
<add name="php" path="*.php" verb="*" modules="IsapiModule" scriptProcessor="C:\Program Files\Parallels\Plesk\Additional\PleskPHP5\php5isapi.dll" resourceType="Unspecified"/>
</handlers>
</system.webServer>
</configuration>

Categories