Using SERVER['REQUEST_URI'] and GET in controlling the website flow - php

I have a small website. It's .htaccess file is like this:
RewriteEngine On
RewriteBase /site/
RewriteRule ^(.+)$ index.php [QSA,L]
So it redirects all the URLs to 'index.php'. I can get the requested URL and act accordingly :
$uri = $_SERVER['REQUEST_URI'];
switch($uri)
{
case 'index':
LoadIndex();
break;
case 'about':
LoadAbout();
break;
case 'Posts':
LoadPosts();
break;
default:
LoadNotFound();
}
Say I want to use $_GET[] in Index page. That changes the URL, so it fails to load the page.
How can I do that? How can I route my site without affecting $_GET[] variables in URLs?

$_SERVER[REQUEST_URI] will be /index.php and not index. $_SERVER[REQUEST_URI] also includes the QUERY_STRING. So, it might be /index.php?var1=abc&var2=def.
If you need only the URI path, try PHP_SELF or SCRIPT_NAME. But keep in mind, that these will be /index.php too, including / and .php.
$uri = $_SERVER['PHP_SELF'];
switch($uri)
{
case '/index.php':
LoadIndex();
break;
...
}
You don't need QSA in your RewriteRule. From RewriteRule Directive
Modifying the Query String
By default, the query string is passed through unchanged.
This means, the $_GET variable is available in your PHP script as before.

Related

move index.php to another directory

I am using this GitHub page: https://github.com/Athlon1600/php-proxy-app and as it's supposed to, when I go to development.stech.software it loads up index.php.
When I choose a link, it makes it a query string like this development.stech.software/index.php?q=y6ml06abkWPdp6pnn6PVl6TLlMSkpmdvzdzUj6WZbqbWoQ (where the random characters is the query).
How do I adjust the index.php file, so that when I go to a URL, it loads it on /index.php/query/y6ml06abkWPdp6pnn6PVl6TLlMSkpmdvzdzUj6WZbqbWoQ or something similar.
I tried this, but it wouldn't work (it reported 500), I found it from URL rewriting with PHP
$path = ltrim($_SERVER['REQUEST_URI'], '/'); // Trim leading slash(es)
$elements = explode('/', $path); // Split path on slashes
if(empty($elements[0])) { // No path elements means home
ShowHomepage();
} else switch(array_shift($elements)) // Pop off first item and switch
{
case 'index':
ShowPicture($elements); // passes rest of parameters to internal function
break;
case 'more':
...
default:
header('HTTP/1.1 404 Not Found');
Show404Error();
}
I also added this to .htaccess FallbackResource htdocs/index.php
To redirect /index.php?q=foobar to /index.php/query/foobar you can use the following Rule in your htaccess file:
FallbackResource htdocs/index.php
RewriteEngine on
RewriteCond %{QUERY_STRING} ^q=(.+)$
RewriteRule ^index.php$ /index.php/query/%1? [L,R]

Rewrite URL in .htaccess just cause 404 error

I'm trying to learn how to rewrite URL in the .htaccess file. I have read some tutorials, but despite that I write as in the example code, nothing happens for me! I'm wondering what I'm doing wrong here? I get a 404-code when I'm trying the code below.
RewriteEngine On
RewriteRule /byggnader/1/ /?p=byggnad&id=1
This is just a test and I wonder if /byggnader/ must be an existing file or just a name in the URL. I'm using a page controler design. So URL /?p=byggnad&id=1 will open the PSelectedBuilding.php file inside the index.php file.
I preciate some feedback to be able to continue.
EDIT: Since it's not working despite the help below, I also add the code from the index.php file that handle the requests. Perhaps that could give a clue why!?
<?php
session_start();
// Allow only access to pagecontrollers through frontcontroller
$indexIsVisited = TRUE;
require_once('config.php');
// pagecontrol
$page = isset($_GET['p']) ? $_GET['p'] : 'start';
switch($page) {
case 'start': require_once('PIndex.php'); break;
case 'karta': require_once('PMap.php'); break;
case 'byggnader': require_once('PBuildings.php'); break;
case 'tips': require_once('PTips.php'); break;
case 'visa-byggnad': require_once('PHandleSessions.php'); break;
case 'byggnad': require_once('PSelectedBuilding.php'); break;
case 'visa': require_once('PSelectedBuilding.php'); break;
case 'visa2': require_once('PHandleSessions.php'); break;
default: require_once('PIndex.php'); break;
}
require_once("CreatePage.php"); // Call file that creates the page
?>
EDIT 2:
This works fine, but not when I'm using requests for some of the pages:
RewriteEngine On
RewriteRule bilder-byggnader-kopenhamn /?p=byggnader
RewriteRule karta-byggnader-kopenhamn /?p=karta
RewriteRule start /?p=start
RewriteRule tips /?p=tips
Remove leading slash from your rule. .htaccess is per directory directive and Apache strips the current directory path (thus leading slash) from RewriteRule URI pattern.
RewriteEngine On
RewriteRule ^byggnader/1/?$ /?p=byggnad&id=1 [L]
Try this one:
RewriteEngine On
RewriteCond %{QUERY_STRING} p=(\w+)&id=(\d+)
RewriteRule ^index.php /%1/%2? [R=301, L]
The RewriteCond mathches the Query String (as per your wish) extracting two variables which you can reuse to build your redirection target in the rewrite rule directive. The final question mark tells Apache not to reappend existing QS. R=301 says that the redirection is permanent, L that this is the last rule to be processed.
You may have to play with the index.php part since you never put the REQUEST_URI part in your question.

