I would personally say that such a security matter is rather useless. In all of the many, many websites I've built. I've never used any of these.
The best way I know of to prevent people from getting into places where you don't want them to go, is to bunch all of your classes into one folder and deny access to said folder from the outside. Then, you use one file in the root (index.php or so) to call upon said files through the requested URL. This would also give you user-friendly URL's.
A little bit of object-oriënted coding should take care of most security issues.
I'll give you a working example of such a feat here:
Your root files:
.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
#Request index.php and put a GET parameter 'request'
RewriteRule ^(.+)$ index.php?request=$1 [QSA,L]
Then, from your index.php, include your main-class and routing
require_once 'application/main.php';
require_once 'application/routing.php';
Your unreachable files:
Put these in a subdirectory, for example, /application/
.htaccess:
#This will deny access from any outside source.
#You reach these files through index.php
deny from all
Main class
class main
{
public $someVar;
public function setSomeVar(){
$this->someVar = "I can get into the main class,
and shall use it for global functions!";
}
}
The requested page class: home.php
class home extends main
{
public function renderTemplate(){
//You can reach the main's functions from here
//You could create a rendertemplate function in the main class
//And set the template from this function for example.
$this->setSomeVar();
echo $this->someVar();
}
}
And then, most importantly, you will have your routing:
$noRequest = true;
$params = array();
$class;
//all routes go from your index.php's location
$filepath = "application/";
//Get the requested class and parameters
$getRequest = explode('/', $request->get('request'));
//Load homepage if no special request is made
if( $getRequest[0] == '' ) {
$page = "home";
} else {
//get the class
$page = rtrim($getRequest[0], '/');
//Get the called function
$getFunction = isset( $getRequest[1] ) ? $getRequest[1] : false;
}
//Include the requested class. Otherwise, give back a 404
if( file_exists($filepath . $page . ".php") ) {
//include the class
require_once $filepath . $page . ".php";
//set the class object
$class = new $page();
} else {
header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found", true, 404);
//TODO:create 404 class
echo "Page not found";
exit();
}
//There is a function being called, go get it!
if( $getFunction ) {
//Make sure you've gotten the parameters as well
$paramCount = count($getRequest);
//skip 0 and 1, as those are the class and function
for( $i = 2; $i < $paramCount; $i++ ) {
$params[] = $getRequest[$i];
}
//Check if method exists
if( method_exists($class, $getFunction) ) {
//Always echo the function for returns. This is made for AJAX calls.
echo call_user_func_array(array(
$class,
$getFunction
), $params);
} else {
die( "function $getFunction was not found in $page" );
}
exit();
} else {
//No function being called, this has to be a pageload;
//Don't echo the function because of the templates
$class->renderTemplate();
}
--
The above is kind of a basic form of how any MVC does it, and it's a dumbed down version of what I've always worked with. Basically, this gives your website one single entry point (the index.php) and makes everything else forbidden. This way, nobody can do anything that your routing will not allow. By having a steady class->function
routing system, nobody can just go wildly going through your urls, looking for holes.
Your urls from this point on, would look like this:
http://website.com/page2
would be the class page2
and do whatever you wanted it to do within said class.
http://website.com/page2/functionOfPage2Class
could be used for ajax calls.
A sidenote:
This way, you could also call said function classes from within your templates, by simply using $this->Myfunction();
.
Now, I'm not going to state that this is the best way or the best answer you'll get. The only thing I'll state is that this is approximately what I've worked with so far, and none of my clients have been hacked as far as I know of.
Please, let me know if I did anything wrong or if there are any questions.
You don't actually need all these classes and such
I thought it would be important to mention that you don't actually have to use this structure I gave you. It is just meant to be an example. Obviously, you can do anything you want, as long as you route whatever you want to do through your index.php
. That's the entire point of the example scripts.
Long story short: You put all your php files into a subfolder and deny ALL access to it.