Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.1.x] PHP 5.5.9-1ubuntu4.13 Trouble binding to closure when the source of the function was a static class method #11029

Closed
dschissler opened this issue Oct 17, 2015 · 32 comments

Comments

@dschissler
Copy link
Contributor

  • Phalcon - 7fdc8831d7bb80e84b17b9be6eefec809dc70e28 - latest
  • Zephir - 3386a95bedd1e27e0cef0683e1e91224089aebac - latest
  • PHP - PHP 5.5.9-1ubuntu4.13

PHP Warning: Cannot bind an instance to a static closure in ...

This is in my private project but I based it off of publicly accessible code in my Webird project, so it should be the same issue.

I'm using a static method in the base Module class to create the view service function. Then each module calls this static method that is then set with module specific view paths (in addition to the common view paths). This was working great in Phalcon 1.3 and 2.0 and it allows me to pre-compile all Volt templates for the build process. The method needs to be public static because I make the typical assumption that only a single module will be called during execution cycle [and the CLI script to create the production build needs to be able to access all of the module view functions] .

So you can see that function returned is not static and it should appear just as a normal function. This seems like some kind of regression in all of the cool closure stuff that appeared in PHP 5.4 and 5.5.

I have no idea why it works like this. I suspect that PHP 5.5 closure stuff is still just internal hacks to make it seem like their is pure support. Zephir or Phalcon are perhaps interpreting something too strictly.

Would this work in PHP 5.6 or 7.0?

@dschissler

This comment was marked as abuse.

@dschissler

This comment was marked as abuse.

@dschissler

This comment was marked as abuse.

@andresgutierrez
Copy link
Sponsor Contributor

PHP doesn't allow to bind an object to a closure created from a static context. I think this is something that must be changed by developers in order to use Phalcon 2.1

@dschissler

This comment was marked as abuse.

@Jurigag
Copy link
Contributor

Jurigag commented Jan 11, 2016

Old validation is only deprecated its should still work in 2.1

@dschissler

This comment was marked as abuse.

@andresgutierrez
Copy link
Sponsor Contributor

@dschissler This is ilegal in Phalcon 2.1 because Phalcon 2.0 does not bind $this to closures. However, as I said before that constraint is introduced by PHP and not by Phalcon

@dschissler

This comment was marked as abuse.

@huyencodon
Copy link

So, don't have any solution for this bug? i have a same problem.

error

@dschissler

This comment was marked as abuse.

@andresgutierrez
Copy link
Sponsor Contributor

Can you please file an issue here https://github.com/phalcon/phalcon-devtools ?

@dschissler

This comment was marked as abuse.

@huyencodon
Copy link

Thanks all, but i fixed it. Because i use PHP ver 5.5 + Phalcon ver 2.1.0 => It's error.
But i replace phalcon ver 2.1.0 by ver 2.0.10 => it's OK.
I think ver 2.1.0 isn't compatible with PHP ver 5.5.

@andresgutierrez
Copy link
Sponsor Contributor

@huyencodon @dschissler It's compatible, but a closure created in a static context cannot be bound to an object, this is a php behavior, it's not something that we introduced arbitrarily.

@andresgutierrez
Copy link
Sponsor Contributor

This is what is happening under the hood:

<?php

class A
{
    public static function b()
    {
      return function() { };
    }
}

$closure = A::b();
\Closure::bind($closure, new \stdClass);
$ php a.php 
PHP Warning:  Cannot bind an instance to a static closure in /Users/andres/a.php on line 13

Warning: Cannot bind an instance to a static closure in /Users/andres/a.php on line 13

@dschissler

This comment was marked as abuse.

@kakuilan
Copy link

@dschissler
Maybe when you get a service, use getService instead of get, for example:
$cache = $this->di->get('cache'); //Phalcon 2.0X
Replace as:
$cache = $this->di->getService('cache'); //Phalcon 2.1

@dschissler

This comment was marked as abuse.

@sergeyklay sergeyklay removed this from the 3.0.2 milestone Aug 29, 2016
@GBraL
Copy link