Understanding the front controller with PHP

I'm very new with PHP, and I've managed to create a really rough CMS. At the moment, it's using many different pages and includes.
However, if possible I'd like to use a controller rather than having lots of pages (I've already got article.php/admin.php).
As an example, I'm trying to convert to something like this:
switch ( 'admin' ) {
case 'home':
include 'view/home.php';
break;
case 'admin':
include 'view/admin.php';
break;
case 'article':
include 'view/article.php';
break;
default:
echo 'default';
break;
}
This would be used with $_GET['page'], so the admin URL looks like: http://cms.dev/?page=admin
However, what happens if I need to go to a subdirectory of admin? For example, if these were hardcoded pages, I would go admin/new-post.php. Is there an equivalent I could get, using the $_GET method?
Sorry if this has not been explained well. Let me know and I will try and edit it. I've used a smorgsaboard of tutorials so I'm not 100% on any of this.
You can have forward slashes in your $_GET['page'] variable, so https://cms.dev/?page=admin/new-post.php should work fine.
Alternatively you can put this into your .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
And then get it from the REQUEST_URI:
$uri = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);

How do I restructure the htaccess to allow for the home page?

Ok so I have a site that has tons of pages and I want to create a php file fore each one...this works great..here is what i have, code wise
Here is my htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
here is my index.php file
$parts = explode('/', $_REQUEST['url']);
switch ($parts[count($parts) - 1]) {
case 'restaurant':
include "pages/restaurant.php";
break;
case 'retail':
include "pages/retail.php";
break;
.......
.......
}
this works great and if i visit the url http://someurl.com/restaurant the proper file in pages/restaurant.php pulls up. The only problem is the home page http://someurl.com when i visit it i get a:
Forbidden
You don't have permission to access /structure on this server.
Is there a way to fix this in the .htaccess to address this issue and should i create a file maybe called home.php in the pages folder or should i just put the content of the home page in the index file in an else condition...any ideas
You forgot to specify a default switch case?
switch ($parts[count($parts) - 1]) {
case 'restaurant':
include "pages/restaurant.php";
break;
case 'retail':
include "pages/retail.php";
break;
default:
include "pages/default_page.php";
break;
.......
.......
}
1. Use this rule somewhere before existing rules:
RewriteRule ^$ index.php?url=home [L]
2. Create pages/home.php
3. Add this to your switch statement:
case 'home':
include "pages/home.php";
break;
P.S. I do not recommend using default: to handle home page. default: should be used to handle 404 page / unknown pages ONLY.
Do you have a default statement in that switch? My bet is you don't.
DirectoryIndex index.php
Do you have this code in your httpd.conf or .htaccess?
It seems like your default file is not index.php

How can I quickly set up a RESTful site using PHP without a Framework?

I would like to quickly set up a RESTful site using PHP without learning a PHP Framework. I would like to use a single .htaccess-file in Apache or a single rule using Nginx, so I easyli can change web server without changing my code.
So I want to direct all requests to a single PHP-file, and that file takes care of the RESTful-handling and call the right PHP-file.
In example:
The user request http://mysite.com/test
The server sends all requests to rest.php
The rest.php call test.php (maybe with a querystring).
If this can be done, is there a free PHP-script that works like my rest.php? or how can I do this PHP-script?
Using Apache Mod Rewrite:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^test$ rest.php [nc]
Yes, make a 404 Redirect to a page called rest.php. Use $url = $_SERVER['REQUEST_URI']; to examine the url. In rest.php you can redirect to wherever you want.
This only requires one rule (404 in your .htaccess file).
You have to be careful and make sure that if the page requested (e.g. mysite.com/test1 doesn't have a test1.php) errors out with a 404 you don't get yourself caught in a loop.
Modified slightly from the way that Drupal does it. This redirects everything to rest.php and puts the original requested URL into $_GET['q'] for you do take the appropriate action on. You can put this in the apache config, or in your .htaccess. Make sure mod_rewrite is enabled.
RewriteEngine on
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ rest.php?q=$1 [L,QSA]
If all you then want to do is include the requested file, you can do something like this
<?php
if (!empty($_GET['q'])) {
$source = $_GET['q'] . '.php';
if (is_file($source)) {
include $source;
} else {
echo "Source missing.";
}
}
?>
You really don't want to do that, however; if someone were to request '/../../../etc/passwd', for example, you might end up serving up something you don't want to.
Something more like this is safer, I suppose.
<?php
if (!empty($_GET['q'])) {
$request = $_GET['q'];
switch ($request) {
case 'test1':
include 'test1.php';
break;
default:
echo 'Unrecognised request.';
break;
}
}
?>

Categories