Skip to main content
gamedev.net
🔒 Locked 🤖 Godot

[web] PHP - Load Page

Started by Ntvu May 24, 2009 at 1:50 PM 2 replies 2.7k views
Original Post
Ntvu
Ntvu
I'm trying to make a page-loading mechanism. It's kind of hard to explain what I'm trying to achieve, but I'll explain it to the best of my ability. I have a website. On the website there are several files. However, they are not placed in the base directory like this:

home.php
about.php
contact.php
portfolio.php
Instead, they are placed in a directory called pages, and index.php in the base directory loads the files from the pages directory.

/index.php
/pages/home.php
/pages/about.php
/pages/contact.php
/pages/portfolio.php
Now to load a page, I would access my site like this:

http://mysite.com/index.php?page=about
And then the script in index.php would access /pages/about.php and then load the page. The contents of about.php would look something like this:

<?php
/**[About]**/
?>

<Content here>
When it's time to load the page, loadPage is called:

function loadPage($page)
{
	if (file_exists(BASE . "/pages/" . $page . ".php"))
	{
		$file = fopen(BASE . "/pages/" . $page . ".php", "r"); 
		fgets($file); 
		
		$title = str_replace(array("/**[", "]**/"), "", fgets($file)); 
		
		fclose($file); 
		
		include BASE . "/section/html.php"; 
		include BASE . "/section/header.php"; 
		include BASE . "/section/leftmenu.php"; 
		include BASE . "/section/rightmenu.php"; 
		
		include BASE . "/pages/" . $page . ".php"; 
		
		include BASE . "/section/footer.php"; 
	}
        else header("Location: /index.php?page=404"); 
}
And the code in index.php would look something like this:

<?php

loadPage( (!empty($_GET['page'])) ? $_GET['page'] : "home"); 

?>
So as you can see, it gets the page title, includes some menus located in the section directory, includes the page file in the page directory, and then includes the footer (another file in the section directory). The problem is though, I think there is a better way to do this. The problem is, I've been thinking about it for a while and I can't seem to find a better solution. I was considering using page templates and I have successfully implemented some, but then say if I add a menu, then I'd probably have to add a snippet of code (eg: {menu-3}) into each of the page files to have them include that menu. But is there a more flexible way of doing this? And can you comment on my method of approaching the problem? Thanks. Edit: I know the code above is vulnerable to LFI / RFI, but the real script filters slashes and null characters so there's no security hole
Verminox
Verminox
1. Make sure to clean the argument to loadPage for any slashes, etc. or else it is vulnerable to attacks. A user can put anything under ?page= and access private files. I see you have considered this.

2. If your script cannot resolve ?page=404 properly, you will go into an infinite loop.

3. I don't think it is necessary in any design to open a file so many times. You have two fgets() and one include of the same page. I am assuming you are initializing $title for the HTML title. I generally avoid page loading and directly use requests to /about.php.
<?php  include '/section/html.php';  htmlBefore('About'); // Prints html head section with given title and menus    /** ALL CONTENT HERE **/  htmlAfter();         // Prints footer section of html?>


I like this method for many reasons. For one, when open an arbitrary PHP file for editing, you can read the include lines at the top and tell whether it is a page with HTML contents, or if it includes mysql.php it is a page that accesses the database, etc.

Also it makes the URLs look cleaner. index.php i reserve only for the front page which has the links to all top level pages and actually behaves like an index.

Also that way your other _GET arguments make sense. search.php?term=foo and user.php?id=25 I find nicer than index.php?page=search&term=foo where 'term' is not an argument for other instances of index.php.

If you want a custom 404 error page, you can configure that using .htaccess.

Also, this is probably be more search engine friendly than the page loading method (unless you are using URL rewrites to rewrite /about to /index.php?page=about
--------------------------------------Amaze your friends! Astound your family! Kennify your text!
leiavoia
leiavoia
about security:

please be aware that auto-hackers just love this "?page=foo" sort of business. Please make darn sure you lock down any potential input from that variable. One way to help is to require all pages to be named "prefix_whatever". That prevents input like a foreign URL or something out of the directory, although you should double-chck for those just to be paranoid.

about templates:

most decent template libs have recursive includes, so you can make a templates that looks like:

{include file=header}
content
{include file=footer}

where header and footer are themselves templates. On my site, i have a page, header, footer, login box, login box wrapper, menu, and submenu all as different templates. They all come together in one page though and the end user is none the wiser.

Check out Smarty if you haven't already. I've loved working with it.

Ntvu
Ntvu
@leiavoia:

Don't worry, I've got that all taken care of. I used this function to prevent Local / Remote File Includes:

[source lang=php]function f_filter($t){    return str_replace(array("\"", "\\", "\'", ".", chr(0)), "", $t); }



And I can always turn off error reporting or validate the input (making sure that ?page is not an array, eg: ?page[]=about) to prevent Full Path Disclosures.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.