php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66622 Closures do not correctly capture the late bound class (static::) in some cases
Submitted: 2014-02-01 02:29 UTC Modified: 2015-05-04 12:37 UTC
Votes:2
Avg. Score:3.5 ± 0.5
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: drewparoski at gmail dot com Assigned: levim
Status: Closed Package: Scripting Engine problem
PHP Version: 5.5.8 OS: CentOS Linux 6.3
Private report: No CVE-ID:
 [2014-02-01 02:29 UTC] drewparoski at gmail dot com
Description:
------------
When a PHP closure is created, it is supposed to capture the late bound class of the enclosing function. There are a number of cases involving derived classes and static methods or static closures (or both) where it doesn't work correctly.

The test script I've included demonstrates the problem. I've tested it on PHP 5.6.0alpha1, but I can also reproduce the problem on various builds of PHP 5.5.

Test script:
---------------
<?php
class A {
  static function name() { return 'A'; }
  function foo() {
    $fn = function() { return static::name(); };
    echo static::name() . ' vs ' . $fn() . "\n";
  }
  function bar() {
    $fn = static function() { return static::name(); };
    echo static::name() . ' vs ' . $fn() . "\n";
  }
  static function baz() {
    $fn = function() { return static::name(); };
    echo static::name() . ' vs ' . $fn() . "\n";
  }
}
class B extends A {
  static function name() { return 'B'; }
}
function test() {
  (new B)->foo();
  B::foo();
  (new B)->baz();
  B::baz();
  (new B)->bar();
  B::bar();
}
test();

Expected result:
----------------
B vs B
B vs B
B vs B
B vs B
B vs B
B vs B

Actual result:
--------------
B vs B
B vs A
B vs A
B vs A
B vs A
B vs A

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-02-04 01:39 UTC] drewparoski at gmail dot com
-PHP Version: 5.6.0alpha1 +PHP Version: 5.5.8
 [2014-02-04 01:39 UTC] drewparoski at gmail dot com
Verified this happens on PHP 5.5.8, which is the current official release. Updated the version number for this bug accordingly, though it's worth noting this bug still happens on PHP 5.6.0alpha1 as well.
 [2014-05-10 03:03 UTC] levim@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: levim
 [2014-05-11 03:05 UTC] levim@php.net
Github is down at the moment; pull request will come in on Monday.
 [2014-06-09 02:07 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2014-06-09 02:07 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2014-12-05 11:06 UTC] taco at procurios dot nl
The fix for this issue introduces a change in previous behaviour for private static methods being called from a closure in a public / protected static method.

The following script used to output "barbar", currently a fatal error is triggered:

Test script:
--------------
<?php
class Foo
{
	private static function bar()
	{
		echo 'bar';
	}

	public static function baz()
	{
		$f = function () { self::bar(); };
		$f();
	}
}

class Bar extends Foo {}

Foo::baz();
Bar::baz();
 [2015-05-04 12:37 UTC] laruence@php.net
as taco at procurios dot nl metioned, this introuducd a new bug : https://bugs.php.net/bug.php?id=69568
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Wed Feb 22 22:01:36 2017 UTC