I'm learning PHP and i block on a problem. I read posts about this issue but i still do not understand.
This is my code (from index.php):
$page = $_GET['page'];
$page = $_GET['action'];
if ($page == "operation" && $action == "liste"){
include("operationForm.php");
}
if ($page == "produits" && $action == "ajout") {
include('../Produits/AddProductForm.php');
}
When i tried to navigate i come across this message:
(404 Not Found : /Fournisseurs/index.php was not found on this
server).
I really don't see where is the problem. Do you have any tips or tutos for solving this problem ?
$page = $_GET['page'];
$page = $_GET['action'];
You are using the same variable name !
This looks better :P
$page = basename($_GET['page']);
$action = basename($_GET['action']);
As for the 404...
../ means parent folder, it seems the file you want to include is not located there. Be careful when using user input, validation / sanitization is mandatory
$page = $_GET['page'];
$page = $_GET['action'];
You set your variables with the same name. So the second $page is overwrite the first $page.
Related
I am using the following code to include the correct page into the shell page using $_GET from the previous page. index.php?page= . I have fixed the error for it being blank but still get errors when the user changes what comes after the equals. How would i prevent these errors below from coming up and what could i do to prevent blind sql injection. I am using mysqli_real_escape_string but is there anything else apart from prepared statements. I have tried curl but i couldn't get it to work in this situation.
Thanks in advance.
failed to open stream: no such file or directory
failed opening pages for inclusion
if(isset($_GET["page"])){
if ($_GET["page"] == ""){
header("Location:index.php");
}else{
$page = $_GET["page"];
include("pages/$page.php");
}
}else{
include("pages/home.php");
}
I think the code can be cleaned up a bit. For instance like this:
$page = 'home';
if (isset($_GET["page"]) &&
file_exists('pages/'.$_GET["page"].'.php')) $page = $_GET["page"];
include("pages/$page.php");
There's no need to reload to 'index.php' since you're already there.
The file_exists() function checks whether or not a file or directory exists.
This function returns TRUE if the file or directory exists, otherwise it returns FALSE.
if(isset($_GET["page"]))
{
if ($_GET["page"] == "")
{
header("Location:index.php");
}
else if( file_exists('pages/'.$_GET["page"].'.php') )
{
$page = $_GET["page"];
include("pages/$page.php");
}
}
else
{
include("pages/home.php");
}
}
Am running the following code to gather some data from my page and store it in my database, however, i need to add some extra functionality to it but i don't seem to be able to do it correctly.
The Code:
// Get Referrer and Page
if (isset($_GET["ref"]))
{
// from javascript
$referer = $_GET["ref"];
$page = ((isset($_SERVER['HTTP_REFERER'])) ? (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH)) : (''));
}
else
{
// from php
$referer = ((isset($_SERVER['HTTP_REFERER'])) ? ($_SERVER['HTTP_REFERER']) : (''));
$page = $_SERVER['PHP_SELF']; // with include via php
}
// Cleanup
if (basename($page) == basename(__FILE__)) $page = "" ;
This script is storing $page as "/site/index.php or /site/about.php", for example. I kinda want it to store it as "Index or About" without the whole /site/ and .php part.
Thanks in advance
Use pathinfo(), for example:
<?php
$page = "/site/index.php";
$page_info = pathinfo($page);
$page_name = $page_info['filename'];
echo $page_name; //output: index
?>
I'm working on a website and this is what I have for my index.php:
<?php
$p = $_GET['p'];
$pages = array('home', 'culture', 'design', 'art', 'about');
$path = 'http://localhost:8080/projects';
include('header.php');
if(!isset($p) || !in_array($p, $pages)) {
include('header.index.php');
include('content.index.php');
} else {
switch($p) {
case "home";
include('header.home.php');
include('content.home.php');
break;
case "culture";
include('content.culture.php');
break;
case "design";
include('content.design.php');
break;
case "about";
include('content.about.php');
break;
case "art";
include('content.art.php');
break;
default:
include('content.index.php');
break;
}
}
include('footer.php');
?>
I get the following error:
**Notice: Undefined index: p in C:\wamp\www\projects\index.php on line 3
Call Stack
# Time Memory Function Location
1 0.0523 680200 {main}( ) ..\index.php:0**
When you assign p initially, p is not set in $_GET
So you can do this
$p = isset($_GET['p']) ? $_GET['p'] : null;
If you don't care about notices, You can disable them in your php.ini by changing error_reporting to E_ALL & ~E_NOTICE, however I wouldn't recommend it
The switch statement you have is somewhat bogus, especially as you already have the $page array. You actually want to verify if the page exists or load the index page (probably?):
$p = isset($_GET['p']) ? (string) $_GET['p'] : NULL;
$pages = array('home', 'culture', 'design', 'art', 'about');
$path = 'http://localhost:8080/projects';
if (!in_array($p, $pages)) {
$p = 'index';
}
// include $p based on $path
However, you still have the problem with the header. So this is the lesson: make the header part of every include. You can stack as many includes as you like, just take care that every include contains it's correct header. Then you're done. And you won't see any warnings.
So the code after following what #hakre suggested should look like this:
$p = isset($_GET['p']) ? (string) $_GET['p'] : NULL;
$pages = array('home', 'culture', 'design', 'art', 'about');
$path = 'http://localhost:8080/projects';
include('header.php');
if (!in_array($p, $pages)) {
$p = 'index';
include('header.index.php');
include('content.index.php');
}
Thanks #hakre for your help..
Just a suggestion maybe try !empty()
if(!empty($p) || !in_array($p, $pages)) {
include 'header.index.php';
include 'content.index.php';
}
This is NOT an error. As the log claims this is a NOTICE. It is meant to inform you about a potential problem, but does not keep the script from being executed.
In this case the interpreter tells you that the array $_GET does not contain an element with index 'p'. It is not initialized, probably cause it has not been specified in the request in this case.
Try to test first if the element exists before you try to access it. Use isset() for this.
i have a PHP site with the following code in it:
<?php
$p = $_GET['p']
include("$p.inc");
?>
Whenever I send a visitor to a page like index.php?p=contact for example I want the file contact.inc to be included. This works fine.
Now I want a certain file to be included (e.g. start.inc) when the visitor is sent to index.php without any GET variables. However, an error message is returned which tells me that $p is undefined (which it logically is).
I tried fixing this problem by using the isset function like so:
<?php
if(!isset($p)) $p = "start";
else $p = $_GET['p'];
include("$p.inc");
?>
but this doesn't work because now $p always contains the string "start" and I can't send the visitor to index.php?p=contact anymore - it will still include start.inc
Can somebody please help me with this issue?
Thanks in advance!
Explicitly specify the allowable values, obtained from outside.
<?php
$allowed_pages = array(
'home' => 'home.inc',
'contact' => 'contact.inc',
);
$page = #$_GET['p'];
$file = array_key_exists($page, $allowed_pages) ? $allowed_pages[$page] : $allowed_pages['home'];
include($file);
?>
You should white-list your pages anyway, for security. so:
<?php
$p = $_GET['p']
switch($p){
case 'contact':
include("contact.inc");
break;
default:
include("start.inc");
}
?>
Define your $p variable just like this:
$p = array_key_exists('p', $_GET) ? preg_replace('!\W!', '', $_GET['p']) : 'start';
you're checking $p instead of $_GET['p'] so, as $p is never set, you always land at starting page.
anyway you have to sanitize this variable first.
good practice would be like this (assuming pages stored in a "pagedata" folder and have .php extension):
if(isset($_GET['p'])) {
$p = basename($_GET['p']);
} else {
$p = "start";
}
$fileName = "pagedata/$p.inc.php";
if(is_readable($fileName)) {
include($fileName);
} else {
include("pagedata/404.html");
}
You should prefer an array-map or a switch like Nanne suggested.
At the very least use basename() if you want to keep using the $p variable directly in the include statement. And this is how you could avoid the "error" (which is a debug notice, btw):
<?php
$p = #$_GET["p"] or $p = "start";
$p = preg_replace("/\W+/", "", $p); // minimum filtering
include("./$p.inc");
?>
Thanks to you all!
I combined most of your suggestions to the following piece of code:
<?php
$pages = array(
'start'=>'Start.inc';
'contact'=>'Contact.inc';
'about'=>'About.inc';
};
$p = array_key_exists(#$_GET['p'], $pages) ? preg_replace('!\W!', '', $_GET['p'] : 'start';
$p = ucfirst($p);
$page = "./$p.inc";
if(is_readable($page)) include($page);
else include(./404.);
?>
I particularly like the array-map (as suggested by Alex and mario) for security reasons aswell as the error page idea by Col. Shrapnel.
Among the following include methods which is the best to practice and why?
$page = $_GET['page'];
Method 1
$pages = array('home', 'blog', 'about');
if( in_array($page, $pages) )
{
include($page.'.php');
{
else
{
die('Nice Try.');
}
Method 2
if($page = 'home'){
include('home.php');
}else if($page = 'blog'){
include('blog.php');
}else if($page = 'about'){
include('about.php');
}
Method 3
if(str_replace("http://", "gth://", $page) == $page){
include_once $page;
}else{
die('Nice Try.');
}
or any other solutions? I dont prefer method 1 and 2 as it always needs to be updated everytime i add a new page.
extending/maintaining the first way is easiest, second way is worse. third way is no way to go, as it relies on user input to require pages... it is going to be a security hole
I believe that the first one is the best of the lot. You can try the second one, but it's for the freshers. And the third one is a BIG NO, because any fresher hacker could hack your "if" condition, & more loopholes will start creeping in.
As for your problem, on adding a new page to the array, every time a new page is created, for the first method, I have one solution:-
Let's say you're putting all the new pages in one folder "abc". Now just write one file code as the following, to read all the files / pages existing in that folder:-
<?php
$page = $_GET['page'];
$pages = array();
/**
* If you are using all the pages existing in the current folder you are in,
* then use the below variable as:-
* $path = ".";
*/
$path = 'abc/'; // Change the Path here, related to this Folder name
$handle = opendir($path);
while (($file = readdir($handle)) !== false) {
$pages[] = $file;
}
closedir($handle);
if( in_array($page, $pages) ) {
include($page.'.php');
}
else {
die('Nice Try.');
}
?>
So you see that the array is getting filled up dynamically, without the need to mention all the pages you create every time. And you are using the first method only. And keep the including pages in one separate folder, which you will need to include every time, in other main pages.
Hope it helps.