hal*_*fer 6 php closures object
我遇到了一个非常奇怪的问题,我想我会记录它以便潜在地发现一个可能的错误.我现在有一个可接受的解决方法.
我的项目是一个基于PHP的部署工具,它使用phpseclib与远程服务器建立SSH和SFTP连接.我有这个比SSH2扩展更幸运,所以我决定暂时坚持下去.我在Dockerised Alpine 3.5环境中运行PHP 7.0.16.当我在PHPUnit中运行连接到真实(本地)SSH服务器的功能测试时,问题浮出水面.
当我准备一个文件进行传输时,它会经历一个创建临时副本的过程,因此我可以使用搜索和替换字符串逐个进行修改.为了测试,虽然我想要一些不那么动态的东西,所以我想我会添加一个类范围的闭包来定义日期的样子:
abstract class Base
{
// (other properties here)
protected $dateGenerator;
public function __construct(QueueState $queueState, BaseFetcher $fetcher)
{
$this->queueState = $queueState;
$this->fetcher = $fetcher;
// Sets a default date generator
$this->dateGenerator = function() { return date('r'); };
}
}
Run Code Online (Sandbox Code Playgroud)
所以这里的想法是闭包是"真正的"生成器,我可以在测试环境中只用静态的东西替换它.
所以,这是问题的表现 - 很多通知:
~ # ./phpunit test/functional/tests/Sftp --stop-on-error
PHPUnit 6.2.2 by Sebastian Bergmann and contributors.
........... 11 / 11 (100%)
Time: 7.56 seconds, Memory: 6.00MB
OK (11 tests, 17 assertions)
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
PHP Notice: Connection closed prematurely in /root/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php on line 3599
Run Code Online (Sandbox Code Playgroud)
请注意,$this->dateGenerator实际上并未在任何地方使用 现在,这是奇怪的,我可以用一个空的闭包替换它,然后我再次收到通知:
$this->dateGenerator = function() {};
Run Code Online (Sandbox Code Playgroud)
但是,如果我发表评论,通知就会消失.
#$this->dateGenerator = function() {};
Run Code Online (Sandbox Code Playgroud)
我已经尝试了很多这方面的事情,我完全相信我只会改变一件事.我想知道问题是否存储在ctor中的闭包,所以我尝试在一个setter中注入空闭包,然后我再次收到通知.
我已经将闭包换成了一个类,问题又消失了.这就是我将如何修复它,但通知问题让我对phpseclib库感到紧张,或者确实是我正在构建的所有内容的稳定性!我很感激,因为我使用PHP,Docker,PHPUnit,phpseclib,ssh和sshd,所以有很多东西可能会引发一个问题.
在phpseclib票证清单上,#1125和#985中提到了这个通知,但两者似乎都有一个特定的原因,而不是我在这里展示的显然不相关的属性.
关于如何研究这个的任何想法?目前我认为封闭具有我不知道的副作用.我甚至试图在析构函数中取消闭包,以防它需要"关闭",但这并没有阻止通知.
在查找 中错误的行号后phpseclib\Net\SSH2,在我看来它来自,当它不是有效资源或已到达 EOF 标记send_binary_packet()时,它会抛出该异常。fsock
我会研究从此类继承的任何对象的使用位置Base,并查看它们的用途。你dateGenerator可能没有被明确地调用,但仍然可能有一些东西看到它并且由于某种原因不喜欢它。甚至可能需要挖掘不属于您自己的代码。:/