寻找处理/接近PHP OOP网站的方法

时间:2014-07-22 11:31:29

标签: php oop

我根本不是PHP或编程新手。但最近我在思考PHP中的网站编程以及在OOP之前它是多么容易。无论如何,我更喜欢OOP而不是旧的程序风格。 我想实现一个网站,但似乎我总是要使用全局变量或静态变量。我开始怀疑,如果没有这些,我该怎么办呢?

无论如何,我所说的是为每个"组件提供一个班级"的网站。 例如,如果它是一个url shortener网站,它将是:链接,成员,数据库。

我所说的更复杂,至少有8个班级。 无论如何,我目前的做法如下:

$database = new Database(...);
$links = new Links($db);
$users = new Users($db);

无论如何,例如,我希望获得用户通过其ID发布的所有链接,我需要使用这两个链接和两个用户组件。

还有其他方法吗?还有其他方法吗?除了将它们作为构造函数参数传递。

3 个答案:

答案 0 :(得分:7)

您应该拥有以下组件:

  1. 业务对象,它模拟和表达一个特定的东西"在你的应用中:

    class Link { ... }
    class User { ... }
    

    这些不做"做"什么,他们只是在那里形式化你的数据结构。这些对象具有getter和setter方法来获取和设置各个属性,这些属性也在那里得到验证:

    public function setUrl($url) {
        if (!/* validate the URL here*/) {
            throw new InvalidArgumentException("$url is not a valid URL");
        }
        $this->url = $url;
    }
    

    所需的最低数据是构造函数的一部分。这可确保您的数据完整性在整个应用程它允许您声明当您有Link的实例时,它所表示的数据是链接的最小有效数据。

  2. 数据库链接。只有连接到数据库的必要的东西,仅此而已。原始PDOmysqli对象也可以。

  3. 数据对象映射器,它接受数据库链接并知道如何在数据库中存储业务对象以及如何检索它们:

    class LinkStorage {
    
        protected $db;
    
        public function __construct(PDO $db) {
            $this->db = $db;
        }
    
    }
    

    该类具有如何从数据库中检索内容的各种方法:

    public function getById($id) {
        $stmt = $this->db->prepare('SELECT ... FROM ... WHERE id = :id');
        $stmt->execute(compact('id'));
    
        if (!$data = $stmt->fetch()) {
            throw new RuntimeException("Record with id $id does not exist");
        }
    
        return new Link($data['url']);
    }
    

    您可以通过这种方式封装各种不同的查询,例如:

    /**
     * Returns all links by a particular user.
     * @param User $user
     * @return Link[]
     */
    public function getAllFromUser(User $user) {
        ...
    }
    
  4. 用法很简单:

    $db          = new PDO(...);
    $linkStorage = new LinkStorage($db);
    $userStorage = new UserStorage($db);
    
    $user  = $userStorage->getById($id);
    $links = $linkStorage->getAllFromUser($user);
    

    然后将这种代码封装在一个服务类中,该服务类包含所有可能的"动作"你可以在你的应用程序中做。 registerUser(array $data)getLinksOfUser($id)newLinkFromPostData(array $data)等。

    我刚刚描述的内容基本上是MVC风格应用程序的模型部分。另外两个部分是调用服务方法的控制器,以及从服务方法中检索输出数据的视图。这种方法可以将职责分开并隔离,并允许您将更高级别的逻辑和功能放在一起,就像构建块一样。业务对象是最低的构建块,它们的结构需要牢固且定义良好,以便其余的工作。数据对象映射器只关心将这些对象放入数据库并再次将它们取回。然后,服务以各种复杂的方式将所有这些组合在一起并使事情发生。

    你不应该对此有任何循环依赖,因为责任是完全分开的。您的个人依赖关系可能仍然有些复杂。如果实例化课程变得太麻烦,您将要查看工厂:

    $factory = new Factory;
    $userStorage = $factory->newUserStorage();
    

    实例化的所有复杂性都封装在这个工厂中。更进一步的是依赖注入容器,您可以在其中配置,例如,XML文件以指定哪个类依赖于什么,然后DI容器将为您处理它。

答案 1 :(得分:0)

  

我在考虑用PHP进行网站编程以及它是多么容易   在OOP之前

那么,坚持程序然后。如果以程序或功能的方式编写一个写得好的网站更容易,那么就反对面向ojbect的方式。坚持你习惯的东西。 OO并不比功能更好。这只是一种不同的方法。

php

中的public void main()

在语言中,我们编写的每一个软件都有一个入口点。 public void main()方法。此方法将触发整个应用程序并传入启动时提供的参数。它也是应用程序中唯一的退出点。应用程序以此方法结束(除非崩溃)。

在php中,没有单一的入口点。我们有一堆文件运行一些脚本,这些脚本可以执行更多的操作,然后在某个地方,另一个脚本决定返回东西和die();

依赖注入以及IoC库如何提供帮助

使用依赖注入时,在创建对象并传递正确的类实例时,a $$会变得非常痛苦。我们开始用丑陋的解决方案来解决这个问题:Singleton,全局,静态,...使我们的软件越来越紧密耦合,更难维护。

控制倒置可以在这里提供帮助。在网络上有一些非常重要的articles

答案 2 :(得分:-1)

您可以在PHP中使用自动加载以获得更好的解决方案:

http://php.net/manual/en/language.oop5.autoload.php