PHP OOP核心框架

我只是发布这个问题,所以你们中的一些人可能能够以正确的方式指出我。 我正慢慢热身到OOP,开始理解这个概念。 我想做一个好的坚实的核心或基础作为CMS后端使用。 它也将使用MVC。 我一直在使用http://gilbitron.github.com/PIP/作为MVC基础。

我无法弄清楚的是:

说,在后端的项目页面我有2个部分:htmltext和项目,我应该能够编辑它们两个。 该URI将是这样的:/ /域/后端/项目(该方法将是索引,并显示2节)

当我点击项目应该如何处理? // domain / backend / projects / projects /或// domain / backend / projects / list /

更进一步,一个项目将会保存一些图片或者一个图库:// domain / backend / projects / edit / 5 / gallery / 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"); } } 

现在我的问题。 如果这个项目有图像,我应该在哪里加载图像类来处理这些图像? 我应该加载它在project_model像$ this-> images = new Images(); 并在模型中有一个函数

 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"); } } 

看起来控制器和模型混淆了这种方式。 然而,从逻辑上讲,项目是一个容纳projectinfo的容器,可以是文本,图像和video。 我怎样才能在逻辑上进行设置呢?

原来的问题

第一部分,关于URLs是所谓的:路由或调度。 关于它与Symfony 2.x的关系有相当好的文章 ,但它背后的想法是重要的。 另外,你可能会研究其他框架如何实现它。

至于你的原始URL的例子,画廊将被存储在数据库。 他们不是吗? 他们将有一个唯一的 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个控制器:

  1. 单一的画廊pipe理
  2. 单一项目pipe理
  3. 处理画廊列表

而示例url将具有类似于此的模式:

 /backend(/:controller(/:id|:page)(/:action(/:parameter))) 

/backend部分是强制性的,但controller是可选的。 如果find控制器,那么id (或页面,当你处理列表)和action是可选的。 如果find操作,则附加parameter是可选的。 如果写成正则expression式,这个结构可以让你处理大部分的路由。

OOP超越课堂

在开始使用或编写某种PHP框架之前,您应该学习如何编写适当的面向对象的代码。 这并不意味着“知道如何写课程”。 这意味着 ,你必须真正理解什么是面向对象编程,它基于什么原则,人们犯了什么常见的错误,以及哪些是最普遍的错误观念。 这里有几个讲座可以帮助你:

  • 遗传,多态性和testing
  • 高级面向对象模式 ( 幻灯片 )
  • unit testing
  • 敏捷devise的原则
  • 全局状态和单身
  • 不要找东西!
  • 超越框架 ( 幻灯片 )
  • 灵活性和质量 ( 幻灯片 )
  • 清洁代码I:参数
  • 清洁代码III:function

这应该给你一些主题的概述..是的,它很多。 但是,怀疑你会喜欢video而不是书。 否则,一些阅读材料:

  • PHP面向对象的解决scheme
  • devise模式的解释
  • 企业应用程序架构的模式

你会注意到很多材料都是语言不可知的。 这是因为基于类的面向对象语言的理论是相同的。

PS

在你的代码中注意extends关键字。 这意味着“ 是一个 ”。 如果class Oak extends Tree ,那么可以,因为所有橡树都是树。 但是,如果你有class User extends Database ,有人可能会得罪。 实际上有一个关于它的OOP原则: Liskov替代原则 ..也有一个很简短的解释

如果这个项目有图像,我应该在哪里加载图像类来处理这些图像? 我应该加载它在project_model像$ this-> images = new Images(); 并在模型中有一个函数

是。 该模型的目标是封装业务逻辑,以便您只需编写一次algorithm,并多次共享它们。 如果我是你,我会做的是将一个getImages()方法添加到项目模型,因为图像是项目的直接属性,这使得每个项目都知道如何检索它自己的图像。

与我使用过的ORMS(水合和同级/表)类相比,你的代码缺less一些关键概念,所以我会尽量保持你的代码。 您可以通过Project对象检索图像,然后通过2种方式中的1种查看图像:

 // 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 ?> 

以上只是示范,但应该给你一个想法。 我build议你看看教义 。 它是一个经过validation和稳定的ORM,它提供了许多你正在尝试写的东西,并且增加了我之前提到的缺less的组件。 水化,对象关系和表类,以及其他许多function,如嵌套集。

(因为这个问题本身就足够长了,所以我不想扩展它,所以我把它作为答案)

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只不过是获取项目数据和相关数据,如图像

 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); } } 

这种方法的好处是,我可以自己使用这个项目类,它就可以工作。 我可以将其封装在项目中,也可以使用它。

这是一个很好的(和正确的)方法来做的东西? 或者将这一切放在一个控制器和一个模型类中会更好吗?