A basic OOP site

The first thing we're going to produce will be a very simple OOP site that has a site class, csite, and a page class, cpage. These two classes will be kept "clean" in that they won't have any idea of the design of the site around them or their content - they'll just render themselves. This means we'll need several site-specific files as well.

First, let's look at the contents of an example file in our site, index.php:

<?php
    include 'stdlib.php';

    $site = new csite();

    // this is a function specific to this site!
    initialise_site($site);

    $page = new cpage("Welcome to my site!");
    $site->setPage($page);

    $content = <<<EOT Welcome to my personal web site! EOT;
    $page->setContent($content);

    $site->render();
?>

The stdlib.php file will contain the site-specific information - all the information that shouldn't be inside our classes and shouldn't be repeated in every page. We set $site to be an instance of our site, and then call a function called initialise_site() to set it up with our basic, site-specific settings - that function will be in stdlib.php.

Next we create a cpage object, passing into the constructor the title of the page, then use the setPage() function of our csite class to add the page to our site for rendering.

The next few lines set up the page-specific content for our cpage, and then calls the setContent() function of the object to add the text to the page. Finally, we call the render() function of our csite object to output the HTML.

Don't worry if that's all as clear as mud right now - we've yet to look at the other files involved. Here's stdlib.php:

<?php
    function __autoload($class) {
        include "$class.php";
    }

    function initialise_site(csite $site) {
        $site->addHeader("header.php");
        $site->addFooter("footer.php");
    }
?>

The first part is the magic __autoload() function. Note how in index.php we don't specify either csite or cpage - we just presume they exist. This is accomplished through the magic __autoload() function, but, when you think about it, that function couldn't go inside one of the classes (there's a recursive bit of logic there!), and neither should it be replicated inside each of the page-specific scripts, as that would be a nightmare to maintain. So, it's in stdlib.php.

The second part is the initialise_site() function, where we add site-specific header and footer files for this site. The addHeader() and addFooter() functions are both part of the csite class, which we'll look at in a moment. Note that the __autoload() function will look for csite.php and cpage.php, so we need to supply those two. Here's csite.php:

<?php
    class csite {
        private $headers;
        private $footers;
        private $page;

        public function __construct() {
            $this->headers = array();
            $this->footers = array();
        }

        public function __destruct() {
            // clean up here
        }

        public function render() {
            foreach($this->headers as $header) {
                include $header;
            }

            $this->page->render();

            foreach($this->footers as $footer) {
                include $footer;
            }
        }

        public function addHeader($file) {
            $this->headers[] = $file;
        }

        public function addFooter($file) {
            $this->footers[] = $file;
        }

        public function setPage(cpage $page) {
            $this->page = $page;
        }
    }
?>

The $headers and $footers variables are both arrays that will store file names of scripts to include at render-time - they are both initialised to be empty arrays when the site is created. The setPage() function takes a cpage object (note the type hint!), and stores it away for rendering.

The main function here is clearly render(), which is what the converts the various disparate parts into a working HTML file. It does that by first including each of the scripts stored in $headers, then calling the render() function of the cpage object, then including all the footer files. In reality it's not likely a site will have more than one header and footer file, but there's no harm being flexible!

Next up, the cpage.php file - here it is:

<?php
    class cpage {
        private $title;
        private $content;

        public function __construct($title) {
            $this->title = $title;
        }

        public function __destruct() {
            // clean up here
        }

        public function render() {
            echo "<H1>{$this->title}</H1>";
            echo $this->content;
        }

        public function setContent($content) {
            $this->content = $content;
        }
    }
?>

So we've got $title and $content variables there, which is predictable enough. Note how the constructor takes the page title as its only parameter - if you look back to index.php you'll see that being used. The setContent() function is pretty predictable, as is the main render() function itself - it's all very basic right now.

The header.php file is site-specific, and so could be anything you want. Here's an example:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>My Website</title>
</head>

<body>

Here's a footer.php example also:

</body>
</html>

That finishes up the code example - go ahead and run it, and you should see a very simple site being outputted. This is one of the big downsides to using OOP for your site: it takes an awful lot of work to get very little. Of course, once you've done that work, the rest of the site is quite easy!

 

Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: A more complex OOP website >>

Previous chapter: The Object-Oriented Website

Jump to:

 

Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.