views:

49

answers:

3

The only object oriented programming experience I have is from C#, so PHP is throwing me some curve balls I could use some help with.

I have a class I use for all my pages, the "pagebase" if you will. It handles the lowest level html structure. That class is inherited by several other classes. Those classes are the different page types the site has. Now: I'm having trouble setting a variable in the "pagebase" from the instance of the class that inherits it. In C# that would be no problem seeing as the class instance behaves as if it were the inherited class.

This is a representation of what I've got:

pagebase.php

<?php
    class pagebase
    {
        var $title = "No title";
        var $body = "<center>No content</center>";

        function setTitle($value) {
            $this->title = $value;
        }

        function setBody($value) {
            $this->title = $value;
        }

        function updateHTML()
        {
            ...
        }

        function drawPage()
        {
            $this->updateHTML();
            echo $this->html;
        }
    }
?>

std_page.php

<?php
    include("includes/pagebase.php");

    class std_page extends pagebase
    {
        function std_page()
        {
            ...
        }

        function updateHTML()
        {
            parent::setBody(
                "
                    <div id=\"main_wrapper\">
                        The page goes here!
                    </div>
                "
            );
        }

        function drawPage()
        {
            $this->updateHTML();
            parent::drawPage();
        }
    }
?>

index.php

<?php
    include "includes/std_page.php";

    $page = new std_page;
    $page->setTitle("Avesta");

    $page->drawPage();
?>

Now among other things, the biggest problem here is that NOTHING WORKS. The values in pagebase aren't changed even though I'm getting no error indicating the function wasn't found or run in any shape, way or form.

Someone please just inform me what I'm doing wrong - Thanks

A: 

This is a case of parent working in static scope, which is why you're using the :: operator.

If it's inheritance, just try $this->setBody for example.

Andrew67
+1  A: 

First thing first, never declare your properties using var keyword, please define its accesibilty using public, private, or protected.

Then when you want to access properties or method from the child class, you just need to use $this keyword. e.g $this->title, $this->setTitle('title')

Then there is static keyword when you define property or method as static you call it using :: operator. e.g if you have public static $title then you can access that using pagebase::$title

Hopes it clear some confusion.

leonardys
That clears the confusion right up :-) Thanks for your reply!
Codemonkey
A: 

I've made some changes to make the code run and fix up some issues. It's still not ideal, but it should work and be instructive...

abstract class pagebase
{
    private $title = 'No title';
    private $body = 'No content';

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

    public function setBody($value) {
        $this->body = $value;
    }

    public function drawPage()
    {
        $this->updateHTML();
        echo $this->body;
    }

    abstract protected function updateHTML();
}

class std_page extends pagebase
{
    protected function updateHTML()
    {
        $this->setBody(
            "
                <div id=\"main_wrapper\">
                    The page goes here!
                </div>
            "
        );
    }
}

Here are the changes:

  • I made pagebase abstract, with updateHTML an abstract method. It makes no sense to render a pagebase, and the way a particular child class expresses its individuality is by creating its own version of the updateHTML method.
  • I made your internal variables private, meaning outside code (including child classes like std_page) can't modify or read them. If child classes need access, you can use protected instead. Those methods accessible from anywhere are public. See visibility in the manual.
  • When accessing methods defined in the parent, you don't need parent::. That's only required when the child has its own implementation that overrides the parent's, but you want to call the parent's version explicitly. This can be helpful if the parent method does some real work, and the child wants to build off of that. See example number 3 in this manual entry.
  • If you're not changing how drawPage works, there's no need to redefine the method. Since you are overloading updateHTML, that overloaded version automatically gets used in the existing implementation of drawPage.
  • I fixed a copy and paste error where your setBody method actually set your title, and you were using $html in some places where presumably you meant $body.
grossvogel
As I mentioned, the code in my question is only a representation of what my problem is. My pagebase class is easily 20 times the size of my representation, thus corrections typos on my code is quite redundant. Most of the corrections you are mentioning I fixed myself after Leonardys pointed out where I was thinking wrong. After reading a flawed tutorial I thought that the parent class was only accessible through parent::That's why both extended class and parent had updateHTML functions. (Note: std_page.updateHTML updates the body while pagebase.updateHTML updates the entire HTML document)
Codemonkey
But your point nr. 4 I was not aware of, so thanks for replying. I voted your reply up for that reason :)
Codemonkey