I'm not new to PHP or programming at all. But recently I was thinking about website programming in PHP and how easier it was before the OOP. Anyway, I prefer OOP than the old procedural style. I want to implement a website but it seems I always have to use a global or a static variables. And I'm starting to wonder, how can I do it without those?
Anyway, what I'm talking about is having a class for each "component" of the website. For example if it was an url shortener website it would be: links, members, database.
What I'm talking about is way more complicated, at least 8 classes. Anyway, my current approach is the following:
$database = new Database(...); $links = new Links($db); $users = new Users($db);
Anyway, for example I want to get all the links a user posted by its ID, I need to use both links and both users components.
Is there any other way I could do this? Any other approach? except passing them as constructor parameters.
You should have the following components:
Business objects, which model and express one particular "thing" in your app:
These don't "do" anything, they're just there to formalise your data structures. These objects have getter and setter methods to get and set individual attributes, which are also validated there:
Minimum required data is part of the constructor. This ensures your data integrity application-wide. It allows you to assert that when you have an instance of
Link, the data expressed by it is minimum valid data for a link.
A database link. Only the bare necessary thing to connect to a database, nothing more, nothing less. A raw
mysqliobject will do just fine.
A data-object mapper, which takes a database link and knows how to store business objects in the database and how to retrieve them:
This class has all the various methods of how to retrieve things from your database:
You can have all sorts of different queries encapsulated this way, e.g.:
The usage is then simple:
This kind of code would then be encapsulated in a service class, which holds all the possible "actions" you can do in your app.
What I've just described is basically the model portion of an MVC-style application. The other two parts would be controllers which call the service methods, and views which output data retrieved from service methods. This approach keeps responsibilities separate and isolated and allows you to put higher-level logic and functionality together like building blocks. Business objects are the lowest building block, their structure needs to be solid and well defined for the rest to work. Data-object mappers just concern themselves with putting those objects into the database and getting them back out again. Services then put all this together in various complex ways and make things happen.
You shouldn't have any cyclic dependencies with this, as responsibilities are well separated. Your individual dependencies may still be somewhat complex. If it becomes too cumbersome to instantiate classes, you'll want to look into Factories:
All the complexity of instantiation is encapsulated in this factory. One step further are dependency injection containers, who you can configure in, for example, an XML file to specify which class depends on what, and then the DI container will take care of it for you.