包含$ _GET的页面

时间:2009-02-13 20:16:57

标签: php

我希望url像index.php?showuser = 512,index.php?shownews = 317用于页面我从db获取内容...和常规页面index.php?page = about等等WITHOUT mod-rewrite

Invision Power Board有这样的网址。我查看了他们的代码,但我无法弄清楚他们是如何做到的。

我可以这样做:

if (ctype_digit($_GET['shownews'])) include('shownews.php'); 
elseif (ctype_digit($_GET['showuser'])) include('showuser.php');

// regular pages
elseif ($_GET['page'] == 'about') include('about.php');
elseif ($_GET['page'] == 'help') include('help.php'); 
elseif ($_GET['page'] == 'login') include('login.php'); 

但这感觉太乱了。 只是好奇IPB如何做到这一点。有更好的方法吗?没有任何mod重写。谁知道?我怀疑他们是否像上面那样做。

我做不到:

if (preg_match('/^[a-z0-9]+$/', $_GET['page'])) include('$_GET['page']');

然后我会得到像index.php?showuser& id = 512这样的链接,我不喜欢。 (我知道只显示原则并不安全)

我喜欢这种方式,它不是最好的但我喜欢它所以请保持模板引擎,框架等安静。只要善待并回答我的问题......我只是想知道IPB是如何做到的。

由于 托梅克

2 个答案:

答案 0 :(得分:2)

我不知道IPB如何做到这一点,让我们解决这个问题。但是,这就是 I 将如何解决这个问题:

首先,我认识到有两种GET参数:页面/标识符,只有页面。这些将分别进行测试。

其次,我认识到所有get参数都匹配他们的文件名,而不是php-suffix,所以我们可以利用这个参数。

要记住的最重要的事情之一是永远不要让GET参数影响我们的代码未经过清理。在这种情况下,我们知道我们可以和想要显示哪些类型的页面,因此我们可以创建一个白名单。

所以,在伪y调度程序代码上:

$pagesWithId = array("shownews", "showuser", "showwhatever");
$justPages   = array("about", "help", "login");

foreach ($pagesWithId as $page) {
  if (isset($_GET[$page])) {
    $id = (int)$_GET[$page]; 

    include($page.'.php');
    die();
  }
}

if (in_array($_GET['page'], $justPages)) {
  include($_GET['page'].'.php');
  die();
}

// page not found
show404OrHandleOtherwise();

答案 1 :(得分:0)

对于页面,您只需使用一个简单的数组。

if (isset($pages[$_GET['page']])) include $pages[$_GET['page']];

对于shownews = 317您可以在应用中进行简单转换。取决于您希望如何优先考虑页面或shownews等:

if (isset($pages[$_GET['page']])) {
  include $pages[$_GET['page']];
} else {
  $possiblePages = array_filter(array_intersect_key($_GET, $pagesWithId), 'ctype_digit');
  if (!empty($possiblePages)) {
    $id = reset($possiblePages);
    $pageName = key($possiblePages);
    $page = $pagesWithId[$pageName];
    include $page;
  } else {
    //no valid pages
  }
}

注意:页面“names”是数组键,值是要包含的路径,文件和扩展名。更可定制。