What's the best way to remove the = and ? in a URL from the get method in PHP? I'm working on the pagination structure of my website and currently this is what the URLs look like:
www.example/test/?page=3
I want it to look like this:
www.example/test/3
Can this be addressed directly in the PHP get method with some extra code or does it have to be done through an htaccess file?
This is what my htaccess file looks like right now:
RewriteBase /
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
RewriteCond %{REQUEST_URI} /index\.html?$ [NC]
RewriteRule ^(.*)index\.html?$ "/$1" [NC,R=301,NE,L]
Here is my try, I compacted some already existing answer from different StackOverflow topics dealing with URL extraction and I came up with this solution :
<?php
function http_protocol() {
/**
* #see https://stackoverflow.com/a/6768831/3753055
*/
return (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://';
}
function http_host() {
return $_SERVER['HTTP_HOST'];
}
function http_uri() {
return parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
}
function http_refactored_query_strings() {
$queries = explode('&', $_SERVER['QUERY_STRING']);
$refactoredQueries = [];
foreach( $queries as $query ) {
$refactoredQueries[] = filter_var(explode('=', $query)[1], FILTER_SANITIZE_STRING);
}
$queries = implode('/', $refactoredQueries);
return $queries ?: '';
}
function http_refactored_url() {
return http_protocol() . http_host() . http_uri() . http_refactored_query_strings();
}
echo http_refactored_url();
?>
Tryied with some examples :
GET http://example.com/test.php : http://example.com/test.php
GET http://example.com/test.php?page=3 : http://example.com/test.php/3
GET https://example.com/test.php?view=page?page=3 : https://example.com/page/3
GET http://example.com/?page=3 : http://example.com/3
For the query string refactoring part, I used $_SERVER['QUERY_STRING] and exploded the value to & character. because the first ? is not contained in $_SERVER['QUERY_STRING']. So you come up with lot of arrays, containing strings like page=3, view=page, ... And foreach one, you split it using = delimiter and get the second element (index : 1) to append it to the solution.
Hope it helps
You can do this by using an intermediate page, say index.php and apply .htaccess rewrite only for index and load page based on GET[] on index.php.
You can refer this:
URL rewriting in PHP without htaccess
Related
My URL is:
example.com/controller/function/parameter
=> example.com/category/index/category_name
I need:
example.com/category/category_name
I have tried several solutions provided by Stackoverflow questions asked on this, but it´s not working. Either it redirects to home or a 404 page not found.
The options I have tried are:
$route['category'] = "category/index"; //1
$route['category/(:any)'] = "category/index"; //2
$route['category/(:any)'] = "category/index/$1"; //3
Another route is:
$route['default_controller'] = 'home';
The htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
RewriteRule ^(.*)$ index.php/$1 [L]
In config file I have:
$config['url_suffix'] = '';
I am not sure why you couldn't get it to work.
Here is some test code I created to check this out...
This is using CI 3.1.5.
.htaccess - same as what you have...
Controller - Category.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Category extends CI_Controller {
public function __construct() {
parent::__construct();
}
public function index($category_name = 'None Selected') {
echo "The Category name is " . $category_name;
}
}
routes.php
$route['category/(:any)'] = "category/index/$1"; //3 - this works
$route['default_controller'] = 'welcome';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
Test URLS
/category/ output: The Category name is None Selected
/category/fluffy-bunnies output: The Category name is fluffy-bunnies
Have a play with that and see if you can find the issue.
I think you have error in your .htaccess file. Please find below code for .htaccess file.
You can use RewriteBase to provide a base for your rewrites.
RewriteEngine On
RewriteBase /campnew/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
RewriteRule ^(.*)$ index.php/$1 [L]
In Controller your method.
public function index($category_name = null) {
$this->load->model('category_model');
$data = array();
if ($query = $this->category_model->get_records_view($category_name)) {
$data['recordss'] = $query;
}
if ($query2 = $this->category_model->get_records_view2($category_name))
{
$data['recordsc2'] = $query2;
}
$data['main_content'] = 'category';
$this->load->view('includes/template', $data);
}
In Model File
public function get_records_view($category){
$this->db->where('a.linkname', $category);
}
Let me know if it not works.
I've seen/read questions about clean URLs with .htaccess, but for the life of me, I cannot get them to work for my specific needs. I keep getting 404 message.
Example: www.mysite.com/article.php?id=1&title=my-blog-title
I would like for url to be: www.mysite.com/article/1/my-blog-title
Here's what I have so far in my .htaccess:
Options -MultiViews
#DirectorySlash on
RewriteCond %{HTTP_HOST} !^www [NC]
RewriteRule .* http://www.%{HTTP_HOST}%{REQUEST_URI} [L]
# Rewrite for article.php?id=1&title=Title-Goes-Here
RewriteRule ^article/([0-9]+)/([0-9a-zA-Z_-]+) article.php?id=$1&title=$2 [NC,L]
#Rewrite for certain files with .php extension
RewriteRule ^contact$ contact.php
RewriteRule ^blogs$ blogs.php
RewriteRule ^privacy-policy$ privacy-policy.php
RewriteRule ^terms-of-service$ terms-of-service.php
Also, is this how I would link to article? article.php?id=<?php echo $row_rsBlogs['id']; ?>&slug=<?php echo $row_rsBlogs['slug']; ?> or article/<?php echo $row_rsBlogs['id']; ?>/<?php echo $row_rsBlogs['slug']; ?>
I'm using Dreamweaver, but I am comfortable hand coding.
Thanks in advance.
You could use a dispatcher by telling the webserver to redirect all request to e.g. index.php..
In there a dispatch instance analizes the request and invokes certain controllers (e.g. articlesControllers)
class Dispatcher
{
// dispatch request to the appropriate controllers/method
public static function dispatch()
{
$url = explode('/', trim($_SERVER['REQUEST_URI'], '/'), 4);
/*
* If we are using apache module 'mod_rewrite' - shifting that 'request_uri'-array would be a bad idea :3
*/
//array_shift($url);
// get controllers name
$controller = !empty($url[0]) ? $url[0] . 'Controller' : 'indexController';
// get method name of controllers
$method = !empty($url[1]) ? $url[1] : 'index';
// get argument passed in to the method
$parameters = array();
if (!empty($url[2])) {
$arguments = explode('/', $url[2]);
foreach ($arguments as $argument) {
$keyValue = explode('=',$argument);
$parameters[$keyValue[0]] = $keyValue[1];
}
}
// create controllers instance and call the specified method
$cont = new $controller;
if(!method_exists($cont,$method)) {
throw new MethodNotFoundException("requested method \"". $method . "\" not found in controller \"" . $controller . "\"");
}
$cont->$method($parameters);
}
}
in .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php
In first .htaccess,I send url to public/index.php:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ public/index.php [NC,L]
And my public/index.php:
<?php
// define root path of the site
if(!defined('ROOT_PATH')){
define('ROOT_PATH','../');
}
require_once ROOT_PATH.'function/my_autoloader.php';
use application\controllers as controllers;
$uri=strtolower($_SERVER['REQUEST_URI']);
$actionName='';
$uriData=array();
$uriData=preg_split('/[\/\\\]/',$uri );
$actionName = (!empty($uriData[3])) ? preg_split('/[?].*/', $uriData[3] ): '' ;
$actionName =$actionName[0];
$controllerName = (!empty($uriData[2])) ? $uriData[2] : '' ;
switch ($controllerName) {
case 'manage':
$controller = new Controllers\manageController($controllerName,$actionName);
break;
default:
die('ERROR WE DON\'T HAVE THIS ACTION!');
exit;
break;
}
// function dispatch send url to controller layer
$controller->dispatch();
?>
I have this directory :
application
controller
models
view
public
css
java script
index.php
.htaccess
I want to have clean URL for example localhost/lib/manage/id/1 instead of localhost/lib/manage?id=1,what should I do ?
Using your current rewrite rules, everything is already redirected to your index.php file. And, as you are already doing, you should parse the URL to find all these URL parameters. This is called routing, and most PHP frameworks do it this way. With some simple parsing, you can transform localhost/lib/manage/id/1 to an array:
array(
'controller' => 'manage',
'id' => 1
)
We can simply do this, by first splitting the URL on a '/', and then looping over it to find the values:
$output = array();
$url = split('/', $_SERVER['REQUEST_URI']);
// the first part is the controller
$output['controller'] = array_shift($url);
while (count($url) >= 2) {
// take the next two elements from the array, and put them in the output
$key = array_shift($url);
$value = array_shift($url);
$output[$key] = $value;
}
Now the $output array contains a key => value pair like you want to. Though note that the code probably isn't very safe. It is just to show the concept, not really production-ready code.
You could do this by capturing part of the URL and and placing it as a querystring.
RewriteRule /lib/manage/id/([0-9]+) /lib/manage?id=$1 [L]
The string inside the parenthesis will be put into the $1 variable. If you have multiple () they will be put into $2, $3 and so on.
the url to access the method is like this:
http://localhost/site/cont/method
I want to access this method using GET method like this:
http://localhost/new-tera/paper/lookup_doi/segment but my segment part is already containing /like this:
http://localhost/lookup_doi/segment/containing/slashes
note that the whole segment/containing/slashes is one value.
I am getting this value in my method like this:
public function method ($variable)
{
echo $variable;
}
//output: segment
and not : segment/containing/slashes
CodeIgniter passes the rest of them as additional arguments. You can either specify the additional arguments (if the number is fixed) or use:
implode('/', func_get_args())
to get the entire string.
.htaccess mast be
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]
so ok...
$route = empty($_GET['route']) ? '' : $_GET['route'];
$exp = explode('/', $route);
results:
$exp[0] = new-tera
$exp[1] = paper
$exp[2] = lookup_doi
$exp[3] = segment
and so we mast be have routing! run example(with my projects):
if($exp[0] == '')
{
$file = $_SERVER['DOCUMENT_ROOT'] .'/controllers/controller_index.php';
}
else
{
$file = $_SERVER['DOCUMENT_ROOT'] .'/controllers/controller_'.$exp[0].'.php';
}
if(!file_exists($file))
{
engine :: away();
}
include_once $file;
$class = (empty($exp[0]) or !class_exists($exp[0])) ? 'class_index' : $exp[0];
$controller = new $class;
$method = (empty($exp[1]) or !method_exists($controller, $exp[1])) ? 'index' : $exp[1];
$controller -> $method();
you can add slashes by adding "%2F" in your query string hope this will work
segment = 'somethingwith%2F'
http://localhost/new-tera/paper/lookup_doi/segment
You can base64 encode it first and decode it after. Really, you can use a variety of methods to change the / to something else (i.e. a -) and change it back.
echo site_url('controller/method/' . base64_encode($variable));
public function method ($variable)
{
$variable = base64_decode($variable);
}
I am submitting a normal <form method="get"> element to the current url... It's part of a search page. The resulting url is below.
http://domain.com/module/controller/action/get1/value1/?get2=get2&value3=value3
The problem is I am using <?= $this->url(array('page' => x)); ?> and similar to navigate around but I want to retain the $_GET params... Whenever I use it, it retains the / slashed $_GET params and looses the ?&= value pairs...
I want to use Mod_Rewrite to change the value pairs to slashes...
My current rule is..
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ zend.php [NC,L]
I'm not confident with Mod_Rewrite and I don't want to conflict with the existing rules.
I also like a trailing slash as well... so that would be a bonus...
Please help!! Many thanks...
PS...
Re "Zend_Router... Zend_Form.." in the title. I am using Zend_Form to construct the form and I realise that I could use javascript on the onSubmit function to write the URL... similarly I could use the Zend_Router to rewrite the url... I think Mod_rewrite is best though...
I do not know how to implement this, using regular expressions and mod_rewrite, but you can extend Zend_Controller_Router_Route like this and use it instead standard router:
<?php
class ZendY_Controller_Router_Route_GetAware extends
Zend_Controller_Router_Route
{
public static function getInstance(Zend_Config $config)
{
$reqs = ($config->reqs instanceof Zend_Config)
? $config->reqs->toArray() : array();
$defs = ($config->defaults instanceof Zend_Config)
? $config->defaults->toArray() : array();
return new self($config->route, $defs, $reqs);
}
public function match($path)
{
foreach ($_GET as $k => $v) {
if (is_array($v)) {
$v = implode(',', $v);
}
$path .= "{$this->_urlDelimiter}{$k}{$this->_urlDelimiter}{$v}";
}
parent::match($path);
}
}
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.