PHP:使对象可用于多个函数

时间:2012-02-23 18:16:07

标签: php oop object

一个初学者问题:我不知道如何最好地构造这段代码,但基本上就是这样(伪代码时间):

 if (form = submitted) {
     submitted();
 }
 else {
     printForm();
 }

 function submitted() {
     process data from form;
     if(errors = found) {
         print warnings;
         printForm();
     } else {
         submit to database;
     }
 }

 function printForm() {
     print form with databound elements;
 }

我使用以下代码来创建一个User对象,但是调用它两次似乎很奇怪 - 一次在submitted()和一次printForm(),特别是在submitted()调用之后printForm()如果发现错误。

不幸的是,从表单处理数据需要数据库访问(检查现有的电子邮件地址等),因此我必须在submitted()printForm()中调用以下代码。

try {
    $db = new Database();
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
    $user = new User($db);
}
catch (PDOException $e) {
    echo "<p>Error connecting to database: </p>".$e->getMessage();
}    

但我的直觉告诉我这很糟糕。是吗?如果是这样,我该如何解决?

3 个答案:

答案 0 :(得分:3)

使用dependency injection

function submitted(Database $db, User $user) {
    // ...
}

function printForm(Database $db, User $user) {
    // ...
}

try {
    $db = new Database();
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
    $user = new User($db);
}
catch (PDOException $e) {
    echo "<p>Error connecting to database: </p>".$e->getMessage();
}

submitted($db, $user);
printForm($db, $user);

当然,最好使用OOP,因为那时你不必将依赖注入每个函数:

class Foo {
    protected $db;
    protected $user;

    public function __construct(Database $db, User $user) {
        $this->db = $db;
        $this->user = $user;
    }

    public function submitted() {
        // use $this->db and $this->user here
    }

    public function printForm() {
        // use $this->db and $this->user here
    }
}

try {
    $db = new Database();
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
    $user = new User($db);
    $foo = new Foo($db, $user);
}
catch (PDOException $e) {
    echo "<p>Error connecting to database: </p>".$e->getMessage();
}

$foo->submitted();
$foo->printForm();

答案 1 :(得分:2)

有几种方法可以让这更好......

一个是在函数调用之前初始化$ user并将其注入每个函数(依赖注入)。

另一种方法是创建用户实例的单例(虽然我可以看到这会导致问题)并使用User::instance()之类的东西检索函数中的实例。

在我看来,依赖注入更好,因为它使您的函数更容易测试。


现在,转到代码的其余部分:

  1. 在函数或类方法中回显任何内容通常不是好习惯。您应该返回数据并在函数外部处理它。
  2. 您的db实例化应该包含在每个脚本顶部的引导程序文件中。如果你的脚本优雅地处理连接错误(让用户知道出错了,给自己发送电子邮件,停止执行其余的脚本),如果连接失败而不是简单地回显错误消息,那么也可能更好。

答案 2 :(得分:0)

虽然在某些情况下Singleton模式被认为是邪恶的,但似乎在PHP中(每个请求都有一个单独的工作进程),在您的情况下,它是实现您想要的最简单的方法。

这样您就可以在任何页面上的任何脚本中启动User的实例,并且您必须在每个项目的一个位置初始化$user对象(不是每个你想要做的脚本。)