从trait方法将资源分配给类属性

问题描述 投票:0回答:1

我决定编写一个特性,负责使用php内置函数连接和断开与ftp的连接。我想使用特征方法登录,连接和断开与主机的连接。

我需要在类的实例中使用$this->conn来使用ftp函数。该变量将保持ftp连接。我想为$this->conn分配connect trait方法返回的值。我想知道是否有办法在课堂内调用它。

我无法在将使用该特征的类中获取$this变量。如何在课堂内访问它?

<?php
trait ConnectionHelper
{
    public function connect(string $host, string $user, string $pwd)
    {
        $this->conn = ftp_connect($host);
        if ($this->conn && ftp_login($this->conn, $user, $pwd)) {
            ftp_pasv($this->conn, true);
            echo "Connected to: $host !";
        }
        return $this->conn;
    }
    public function disconnect()
    {
        return ftp_close($this->conn);
    }
}

class FTPManager
{
    use ConnectionHelper;
    private $url;
    private $user;
    private $password;

    /* Upload */
    public function upload(array $inputFile, string $dir = null)
    {
        if (!is_null($dir)) {
            ftp_chdir($this->conn, "/$dir/");
        }
        $upload = ftp_put($this->conn, $inputFile['name'], $inputFile['tmp_name'], FTP_BINARY);
        if ($upload) {
            echo 'File uploaded!';
        }
    }
}
?>

注意:在类构造函数中调用trait的connect方法可以是一个很好的解决方案吗?

<?php
class myclass{

use mytrait;

public function __construct(){
    $this->conn = $this->connect($host, $user, $pass);
}

}
?>
php oop traits
1个回答
0
投票

特征可以用来做你想做的事情,但最好实际使用特征来做他们能做的事情:从类属性中分配和读取。

在特征中,当你分配给$this->conn时:

$this->conn = ftp_connect($host);

该属性是为使用特征的类实例定义的。因此,不需要使用$this->conn = $this->connect(),因为$this->conn已经包含连接资源。

所以在构造函数中,只需调用connect方法:

public function __construct()
{
    $this->connect($host, $user, $pass);
    // $this->conn will now contain the connection made in connect()
}

不需要return $this->conn;的特质。要确保释放资源,请从disconnect()的析构函数中调用FTPManager

public function __destruct()
{
    $this->disconnect();
}

话虽如此,这是一种相当古怪的管理方式。必须在每个使用该特征的类中手动调用connect()都容易出错,并且可能导致可维护性问题(这些类中的每一个都需要知道ftp凭证,例如,将它们紧密地耦合到配置)。

考虑到这一点,这些类实例不依赖于ftp凭证,它们依赖于活动的ftp连接。因此,在类的构造函数中实际请求ftp连接更简洁,而不是在实际需要ftp连接的每个类中调用connect()disconnect()

我们可以想到一个连接包装类,它可以大大简化这里的事情:

class FTPWrapper {
    private $connection;
    public function __construct(string $host, string $user, string $pwd)
    {
        $this->connect($host, $user, $pwd);
    }
    public function __destruct()
    {
        $this->disconnect();
    }
    public function getConnection()
    {
        return $this->connection;
    }
    private function connect(string $host, string $user, string $pwd): void
    {
        $this->connection = ftp_connect($host);
        if ($this->connection && ftp_login($this->connection, $user, $pwd)) {
            ftp_pasv($this->connection, true);
            echo "Connected to: $host !";
        }
    }
    private function disconnect(): void
    {
        ftp_close($this->conn);
    }
}

然后,将该包装器注入需要使用它的任何类。

© www.soinside.com 2019 - 2024. All rights reserved.