Welcome Guest, Not a member yet? Register   Sign In
Extended Controller class not found - stumped!
#1

[eluser]CodeSpeed[/eluser]
I'm developing a billing software (it's more of an experiment to get familiar with CI) and I was doing so under Windows XP with no problems.

I recently switched to Linux and I started getting a "class not found" error, I thought it might have been because of incorrect filenaming (linux is case sensitive) but after a code review I found no such errors.

So I downloaded CI again and setup a clean install.

Then I proceeded to extend the controller class with only a constructor to keep it simple:

Code:
<?php
/* FILE 'application/libraries/my_controller.php' */

class MY_Controller extends Controller
{
    public function __construct()
    {
        parent::__construct();
    }
}
?>

Then in the 'application/controllers/welcome.php' controller I changed the name of the "Controller" class it extends to my new extended class "MY_Controller"

Code:
<?php

class Welcome extends MY_Controller
{
    public function Welcome()
    {
        parent::__construct();    
    }

    public function index()
    {
        $this->load->view('welcome_message');
    }
}

/* End of file welcome.php */
/* Location: ./system/application/controllers/welcome.php */

Then I run the site and I get

Quote:Fatal error: Class 'MY_Controller' not found in /home/joseph/public_html/samp/system/application/controllers/welcome.php on line 4

But if I add this to the beginning of the welcome.php file, it will work.

Code:
require_once(APPPATH.'libraries/my_controller.php');

So CI is not being able to see the extension file. Maybe it's a path problem since I didn't have this problem under Windows, but I ran out of ideas.

What am I doing wrong??? I hope you can help me Sad

Thank you!
#2

[eluser]dmorin[/eluser]
A couple of things.

In MY_Controller, I think it should be

Code:
parent::Controller();
Not
Code:
parent::__construct();

because the constructor in the CI controller lib is called Controller.

Second, your file should be named "MY_Controller" with a Capital "MY_C".

Let us know if that fixes it.
#3

[eluser]CodeSpeed[/eluser]
You... Sir... Are... God...

Smile
#4

[eluser]dmorin[/eluser]
Glad to hear it works.
#5

[eluser]Artemis Mendrinos[/eluser]
What if we want to name the extended controller differently?

For example, I like a name: Admin_controller for controllers with restricted session access.
#6

[eluser]philpem[/eluser]
[quote author="dmorin" date="1226887223"]
In MY_Controller, I think it should be

Code:
parent::Controller();
Not
Code:
parent::__construct();

because the constructor in the CI controller lib is called Controller.
[/quote]

It shouldn't matter -- __construct() is the "old" PHP way of doing it, but IMHO it's a better way than ClassName::ClassName(), because it saves work (and potential screw-ups) if you ever have to change a class name.

That one has bitten me on the backside on more than one occasion...
#7

[eluser]dmorin[/eluser]
I believe it does matter in this case. "__construct" is not the OLD way, it is the NEW way. CI uses the OLD way of using the class name for the constructor so it's supported in PHP4. Either are acceptable for naming the constructor method.

However, in that example, we aren't talking about naming the constructor method, we're talking about calling it from an extending class, in which case, I believe you must use the name of the method in the parent class, not either/or.

Edit:
I stand corrected. You can call the parent constructor using either method. I didn't know that. I still think I'm correct with __construct being the new and preferred way though.
#8

[eluser]philpem[/eluser]
[quote author="dmorin" date="1256089857"]I believe it does matter in this case. "__construct" is not the OLD way, it is the NEW way. CI uses the OLD way of using the class name for the constructor so it's supported in PHP4. Either are acceptable for naming the constructor method.[/quote]

Mea culpa. You're absolutely right...

From http://uk.php.net/__construct:

"For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics."

So I guess you lose compatibility with PHP4 (just trying to see if I care about that..... nope, I don't think I do), but gain the ease of refactoring. You still have to add a call to the parent constructor though:

"Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required."

[quote author="dmorin" date="1256089857"]Edit:
I stand corrected. You can call the parent constructor using either method. I didn't know that. I still think I'm correct with __construct being the new and preferred way though.[/quote]
See above.
#9

[eluser]InsiteFX[/eluser]
You can name the MY_Controller Class anything you want, but it must be saved in
application/libraries/MY_Controller

Just make sure you save it as MY_Controller...

Example MY_Controller:

Code:
class Auth extends Controller {

    function Auth()
    {
        parent::Controller();
    }
}


// Then extend your new Controller like this:

class Admin extends Auth {

    function Admin()
    {
        parent::Auth();
    }
}

Enjoy
InsiteFX
#10

[eluser]dmorin[/eluser]
Having different file names and class names is a sure way to confuse yourself or anyone else who may have to maintain it down the road. Is that really better than just including the file at the top, or better yet, adding an autoloaded? The answer to this will be different for everyone, but I wouldn't mix names; the potential for confusion is just too high.




Theme © iAndrew 2016 - Forum software by © MyBB