Назначить ресурс свойству класса из метода trait - PullRequest
0 голосов
/ 22 апреля 2019

Я решил написать характеристику, которая будет отвечать за подключение и отключение от ftp с помощью встроенных функций php.Я хочу войти в систему, подключиться и отключиться от хоста, используя методы trait.

Мне нужно использовать $this->conn внутри экземпляра класса, чтобы использовать функции ftp.Переменная будет содержать FTP-соединение.Я хочу присвоить $this->conn значение, возвращаемое методом черты соединения.Я хочу знать, есть ли способ вызвать его внутри класса.

Я не могу получить переменную $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!';
        }
    }
}
?>

Примечание: может быть хорошим решением для вызова метода соединения свойства внутри конструктора класса?

<?php
class myclass{

use mytrait;

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

}
?>

1 Ответ

0 голосов
/ 22 апреля 2019

Черты могут использоваться, чтобы делать то, что вы хотите, но было бы лучше использовать черты для того, что они могут делать: назначать и читать из свойств класса.

В чертах, когда вы назначаете $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 в конструкторе класса и не беспокоиться о вызовах connect() и disconnect() в каждом классе, который действительно нуждается в соединении ftp.

Мы могли бы подуматькласс-оболочка подключения, который значительно упростил бы ситуацию:

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);
    }
}

Затем вставьте эту обертку в любой класс, который ее использует.

...