Welcome Guest, Not a member yet? Register   Sign In
Best Practice for instantiating classes in Libraries that are non-singletons?
#1

[eluser]glopv2[/eluser]
Hi all!

First, I am a big fan of CI. What a great project! And expertly done. So much so, that this is the first time I've ever felt the need to post and it's more of a best practices question than a "how do I do this?" question (disclaimer: I'm not great with PHP). Unfortunately, I couldn't find a relevant answer on the forums searching. Okay, here goes:

- - - - - - - - -

I want to push data around on my site using objects and classes. Let's say I have this:
Code:
class person {
  public $name;
  public $age;
  
  public function __construct($newName, $newAge) {
    $name = $newName;
    $age = $newAge;
  }
}
I want this to be the format that some models return data, and the format in which some views expect data.

My question is where do I store the code that defines the class?

- - - - - - - - -

1. The first obvious answer is as a library, but the problem is a library seems to only work for the singleton pattern. I want lots of persons, each one with unique data. I don't want to attach one instance to the $CI object. I just want my whole application to be on the same page about what a "person" object is when it gets passed around.

2. The second answer was a helper file, but the problem here is that the (excellent) documentation indicates that helper files are really for simple scripts and functions. Not for classes.

3. The third answer was to use a require_once() call and make a new directory for these classes. This seems bad to me, because it lives outside of the framework in a sad lonely island by itself. I want to adhere to the principle of least surprise, and seemingly random require_once() calls may be confusing to every developer but me.


So, having suggested and shot down those 3 ideas, can anyone tell me which one they think is best, or what is a great 4th alternative?



Thanks!
#2

[eluser]InsiteFX[/eluser]
libraries

InsiteFX
#3

[eluser]Unknown[/eluser]
I was wondering the same thing...

Libraries do seem like the way to go, but is there any answer to OP's observation that they seem to be designed to use the singleton pattern?

Regards,
Stephen
#4

[eluser]glopv2[/eluser]
@InsiteFX thanks for your reply! My problem is, I want multiple instances of my class and using the CI loader forces me to instantiate exactly one.
#5

[eluser]Jelmer[/eluser]
Not exactly, it forces you to have at least one. You can always instantiate more using normal PHP syntax.

For instance with a class Rss_reader:
Code:
$this->load->library('Rss_reader');
// Instance #1 will be in $this->rss_reader

// Create instance #2
$instance_2 = new Rss_reader();

// Create instance #3
$instance_3 = new Rss_reader();

// Create instance #4
$instance_4 = new Rss_reader();
#6

[eluser]glopv2[/eluser]
Thanks Jelmer!

Incidentally, is there any way to suppress the first instance?

It seems like in design patterns like mine it would be a waste of resources to have $this->rss_reader lounging around in memory somewhere. Is this a rare problem?
#7

[eluser]Jelmer[/eluser]
If you don't want to have that first instance you don't really need the CI loader. The most important job of the loader is to make that first instance globally available throughout the system and to prevent loading it twice. If you don't want the $this->rss_reader instance, you won't need an instance that's globally available so you only have to prevent loading it twice.

Solution 1: use require_once() or include_once(), or maybe write your own loader function using one of these so you don't have to include the entire path each time.

Solution 2: don't use require() or include(), but use an autoloader like the one I posted in this topic.

The load->library is mostly usefull when you're only using one instance and need to have it available in every model and throughout the controller (indeed a bit like the singleton pattern, though not fully if memory serves me right).
#8

[eluser]glopv2[/eluser]
Both are excellent suggestions. Thanks again!
#9

[eluser]WanWizard[/eluser]
You should be able to use
Code:
$instance = load_class('myclass', FALSE);
to load a class without instantiate is as a library.
#10

[eluser]Jelmer[/eluser]
Good point Wanwizard, I forgot about that function. Though I'm not sure about how you put it.

For that first instance you need to put it like this:
Code:
$instance = load_class('myclass', TRUE);
When set to FALSE it only returns TRUE after load.

I prefer the autoloader solution, but if you want to do it this way I'd use it like this:
Code:
load_class('myclass', FALSE);
$instance = new Myclass();




Theme © iAndrew 2016 - Forum software by © MyBB