Are there any known side effects when storing PHP closures in object properties?

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.

+7
closures object php
source share
1 answer

After looking at the error line number in phpseclib\Net\SSH2 it seems to me that it comes from send_binary_packet() , which throws this exception when its fsock either not a valid resource or has reached the EOF token.

I would look where any objects that inherit from this Base class are used and see what is being done with them. Your dateGenerator may not be called explicitly, but there might still be something there seeing it, and for some reason it doesn't like it. You may even have to dig through code that is not your own.: /

+1
source share

All Articles