I ran into a very strange problem, and it seemed to me that I would write it down to identify a possible error. At the moment, I have an acceptable workaround.
My project is a PHP-based deployment tool that uses phpseclib to connect SSH and SFTP to a remote server. I had more luck with this than the SSH2 extension, so I decided to stay with him for now. I am running PHP 7.0.16 inside a Dockerised Alpine 3.5 environment. The problem occurs when I run functional tests inside PHPUnit that connect to a real (local) SSH server.
When I prepare the file for transfer, it goes through the process of creating a temporary copy, so I can make changes for each case using search and replace strings. For testing, although I want something less dynamic, so I thought I'd add a cool close to determine what the date looks like:
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'); }; } }
So, the idea here is that a closure is a βrealβ generator, and I can replace it in test environments with just something static.
So, here is a manifestation of the problem - a lot of notifications:
~ # ./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
Note that $this->dateGenerator is not actually used anywhere. Now here's the weird thing, I can replace it with an empty closure, and again I get notifications:
$this->dateGenerator = function() {};
However, if I comment on this, the notifications will disappear.
#$this->dateGenerator = function() {};
I have tried many things around this, and I am absolutely sure that I am only changing one thing. I wondered if the closure problem persisted in ctor, so I tried to enter an empty closure in the setter, and again I get notifications.
I changed the class closure and the problem disappeared again. Here's how I fix it, but the notification issue makes me nervous about the phpseclib library or even the stability of everything I'm building! I appreciate that since I use PHP, Docker, PHPUnit, phpseclib, ssh and sshd, there are a lot of things that could insert a problem.
On the phpseclib ticket list, this notice is mentioned in # 1125 and # 985 , but both seem to have a specific reason, and not the clearly unrelated property, which I demonstrate here.
Any ideas on how I can research this? Currently, I believe closures have a side effect that I don't know about. I even tried to eliminate the closure in the destructor if it should be βclosedβ, but this did not stop the notification.