我刚刚发布了这个问题,所以你们中的一些人可能会向我指出正确的方向。我正在慢慢地适应OOP,开始理解这个概念。我想做一个好的坚实的核心或基础,用作CMS后端。它还将使用MVC。我一直在使用http://gilbitron.github.com/PIP/作为MVC基础。
我想不通的是:
比方说,在后台的项目页面上,我有两个部分:htmltext和projects,我应该能够编辑它们。uri应该是这样的://域/后端/项目(方法将是索引并显示2个部分)
当我点击项目时,应该如何处理?//域/后端/项目/项目/或//域/后端/项目/列表/
更进一步,一个项目将保存一些图像或图库://域/后端/项目/编辑/5/库/2
我的问题是,首先:这是一个好的方法吗?更重要的是,如何在OOP 中实现这一点
主要项目控制者:
class projects {
function index(){
// view index
}
function edit{
$project = new Project();
$projectdata = $project->load(5);
}
}
单个项目控制器
class project {
function __construct(){
$this->projectmodel = $this->loadModel('project_model'); // prepare the model to be used
}
function load($id){
$this->projectmodel->loadproject($id);
}
}
项目模型
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");
}
}
现在是我的问题。如果这个项目有图像,我应该在哪里加载图像类来处理这些图像?我应该像$this->images=new images()那样在project_model中加载它吗;并且在模型内部具有功能
function loadimages($id){
$this->images->load($id);
}
然后图像将类似于:
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");
}
}
控制器和模型似乎以这种方式混淆了。然而,从逻辑上讲,项目是一个容纳项目信息的容器,可以是文本、图像,也可以是视频。我该如何从逻辑上设置它呢。
原始问题
关于URL的第一部分叫做:路由或调度。关于它与Symfony 2.x的关系,有一篇很好的文章,但它背后的想法才是最重要的。此外,您还可以看看其他框架是如何实现它的
至于您的原始URL示例,库将存储在DB中。不是吗?它们将有一个唯一的ID。这使得/backend/projects/edit/5/gallery/2
毫无意义。相反,你的URL应该看起来更像:
/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
URL应该只包含真正需要的信息。
这也将指示3个控制器:
- 单通道管理
- 单一项目管理
- 处理画廊列表
示例URL的模式与此类似:
/backend(/:controller(/:id|:page)(/:action(/:parameter)))
其中/backend
部分是强制性的,但controller
是可选的。若找到了控制器,则id
(或页面,当您处理列表时)和action
是可选的。如果找到操作,则额外的parameter
是可选的。如果将此结构写成正则表达式,则可以处理大多数路由。
OOP超越类
在开始使用或编写某种PHP框架之前,您应该学习如何编写正确的面向对象代码。这并不意味着"知道如何写一堂课"。的意思是,你必须真正理解什么是面向对象编程,它基于什么原则,人们会犯什么常见错误,以及最普遍的误解是什么。以下是一些可能对你有所帮助的讲座:
- 遗传,多态性,&测试
- 高级OO模式(幻灯片)
- 单元测试
- 敏捷设计原理
- 全球状态与辛格尔顿
- 不要找东西
- 超越框架(幻灯片)
- 灵活性和质量(幻灯片)
- Clean Code I:参数
- Clean Code III:函数
这应该会让你对这个主题有一些了解。。是的,很多。但我怀疑你会更喜欢视频而不是书。否则,一些阅读材料:
- PHP面向对象解决方案
- 设计模式说明
- 企业应用程序体系结构的模式
你会注意到很多材料都是语言不可知论者。这是因为基于类的面向对象语言的理论是一样的。
P.S
小心代码中的extends
关键字。意思是"是一个"。如果class Oak extends Tree
,那也没关系,因为所有的橡树都是树。但如果你有class User extends Database
,有人可能会被冒犯。实际上有一个OOP原理在谈论它:利斯科夫替代原理。。还有一个非常简短的解释
如果这个项目有图像,我应该在哪里加载图像类来处理这些图像?我应该像$this->images=new images()那样在project_model中加载它吗;并且在模型内部具有功能
是的。该模型的目标是封装业务逻辑,这样您只需要编写一次算法,并多次共享它们。如果我是你,我会做的是在项目模型中添加一个getImages()
方法,因为图像是项目的直接属性,这样每个项目都知道如何检索自己的图像。
与我使用过的ORMS(水合和peer/table)类相比,您的代码缺少了一些关键概念,所以我将尝试使用您的代码。您可以通过Project对象检索图像,然后通过以下两种方式之一的视图引用图像:
// 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 ?>
以上只是示范,但应该给你一个想法。我建议你看一下教义。它是一个经过验证且稳定的ORM,提供了您试图编写的大部分内容,此外,它还添加了我前面提到的缺失组件;水合、对象关系和表类,以及许多其他功能,如嵌套集。
(由于问题本身就足够长,我不想扩展它,所以我添加了它作为答案)
projects.php该控制器扩展了项目控制器。主要目的是使用自己的模型处理多个getAllProjects(),然后将其传递给项目控制器getProject()
class Projects extends Project{
public function __construct()
{
parent::__construct();
$this->projects_model = new Projects_model();
}
public function getAllProjects()
{
$res = $this->projects_model->getAllProjects();
if($res) foreach($res as $v) $projects[] = $this->getProject($v);
return $projects;
}
}
project.php
project_model只不过是获取projectdata和图像等相关数据
class Project{
public function __construct()
{
$this->project_model = new Project_model;
$this->images = new Images();
}
public function getProject($data=NULL)
{
if($data==NULL) $data = $this->project_model->loadProject($data['id']);
$images = $this->project_model->loadProjectImages($data['id']);
return array('project_id' => $data, 'project' => $data, 'images' => $images);
}
public function getProjectByID($id)
{
$data = $this->project_model->loadProject($id);
return getProject($data);
}
}
这种方法的好处是,我可以单独使用项目类,它会起作用。我可以将它封装在项目中,也可以使用它。
这是一种好的(也是正确的)做事方法吗?或者把这些放在一个控制器和一个模型类中会更好吗?