Firstly, I'd just like to start by saying that I believe __get
and __set
magic methods are bad practice, and should be reserved for times when the alternative is either making member variables public, or when there is no logic in any things that are 'get' or 'set'. Even then, those are code smells of a "Data Class" which probably have a better solution. (Read "Refactoring" by Martin Fowler (1999)). Saying that, using it in a single class, within the top level abstract class for an Active Record or similar does make sense. Speed is rarely the issue these days; well-written code that is readable, flexible, and so on, is. But as detailed in a previous SO answers, use them sparingly and wisely. use them sparingly and wisely.
Firstly, I'd just like to start by saying that I believe __get
and __set
magic methods are bad practice, and should be reserved for times when the alternative is either making member variables public, or when there is no logic in any things that are 'get' or 'set'. Even then, those are code smells of a "Data Class" which probably have a better solution. (Read "Refactoring" by Martin Fowler (1999)). Saying that, using it in a single class, within the top level abstract class for an Active Record or similar does make sense. Speed is rarely the issue these days; well-written code that is readable, flexible, and so on, is. But as detailed in a previous SO answers, use them sparingly and wisely.
Firstly, I'd just like to start by saying that I believe __get
and __set
magic methods are bad practice, and should be reserved for times when the alternative is either making member variables public, or when there is no logic in any things that are 'get' or 'set'. Even then, those are code smells of a "Data Class" which probably have a better solution. (Read "Refactoring" by Martin Fowler (1999)). Saying that, using it in a single class, within the top level abstract class for an Active Record or similar does make sense. Speed is rarely the issue these days; well-written code that is readable, flexible, and so on, is. But as detailed in a previous SO answers, use them sparingly and wisely.
Firstly, I'd just like to start by saying that I believe __get
and __set
magic methods are bad practice, and should be reserved for times when the alternative is either making member variables public, or when there is no logic in any things that are 'get' or 'set'. Even then, those are code smells of a "Data Class" which probably have a better solution. (Read "Refactoring" by Martin Fowler (1999)). Saying that, using it in a single class, within the top level abstract class for an Active Record or similar does make sense. Speed is rarely the issue these days; well-written code that is readable, flexible, and so on, is. But as detailed in a previous SO answers, use them sparingly and wisely.
Firstly, I'd just like to start by saying that I believe __get
and __set
magic methods are bad practice, and should be reserved for times when the alternative is either making member variables public, or when there is no logic in any things that are 'get' or 'set'. Even then, those are code smells of a "Data Class" which probably have a better solution. (Read "Refactoring" by Martin Fowler (1999)).
Firstly, I'd just like to start by saying that I believe __get
and __set
magic methods are bad practice, and should be reserved for times when the alternative is either making member variables public, or when there is no logic in any things that are 'get' or 'set'. Even then, those are code smells of a "Data Class" which probably have a better solution. (Read "Refactoring" by Martin Fowler (1999)). Saying that, using it in a single class, within the top level abstract class for an Active Record or similar does make sense. Speed is rarely the issue these days; well-written code that is readable, flexible, and so on, is. But as detailed in a previous SO answers, use them sparingly and wisely.
Firstly, I'd just like to start by saying that I believe __get
and __set
magic methods are bad practice, and should be reserved for times when the alternative is either making member variables public, or when there is no logic in any things that are 'get' or 'set'. Even then, those are code smells of a "Data Class" which probably have a better solution. (Read "Refactoring" by Martin Fowler (1999)).
I believe all your questions would be answered by referencing the above book, and "Design Patterns" (Erich Gamma et. al. 1995) and particularly for your question, "Patterns of Enterprise Application Architecture" by Martin Fowler (2003).
Fowler (2003) goes into various OOP patterns for data layers. It will give you some real epiphanic moments, and you'll never let the book leave your side.
To give you some insight as to why the book is so important to read, the decision about how to implement your data layer depends on the rest of your system architecture. It's not a case of one layer being dependent on the other, since that is an anti-pattern, but rather how correctly chosen layers can have a synergy (while still being as independent as possible).
There are different data source patterns he covers:
- Table data gateway
- Row data gateway
- Active record
- Data mapper
And then more complex Object-relational mapping, structural and metadata patterns.
I believe a wise nugget of wisdom I've read in many programming books are to not over-complicate things. It's not an easy balance, but if you use techniques like writing tests as you write code, (TDD or milder versions) then you will not be afraid of refactoring to a more complex pattern when you know you will use it. The ultimate goal really is to make your life as easy as possible.
The most concrete advice I can give you is keep your code DRY. So, don't copy and paste code. Ever. Just about anything is better than that.
And to answer your question, out of the patterns in Fowler (2003), I would suggest the Active Record pattern. It sort of gives a domain-level interface for accessing data in an intuitive way that can be a very tidy solution for smaller applications. (In my experience, one with no complicated joins, although there are exceptions.) You might implement it like this:
Write an abstract class that understands how to access the database and query it. Then for each table (or even a set of tables, such as a person and related tables like the person's phone numbers) write a subclass that uses the services of the parent, and define a top level interface which would be used by your domain code. For example, defining $person->setPhoneNumber($number)
. It really bundles up the data layer tidily.
I can't recommend the book strongly enough - it gives advice even on how to mix and match related patterns, showing that they aren't actually mutually exclusive - sometimes it makes sense to have different patterns for the same layer, depending on the problem in that portion of the application.
But to give you some confidence, it's worth remembering that patterns are just that; they're not identical implementations each time; the developer often will tweak things. There are some general principles to follow, such as S.O.L.I.D., and just following your nose. If something smells bad, or if things just seem to be getting messy, take a step back and investigate alternatives.