1

Possible Duplicate:
Return a loop in function php

To make my question more clear, I'll explain the situation a bit... I'm trying to make a simple yet powerfull PHP-ORM-tool. First versions ( only 25 kB of code ) and tests are quite promising, it has e.g. lazy-loading. Now I'm optimizing the thing by e.g. minimizing the number of queries, ...

For the lazy-loading, I use a Proxy-class. The Child-property of the Parent-class is a Proxy at first. That Proxy contains an empty object...

class Parent {
    getChild() { ... }
    //other code
}

class Child {
    getName() { ... }
    //other code
}

class Proxy {
    $object = false;    
    public function _query() { /*some code to get the objects*/ }
    __call() { 
        if(!$objects) 
            $this->_query();
        //perform called function on the $object(s)
    }
    //other code
}

When we ask the Child from the Parent, we assume it is a Child, but in fact it is a Proxy. As long as we don't do anything with it, we don't have to query the database... Whenever we ask the Child something ( like getName() ), the magic call function comes in action, queries the database an performs the called function on the new object. The principle is easy, but it is a lot more difficult in code... (it also support lists of objects, triggers in loops, has arraysaccess, the querying is quite complex too, ...)

The problem now is the following:

foreach( $parents as $parent ) {
    echo $parent->getChild()->getName();
}

Every call in the foreach loop, triggers a query to the database... I don't want that! Because I already know that I want the children of a list of parents (thats what the human mind says at least...)

Let's assume I have knowledge of all the Proxies of the same type, I would like to do something like this:

class Proxy {
    _query() {
        ## some code to test if the call originates from within a loop ##
            //if so: fill all the Proxies of this type with their object(s)
            //else fill this Proxy with its object(s)
    }
    //other code
}

I know I'm simplyfying this a bit, but that's the general idea...

debug_backtrace can give me the method from which a function was called, but I want information on the loop-structures... (if possible even the original list etc...)

Community
  • 1
  • 1
Stivni
  • 437
  • 1
  • 6
  • 15

3 Answers3

2

Why not just using a parameter like

function _query($loop = false)

when called in a loop you could use _query(true), to tell the function you are in a loop.

Otherwise you could use an internal counter-variable to count the calls for the query. ;)

Daniel Jäger
  • 177
  • 1
  • 3
  • 13
  • The big idea about having an ORM is that the programmer who uses it, doesn't need to know to underlying mechanisms and performance-measures. He doesn't calls the _query-function himself, it gets called by the orm system! – Stivni Nov 27 '11 at 19:21
  • Then you should use an internal counter. Increment it when the function is called - save the query in a temporary variable to check if the same query gets called more than one time. – Daniel Jäger Nov 27 '11 at 20:45
1

No, it can't detect that as far as I know but you could always send a parameter when calling the method no?

jprofitt
  • 10,874
  • 4
  • 36
  • 46
span
  • 5,405
  • 9
  • 57
  • 115
  • As I explained to Daniel Jager, I am not in the possibility to call it with a parameter, as the ORM-user doesn't know that he's working with a Proxy instead of the real Child! – Stivni Nov 27 '11 at 19:23
1

You can't programmatically, but one hack I can think of is to set a global flag variable before any loop?

You can examine the call stack, but the overhead will be huge.

Bill
  • 3,059
  • 3
  • 31
  • 47
  • Bill, I think you get the idea... What size of overhead are you talking about? Querying for every Child in a list of Parents is overhead too, I think... – Stivni Nov 27 '11 at 19:25
  • Frankly, that feature should only be used for when exception/error/debugging happens. I personally wouldn't use it for any site, however, the additional parameter idea by @Daniel Jager is probably a better idea. – Bill Nov 27 '11 at 19:27
  • 1
    I can't disagree... I'm that kind of programmer-purist too, use things for what they're intended for. It's from that point of view I want an ORM that doesn't interfere with the models at all. I want a complete seperation of concerns... Thank you! – Stivni Nov 27 '11 at 19:30
  • How about a signal from from child to the parent? – Bill Nov 27 '11 at 19:32
  • That's the solution for the filling of the objects, but still I don't know if I need to fill them... The Microsoft .Net Entity Framework does it quite good, an I Microsoft can in .Net, why wouldn't I in PHP ;-) – Stivni Nov 27 '11 at 19:36