我很初学者到OOP,现在我尝试写一些PHP类与FTP服务器连接。
class ftpConnect {
private $server;
private $user;
private $password;
private $connection_id;
private $connection_correct = false;
public function __construct($server, $user = "anonymous", $password = "anonymous@mail.com") {
$this->server = $server;
$this->user = $user;
$this->password = $password;
$this->connection_id = ftp_connect($this->server);
$this->connection_correct = ftp_login($this->connection_id, $this->user, $this->password);
if ( (!$this->connection_id) || (!$this->connection_correct) ){
echo "Error! Couldn't connect to $this->server";
var_dump($this->connection_id);
var_dump($this->connection_correct);
return false;
} else {
echo "Successfully connected to $this->server, user: $this->user";
$this->connection_correct = true;
return true;
}
}
}
我认为这个类的身体此刻微不足道。
主要问题是,我有一些问题了解OOP的想法。
我想添加发送电子邮件时,都会运行代码时。 我已经下载的PHPMailer类和扩展我的课吧:
class ftpConnect extends PHPMailer {...}
我添加了一些变量和方法,一切都会按预期到这一点。
我想:为什么不增加存储在数据库中的一切。 上面的代码每次用户运行,正确的信息应该存储在数据库中。
我可以编辑我的ftpConnect class
,并添加数据库连接构造,以及其他一些方法来更新表。 但是,数据库连接和所有的东西可以通过其他类在未来被使用,因此,一定要在独立的类来实现。 但我的“主” ftpConnect class
已经扩展一个类,并不能延长不是单一的一个。
我不知道我怎么能解决这个问题。 也许我ftpConnect class
是复杂的,我应该以某种方式把它分成几个更小的类? 任何帮助深表感谢。
对于初学者来说,我认为你必须在你的类设计缺陷。 你的构造做的工作。 这不是一个构造函数应该在适当的OOP做。 构造函数应该只设置的属性,你应该有一个单独的方法connect()
其次ftpConnect
永远也不会延长PHPMailer
。 他们是两个完全不同的事情。 阅读关于里氏替换原则是部分SOLID原则 。
如果你的类需要做一些与数据库或需要发送邮件,你需要这些实例注入到你的类,而不是延长他们的。 这就是所谓的依赖注入 ,这将使它便于以后做单元测试,因为你可以很容易地使用一个模拟邮件类,或者是模拟数据库类。
如果你想发送邮件,有数据库访问和使用FTP,你至少需要3个不同的(分开)类(甚至可能更多的是为DB等一些映射)。 基本上每类应该有一个责任,且只有一个。 这就是所谓的单一职责原则 。
对于一些一般参考文献,参见:
这也可能是组成在继承问题请参见本不想在组成继承? 只需使用邮件的对象类内,这同样适用于数据库,而不是你的类扩展它们。
class my_class
{
private $mailer;
public function __constructor()
{
$this->mailer = new Mailer();
}
}
对于数据库存储部分,你可以创建一个单独的类,它有与数据库的连接。 你可以通过这个类的一个实例,以您的ftpConnect
通过它的构造函数的类。 给你的fptConnect
类的属性,您可以存储在这个新的数据库对象,这样就可以在您的整个访问该对象ftpConnect
类。
你ftpConnect
类目前有一个构造函数,或者返回true
或false
,不要让构造函数返回任何值,因为它西港岛线需要返回ftpConnect类,您将需要存储在变量中的一个实例。 因此,你可以做在一个单独的方法,实际的连接。 所以,你的类可以是这个样子。
class FtpConnect {
private $server;
private $user = "anonymous";
private $password = "anonymous@mail.com";
private $connection_id;
private $connection_correct = false;
//this will take care of the storage
private $database_handler;
public function __construct($server, $user, $password, $database_handler) {
$this->server = $server;
$this->user = $user;
$this->password = $password;
$this->database_handler = $database_handler;
//store the appropriate data, this will be done everything a new instance is created
$this->database_handler->store_data($data_to_store);
}
public function connect() {
//data to store, everytime a connection is made
$this->database_handler->store_data($data_to_store);
$this->connection_id = ftp_connect($this->server);
$this->connection_correct = ftp_login($this->connection_id, $this->user, $this- >password);
if ( (!$this->connection_id) || (!$this->connection_correct) ){
echo "Error! Couldn't connect to $this->server";
var_dump($this->connection_id);
var_dump($this->connection_correct);
return false;
} else {
echo "Successfully connected to $this->server, user: $this->user";
$this->connection_correct = true;
return true;
}
}
}
Ofcourse,这是一个可能的方式做到这一点,有可能西港岛线更加优雅的解决方案。 方式邮寄完成可以使用相同的概念来实现。
从外面看起来是这样的
$ftp = new FptConnect('server', 'user', 'password', new DbHandler('server', 'user', 'password', 'host'));
$ftp->connect();