Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中的依赖注入-简单示例回顾_Php_Oop - Fatal编程技术网

PHP中的依赖注入-简单示例回顾

PHP中的依赖注入-简单示例回顾,php,oop,Php,Oop,我是OOP新手,最近我有过这样的经历,这让我觉得: 每一个“操作”都应该在不同的课堂上进行 我所面临的问题应该通过依赖注入来解决 对于整个应用程序,I不能有一个对象 假设我有以下代码: class FtpConnect { public $server; private function connect () { ... } public __construct ($db, $mailer, $server) { $this->ser

我是OOP新手,最近我有过这样的经历,这让我觉得:

  • 每一个“操作”都应该在不同的课堂上进行
  • 我所面临的问题应该通过依赖注入来解决
  • 对于整个应用程序,I不能有一个对象
假设我有以下代码:

class FtpConnect {
     public $server;

     private function connect () { ... }

     public __construct ($db, $mailer, $server) {
         $this->server = $server;
         $this->connect();
     } 
}

class Database {
    public $database_property;
    ...
}

class Phpmailer {
    public $phpmailer_property;
    ...
}

$db = new Database();
$mail = new Phpmailer();

$ftp = new Ftpconnect ($db, $mail, "ftp.mozilla.org");

$ftp->db->database_property;
$ftp->mail->phpmailer_property;
这是正确的做法吗?似乎我还有一个对象
$ftp


读取属性或调用方法,如
$ftp->db->database\u属性这是正确的方法吗?

构造函数会自动放弃所有内容,除了传递给它的第三个参数。为什么要在ftp中放置db对象?这看起来有点奇怪

除此之外,您已经初始化了db/mail对象的变量,因此应该使用它们(较少的链接使代码更易于阅读)或编写如下内容:
$ftp=new-Ftpconnect(new-Database,new-Phpmailer,“ftp.mozilla.org”)不要让代码变得更加模糊


不要给ftp对象提供它不会使用的内容。此外,如果您尝试访问的属性不是特定于实例的(在该类的所有对象中都是相同的),则应使用类常量或静态变量

在您的示例中有一些好的方面和一些坏的方面!首先,祝贺您认真尝试学习良好的编程实践。你走对了方向

好东西:

  • 您正在使用正确的构造函数注入(DI的形式),因此您只在示例的最高级别上编写
    新的
    语句,而不在类内部编写
  • 您已经为每个不同的服务编写了一个类,非常好
坏事:

  • 您正在通过ftp实例访问db和mail的属性,不要这样做
  • 您正在使用公共属性,将属性设置为私有,并使用公共getter和setter
  • 您在构造函数中调用main方法,不要这样做,您不应该在类内部调用它,而应该在类外部调用它
  • 您没有对传递给ftp实例的$mailer实例执行任何操作,ftp类真的需要mailer类吗
改进的示例,假设您的ftp类确实需要数据库和邮件:

class FtpConnect {

     private $db;
     private $mailer;

     private $server;

     public function connect () { ... }

     public __construct ($db, $mailer, $server) {
         $this->setServer($server);
         $this->setMailer($mailer);
         $this->setDb($db);
     }

     public setServer($server)
     {
         $this->server = $server;
     }

     public setDb($db)
     {
         $this->db = $db;
     }

     public setMailer($mailer)
     {
         $this->mailer = $mailer;
     }
}

class Database {
    private $databaseProperty;
    public getDatabaseProperty()
    {
        return $this->databaseProperty;
    }
}

class Phpmailer {
    private $phpmailerProperty;
    public ... see above...
}

$db = new Database();
$mail = new Phpmailer();

$ftp = new FtpConnect ($db, $mail, "ftp.mozilla.org");
$ftp->connect();

$someProperty = $db->getDatabaseProperty();

这可能不是建设性的(
…这个问题可能会引发辩论、争论、投票或广泛的讨论
),也可能会更好,但我不确定这两个问题。而且看起来你应该好好学习/记住-FTP可能不应该知道任何关于邮件或电子邮件的信息DB@DaveRandom建立FTP连接后,我想将datetime、主机名保存到数据库,并将其与电子邮件一起发送。我认为,这就是类相互依赖的原因。我不同意
$ftp=newftpconnect(新数据库,新Phpmailer,“ftp.mozilla.org”)99%的情况下,它直接与您自己的语句“不要让代码变得更模糊,那么它必须是”IMHO.
您为什么要在ftp中放置db对象?这看起来有点奇怪。
我要做的就是记录到数据库的每个ftp\u连接。当脚本运行并建立ftp_连接时,我想保存日期时间、主机名等@user1292810我可能会为此创建一个中间对象,类似于
FTPLogger
,它包含数据库对象并被注入ftp连接器。这样,如果您更改日志记录的方式(例如改为记录到文件),则不必修改FTP连接器。请参阅您建议使用未使用的变量污染上下文的@DaveRandom。如果您不为每一个甚至不会在该上下文中使用的微小的位创建一个变量,那么gc的工作将变得非常容易。user1292810这很有道理:)@kaka91…但您上面看到的只是一些简单的类定义和引导。从长远来看,这些额外的变量在功能上没有什么不同,但它们确实使引导程序更易于阅读。回答得真棒!但是在构造函数内部调用main方法有什么错呢?您将自己绑定到使用该类的特定方式。也许有一次你想立即建立连接,也许有一次你想等到你真正需要它(惰性连接)。不要定义如何在构造函数中使用实例@markus tharkun我非常感谢你的回答,现在一切似乎都清楚了。@markus tharkun我还有一个问题:我需要所有这些
set
方法吗,它们都是在构造函数中调用的?为什么不干脆用
$this->server=$server在构造函数中设置属性?两者都有利弊。如果以后要扩展该类,可能需要将setter保留在构造函数中。