I am somewhat a newby at PHP ... so what im trying to do is to get the the page using the following code
<?php include $_GET['topic']; ?>
to get the url like this http://ulixtxteditor.org/entities/helpCentre?topic=credits
that much works great for me however if no page is found i would like to use the else statement to display an error instead of a blank page. What should I do? ex: http://ulixtxteditor.org/entities/helpCentre?topic= so this part would display an error?
<?php if(isset){include $_GET['topic'];} else {echo "error"} ?>
I tried this but it wont work.
Use something like this:
<?php
// In case topic parameter wasn't provided you will have fallback.
$topic = isset($_GET['topic']) ? $_GET['topic'] : '';
// Now you can check topic and have valid file name.
switch ($topic) {
case 'credits':
$fileName = 'credits.php';
break;
default:
$fileName = 'index.php';
break;
}
// Now it is possible safely include file.
include __DIR__ . DIRECTORY_SEPARATOR . $fileName;
Using $_GET['topic'] directly in include or require construction is unsafe because you vulnerable to "Directory traversal attack". Moreover you always must validate input parameters with purpose avoid include in php script css files etc...
<?php include $_GET['topic']; ?>
Don't do that. It creates a massive and easily-exploited security vulnerability.
For example:
?topic=index.php -- creates an infinite loop
?topic=/etc/passwd -- displays sensitive data from the server
?topic=/proc/self/environ -- executes code from the process environment. This will frequently include user-controlled data like the values of HTTP headers, allowing for remote code execution.
Your site will be exploited if you implement this. There are numerous bots which scan public web sites for this vulnerability, many of which will attempt to exploit it automatically upon detection.
If you want to include a file based on the value of a GET variable, use switch($_GET['topic') to define the acceptable values of that variable. This will also allow you to implement error handling as a default: clause.
This is a fairly common way of implementing a simple junction box/router. Use a switch statement.
$topic = isset($_GET['topic']) ? $_GET['topic'] : '';
switch ($page) {
case 'credit':
case 'otherpage':
case 'otherpage2':
require_once(dirname(__FILE__) . '/' . $page . '.php');
break;
default
require_once(dirname(__FILE__) . '/' . 'default.php');
}
You whitelist your pages/topics by adding a case statement at the top for each, and anything that doesn't match or have a page is processed by loading the default page.
In this example, I assume all the topic pages are in the same directory as this script (typically named index.php).
Related
I currently have this setup
<?php
$nav = filter_input(INPUT_GET, 'nav', FILTER_SANITIZE_STRING);
$Working_On = true;
//$Working_On = false;
if ($Working_On == true) {
$title = '- Under Construction';
$error_msg = "Website Under Construction.";
include('404.php');
exit;
} else {
switch ($nav) {
case "":
include('main.php');
break;
default:
$title = '- 404 Page Not Found';
include('404.php');
break;
}
}
I'd love to know if there is a better way more efficent way of orginising this type of setup so i can easily add more options ?
While accessing a page with
example.com/?nav=examplepage
is a valid approach (that I also used in past projects), today's standard is to use something like
example.com/examplepage
This creates URLs that are easier to understand by humans and more semantic than query parameters. Doing so will also prevent you from running into possible caching issues with URLs defined by query parameters.
It also brings you the benefit of including even more information in the URL without the need for query parameters, for example
example.com/posts/view/20
Such URLs are usually parsed by a "Router". There are many reference and open source implementations for PHP routing on the web, just search for "PHP Router", take a look and decide what best fits your needs.
Side note:
use type-safe checks, aka === instead of == to save you a lot of headache and follow security best practices; if you're still at the beginning of your project, you might want to take a look at https://phptherightway.com/
you exit() if the site is on maintenance. In that case you don't need to put the switch statement inside else{}, you can just put it after the if clause
I am creating a booking engine . Same code will be used on two different domain BUT there should be an identifier to tell which domain will be using which code . Say in database I Identify AAA.COM should use code instance A and BBB.COM should use code instance B .
Both the domains are on same server .
Can anyone suggest how do I do that via apache or any tips to accomplish which I am looking for .
Well, php does have access to the HOST header being part of the request. Just use $_SERVER['SERVER_NAME'] or $_SERVER['HTTP_HOST']. Check the documentation for the difference: http://php.net/manual/en/reserved.variables.server.php
Using that you can create a condition inside your php scripts:
<?php
// ...
switch ($_SERVER['SERVER_NAME']) {
case 'aaa.com':
// use database A
break;
case 'bbb.com':
// use database B
break;
default:
throw new Exception('undefined host at runtime');
}
// ...
Im doing a game and i created an "administration" panel for it.
it works like this:
admin.php
admin/code1.php
admin/code2.php
admin.php:
<?php
include("lib.php");
$player = check_user($secret_key, $db);
if($player->rank != "Administrador")
{
header("Location: personagem.php");
exit;
}
include("templates/private_header.php");
head("Admin Panel","adminpanel.png");
startbox();
if(isset($_GET['page']))
{
include("admin/" . $_GET['page'] . ".php");
}
else
{
?>
Kill Players<br>
Heal Players<br>
<?php
}
endbox();
include("templates/footer.php");
?>
i want to know if im prone to hacking.
the code1.php and code2.php uses a custom query library that is included in lib.php so there is no way to execute them directly without falling in to an error.
Also in My template i have:
if($player->rank == "Administrador")
{
echo "<a href='admin.php'>Admin Panel</a>";
}
so i can access the panel more quickly.There is risk in there too?
Just note that $player is a object created from a query to the player Database that represents the actual player. In my thoughts the only way to hack this is changing they "rank" status in the table to "Administrador" am i right? or there is something i let pass?
Thanks in advance
include("admin/" . $_GET['page'] . ".php");
This is a huge security hole.
Something like blah.php?page=../../../../etc/passwd%00 would include /etc/password and of course you can also do this with other files - maybe even some files uploaded by the user that contain PHP code (could be even an image as long as it contains <?php [code] somewhere)
And even if only you are administrator, not closing holes like that would not be wise - you might have other administrators at some point.
Never trust user input
Never work with any of $_GET $_POST, $_COOKIE without verifying them first (or anything else user-generated for that matter, even stuff from your own database might be dangerous).
include("admin/" . $_GET['page'] . ".php");
Don't do this. otherwise you can include any file you want. I suggest you whitelist all allowed pages to be included like so:
$allowed = array("admin_index", "page1", "page2");
if(in_array($_GET['page'], $allowed)){
include("admin/" . $_GET['page'] . ".php");
}
else{
// perform error handling
}
Here's a useful function that you could take a look at, if you don't want to whitelist all pages: basename() - this will always only return the filename part, without any directory-changing part.
Furthermore, I do not recommend you work with includes like this at all, but rather have some Controller-hierarchy that can decide what to do on each request.
What about the authentication?
Show us your code for the authentication. That's a crucial part of your system that needs to be secure.
The code below ensures that when a user accesses control panel, they are ran through a quick verification process to validate what their entities are. For instance, if a user is level 1 they are only given access to video feed which means nothing else is available to them.
When I look at the code though, I can see video feed being called when case 1 and 3 are called. I would possibly enjoy an alternative to make the code more efficient.
I was told a possible array could make things a little easier but then again this is faster.
switch ($_SESSION['permission']) {
case 1: // Level 1: Video Feed
include ("include/panels/videofeed.index.php");
break;
case 2: // Level 2: Announcements / Courses / Teachers
include ("include/panels/announcements.index.php");
include ("include/panels/courses.index.php");
include ("include/panels/teachers.index.php");
break;
case 3: // Level 3: Announcements / Video Feed / Courses / Teachers / Accounts / Logs
include ("include/panels/announcements.index.php");
include ("include/panels/videofeed.index.php");
include ("include/panels/courses.index.php");
include ("include/panels/teachers.index.php");
include ("include/panels/accounts.index.php");
include ("include/panels/log.index.php");
break;
case 4: // Level 4: Teachers
include ("include/panels/teachers.index.php");
}
It's fine the way it is. I think you don't mean "efficiency" when you refer to the "repeated" includes. You mean you could compact your code by using the switch fall-through.
While this might make your code smaller, it has no significant impact of efficiency (the time the script takes to run) and it will actually make the code harder to read. Leave it be.
Frist you may run better if you use require_once if its possible.
The second point is to shorten the url it seems that its every include the same.
Maybe try to use it in a function for example:
$permission_id = $_SESSION['permission']
function requireModule($moduleName, $path = 'include/panels/') {
$moduleName .= '.index.php';
require_once($path . $moduleName);
}
// if you want you can add an arry for it:
$permissionModules = array(
array('videofeed'),
array('announcements', 'courses', 'teachers'),
array('announcements', 'courses', 'teachers', 'accounts', 'log', 'videofeed'),
array('teachers')
);
// now we can put it in a more effectiv way
if(array_key_exists($permission_id, $permissionModules)) {
foreach($permissionModules[$permission_id] as $includes) {
requireModule($includes);
}
}
Wrong ? Correct me!
I want to control the access in php website.
I have a solution right now with switch case.
<?php
$obj = $_GET['obj'];
switch ($obj)
{
case a:
include ('a.php');
break;
default:
include ('f.php');
}
?>
But when i have so many pages, it becomes difficult to manage them. Do you have better solutions?
Right now, i develop the application using php4. And i want to use php5. Do you have any suggestions when i develop it using php5?
Thanks
$obj = $_GET['obj'];
$validArray = array('a','b','c','d','e');
if (in_array($obj,$validArray)) {
include ($obj.'.php');
} else {
include ('f.php');
}
The more pages you have the harder it will be to control this.
Your best off using a framework of some sort, my personal preference is CodeIgniter.
why not just address a page itself?
first page
another page
I am not saying that this is the best solution, but years ago I used to have a website which used a database to manage the key, the page to be included, and some informations like additional css for instance.
So the code was something like:
<?php
$page = htmlspecialchars($_GET['page']);
$stuffs = $db->query('select include,css from pages where pageid = "' . $page . '" LIMIT 1');
?>
So when we needed to add a page, we just created a new field in the database. That let us close a part of the website too: we could have a "available = {0,1}" field, and if zero, display a static page saying that this page was under maintenance.