GBraL commented Sep 8, 2016

Using Phalcon 3 and PHP 5.6 I can't remove this message?

@Jurigag
Copy link
Contributor

Jurigag commented Sep 8, 2016

As far as i understand no - #11029 (comment)

This is limitation of php, not phalcon bug.

@GBraL
Copy link

GBraL commented Sep 8, 2016

So, what I need to do to work with phalcon 3 and php 5.6?

Because the warning messages can cause problems when rendering the page.

@dschissler

This comment was marked as abuse.

@GBraL
Copy link

GBraL commented Sep 9, 2016

Thank you.

@dugwood
Copy link
Contributor

dugwood commented Sep 26, 2016

Hit the same bug/behaviour with Debian stable:

$di['cache'] = function () {
    return []; // empty array
};

Then, when calling the service:

var_dump(\Phalcon\Version::get(), PHP_VERSION);
var_dump($di->getCache());

Result:

string '3.0.1' (length=5)
string '5.6.24-0+deb8u1' (length=15)
( ! ) Warning: Cannot bind an instance to a static closure in index.php on line 15
 array (size=0)
  empty

Will it be fixed in 3.0.2? Or will this behaviour persists with PHP 5.6? If it's a PHP limitation, as Phalcon 3.0.x is compatible with 5.6, this should be fixed in Phalcon... isn't it?

@Jurigag
Copy link
Contributor

Jurigag commented Sep 26, 2016

Also i don't understand this. I have 5.6.19 and your code for me is returning:

string(5) "3.0.1" string(6) "5.6.19" array(0) { }
$di = new Phalcon\DI\FactoryDefault();

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$di['cache'] = function () {
    return []; // empty array
};
var_dump(\Phalcon\Version::get(), PHP_VERSION);
var_dump($di->getCache());

This is my whole code, i missed something here ?

@dugwood
Copy link
Contributor

dugwood commented Sep 26, 2016

You're right, if I only run:

$di = new \Phalcon\DI\FactoryDefault();
$di['cache'] = function ()
{
    return [];
};
var_dump(\Phalcon\Version::get(), PHP_VERSION, $di->getCache());
exit;

It works well... so that must be the class I'm using to get the DI that goes wrong... I'll let you know (as many people still seem to have the issue!).

@dugwood
Copy link
Contributor

dugwood commented Sep 26, 2016

OK, my issue is that I've done something like:

class Kernel {
    public static function getDI($module) {
        $di = new FactoryDefault();
        $di['cache'] = ....
        return $di;
    }
}
$di = Kernel::getDI('frontend');

If I use a non-static «getDI» function, it works like a charm. I'll change it soon :-)

Thanks @Jurigag!

@Jurigag
Copy link
Contributor

Jurigag commented Sep 26, 2016

The problem is in currently in php there is no way to check if closure is static.

The only "hack" to fix this warning can be just add suppress warningns in zephir.

@dugwood
Copy link
Contributor

dugwood commented Sep 26, 2016

I understand, but the fact that the DI is created in a static function returns the same error, which I found weird... But as long as there's a solution without suppressing the error, that's fine by me.
Hum, after reading @andresgutierrez answer again, I understand it correctly: «in a static context», that's exactly what I've done (wrong).

@Jurigag
Copy link
Contributor

Jurigag commented Sep 26, 2016

Just there is not a bug at all in phalcon. We can't check if it's static context in php. Only one way i guess to do this is add something to zephir to check it, not sure if it's possible or as i wrote add @ in zephir.

@dugwood
Copy link
Contributor

dugwood commented Sep 26, 2016

I think you shouldn't hide the PHP error. It's not a bug in Zephir, but I didn't see any global explanation or answer about what was causing it.
You said: #11029 (comment) so to me there wasn't any solution to avoid this PHP error with PHP 5.6. But there is! Your comment may be understood the wrong way.
So it's a PHP error, not a Zephir bug, and the solution is to avoid declaring the DI within a static method. Which is quite easy to achieve (I've done it in less than 10 minutes on my whole application, once I've understood the issue).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants