PHP Frontpage / Page控制器

I using the following as Frontpage/Page Controller(s) and it's working ok so far, except two problems I'm facing which as you can see are the $pages array and the switch, which are actually much much longer as the one I've pasted here. Everytime there is a need for a new page controller I have to add it to $pages array and to switch which makes that list very long. How would you overcome this problem and do you see any other improvement on this code? loadLogic() in page controllers it is used to get functions under pages/controllername/logic/function.php.

Frontpage Controller - index.php:

include 'common/common.php';
if(!isset($_GET['p']) OR $_GET['p'] == ''){
    $_GET['p'] = 'home';
    header('Location: index.php?p=home');
}

$pages = array('home','register','login','logout','page1','page2','page3');

$_GET['p'] = trim($_GET['p']);

if(isset($_GET['p'])){
    if(in_array($_GET['p'], $pages)){
        switch ($_GET['p']) {
            case 'home':
                include 'home.php';
                break;
            case 'register':
                include 'register.php';
                break;
            case 'login':
                include 'login.php';
                break;
            case 'logout':
                include 'logout.php';
                break;
            case 'page1':
                include 'page1.php';
                break;
            case 'page2':
                include 'page2.php';
                break;
            case 'page3':
                include 'page3.php';
                break;
        }
    }else{
        echo '404!';
    }
}

Page Controller - {home,register,login,logout,page1,page2,page3}.php:

include 'tpl/common/header.php';
contentStart();

if(isset($_SESSION['logged'])){
    loadLogic('dashboard');

}else{
    loadLogic('nologin');

}


//Display login form in logic page instead links
//
if(!isset($_SESSION['logged'])){
    contentEnd();
    loadLogic('nologinForm');
}else{
  contentEnd();
  include'tpl/common/rcol.php';

}
include 'tpl/common/footer.php';

function loadLogic():

function loadLogic($logic) {
    $path = dirname(__DIR__) . '/pages';

    $controller = preg_split('/&/',$_SERVER['QUERY_STRING']);
    $controller = trim($controller[0],"p=");
    $logicPath = 'logic';
    $logic = $logic . '.php';
    $err = 0;
    $logicFullPath = $path.'/'.$controller.'/'.$logicPath.'/'.$logic;

    if($err == '0'){
        include "$logicFullPath";

    }
}

Folder Structure:

projectName
  |
   ---> common
  |
   ---> pages
  |   |
  |    --->home
  |   |
  |    --->register
  |   |
  |    --->login
  |   |
  |    --->logout
  |   |
  |    --->page1
  |   |
  |    --->page2
  |   |
  |    --->page3
  |
   ---> tpl
  |   |
  |    ---> common
  |
   --> home.php
  |
   --> register.php
  |
   --> login.php
  |
   --> logout.php
  |
   --> page1.php
  |
   --> page2.php
  |
   --> page3.php

For the frontpage controller, why so many case statements. You already know what pages are valid to include and you check if it's in the valid pages.

You can just do:

if(isset($_GET['p']))
{
    if(in_array($_GET['p'], $pages))
    {
         include($_GET['p'] . '.php');
    }
}

If you wanted it to have different names passed to $_GET for obfuscation, along with different potential extensions, then you could do:

$pages = array('home'=>'index.php','register'=>'registerpage.htm','page1'=>'one.html');

if(isset($_GET['p']))
{
    if(array_key_exists($_GET['p'],$pages))
    {
          include($pages[$_GET['p']]);
    }
}

If you wanted to make the array of pages more easily managable you can break it up into multiple lines:

$pages = array(
'home'=>'index.php',
'register'=>'registerpage.htm',
'etc'=>'/home/user/public_html/directory/etc.php'
);

Oh, also, since it's sort of ugly to have the home page be http://www.domain.com/?p=home, just make home be the default include if the value for p is not in the array or not an array key, depending on which you'd use.

So:

if(isset($_GET['p']) && in_array($_GET['p'],$pages)) //You can combine these like this as well, same functionality.  If p isn't set, it won't even try the in_array()
{
    include($_GET['p'] . '.php');
}
else
{
    include('home.php');
}

Then you can get rid of that if !isset $_GET['p'] or $_GET['p'] == '' at the top. You can also combine the isset and in_array/array_key_exists into the same if statement with an &&. If the first evaluation is false and it hits an && then it just stops and doesn't evaluate the rest, so no errors or anything, and it also means that you can easily set a default response just once, as having them nested means that you'd have to have a default for both ifs.

More edits. If you really wanted to have a 404 when a user tries to go to a p= that's non existant instead of just getting booted to the home page, you could do this at the top:

if(isset($_GET['p']))
{
$fourohfour = true; 
}

and then down in the If structure to include the pages, do an else if before the else include home.php like:

else if(isset($fourohfour))
{
    include('404.php');
}

So that if p is set but doesn't check out then it will include 404, but if it isn't set, it will go to home.php