2017-05-22 152 views
1

我有一个项目是使用结构化编程创建的,我想以最“最佳实践”方式重构为面向对象的项目。我可能是唯一一个使用这个项目的人,但这不是其他人的意思。但我可能会向其他人展示它作为卓越的例子;)PHP项目结构

我的问题很普遍,但我希望这是好的。

我在考虑让它分成三种方式;后端(主类),前端(获取和发布检查,调用类功能),可视化(使用Twig模板)。 我的项目将使用IPS论坛软件的外部整合(用户会话将保留在那里)。 有关我的代码思路,请参阅以下内容来了解​​如何构建此代码。

我的问题:

  1. 是我的总体结构确定从“前端”像这样分开的课吗?
  2. 我的想法是在类的外部使用IPS进行成员查找/处理,因为我稍后可以切换到前端的其他成员功能而不会影响后端?只要将成员对象放在任何地方的类中,确保至少设置了什么类的使用。
  3. 我应该将成员数据作为参数发送给类(构造),还是像现在一样保留它,并从前端设置公共类var?
  4. 我的类应该抛出异常或返回true/false并设置错误消息?
  5. 前端也应该是班级吗?扩展主类?
  6. 像这样在__construct中设置错误信息是好的,还是应该在其他地方完成?
  7. MyProject类应该分成多个类吗?目前在结构代码中的项目是10000行,因为我拿出大量的可视化渲染的东西,所以新的类可能大约一半。也许类为MyProjectDisplayData和MyProjectCreateData等?
  8. 如果对7的回答是肯定的,我是否应该为其他特定类“扩展”的消息,数据库和一般功能提供一个核心类?
  9. 还有别的人可能想要做不同吗?

myproject_class.php:

namespace MySpace; 

use \PDO; 
use \PDOException; 
use \Exception; 

class MyProject { 

    public $projectdata; 
    public $errormessages; 
    public $ips_member; 

    function __construct() { 
     //set up vars for error messages 
     $this->errormessages["database_queryfailed"] = "Query failed"; 
     $this->errormessages["general_missingdata"] = "Missing data"; 
     $this->errormessages["handling_something"] = "Some error"; 
    } 

    public function displaySomeData ($id) { 
     if ($id == ""){ 
      throw new Exception($this->$errormessages["general_missingdata"]); 
     } 

     try{ 
      $sql = "GET SOME DATA FROM DB"; 
      //PDO execute 
     }catch (PDOException $e) { 
      throw new Exception($this->$errormessages["database_queryfailed"] . " SQL: " . $sql); 
     } 

     $this->projectdata = array(); 
     $this->projectdata["one"] = "cool"; 
     $this->projectdata["two"] = "verycool"; 

     if ($someerror){ 
      throw new Exception($this->$errormessages["handling_something"]); 
     } 
    } 

    public function createSomeData(){ 
     try{ 
      $sql = "INSERT SOME DATA IN DB"; 
      //PDO execute 
     }catch (PDOException $e) { 
      throw new Exception($this->$errormessages["database_queryfailed"] . " SQL: " . $sql); 
     } 
    } 
} 

前端的index.php:

require_once 'vendor/autoload.php'; 
require_once 'myproject_class.php'; 
require 'forum/init.php'; 

//forum initialize 
\IPS\Session\Front::i(); 
$ips_member = \IPS\Member::loggedIn(); 

//load class 
try { 
    $myproj = new MySpace\MyProject(); 
    $myproj->ips_member = $ips_member; 
} catch (Exception $e) { 
    die($e->getMessage()); //not die, but handle in some way 
} 

//check get or post var to decide what to do 
if ($_GET["dowhat"] == "display"){ 
    try { 
     $myproj->displaySomeData($_GET["id"]); 
    } catch (Exception $e) { 
     die($e->getMessage()); //not die, but handle in some way 
    } 
} 

//twig rendering 
$loader = new Twig_Loader_Filesystem('template'); 
$twig = new Twig_Environment($loader); 
$template = $twig->load('myproject.html'); 

echo $template->render(array('projectdata' => $myproj->projectdata, 'member' => $ips_member)); 

谢谢您的帮助!

+2

这个问题更好的属于https://codereview.stackexchange.com/ – MikeT

回答

0

如果你的代码库大概是10K行,那么你不能在两三个类中填充它(当然,显然你可以,但这是一个可怕的想法)。

首先,你应该在模板中提取你的HTML。枝条是一个不错的选择,应该为你服务。但下一步可能会引入路由逻辑,这会让您自动选择要渲染的模板。

关于您对OOP的一般理解,我会建议您观看thisthis讲座。因为我有一种感觉,那就是你不完全了解面向对象的范例。

而且不要滥用extends关键字。在OOP中有这样的旧报价:“你应该赞成合成而不是继承”。这总结得非常好。

关于错误处理,我前几天写了一些关于它的文章,所以我只会懒惰地指导一个older post,它简要地介绍了常见的方法,并提到了每种方法的一些缺点。

最后,为了处理DB:每个需要访问数据库的类都应该有一个PDO(或MySQLi)实例传入其构造函数中。如果您有多个这样的课程,那么阅读this post可能有助于共享该连接实例。