I am just posting this question so some of you might be able to point me in the right way. I am slowly warming up to OOP, starting to understand the concept. I want to make a good solid core or foundation to be used as a CMS backend. It will also use MVC. I have been using http://gilbitron.github.com/PIP/ as the MVC- base.
The thing I cant figure out is the following:
Say, on the projectpage in the backend I have 2 sections: htmltext and projects and I should be able to edit them both. The uri would be something like: //domain/backend/projects (the method would be the index and show the 2 sections)
When i click on projects how should it be handled? //domain/backend/projects/projects/ or //domain/backend/projects/list/
One step further, a project will hold some images or a gallery: //domain/backend/projects/edit/5/gallery/2
My question here is, first: would this be a good way to go and even more important how would this be implemented in OOP
the main projects controller:
class projects {
function index(){
// view index
}
function edit{
$project = new Project();
$projectdata = $project->load(5);
}
}
A single project controller
class project {
function __construct(){
$this->projectmodel = $this->loadModel('project_model'); // prepare the model to be used
}
function load($id){
$this->projectmodel->loadproject($id);
}
}
project model
class project_model extends model { //extends for DB access and such
function __construct(){
// do stuff
}
function loadproject($id){
return $this->db->query("SELECT * FROM projects where id=" . $id . " LIMIT 1");
}
}
Now my question. If this project has images, where should I load the image class to handle those? Should I load it in the project_model like $this->images = new Images(); and have a function inside the model
function loadimages($id){
$this->images->load($id);
}
and then images would be something like:
class image extends model { //extends for DB access and such
function __construct(){
}
function load($id){
return $this->db->query("SELECT * FROM project_images where id=" . $id . " LIMIT 1");
}
}
It seems controllers and models gets mixed up this way. Yet in a logical way a project is a container that holds projectinfo, which could be text, images and maybe video's. How would I go about to set that up logically as well.
PHP What is OOP? OOP stands for Object-Oriented Programming. Procedural programming is about writing procedures or functions that perform operations on the data, while object-oriented programming is about creating objects that contain both data and functions.
@asadali007 Laravel is built using object-oriented PHP so yes, a knowledge of OOP is going to be beneficial in understanding the framework code and writing your own objects that make us of the classes and methods provided by Laravel.
PHP is a server-side scripting language, mainly used for web development but also used as a general-purpose programming language. Object-Oriented Programming (PHP OOP), is a type of programming language principle added to php5, that helps in building complex, reusable web applications.
In fact, PHP was initially developed as a procedural language and only later extended to OOP. PHP programmers cannot agree on which style is preferable. For me, the most effective method of programming is simply a matter of opinion, the demands of the project, and experience level.
The first part, about the URLs is something called: Routing or Dispatching. There is quite good article about it in relationship with Symfony 2.x, but the the idea behind it is what matters. Also, you might looks at ways how other frameworks implement it.
As for your original URL examples, galleries will be stored in DB. Won't they? And they will have a unique ID. Which makes this, /backend/projects/edit/5/gallery/2
quite pointless. Instead your URL should look more like:
/backend/gallery/5/edit // edit gallery with ID 5
/backend/project/3 // view project with ID 3
/backend/galleries/project/4 // list galleries filtered by project with ID 4
The URL should contain only the information you really need.
This also would indicate 3 controllers:
And the example URLs would have pattern similar to this:
/backend(/:controller(/:id|:page)(/:action(/:parameter)))
Where the /backend
part is mandatory, but the controller
is optional. If controller is found , then id
( or page, when you deal with lists ) and action
is optional. If action is found, additional parameter
is optional. This structure would let you deal with majority of your routes, if written as a regular expression.
Before you start in on using or writing some sort of PHP framework, you should learn how to write proper object oriented code. And that does not mean "know how to write a class". It means, that you have to actually understand, what is object oriented programming, what principles it is based on, what common mistakes people make and what are the most prevalent misconceptions. Here are few lecture that might help you with it:
This should give you some overview of the subject .. yeah, its a lot. But is suspect that you will prefer videos over books. Otherwise, some reading materials:
You will notice that a lot of materials are language-agnostic. That's because the theory, for class-based object oriented languages, is the same.
Be careful with extends
keyword in your code. It means "is a". It is OK, if class Oak extends Tree
, because all oaks are trees. But if you have class User extends Database
, someone might get offended. There is actually an OOP principle which talks about it: Liskov substitution principle .. also there is a very short explanation
If this project has images, where should I load the image class to handle those? Should I load it in the project_model like $this->images = new Images(); and have a function inside the model
Yes. The goal of the model is to encapsulate business logic so that you only need to write the algorithms once, and share them multiple times. What I would do if I were you is to add a getImages()
method to the Project model as the images are a direct attribute to a project, this makes it so that each project knows how to retrieve it's own images.
Your code is missing a few key concepts compared to ORMS I have worked with (hydration and peer/table) classes, so I will try to stick with your code. You can retrieve the images through the Project object, then reference the images via the view 1 of 2 ways:
// Controller
$this->project = new Project();
$this->projectImages = $project->getImages(); // Implemenation #2
// View
// Implemenation #1 (reference to object initialized in controller)
<?php foreach ($project->getImages() as $image): ?>
<img src="<?php echo $image['path'] ?>" />
<?php endforeach ?>
// Implemenation #2 (reference to separate variable initialized in controller)
<?php foreach ($projectImages as $image): ?>
<img src="<?php echo $image['path'] ?>" />
<?php endforeach ?>
Above is demonstrative only, but should give you an idea. I would suggest that you take a look at Doctrine. It is a proven and stable ORM which provides much of what you are attempting to write, plus it adds the missing components that I mentioned earlier; hydration, object relations, and Table classes, along with many other features such as nested sets.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With