CodeIgniter Forums

Full Version: Where to put plain object classes?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5
(12-30-2014, 02:59 PM)mwhitney Wrote: [ -> ]That's what this code does. The primary purpose of extending CI_Model is more or less to utilize this function, usually for the purposes of accessing $this->db from within your model.

Yes, I know it's a shortcut to the CI object, but I don't understand why sneakyimp is expecting problems because of that. Everybody uses this class without problems!
(12-30-2014, 10:11 AM)includebeer Wrote: [ -> ]What's your point? You don't want to use the CI_Model class at all?
My point is that it doesn't seem worthwhile to use it so why should I. I'd even go further to say that it might be detrimental to use it because, as mwhitney confirms, it would mingle the properties of my model class with those of the CI object due to the magic __get method.

(12-30-2014, 10:11 AM)includebeer Wrote: [ -> ]Why would it cough up CI properties?
See mwhitney's post. Also, PHP docs on the __get magic method might be helpful.
I know what it does. I just don't understand your concern. If you're afraid to use this class, then don't. CI doesn't force you to use anything. But I don't see any good reason not to. Can you give an example where it would cause problems?
(12-31-2014, 12:19 PM)includebeer Wrote: [ -> ]I know what it does. I just don't understand your concern. If you're afraid to use this class, then don't. CI doesn't force you to use anything. But I don't see any good reason not to. Can you give an example where it would cause problems?
I don't expect I will use CI_Model, mostly because it might get confusing if I wanted to give my own model class a property with any of these names:
Code:
benchmark
hooks
config
log
utf8
uri
router
output
security
input
lang
load
session
db
All of these properties are defined by the CodeIgniter object and if you define a trivial class with no properties that extends CI_Model, it looks like that trivial object has all of those properties. I can see how this might be handy, but This just seems weird to me:
Code:
class Test_model extends CI_Model {
    public function __construct() {
        var_dump($this->lang); // yields object(CI_Lang)#11 (2) { ["language"]=> array(0) { } ["is_loaded"]=> array(0) { } }
    }
}
I can see how it might be convenient to have access to the entire CI environment within one's models, but I believe it reduces the modularity of one's code to depend on this elaborate object automatically being instantiated whenever I need a model. If I did actually want such a complex object attached automatically to every model I create, I would defintely want it at least to have its own property within my model class (e.g., $this->ci->lang) instead of automagically inserting its own 14 properties into every model I have.

I have also noticed that creating a class that extends CI_Model like this:
PHP Code:
class Test_model extends CI_Model {
    public function 
__construct() {
        die(
"Here i am!");
    }

will mean you have to include/require system/core/Model.php or you get this error:
Code:
Fatal error: Class 'CI_Model' not found in /var/www/erep-v4/application/models/Test_model.php on line 2
Quote:will mean you have to include/require system/core/Model.php or you get this error:


Code:
Code:
Fatal error: Class 'CI_Model' not found in /var/www/erep-v4/application/models/Test_model.php on line 2

What? I don't know what you have done but you don't need to include anything to use a model!
That error should not occur if you use $this->load->model(), but it will probably occur if you load the model some other way (such as via an external autoloader). If you intend to autoload the class, it probably shouldn't extend CI_Model.

As for the rest, it's simply a different way of writing code. I understand the desire to not have $this cluttered with everything which might be loaded by CI, but it can certainly be convenient in some cases. There's nothing stopping you from creating models which don't extend CI_Model (or even a base model which doesn't extend CI_Model), but you do have to remember that when you extend the CI classes you may be requiring the use of CI's loader for your classes.
I don't understand the debate. Maybe it is case of the framework getting in the way of thinking clearly Wink However, using the following code, I'm extending, overloading and whatever else like crazy. No include_once's anywhere, just a simple autoloader I added to config/config.php

Code:
/*
|--------------------------------------------------------------------------
| Auto-load models, controllers, libraries and more oh my
|--------------------------------------------------------------------------
*/

function application_autoloader($class) {
$locations = array(
APPPATH.'models'.DIRECTORY_SEPARATOR.strtolower($class).'.php',
APPPATH.'controllers'.DIRECTORY_SEPARATOR.ucfirst(strtolower($class)).'.php',
APPPATH.'libraries'.DIRECTORY_SEPARATOR.ucfirst(strtolower($class)).'.php',
APPPATH.'core'.DIRECTORY_SEPARATOR.strtolower($class).'.php',
);

foreach($locations as $location) :
if(file_exists($location)) :
include $location;
endif;
endforeach;
}
spl_autoload_register('application_autoloader');

function system_autoloader($class) {
$class = ucfirst(str_replace('CI_', '', $class)).'.php';

$locations = array(
BASEPATH.'libraries'.DIRECTORY_SEPARATOR.$class,
BASEPATH.'core'.DIRECTORY_SEPARATOR.$class,
);

foreach($locations as $location) :
if(file_exists($location)) :
include $location;
endif;
endforeach;
}
spl_autoload_register('system_autoloader');
(01-01-2015, 12:30 PM)includebeer Wrote: [ -> ]What? I don't know what you have done but you don't need to include anything to use a model!
You are incorrect, sir! If you want to extend CI_Model, you must either
a) include/require system/core/Model.php explicitly
OR
b) call $this->load->model() to get CI to require/include the CI_Model class for you.

To prove, try downloading a fresh CI3 from here:
http://www.codeigniter.com/download

Edit the Welcome controller so it's index function looks like this:
Code:
public function index()
        {
                require_once APPPATH . "models/Testmodel.php";
                $v = new Testmodel();
                $v->foo();
        }

And create a Testmodel class in application/models/Testmodel.php that contains this:
Code:
class Testmodel extends CI_Model {
  public function foo() {
    echo "congratulations! foo is running\n";
  }
}

The result:
Code:
Fatal error: Class 'CI_Model' not found in /path/to/CI/application/models/Testmodel.php on line 2
(01-02-2015, 01:26 PM)mwhitney Wrote: [ -> ]That error should not occur if you use $this->load->model(), but it will probably occur if you load the model some other way (such as via an external autoloader). If you intend to autoload the class, it probably shouldn't extend CI_Model.
Unless I take care to also autoload CI classes too, as ivantcholakov's class does

(01-02-2015, 01:26 PM)mwhitney Wrote: [ -> ]As for the rest, it's simply a different way of writing code. I understand the desire to not have $this cluttered with everything which might be loaded by CI, but it can certainly be convenient in some cases. There's nothing stopping you from creating models which don't extend CI_Model (or even a base model which doesn't extend CI_Model), but you do have to remember that when you extend the CI classes you may be requiring the use of CI's loader for your classes.
I certainly agree that the default/native means of loading classes with CI is a certain way of writing code. I just thought that some of the early answers to the original question "where to put plain object classes?" were a bit oversimplified. I like that CI is lightweight and doesn't force you to use all of its features. I personally am still wondering how one determines which classes go into libraries and which classes go into models.
You'll probably never find a satisfactory generalized answer to the question of which classes are libraries and which are models. I generally think of libraries as a location for things which tend to interact with multiple parts of the MVC pattern, or don't easily fit into the pattern. I also frequently use it for code which was not originally written for an MVC framework in the first place, or even libraries originally written for other frameworks, even if they are MVC frameworks.

Models I tend to use primarily for data access, whether the data happens to be in a database or some other form. I tend to put my business rules into models, but I rarely have reason to store the business rules separate from the model(s) which interface the data to which those rules apply. In many cases I also include methods in my models which allow those rules to be retrieved or executed by the controller (more often than not because it simplifies working with certain libraries in CI, like form_validation).
Pages: 1 2 3 4 5