I asked this question before, but I think it was misinterpreted, so I’m going to try to reword it in a less confusing way.
Where should I put my own custom classes in CodeIgniter? I’m not talking about Models, Views, Controllers, Libraries, Helpers, Plugins, or anything else along those lines. I’m talking about my own custom data structures, which I can instantiate in my Controllers.
Here’s a very simple textbook-ish example of a class that would meet these criteria (I don’t want to build this class, but it’s representative of what I mean):
class Dog { var $name; var $age;
function Dog($n, $a){ $this->name = $n; $this->age = $a; }
function getName(){ return $this->name; }
function bark(){ echo 'Woof woof, my name is ' . $this->name . '!'; }
Then, in a CONTROLLER (or model), I would like to be able to do stuff like this:
$myDog = new Dog('Bowser', 4); $yourDog = new Dog('Peach', 9);
$myDog->bark();
$foo = $yourDog->getName();
Where is the proper place to put this custom Dog class, so that it’s properly accessible by my Models/Controllers, and I can create instances (possibly multiple instances) of it within the Models/Controllers?
Note: I understand that there are other ways to achieve the same results, but this is a pretty necessary thing to be able to do in OOP, so I’m sure I’ve just missed the part of the documentation that explains it. Thanks in advance!
EDIT: (this is a copy from the post below, so ppl don’t have to scroll)
The object I’m making (the Dog example follows this) is essentially a custom data type (the example is one you see in OO books all the time). I’d like the same freedom with it that I have with a String; I can put many instances of it in an array, I can assign an instance of it as the value in another object, etc… from what I understand, this is not how a Model should be used.
I’ve heard varying opinions on multiple instances of a model, but it seems like they’re not meant to be instantiated more than once. Do you have any articles/examples where a model is instantiated more than once in a controller (or in another model) that I can look at?
The object I’m making (the Dog example follows this) is essentially a custom data type (the example is one you see in OO books all the time). I’d like the same freedom with it that I have with a String; I can put many instances of it in an array, I can assign an instance of it as the value in another object, etc… from what I understand, this is not how a Model should be used.
It appears you’re hoping to instantiate your class in the traditional way. Of course that’s always an option for you, once the file has been loaded. But you might consider adhering to CI’s design a bit here.
$this->load->model('Dog');
$this->dog->bark();
If you need multiple simultaneous instances of the Dog class, then you can do this:
$this->load->model('Dog', 'dog2');
$this->dog2->bark();
Once loaded, the models are accessible from within view files, as well.
It appears you’re hoping to instantiate your class in the traditional way. Of course that’s always an option for you, once the file has been loaded. But you might consider adhering to CI’s design a bit here.
$this->load->model('Dog');
$this->dog->bark();
If you need multiple simultaneous instances of the Dog class, then you can do this:
$this->load->model('Dog', 'dog2');
$this->dog2->bark();
Once loaded, the models are accessible from within view files, as well.
This seems to be what I was looking for, but let me make sure. In the example you provided, is “dog2” an object of the class Dog? So like for example, could I go like this:
If there was a short post on how to load multiple instances of the same model, that would be great. Also, is it ever proper form to load a model within another model?
The second parameter determines whether you want your class loaded under a custom name. At the moment, you can only specify a single name. You’d need to make multiple calls to the $this->load->model() method to get all of your instances. I think that’s a good feature request you could make… allow an array of names to be passed into the second parameter at which point you end up with multiple instances.
Ah, that makes perfect sense (and now I understand what the point of that model feature is in the first place ). So, theoretically, I could go like this:
Interesting thread. Initializing multiple instances of a model seems straightforward but seems not to be the most ideal solution for a system I am working on.
I am involved in an open-source bibliography management project (www.aigaion.nl) and we are working on the specification of Aigaion 2.0 at this very moment. We decided to switch to CI/MVC and are now implementing the very basics.
We have both single publication views as publication lists, both having their own model classes. Since in a publicationlist model we can have arbitrarily many publications we create an array with single publications.
Since the CI overhead on a single publication model instance is pretty large we decided to separate the data structure from the model, by defining a publication_data class. The publicationlist model now contains an array of publication_data instances.
Now the question remains: What would be the best suited place to have the publication_data class?
Now the question remains: What would be the best suited place to have the publication_data class?
Ok so if you want a Model to return custom data objects instead of just stdClasses, I see a couple of places to do this.
First, if the objects are only generate by one model, you could place them in the same file as the model itself. This makes them avaialable anywhere, but makes it a requirement to load the model.
Another thing you can do is to have e.g. a place in your application that’s most logical to you to store your data classes. Suggestions would include:
Since it is related to models, I think a sub directory to models may be a good place. Or something competely separate. Then inside your Model don’t be afraid to just use the php include statement.
<?php // include my data objects include_once('dataclasses/pubdata.php'); class publicationlistmodel extends Model { ... }
As opposed to others here, I’m not one that insists on the loader loading everything. ‘Include’ is valid php syntax and if you’re not loading a framework object it’s just fine to use it, IMHO. The Loader class also has a function ‘file’, so you could use that as well - though you have to pass it an absolute path methinks.
...don’t be afraid to just use the php include statement…
HTH
I agree. This is what I was thinking. I don’t see any benefit from using the CI loading mechanism for “generic objects” (those that aren’t part of the MVC aspect of the design, aren’t related to the CI infrastructure, and don’t require any coupling to CI specifically). Remember, we are still coding PHP here, and lots of goodies come from the native environment. No need to unnecessarily bind it to the framework.
That’s the ‘how’. As for ‘where’, I don’t think the directory structure of CI is somehow sacrosanct, in that you can add another directory below /application. As long as you keep DRY in mind, and build a directory structure in a way that supports the logic of your app, I think it makes more sense to customize your /application directory to fit your app, rather than to expect every need to fit neatly into a base CI installation.
Oh, and symlinks are your friend :)
One last thing, mostly related. I personally have been keeping all the php-related infrastructure under /application, but keeping my other “site” related stuff (css, javascript, images) above the /system folder, customizing my .htaccess file to avoid http requests for such data from being handled through CI. My impression is that this is a common best practice.
One last thing, mostly related. I personally have been keeping all the php-related infrastructure under /application, but keeping my other “site” related stuff (css, javascript, images) above the /system folder, customizing my .htaccess file to avoid http requests for such data from being handled through CI. My impression is that this is a common best practice.
It probably is the best from a security perspective. Lately however I’ve been adjusting my method there a little bit as I’m now managing a growing number of CI sites and I’m not hosting all of them. Therefore I often only have access to the webroot. What I tend to do is to pull application out of the system to keep the site more upgradable with CI releases. I rename the system to reflect the CI version. I have index.php and .html files in either to block direct access and also add stuff to my .htaccess to forbid access to either directory. That keeps it pretty safe as well and I don’t have to massage my front controller other than renaming the system folder. This allows me to test very quickly if a site would run on a newer CI release.
I wish there was a voting system on posts. Jake and Mirage’s two posts are full of excellent information.
You mean a ‘rating’ system? I agree. I love how the apple forums have this. They also allow you to mark whether a post answered a particular question one had, therefore being able to better rank thread/post/member to a finer degree.
An excellent feature request for the EE Forums mod.