从 trait 方法将资源分配给 class 属性
Assign resource to a class property from trait method
我决定编写一个特征,负责使用 php 内置函数连接和断开与 ftp 的连接。我想使用特征方法登录、连接和断开与主机的连接。
我需要从 class 的实例内部使用 $this->conn
来使用 ftp 函数。该变量将保持 ftp 连接。我想将连接特征方法返回的值分配给 $this->conn
。我想知道是否有办法在 class.
中调用它
我无法在 class 中获取将使用该特征的 $this
变量。如何在 class?
中访问它
<?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!';
}
}
}
?>
注意:在 class 构造函数中调用 trait 的 connect 方法是一个很好的解决方案吗?
<?php
class myclass{
use mytrait;
public function __construct(){
$this->conn = $this->connect($host, $user, $pass);
}
}
?>
Traits 可以用来做你想做的事,但最好实际使用 traits 来做它们可以做的事情:分配和读取 class 属性。
在特征中,当你分配给$this->conn
时:
$this->conn = ftp_connect($host);
属性 是为使用特征的 class 个实例定义的。因此,无需使用 $this->conn = $this->connect()
,因为 $this->conn
已经包含连接资源。
所以在构造函数中,只需调用连接方法:
public function __construct()
{
$this->connect($host, $user, $pass);
// $this->conn will now contain the connection made in connect()
}
不需要return $this->conn;
在特征中。为确保释放资源,请从 FTPManager
的析构函数中调用 disconnect()
:
public function __destruct()
{
$this->disconnect();
}
话虽这么说,但这是一种相当古怪的管理方式。必须在每个使用特征的 class 中手动调用 connect()
很容易出错,并且可能导致可维护性问题(每个 class 都需要注意 ftp凭据,例如,将它们与配置紧密耦合)。
考虑一下,这些 class 实例不依赖于 ftp 凭据,它们依赖于 活动的 ftp 连接 。因此,在 class 的构造函数中实际请求 ftp 连接更清晰,而不用在每个 class 中调用 connect()
和 disconnect()
] 实际上需要 ftp 连接。
我们可以想到一个连接包装器 class 来大大简化这里的事情:
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);
}
}
然后,将该包装器注入任何需要使用它的class。
我决定编写一个特征,负责使用 php 内置函数连接和断开与 ftp 的连接。我想使用特征方法登录、连接和断开与主机的连接。
我需要从 class 的实例内部使用 $this->conn
来使用 ftp 函数。该变量将保持 ftp 连接。我想将连接特征方法返回的值分配给 $this->conn
。我想知道是否有办法在 class.
我无法在 class 中获取将使用该特征的 $this
变量。如何在 class?
<?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!';
}
}
}
?>
注意:在 class 构造函数中调用 trait 的 connect 方法是一个很好的解决方案吗?
<?php
class myclass{
use mytrait;
public function __construct(){
$this->conn = $this->connect($host, $user, $pass);
}
}
?>
Traits 可以用来做你想做的事,但最好实际使用 traits 来做它们可以做的事情:分配和读取 class 属性。
在特征中,当你分配给$this->conn
时:
$this->conn = ftp_connect($host);
属性 是为使用特征的 class 个实例定义的。因此,无需使用 $this->conn = $this->connect()
,因为 $this->conn
已经包含连接资源。
所以在构造函数中,只需调用连接方法:
public function __construct()
{
$this->connect($host, $user, $pass);
// $this->conn will now contain the connection made in connect()
}
不需要return $this->conn;
在特征中。为确保释放资源,请从 FTPManager
的析构函数中调用 disconnect()
:
public function __destruct()
{
$this->disconnect();
}
话虽这么说,但这是一种相当古怪的管理方式。必须在每个使用特征的 class 中手动调用 connect()
很容易出错,并且可能导致可维护性问题(每个 class 都需要注意 ftp凭据,例如,将它们与配置紧密耦合)。
考虑一下,这些 class 实例不依赖于 ftp 凭据,它们依赖于 活动的 ftp 连接 。因此,在 class 的构造函数中实际请求 ftp 连接更清晰,而不用在每个 class 中调用 connect()
和 disconnect()
] 实际上需要 ftp 连接。
我们可以想到一个连接包装器 class 来大大简化这里的事情:
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);
}
}
然后,将该包装器注入任何需要使用它的class。