I just can't figure out, how to make this work.
I have a main page into which I am including other pages, creating URL's without file extensions:
switch ($_GET['page'])
{
case "search":
include "pages/search.php";
break;
}
Then I have a GET form sending a value from the main page to the one included.
The URL looks like this: www.page.com/search?word=value but based on var_dump($_GET) there is no $_GET['word'].
From what you described it looks like you are using .htaccess to redirect the requests from /search to /index.php?page=search.
If that's the case, you are probably looking for [QSA] mod_rewrite flag. Read the documentation at https://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_qsa.
Related
When you edit a question on stackoverflow.com, you will be redirected to a URL like this:
https://stackoverflow.com/posts/1807421/edit
But usually, it should be
https://stackoverflow.com/posts/1807491/edit.php
or
https://stackoverflow.com/posts/edit.php?id=1807491
How was
https://stackoverflow.com/posts/1807421/edit
created?
I know that Stackoverflow.com was not created by using PHP, but I am wondering how to achieve this in PHP?
With apache and PHP, you might perform one of your examples using a mod_rewrite rule in your apache config as follows:
RewriteEngine On
RewriteRule ^/posts/(\d+)/edit /posts/edit.php?id=$1
This looks for URLs of the "clean" form, and then rewrites them so that they are internally redirected to a particular PHP script.
Quite often rules like this are used to route all requests into a common controller script, which might do something like instantiate a "PostsController" class and ask it to handle an edit request. This is a common feature of most PHP application frameworks.
It's called routing. Take a look at tutorials on the subject.
If you use a framework such as cake php it should be built in.
As #mr-euro stated you can use mod_rewrite but front controller is a far better solution.
You force every request to index.php and you write your application controlling in index.php.
You use Apache's .htaccess/mod_rewrite, and optionally a PHP file, which is the approach I like to take myself.
For the .htaccess, something like this:
RewriteEngine On
RewriteRule ^(.*)$ index.php
Then in your PHP file, you can do something like this:
The following should get everything after the first slash.
$url = $_SERVER['REQUEST_URI'];
You can then use explode to turn it into an array.
$split = explode('/', $url);
Now you can use the array to determine what to load:
if ($split[1] == 'home')
{
// display homepage
}
The array is starting from 1 since 0 will usually be empty.
It's indeed done by mod_rewrite, or with multiviews. But i prefer mod_rewrite.
First: you create a .htaccessfile with these contents:
RewriteEngine On
RewriteRule ^posts/([0-9])/(edit|delete)$ /index.php?page=posts&postId=$1&action=$2
Obvious, mod_rewrite must be enabled by your hostingprovider ;)
Using mod_rewrite this can be achieved very easily.
I am poor at this but i do know you can redirect urls using apache mod_rewrite and by touching config files. From what i remember htaccess can be used to redirect. Then internally when the user hits
http://stackoverflow.com/posts/1807421/edit it can use your page http://stackoverflow.com/edit.php?p=1807421 instead or whatever you want.
You could use htaccess + write an URI parser class.
i want to build a website with different views, but a stable header and footer - no problem so far. But i dont like the kind of urls i got at the moment with the php GET method.
My site at the moment works like this (what istn working properly):
$_page = $_GET['p'];
if ($_page == "city-sitemap"){ include "views/city-sitemap-view.php"; }
if ($_page == "place"){ include "views/place-view.php"; }
else { include "views/index-view.php";}
this isnt a very sweet solution but i dont know a other for now. I tried to use a mvc framework but failed dramatically. So everytime i add a link i use for example this "index.php?p=place" - not very nice.
The including of the views isn very smart as well? is there a better way?
I would like to use something like the rewriteEngine that the new url is like a folder.
Can you help me to find a better solution?
Thanks a lot
Page including
For the page inclusion, you can use a simple array to dynamically allocate your page to a specific name. As so:
$pages = array('city-sitemap'=>'views/city-sitemap-view.php',
'place'=>'views/place-view.php',
)
if(array_key_exists($_GET['p'], $pages){
include $pages[$_GET['p']];
}else{
include 'views/error.php';
}
This array should be added in a general configuration file. With this configuration if you want to display your city-sitemap-view.php view, you will have to write this url: http://www.domain.com/index.php?p=city-sitemap
Url rewriting
It is possible to rewrite an URL with a .htaccess file. Here is an example of code you would can to write in your .htaccess file.
RewriteEngine On
RewriteRule ^(.*)$ index.php?p=$1 [L,QSA]
An url that looks like this:
http://www.domain.com/index.php?p=city-sitemap
will be converted to this one:
http://www.domain.com/city-sitemap
There is something called the front controller that you should look into. You can write a very simple one yourself. It works in conjunction with URL rewriting. If for example your url looks like this:
/mypage.html
the url rewriter will reroute the request to index.php .
Index.php will then look at the URL and do somehting like this:
1) break the page out into string, ignoring .html extention
preg_match("\/(.*?)\.html", $_REQUEST['URI'], $matches);
$pageClass = $matches[1];
//$pageClass = "mypage"
2) look for and load a class named "Mypage.php"
$controller = new $pageClass();
3) call the run method on the page class, passing it all the request parameters
$request = new Request($_REQUEST);
$controller->run($request);
you can then do all the page specific stuff inside your controller class that is specific to the page.
At each simple step along the way, you will find you want to do more and more things like authentication, filtering, tracking, etc. You will get end up developing a front controller that is specific to your needs, as well as a base Controller class that does a bunch of standard stuff that all your controllers have in common.
As per my comment, i really think you should consider the framework i linked, (it is very logical) or any other micro framework, but if you really wish to do this yourself then you can handle your includes like so:
<?php //index.php
$requested_page=isset($_GET['p'])?$_GET['p']:'home';
//maybe have this included from pages.php for organization
$pages=array(
'home'=>'home_content.php',
'about'=>'about_content.php',
'contact'=>'contact_content.php'
);
include "views/header.php";
if(array_key_exists($requested_page, $pages)){
include "views/".$pages[$requested_page];
}else{
header('HTTP/1.0 404 Not Found');
include "views/error404.php";
}
include "views/footer.php";
This keeps your pages in a single array, and protects against arbitrary inclusion vulnerabilities.
For nicers urls, see The other users .htaccess rewrite rules
I'm developping a web application in PHP and I would like to refresh a single part of my application. I found some post which explains how to do that with some parameters passing into the URLlike follow:
index.php:
if ((isset($_GET['page'])) && (isset($authorizedPage[$_GET['page']]))) {
require_once ($authorizedPage[$_GET['page']]);
} else {
require_once ('./home.php');
}
So the URL http://example.com/index.php?page=login will display my login page without reloading my index.php... it's ok so far.
But my problem is more how to have the same behavior without passing parameter in the URL. Meaning that if I would like display the login page I will have the following URL http://example.com/login/
Could you help me please ?
For your information in the future, I will need to integrate the notion of multilingual website.
Thanks
I think that you want to change the way people load pages on your website, don't you? So that people can load pages like example.com/login/ and example.com/faq/ instead of example.com?page=login and example.com?page=faq.
You should use the mod_rewrite in a .htaccess file in the root of you server. See http://httpd.apache.org/docs/current/mod/mod_rewrite.html for documentation.
I use the code
<IfModule mod_rewrite.c>
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteRule ^([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?$ index.php?0=$1&1=$2&2=$3&3=$4&4=$5&5=$6&6=$7&7=$8&8=$9 [L,QSA]
</IfModule>
in my .htaccess file to pass all the requests to my index.php file. Each folder in the url will be a GET parameter.
That's the first part of your problem. When you want to reload just a part of your webpage, use JQuery with AJAX, like Marek commented earlier.
The RewriteRule line in my code is a good pattern and will load the index.php file when someone is loading my website. So if someone loads http://mydomain.com/folder1/folder2/file, the file index.php?0=folder1&1=folder2&3=file&4=&5=&6=&7=&8=&9= will be loaded. Then in PHP you can switch on the $_GET parameters to load the right page:
<?php
switch ($_GET['0']) {
case 'faq':
{code}
break;
case 'login':
{code}
break;
default:
{code of you home page}
break;
}
?>
You can paste my .htaccess file in a blank notepad, save it as ".htaccess" and store it in the root of you server. Should work directly.
I am seeing this url format at most websites.
site.com/extension/rar
I wonder how they get the value='rar' using $_GET.
What I know is that $_GET can be use in here
site.com/extension/index.php?ext=rar
Now I wanted to change my way of calling a variable.
I wanted to apply what most websites do.
How can I call variable in the former?
Perhaps this works to get the "rar":
$name = basename($_SERVER['REQUEST_URI']);
I most likely being done using .htaccess
It is an Apache module that allows you "rewrite" urls at the engine level based on your own set of rules. So basically it rewrites URLs on the fly.
So, in your example you could have a file named .htaccess with the following contents: (there may be other options)
RewriteEngine On
RewriteRule ^extension/([a-z0-9]+)$ somefile.php?extension=$1 [L]
Basically, you are saying: If someone is looking for a URL that looks like "extension/somenumbers-and-letters" then show the contents of "somefile.php?extension=whatever-those-number-and-leters-are".
Do a search on Apache mod_rewrite to find more information.
I would like to make my urls more seo friendly and for example change this:
http://www.chillisource.co.uk/product?&cat=Grocery&q=Daves%20Gourmet&page=1&prod=B0000DID5R&prodName=Daves_Insanity_Sauce
to something nice like this:
http://www.chillisource.co.uk/product/Daves_Gourmet/Daves_Insanity_Sauce
What is the best way of going about doing this? I've had a look at doing this with the htaccess file but this seems very complicated.
Thanks in advance
Ben Paton, there is in fact a very easy way out. CMSes like Wordpress tend to use it instead of messing around with regular expressions.
The .htaccess side
First of, you use an .htacess with the content below:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Let me explain what it does (line by line):
if the apache module named mod_rewrite exists..
turn the module on
let it be known that we will rewrite anything starting after the
domain name (to only rewrite some directories, use RewriteBase
/subdir/)
if the requested path does not exist as a file...
and it doesn't even exist as a directory...
"redirect" request to the index.php file
close our module condition
The above is just a quick explanation. You don't really need it to use this.
What we did, is that we told Apache that all requests that would end up as 404s to pass them to the index.php file, where we can process the request manually.
The PHP side
On the PHP side, inside index.php, you simply have to parse the original URL. This URL is passed in the $_SERVER variable as $_SERVER['REDIRECT_URL'].
The best part, if there was no redirection, this variable is not set!
So, our code would end up like:
if ( isset( $_SERVER['REDIRECT_URL'] ) ) {
$url = explode('/', $_SERVER['REDIRECT_URL'] );
switch($url[0]){
case 'home': // eg: /home/
break;
case 'about': // eg: /about/
break;
case 'images': // eg: /images/
switch( $url[1] ){
case '2010': // eg: /images/2010/
break;
case '2011': // eg: /images/2011/
break;
}
break;
}
}
Easy Integration
I nearly forgot to mention this, but, thanks to the way it works, you can even end up not changing your existing code at all!
Less talk, more examples. Let's say your code looked like:
<?php
$page = get_page($_GET['id']);
echo '<h1>'. $page->title .'</h1>';
echo '<div>'. $page->content .'</div>';
?>
Which worked with urls like:
index.php?id=5
You can make it work with SEO URLs as well as keep it with your old system at the same time. Firstly, make sure the .htaccess contains the code I wrote in the one above.
Next, add the following code at the very start of your file:
if ( isset( $_SERVER['REDIRECT_URL'] ) ) {
$url = explode('/', $_SERVER['REDIRECT_URL'] );
$_GET['id'] = $url[0];
}
What are we doing here? Before going on two your own code, we are basically finding IDs and information from the old URL and feeding it to PHP's $_GET variable.
We are essentially fooling your code to think the request had those variables!
The only remaining hurdle to find all those pesky <a/> tags and replace their href accordingly, but that's a different story. :)
It's called a mod_rewrite, here is a tutorial:
http://www.workingwith.me.uk/articles/scripting/mod_rewrite
What about using the PATH_INFO environment variable?
$path=explode("/",getenv("PATH_INFO"));
echo($path[0]."; ".$path[1] /* ... */);
Will output
product; Daves_Gourmet; Daves_insanity_Sauce
The transition from using $_GET to using PATH_INFO environment is a good programming exercise. I think you cannot just do the task with configuration.
try some thing like this
RewriteRule ^/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+) /$1.php?id1=$2&id2=$3 [QSA]
then use $_GET to get the parameter values...
I'll have to add: in your original url, there's a 'prod' key, which seems to consist of an ID.
Make sure that, when switching to rewritten urls, you no longer solely depend upon a unique id, because that won't be visible in the url.
Now, you can use the ID to make a distinction between 2 products with the same name, but in case of rewriting urls and no longer requiring ID in the url, you need to make sure 1 product name can not be used multiple times for different products.
Likewise, I see the 'cat'-key not being present in the desired output url, same applies as described above.
Disregarding the above-described "problems", the rewrite should roughtly look like:
RewriteRule ^/product/(.*?)/(.*?)$ /product?&cat=Grocery&q=$1&page=1&prod=B0000DID5R&prodName=$2
The q & prodName will receive the underscored value, rather than %20, so also that will require some patching.
As you can see, I didn't touch the id & category, it'll be up to you to figure out how to handle that.