0

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

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

8 Comments

@Phoenix thank you for your suggestions so far, is there any else you could tell me about frontpage/page controller in general? Any tips? I'll wait for another hour or two, if this question haven't got any more answers I'll mark yours as accepted.
Well, you might consider looking up how to do .htaccess rewrite rules, so that when a user goes to ?p=pageone, it will show up as /pageone. You can also use the same sort of logic as on the front page controller to control sub pages of a sub page. I had a similar system once with a library of text files, and ?p=library would just go to an index of books, and ?p=library&lib=book1 would go to the book. The library page had the book index as it's default include, and checked $_GET['lib'] against txt files in a specified directory with file_exists() and included it, or the default if it didnt.
Also, another form of obfuscation is changing the extension. Included files can literally have any extension, could be home.gobbledygook. Include pretty much treats includes all the same, if it finds php code inside, it will run it. You could rename a .php to .jpg and it will run the code. Just have to make sure that apache or whatever server you're using will treat it as a php file if requested directly, or not allow access from outside the server, because otherwise the source would be downloadable if someone guessed the name and extension, but it would still run even if you didn't.
Oh, that's one reason why you should never directly include() a user uploaded file, even if you know that it should be a .jpg and not a .php, though I don't see why anyone might want to do so.
@Phoenix do you think it's easy to implement template logic on the page controller? if yes how folder structure would be ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.