Part of the EllisLab Network
   
1 of 2
1
Where to put custom classes in CodeIgniter?
Posted: 27 March 2007 02:48 PM   [ Ignore ]  
Summer Student
Avatar
Total Posts:  15
Joined  03-19-2007

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.

Profile
 
 
Posted: 27 March 2007 03:07 PM   [ Ignore ]   [ # 1 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  735
Joined  10-18-2006

It can be a model. It is accesible by other models and controllers, and you can have multiple instances. If model is no good, please specify why not.

 Signature 

Once in a while I remember I use Twitter

Profile
 
 
Posted: 27 March 2007 03:14 PM   [ Ignore ]   [ # 2 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1739
Joined  06-23-2006

What you’re describing is a Model class. A Model approximately models a real-world object or collection of data. It belongs in the /models directory.

Maybe you have a different definition for “Model”?

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 27 March 2007 03:17 PM   [ Ignore ]   [ # 3 ]  
Summer Student
Avatar
Total Posts:  15
Joined  03-19-2007

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.

Profile
 
 
Posted: 27 March 2007 03:17 PM   [ Ignore ]   [ # 4 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1739
Joined  06-23-2006

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.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 27 March 2007 03:23 PM   [ Ignore ]   [ # 5 ]  
Summer Student
Avatar
Total Posts:  15
Joined  03-19-2007
coolfactor - 27 March 2007 03:17 PM

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:

$this->load->model('Dog', 'dog2', 'dog3');
$this->dog2->bark();
$this->dog3->bark();

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?

Profile
 
 
Posted: 27 March 2007 03:33 PM   [ Ignore ]   [ # 6 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1739
Joined  06-23-2006

Check the User Guide.

http://www.codeigniter.com/user_guide/general/models.html

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.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 27 March 2007 03:49 PM   [ Ignore ]   [ # 7 ]  
Summer Student
Avatar
Total Posts:  15
Joined  03-19-2007

Ah, that makes perfect sense (and now I understand what the point of that model feature is in the first place smile ).  So, theoretically, I could go like this:

$this->load->model('dog', 'dog1');
$this->load->model('dog', 'dog2');

$this->dog1->bark();
$this->dog2->bark();

Also, how can I pass values to the constructor (if I even can)?

Profile
 
 
Posted: 27 March 2007 04:11 PM   [ Ignore ]   [ # 8 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1739
Joined  06-23-2006

There is no way to pass data into the Model’s constructor directly. You’d need to call a method or set the values directly.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 27 March 2007 08:53 PM   [ Ignore ]   [ # 9 ]  
Summer Student
Avatar
Total Posts:  15
Joined  03-19-2007

Awesome, thanks so much for the help.  Really appreciate it.

Profile
 
 
Posted: 28 March 2007 06:57 AM   [ Ignore ]   [ # 10 ]  
Summer Student
Total Posts:  9
Joined  01-29-2007

Hi,

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?

Thanks,
Wietse

Profile
 
 
Posted: 28 March 2007 11:00 AM   [ Ignore ]   [ # 11 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  572
Joined  09-30-2006
wietseb - 28 March 2007 06:57 AM

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:

application
    
- dataclasses
        
- pubdata.php
    
- models
        publicationlistmodel
.php
        myothermodel
.php
        
- dataclasses
            
- pubdata.php
    
- libraries
        
- dataclasses
            
- pubdata.php

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.

HTH

Profile
 
 
Posted: 28 March 2007 01:42 PM   [ Ignore ]   [ # 12 ]  
Summer Student
Total Posts:  7
Joined  03-15-2007
CI mirage - 28 March 2007 11:00 AM

...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.

Jake

Profile
 
 
Posted: 28 March 2007 02:01 PM   [ Ignore ]   [ # 13 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  572
Joined  09-30-2006
j2geek - 28 March 2007 01:42 PM

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.

So this is what I end up with:

webroot
    
.htaccess
    
- application
    
- css
    
- img
    
- js
    
- system_152
    index
.php

Cheers!

Profile
 
 
Posted: 28 March 2007 02:35 PM   [ Ignore ]   [ # 14 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1739
Joined  06-23-2006

I wish there was a voting system on posts. Jake and Mirage’s two posts are full of excellent information.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 28 March 2007 02:39 PM   [ Ignore ]   [ # 15 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  572
Joined  09-30-2006
coolfactor - 28 March 2007 02:35 PM

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.

Profile
 
 
   
1 of 2
1
 
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 719, on June 06, 2008 10:16 AM
Total Registered Members: 66411 Total Logged-in Users: 30
Total Topics: 84748 Total Anonymous Users: 0
Total Replies: 454808 Total Guests: 227
Total Posts: 539556    
Members ( View Memberlist )
Newest Members:  alexmuellerkizerdrixcaptainredmuffquinodligtharttechsivamDjordjesammozzazodman23mbsa