我有一个PHP站点,其中包含以下代码:
<?php
$p = $_GET['p']
include("$p.inc");
?>
每当我将访问者发送到index.php?p=contact
这样的网页时,我希望包含文件contact.inc
。这很好。
现在,当访问者被发送到start.inc
而没有任何GET变量时,我希望包含某个文件(例如index.php
)。但是,会返回一条错误消息,告诉我$ p未定义(逻辑上是)。
我尝试使用isset函数修复此问题,如下所示:
<?php
if(!isset($p)) $p = "start";
else $p = $_GET['p'];
include("$p.inc");
?>
但这不起作用,因为现在$ p总是包含字符串“start”,我无法再将访问者发送到index.php?p=contact
- 它仍将包含start.inc
有人可以帮我解决这个问题吗? 提前谢谢!
答案 0 :(得分:1)
出于安全考虑,您应该将页面列入白名单。这样:
<?php
$p = $_GET['p']
switch($p){
case 'contact':
include("contact.inc");
break;
default:
include("start.inc");
}
?>
答案 1 :(得分:1)
像这样定义你的$ p变量:
$p = array_key_exists('p', $_GET) ? preg_replace('!\W!', '', $_GET['p']) : 'start';
答案 2 :(得分:1)
你正在检查$ p而不是$ _GET ['p']所以,因为$ p从未设置,所以你总是登陆起始页。
无论如何,你必须首先清理这个变量
好的做法是这样的(假设页面存储在“pagedata”文件夹中并且扩展名为.php):
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");
}
答案 3 :(得分:1)
明确指定从外部获得的允许值。
<?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);
?>
答案 4 :(得分:0)
您应该更喜欢阵列地图或像Nanne建议的switch
。
如果要在include语句中直接使用$ p变量,至少使用basename()
。这就是你如何避免“错误”(这是一个调试通知,顺便说一句):
<?php
$p = @$_GET["p"] or $p = "start";
$p = preg_replace("/\W+/", "", $p); // minimum filtering
include("./$p.inc");
?>
答案 5 :(得分:0)
谢谢大家!
我将大部分建议合并到以下代码中:
<?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.);
?>
我特别喜欢阵列图(由Alex和mario建议)出于安全原因以及Col. Shrapnel的错误页面构思。