1

I'm in the process of learning OOPHP, and I'm looking for some 'best practice' advice.

With a relational db, there's obviously foreign keys in many tables. When I am creating Models for my site I am trying to determine if it is better to do JOIN queries in the model, or have one model call another?

Calling other models seems to keep the code more modular. Either way seem to create dependencies, whether it be on another table or anther model.

If I go with the 'call other models' approach I seem to run into another problem: infinite loops. Here's the example I'm running into. I have 2 tables, person and school. Each person has a favorite school, represented by a schoolId. Each school has a principal, that is a personId.

The person object the row is mapped to accepts a school object in its constructor, but the school object the school row is mapped to accepts a person object in its constructor.

From what I've found, something about lazy loading, seems to be the solution, but (I could be wrong) it seems if I do that I can't use PHP's type hinting.

(I'm guessing many will suggest an ORM tool like Doctrine to me, and it's something I will definitely look into in the future. I am avoiding it now because of its supposed steep learning curve, and because I feel I understand those tools better later on if I try it myself once)

tereško
  • 58,060
  • 25
  • 98
  • 150
Andrew Brown
  • 5,330
  • 3
  • 22
  • 39
  • having a lot of models instead of joins do create dependencies and i dont think thats what you want to do. Using joins is normal and i dont see any problem with it. – GGio Feb 04 '13 at 19:18
  • but don't join create dependencies as well? if a table is edited that is used in a ton of joins, you'll have to edit all those join queries. with many models, you'd update 1 model, and the changes would propagate to everyone that called it. – Andrew Brown Feb 04 '13 at 19:31

1 Answers1

0

Nice question! I had/have same thoughts. And I think it's a really good idea to start code your own before looking at frameworks :)

When I coded my model generator I decided once not to use JOINS and use 'lazy loading'. Meaning I have classes like this (just pseudo code):

class Person extends Model_Resource {

    /**
     *
     */
    protected $name;

    /**
     * @var Address <-- external reference
     */
    protected $address;

    /**
     * @return Person
     */
    public static function select($filter) {
        return DB::instance(filter_query('SELECT * FROM `person`', $filter));
    }


    /**
     * @return Address
     */
    public function getAddress() {
        // lazy loading :
        if(is_null($this->address)) {
            $this->address = Address::select(new Filter('p_id', $this->id));
        }
        return $this->address;
    }

}

That worked good for me in a medium size application over years. When I really need to speed up things or using a somewhat inregular query, then I'm free to overwrite the auto generated methods and use JOINS, UNION etc...

I'm curious what will others say.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • I will admit I've recently started using CodeIgniter. Its form validation is what really sold me. I could've spent days doing my own validation, when it does it in minutes. – Andrew Brown Feb 04 '13 at 19:30
  • I not told, don't use them. If you are happy with it then use frameworks, of course! ;) – hek2mgl Feb 04 '13 at 19:32
  • Your posted code raises another interesting point. I've run across a couple people who like to divide the MVC pattern into 1 more (psuedo) layer, something I've seen called 'Entities'. For example I would have a `person` class that simply stored the info like `firstName,`lastName`, `email`, and simple helper methods like getName() that would concatenate and capitalize the first and last name. And then have a personModel actually perform the DB interaction and CREATE the person class. I actually like this approach, and use it. but this makes lazy loading a little more difficult. thoughts? – Andrew Brown Feb 04 '13 at 19:50
  • I think not. I use the 'same?' approach. In my application there is an auto generated BasePerson with data base code + simple set/get operations and Person which extends BasePerson and will contain code written by the programmer. I see no problem with lazy loading. In my app it is done in BasePerson. Btw, I think coding such things is really fun!!! :) – hek2mgl Feb 04 '13 at 19:54
  • as I was reading some other comments, a thought occurred. without using JOINS it would make sorting data a lot harder. It would have to be done using PHP rather than SQL sorting. How did you solve this issue? or was sorting not a huge deal for your application? – Andrew Brown Feb 04 '13 at 23:06
  • Yes you are right. If the application requires filtering and sorting of large data sets you should use the power of sql servers. But my approach above and the power of SQL servers can cooperate. However its hard to argument without having a 'real life' case. Btw, I'm about to release my code on github. can drop a comment when I've done. (expected ~2 months ;) – hek2mgl Feb 04 '13 at 23:29