rfc:closures:removal-of-this

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

rfc:closures:removal-of-this [2009/01/26 22:25]
cseiler added tidbits on reflection
rfc:closures:removal-of-this [2017/09/22 13:28]
Line 1: Line 1:
-====== Removal of $this in closures ====== 
- 
-(NOTE THAT THIS IS NOT COMMITTED YET. THIS PAGE IS STILL WORK IN PROGRESS) 
- 
-This document describes the changes that were done in order to remove $this support from closures for PHP 5.3 beta1. This has become necessary in order to make sure that when a consensus is found on how to add $this to closures, it will be able to integrate that without BC issues. 
- 
-===== Userland perspective ===== 
- 
-In the userland perspective, $this may not be used in closures. Also, using the static keyword in front of function is not allowed anymore. Examples: 
- 
-<code php> 
-$closure = function () { }; // still works 
-$closure = static function () { }; // DOES NOT WORK 
-class Foo { 
-  public $pubMember; 
-  private $privMembeR; 
-  function bar { 
-    $closure = function () { 
-      return $this; // DOES NOT WORK 
-    }; 
-    $closure = static function () { // DOES NOT WORK 
-    }; 
-    $closure = function () { echo "Hello World!\n"; }; // still works 
-    $closure = function () use ($this) { ... }; // DOES NOT WORK 
-    $self = $this; 
-    $closure = function () use ($self) { // still works 
-       echo $self->pubMember; // still works 
-       echo $self->privMember; // DOES NOT WORK 
-    }; 
-  } 
-} 
-</code> 
- 
-Yes, these are quite some restrictions on closures, however, this is the only possibility to ensure that support for $this can be added in any fashion that may later be required. 
- 
-===== Internals perspective ===== 
- 
-   - zend_closure structure: this_ptr member is gone. 
-   - removed zend_get_closure() prototype in zend_closures.h (was not implemented anyway anymore since it's now done via a handler) 
-   - removd scope and this_ptr parameters from zend_create_closure() 
-   - removed zend_get_closure_this_ptr 
- 
-==== Important note on get_closure handler ==== 
- 
-However, the get_closure handler prototype was **NOT** changed (only the implementation for closures, which always set the scope and object ptr to NULL) and still allows the handler implementation to set a scope and this_ptr because the handler is also responsible for __invoke on normal objects! 
- 
-===== Reflection ===== 
- 
-Reflection was changed a bit in order to make sure Non-OOP-Closures are supported consistently. 
- 
-==== getClosure() / getClosureThis() removal ==== 
- 
-**Removed** ''ReflectionFunction::getClosure()'' and ''ReflectionFunction::getClosureThis()''. Removal of ''getClosureThis()'' is obvious (no $this stored in closures anymore). However, ''getClosure()'' must also be removed. This is due to the simple fact that in the previous implementation, one could do ''$reflectionMethod->getClosure ($object)'' (ReflectionMethod inherits from ReflectionFunction) and get a Closure that calls the method for the specific object, which means that a closure with bound $this was returned. 
- 
-Since allowing that for this special case would perhaps inhibit the possibility of later adding JS-like $this binding to closures at all, it is best to simply remove the method and perhaps later re-add it when the type of implementation is clear. 
- 
-==== Modified ReflectionFunction / ReflectionMethod dynamic ==== 
- 
-In the original RFC, ReflectionMethod also accepted solely $closure as a parameter to the constructor and implied ''_invoke'' as method name. Those however only gave access to the dynamic invoke method and not the closure method itself. Somewhat later, somebody added the possibility to simply use $closure as parameter for ReflectionFunction. 
- 
-This is now consolidated: 
- 
-  - ReflectionFunction now accepts $closure as sole parameter 
-  - ReflectionMethod now does not automatically infer ''_invoke'' as method name for single objects that were passed. 
- 
-Thus, a ''new ReflectionFunction($closure)'' has access to the real user-defined closure details and ''new ReflectionMethod($closure, "_invoke")'' has access to the internal auto-generated handler method. 
- 
-==== isClosure ==== 
- 
-isClosure now detects a closure according to the flags (fn_flags & ZEND_ACC_CLOSURE). 
  
rfc/closures/removal-of-this.txt · Last modified: 2017/09/22 13:28 (external edit)