I'm making a forum system in PHP, and I'm stumbling accross an annoying problem when writing the code to insert a new topic. I'm using a bunch of objects, like User, Post and Topic, all of them take a PDO object in their constructor (dependency injection).
Note I know that similar questions have been asked before, but all the answers that I found recommand using dependency injection, and in this case I don't find it very clear or convenient to use, since there would be at least 3, sometimes more, dependencies to inject into many different functions.
Currently, when I'm making a new topic (thread), it's calling a parsing page that does all the check : user has to be logged in, title has to be at least 3 characters long, and so on. To avoid nested if
's, I'm wrapping all that code inside a function, so I can just use return
to get out when something goes wrong.
The problem with this is that my function doesn't have access to the User, Post and Topic objects that are created in an init
page, required on all pages automatically.
I know about dependency injection
, but it doesn't make sense to me to pass four different objects as parameters to my function.
Here's a sample of code for that newTopic
function, which is inside the parsing page mentionned above :
if(!empty($_POST['newTopic']))
newTopic();
function newTopic()
{
//Check that the user is connected
if(!$User->isConnected())
return false;
//Other checks ...
$Topic->new($author, $title, $content);
}
Of course, the $User
and $Topic
objects aren't accessible inside of a function. I can either pass it as a parameter, or use global
. I know that the usage of global
is not recommanded, however I don't think that passing four different objects to each functions is a much better practice ..
The question What's the best thing to do in this case? Pass my objects as parameters to the newTopic
function? Use global
's ? Use nested if
's instead of a function?
Might be a good spot for a builder.
$builder = new TopicBulder()->setAuthor($author)->setTitle($title)->setContent($content)->getTopic();
Where TopicBuilder is a class with each method returning and reference to $this.
class TopicBuilder {
private $topic;
function __construct() {
$this->topic = new Topic();
}
public function setAuthor($author) {
$this->topic->setAuthor($author);
return $this;
}
....
public function getTopic() {
return $this->topic.
}
}
Or something cleaner then that ;)
You may separate logic of a new topic creation, such as checks, maybe DB operations and so on, and creation of a new object of Topic class. Note, that creation of a Topic object is necessary means it should be persistent at once. Topic class may only be a struct for topic data.