Now, if you remember this diagram from the beginning of the project, one of the things related to
database that I wanted us to create is a model class.
This would abstract not the whole database, but instead it would relate to one single table.
So you can create a model that will represent the post, the comment and the user.
The reason for that is typically you might have to write some more complex queries and that's fine.
That's a separate problem.
But a lot of those queries are super simple.
You just fetch one individual record or you fetch all of them, or you just need to count the models,
or you need to create a new record or update it.
And for those cases, it would be super useful to have a generic model class that can do all of that
without us Having to write the same queries over and over again for every single table that we have
and we might have in the future.
That's why in this video, we are going to create this base model class that all the future models that
we're going to have will use.
So our model class will heavily use this database class.
It's going to get access to it through the container.
Let me close the database for now.
And inside the core let's create the model.
PHP file.
And this time I'm not gonna forget the core namespace.
So this is our class model.
And I think that this should be an abstract class.
It should not exist on its own.
It only needs to be extended.
So we add a protected field that is static and it's a table name.
So every model that extends this base model class would have to define the table name.
That can be posts, users or comments in our case.
So I think that it would make a lot of sense if I would begin this by defining the names of methods
that this model would have.
So let me start with the public ones and they are static.
So we're going to have an all method which will just return all instances of this model.
And that's always an array.
Now I'm not going to implement it right away.
I'm just defining those methods methods first so we can see what's the generic idea.
Then we have a find method.
And this accepts an id I think it should be mixed because it can be a number.
Sometimes we also might use strings as primary keys, so we shouldn't be limited here.
And this should return an instance of our model class.
So I will define this as static or null if the model can't be found.
But then we should also have some shortcut methods to quickly create a new model.
So this would just be called create.
And this is going to accept the array with the data with all the fields.
And this should create an instance of this model.
I'm using static as the return type.
Because once we extend this base model class, this return type would have the proper class type.
So it would be a specific model like post comment or a user, not the model class.
So why won't we just go ahead and implement those methods starting with all?
Now we need to get the database first.
For that we're going to be using the app class, our dependency injection container.
Now here is a thing in PHP, if you have classes at the same level of the namespace, you don't need
to add use statements for them and model and app seem to be at the same level.
That's why I can just do app get and I get the database.
Now remember I told you that we won't have the suggestions with the methods of the database class,
but we are going to fix that later.
In the meantime, let's have the results by doing the DB query.
And we're just going to select all columns from the specific table which is just static table.
That's everything.
This method is this simple.
And we're going to do fetch all because this returns a statement.
And then we're just going to say that using PDL we want to fetch that as an associative array.
Let's make sure I got this PDL object imported because this one actually has to be imported.
Now the problem with this is that we're going to get an array an array of arrays.
So this would be a multi-dimensional array.
And what I'd like instead is to have an array of objects.
So every single time we use the model to fetch the data we wanted returned us this model class.
So as a post or as a comment.
Now this is not easily doable if we want to fetch multiple records.
That's why we would need a helper method that we're going to make it protected.
And I will call that create from array.
And this receives an array data and returns static.
So the current model we are working on.
So we're going to be creating a new instance of static which means the current class whatever that is
post comment user.
Because this class always has to be extended.
Then we're gonna go over the data which should be keys and values because that's an associative array.
And then if the property is defined on the model.
So there is this property exists function in PHP which accepts object or class.
Well we have an object and the name of the property is the key.
So if that's the case, if this property is defined I seem to forget to ask you what here.
So if it is defined we just do model key.
So we dynamically calculate the property name by using a variable.
And we set that to value.
And then we return a model.
Now in the model PHP versions since PHP 8.2 I think you shouldn't really set the properties on classes
dynamically.
That was previously a feature of PHP.
Now, if you use an object of a specific class, you have to define the properties explicitly.
So this is deprecated.
And if you would try to set the properties dynamically without them being explicitly defined on the
class, this would cause a notice or warning.
We're going to see that later on.
Anyway, we need to use this method to now convert an array of arrays into an array of objects.
So now we would like every single record of data that sits inside this results array to be converted
to an object.
And for that we're going to use our newly created create from array method.
Now to convert every single record that is returned.
Because this is results variable with multiple possible results, we can use an array map.
This can be done different ways.
We can also use a for each loop, but I think the array map makes the most sense.
Let me start with the second argument.
This would be the results array.
And now going back to the first argument, this needs to be a callback.
But here we don't have a function.
We have a class method that is static.
To parse it, we're going to use an array where the first element of the array is the name of the class.
Now, to get the name of the current class, we can use the static keyword and it should have a class
constant.
Every class has this special constant that will give you the full class name, including the namespace,
and after a comma.
The second element is the method name.
In our case, that's create from array.
Now this is actually an important thing to remember that every single time you need to pass a method
of a class, like in this case that's a class method.
Or if you would need to pass a method of an object, then this first element of the array can be a variable
with an object.
And that's the way you can use if you pass a callback that is just a part of a class or a method, not
a simple function.
Okay, next up, let me build this find method.
It would be pretty similar to the all method.
There are of course some slight differences.
That's why I'm just gonna copy and paste some of the code.
So in the find method, we expect just a single result.
We can still use this database query method.
We're gonna select a record from the same table.
This stays the same.
But here we need some filters.
That's why we are adding a Where clause to specify some conditions.
In our case this is an ID and we're going to use prepared statements.
That's why I'm going to add a question mark here for the positioned query arguments.
And then I can pass the ID.
So when you are using those question marks in prepared statements the order of them matters.
Because then you just need to pass the parameters that you want to pass there.
In the same order.
So in this case, we will be using just a fetch method to get one record.
Well, we can also use PDO fetch as sock to fetch the data as an associative array.
Just a single record.
And then we return the result depending on whether the result is not null.
So if it is not null, we're going to use the static create from array method on the result array.
Otherwise we return null.
Now the last thing remaining so far is this create static method that will just insert one record into
the database.
Now this might take some time to implement and also explain, because we need to go in more details
into how the insert SQL query works.
That's why I think we should take a short break right now and just go back to it in the next video.