2011-04-15 42 views
1

我有一個PHP站點用下面的代碼在它的文件:問題與包括基於(非限定)可變

<?php 
$p = $_GET['p'] 
include("$p.inc"); 
?> 

每當我送一個遊客到頁面像index.php?p=contact比如我想要的文件包括contact.inc。這工作正常。

現在我想要包含某個文件(例如start.inc),當訪問者發送到index.php沒有任何GET變量。但是,返回的錯誤消息告訴我$ p是未定義的(邏輯上它是)。

我試圖通過使用isset函數像這樣解決這個問題:

<?php 
if(!isset($p)) $p = "start"; 
else $p = $_GET['p']; 
include("$p.inc"); 
?> 

但是,這並不工作,因爲現在$ P始終包含字符串「開始」,我不能送訪客index.php?p=contact了 - 它仍然會包含start.inc

有人可以幫我解決這個問題嗎? 在此先感謝!

回答

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); 
?> 
1

爲了安全起見,無論如何您都應該列出您的網頁。所以:

<?php 
    $p = $_GET['p'] 
    switch($p){ 
     case 'contact': 
     include("contact.inc"); 
     break; 
     default: 
     include("start.inc"); 
    } 
?> 
0

你應該更喜歡一個array-map或者像Nanne建議的switch

如果要直接在include語句中使用$ p變量,至少應使用basename()。這是你如何能避免「錯誤」(這是一個調試通知,順便說一句):

<?php 
    $p = @$_GET["p"] or $p = "start"; 

    $p = preg_replace("/\W+/", "", $p); // minimum filtering 
    include("./$p.inc"); 
?> 
+0

你介意解釋下面的內容嗎? '$ p = preg_replace(「/ \ W + /」,「」,$ p);' – fruitbooter 2011-04-16 00:32:21

+1

是的。這是一個正則表達式過濾器。它刪除任何「非單詞」字符。意思是隻留下字母,數字或下劃線。 – mario 2011-04-16 00:34:32

+0

啊謝謝!如果變量被訪問者操縱,我想這是特別有用的嗎?如果我是代碼的唯一負責人,我不需要過濾我的變量,對嗎? – fruitbooter 2011-04-16 01:53:13

1

定義你的$ p變量就​​像這樣:

$p = array_key_exists('p', $_GET) ? preg_replace('!\W!', '', $_GET['p']) : 'start'; 
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"); 
} 
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和馬里奧)藏漢由上校的錯誤頁面的想法。彈片。