3

I've been working lately on a custom framework, so before posting my concern I will explain the way I organized the framework.

There is a main class, from which all other classes are extended. All the other classes are interconnected between them with a a variable which has the name of the class. Easier said, I have the MAIN class. I also have the classes THEME, URI, INIT.

After the framework has initialized, if I get the MAIN instance and assign it to a variable, lets say $main, and I can use the other classes like this:

$main->theme;
$main->uri;
$main->init;

I can even use $main->theme->uri->theme->init if I want :D, but no way $main->theme->theme.

Also, from inside the classes (other than MAIN), I can access the other classes like $this->init, $this->theme, etc. The properties that point to those classes are references.

Now my concern, when I print_r the $main variable, I get a lot of RECURSION elements. The framework loads fast, and the memory consumption is 28MB, but still I get that recursion. Does it mean that the way I organized my framework is wrong, or it's just the print_r function that sees pointers pointing to same classes, and avoids infinite recursion?

Ok, here's a print_r of the TF_TFUSE class (the main one i was talking about). Here only two other classes have been implemented (too reduce output).

TF_TFUSE Object
(
    [framework_version] => 2.1
    [load] => TF_LOAD Object
        (
            [_the_class_name] => LOAD
            [framework_version] => 2.1
            [buffer] => TF_BUFFER Object
                (
                    [_filters:protected] => Array
                        (
                        )

                    [_buffer:protected] => 
                    [_the_class_name] => BUFFER
                    [_is_end:protected] => 
                    [framework_version] => 2.1
                    [load] => TF_LOAD Object
 *RECURSION*
                )

        )

    [buffer] => TF_BUFFER Object
        (
            [_filters:protected] => Array
                (
                )

            [_buffer:protected] => 
            [_the_class_name] => BUFFER
            [_is_end:protected] => 
            [framework_version] => 2.1
            [load] => TF_LOAD Object
                (
                    [_the_class_name] => LOAD
                    [framework_version] => 2.1
                    [buffer] => TF_BUFFER Object
 *RECURSION*
                )

        )

)
1

4 Answers 4

2

The problem is that you are linking everything together inside your objects. This problem is normally solved by creating a container class that holds the other objects and creates interactions between them.

To be able to do $main->theme->uri->theme->uri->theme->uri->theme->uri->theme->uri->theme->uri->theme->uri->theme->uri->theme->uri->theme->uri->theme->init should give you an indication that something is wrong . . .

A possible solution is represented generically below:

class Manager {
    $theme;
    $uri;
    $init;
}

And THEME, URI, and INIT no longer have direct relationships to each other.

Sign up to request clarification or add additional context in comments.

3 Comments

They need to have relations between them. I need to access the functionalities of one class in another one, but do it the way it is done in most frameworks (codeignitier, phpcake,etc)
What @Levi proposed still gives each object access to all the objects contained within the manager. The only difference is your classes have a dependency on the Manager, and not all with eachother.
This means that I have to access the other classes like this: $manager->theme; $manager->uri; or $this->manager->theme; etc.. But, I think the way it's done in CodeIgniter is different.
2

I believe your problem is more related to the fact you have instances of each of the other classes inside each other. theme->uri should not be possible if uri->theme is possible. Only one should have an instance of the other, if either are to have instances of other classes at all.

Think of it like this: I have a Player, he is holding a Bat and a Ball. You have a Player, he is holding a Bat and a Ball, the Bat is holding a Player and a Ball, and the Ball is holding a Bat and a Player.

You don't need all those cross-references, you need to establish a sane hierarchy of objects.

Comments

1

The print_r() function will note that it's printing out the same object more than twice and will list it as a *RECURSION* entry.

The way that you've organized the objects isn't wrong but consider a different approach, namely, passing only the necessary objects to the constructor. This allows you to clearly see what objects can access and modify which ones and provides better roles for your classes.

For more information you can read up on http://en.wikipedia.org/wiki/Dependency_injection

4 Comments

I guess this is exactly what I am doing. I am purposely injecting the isntances of other classes inside a current class, so I can access the other classes by a property of current class. However, I am not sure from that link, if I am doing it wrong or if it's just something normal for such a pattern
It seems that you're passing an object with all other objects onto every object (confusing). You should only pass objects that each class requires via the constructor (objects that the class depends on).
Each class has a required dependacy on every other class, except main from which it was extended.
Can you provide a simplistic example of your class structure? It would help to have a visual of what you're trying to do.
0

There is a main class, from which all other classes are extended.

I am sorry, this is not a direct answer to your question, but if this is the case you are very likely doing something fundamentally wrong. Why is there a need for all classes to extend main?

I think this conceptual problem is the root of your other problems.

5 Comments

I agree that he shouldn't be extending main, but that isn't the root of his problem.
@LeviMorrison He doesn't seem to be extending them through an is-a relationship (inheritance), but with a has-a relationship (main contains instances of other classes.) In that sense, it very well could be the root of his problem.
@middus, That seems to be the case and is the problem I noted in my answer, and the one Chris Browne noted after me. That doesn't seem to be clear in your post. If it was, I would have just +1 and moved along and never written an answer.
@LeviMorrison: I wrote that comment, not middus. I agree it's not completely clear here. :)
@robjb My apologies, mate. It's early in the morning for me :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.