Welcome Guest, Not a member yet? Register   Sign In
How can I use an abstract class in CodeIgniter?
#1

[eluser]php_princess[/eluser]
I want this class (we'll call it Dog_create) to extend MY_Controller and then I want two classes to extend Dog_create (we'll call them From_scratch and From_breeding).

Why do I want to do this? From_scratch and From_breeding will do some of the same things.
#2

[eluser]apodner[/eluser]
The only way I have managed to make this work is to include the file with the abstract class immediately before the child class declaration.

I thought a pre controller hook to include the file would do it, but I couldn't seem to make that work. And a pre system hook was executing too early to work properly.

I am not a fan of doing an include like this in a class definition file. You could possibly put an autoloader in to make it cleaner, but that seems like overkill given that one line of code will clean it up.

Abstract Class
Code:
abstract class MyAbstractClass extends CI_Controller
{
    public function someMethod()
    {
       /*code*/
    }

}


Concrete Child Class
Code:
require_once APPPATH.'controllers/myAbstractClass.php'
class myConcreteClass extends MyAbstractClass
{
     public function index()
     {
          /* CODE */
     }
}

#3

[eluser]php_princess[/eluser]
Thank you for your reply and hmm I see.

Another question: Do you know of a way to use interfaces with CodeIgniter? Do you do it the same way you would if you weren't using a framework?
#4

[eluser]apodner[/eluser]
I would probably approach it the same way as I described above. just create the interface and include the file above the declaration of any class that implements the interface.

If I were using more than one different abstract class and/or interface in the same app, I might spend the time to go ahead and do an autoloader. Would probably invoke the autoloader with a pre system hook.

I may play around with that concept and see how it does. Will post back here if I come up with something.
#5

[eluser]apodner[/eluser]
ok, here is a way to do it with a pre-system hook & autoloader:

Assumptions:
1) You use a specific folder for your abstract classes & interfaces (I used 'application/models/abstract')
2) File names for interfaces and abstract classes are lowercase versions of the class/interface name

config/hooks.php
Code:
$hook['pre_system'] = array(
                        'function' => 'callAutoloader',
                        'filename' => 'autoloader.php',
                        'filepath' => 'hooks',
                        );


hooks/autoloader.php
Code:
function callAutoloader()
{
    spl_autoload_register('autoloadInterfaces');
}


function autoloadInterfaces($className)
{
    $filename = APPPATH . 'models/abstract/' . strtolower($className) . '.php';
    if (file_exists($filename)) {
        require_once  $filename;
    }
}

So basically this autoloader is set up to only load classes and interfaces that are in the 'applications/models/abstract' folder. All other classes will be ignored so as not to interfere with Codeigniter's system core and loaders. It's not that fancy but it will get the job done, and keep you from having to put include/require statements into every class declaration.
#6

[eluser]php_princess[/eluser]
Could you put the abstract classes in "application/abstract"?
#7

[eluser]apodner[/eluser]
yeah, you would just change the autoloader function to say...

Code:
$filename = APPPATH . 'abstract/' . strtolower($className) . '.php';

...and be sure to create the folder.
#8

[eluser]Aken[/eluser]
You can put as many classes as you want in the MY_Controller.php file. You don't even need a MY_Controller class, you just need it to be named that.

CI isn't too classy when it comes to OOP / autoloading and such, so there really is no standard way to handle a lot of classes like this. You can always do your own includes/requires wherever it's convenient (index.php, config file(s), in your controller, a base controller, etc...).

Code:
// application/core/MY_Controller.php

abstract class Base_Controller extends CI_Controller {

    function foo() {}
    function bar() {}

}

class Scratch extends Base_Controller {}
class Sniff extends Base_Controller {}

// An example controller in application/controllers:

class Dogs extends Sniff {

    // ...

}
#9

[eluser]php_princess[/eluser]
You can put multiple classes in MY_Controller? Wow, I never knew that.

New Question: Why doesn't CodeIgniter have more features to support development with OO PHP? Is it because you're supposed to do things your own way?

#10

[eluser]apodner[/eluser]
I would agree that technically you can put multiple classes in the same file and your code will work as intended. However over the long term, you may want to avoid that if you can. Typically, you want to have one class per file to promote maintainability and readability.

CI is heavily object oriented in its design. If you think about it, every call you make to display a view or interact with a model is done so in an object oriented way. $CI or ($this) itself is a huge object.

I do agree though, that the some of the more advanced constructs of OOP are not natively available in CI, and it takes a little work to get them up and running. I think one of the limiting factors is the lack of a native autoloader. The bottom line is that no framework is a one-size fits all solution. A framework is a tool, and as the axiom goes, "you have to have the right tool for the job".

It may be that CI is not the right fit for your particular application requirements. I think it is always important to know what a particular framework is best suited, and what it isn't. However, one nice thing about CI is that it is pretty easy to extend core functionality if you really want to use it, but there is just something it doesn't do out of the box.





Theme © iAndrew 2016 - Forum software by © MyBB