Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP 'non-object' error [duplicate]

Tags:

php

I'm working on a small MVC framework in PHP for an exercise. PHP, however, doesn't seem to like my Controller class. The class contains an instance of a loader that loads views:

abstract class Controller
{
    public $load;
    function __construct($load) 
    {
        $this->load = $load;
    }
    abstract public function index();
}

From there, I can override Controller for all my controllers. For instace, my index controller:

class Index extends Controller
{
    public function index()
    {
        $this->load->view("hello_world");
    }
}

But when I create it:

require 'Controller.php';
require 'Load.php'
require 'controllers/Index.php';
$i = new Index(new Load());
$i->index();

I get this error:

PHP Fatal error:  Call to a member function view() on a non-object in /var/www/controllers/Index.php on line 7

Can you guys help me out? I know I set the load in the constructor, and the load class does have a method called view, so why is it giving me this error? Also: Load class, just for good measure

class Load
{
    public function view($filename, $data = null)
    {
        if(is_array($data)) extract($data);
        include ROOT.DS.'views'.DS.$filename.'.php';
    }
}
like image 224
DelishusCake Avatar asked Dec 26 '22 22:12

DelishusCake


2 Answers

The problem is with this code, and it's not always obvious:

class Index extends Controller
      ^^^^^
{
    public function index()
                    ^^^^^
    {
        $this->load->view("hello_world");
    }
}

This is the same name and therefore a PHP 4 backwards compatible constructor. The parent's constructor then is not called, $load not set and the function not defined.

Knowing this, there are many solutions, including:

namespace DelishusCake;

Introduce a Namespace

This automatically fixes your issue. You need to place this on top of the file.

class Index extends Controller
{
    public function index($load = NULL)
    {
        isset($load) && $this->load = $load;
        $this->load->view("hello_world");
    }
}

Make the PHP4 backwards compatible constructor work

Or:

class MyIndex extends Controller
{
    public function index()
    {            
        $this->load->view("hello_world");
    }
}

Rename the class

Or:

class Index extends Controller
{
    public function __construct($load) {
        parent::__construct($load);
    }
    public function index()
    {            
        $this->load->view("hello_world");
    }
}

Add a PHP 5 constructor, call the parent's constructor

Keep in mind that you only need this because it's the same name. The in depth description you can find as well in the PHP Manual on the Constructors and Destructors page.

like image 191
hakre Avatar answered Jan 11 '23 07:01

hakre


You need to instantiate the parent class.

class Index extends Controller
{
    public function __construct($load) {
      parent::__construct($load);
    }

    public function index() {
      $this->load->view("hello_world");
    }
}
like image 25
flowfree Avatar answered Jan 11 '23 08:01

flowfree