dak*_*kis 7 php php-7 php-7.4 php-8
我正在逐步将我的项目从PHP 7.1迁移到PHP 8.0。
在PHP官方手册中,在“从PHP 7.3.x迁移到PHP 7.4.x”一章的“弃用功能”子章节中,我尝试理解以下弃用描述:
解除绑定
$this时$this使用解除绑定
$this使用的非静态闭包$this解除绑定。
虽然,没有成功。
这就是为什么如果有人能详细解释我这意味着什么,我将不胜感激。也许代码片段也有帮助。
非常感谢您的宝贵时间!
也许这也有助于解释:
在我的项目中,我认为只有一种情况可以应用此弃用通知:下面介绍的类executeGroupHandler的方法RouteCollection。我更愿意粘贴更多的类代码,以帮助您理解我使用该方法的上下文executeGroupHandler。
路由集合类:
<?php
namespace Packages\Router;
//...
use Packages\Router\RouteCollectionInterface;
/**
* Route collection.
*/
class RouteCollection implements RouteCollectionInterface {
//...
/**
* Group patterns list. Indexed array.
*
* Each time a group handler is executed its pattern is saved in this list.
* All addRoute operations taken place inside the scope of a group handler
* prefix the pattern of the corresponding route with the saved group pattern.
*
* @var array
*/
private $groupPatterns = [];
//...
/**
* Add a group (helper method).
*
* @param string $pattern Group pattern.
* @param \Closure $handler Group handler.
* @return $this
*/
public function group(string $pattern, \Closure $handler) {
$this->addGroup($pattern, $handler);
return $this;
}
/**
* Add a group.
*
* @param string $pattern Group pattern.
* @param \Closure $handler Group handler.
* @return $this
*/
private function addGroup(string $pattern, \Closure $handler) {
$this->saveGroupPattern($pattern);
$this->executeGroupHandler($handler);
/*
* Remove the last group pattern from the group patterns list. This step
* is performed only after all calls for adding groups/routes inside the
* scope of the current group handler have finished their processing.
*/
$this->popLastGroupPattern();
return $this;
}
/**
* Save a group pattern.
*
* @param string $pattern Group pattern.
* @return $this
*/
private function saveGroupPattern(string $pattern) {
$this->groupPatterns[] = $pattern;
return $this;
}
/**
* Execute a group handler.
*
* Temporarily bind the group handler to the route collection
* object - defined by the argument in Closure::call - and
* execute it. Inside the scope of the group handler, the route
* collection will be accessed using the keyword "$this".
*
* @link https://www.php.net/manual/en/closure.call.php Closure::call
*
* @param \Closure $handler Group handler.
* @return mixed The return value of calling the handler.
*/
private function executeGroupHandler(\Closure $handler) {
return $handler->call($this);
}
/**
* Pop the group pattern off the end of group patterns list.
*
* @return string The popped group pattern.
*/
private function popLastGroupPattern() {
return array_pop($this->groupPatterns);
}
}
Run Code Online (Sandbox Code Playgroud)
RouteCollection类的使用:
定义了该类后RouteCollection,我使用它类似于以下内容:
<?php
use Packages\Router\RouteCollection;
use SampleMvc\App\View\Template\Users\AddUser as AddUserView;
use SampleMvc\App\Controller\Users\AddUser as AddUserController;
$routeCollection = new RouteCollection();
// Add a group of routes to the route collection.
$routeCollection->group('/users/add', function() {
$this->get('', [AddUserView::class, 'index']);
$this->post('', [
'controller' => AddUserController::class,
'view' => [AddUserView::class, 'addUser'],
]);
});
//...
Run Code Online (Sandbox Code Playgroud)
此 RFC 中提出(并接受)了弃用,其中提供了有关弃用内容及其原因的更多详细信息。
最后一句解释了哪些关闭受到影响:
特别是这适用于在非静态方法内声明的非静态闭包。
$this首先可以通过将闭合标记为静态来避免绑定。
后来在此提交中进一步缩小了范围,以便它仅适用于$this闭包中实际提到的闭包。
与此同时,第一句话给出了一个更清晰的例子来说明什么是被弃用的:
目前,可以通过使用 来解除 $this 变量与最初具有该变量的闭包的绑定
$closure->bindTo(null)。
关键字是unbind而不是rebindnull ,以及示例中的the 。
尼基塔在此评论中提供了更多背景信息:
我们对此弃用感兴趣的原因完全是为了在 PHP 8 中实现与 $this 访问相关的一些性能改进,这是通过删除对非静态方法的静态调用来实现的。$this 访问可以分为两类:我们知道 $this 为非空的访问和我们不知道的访问。方法调用(will)属于前一类。随着这种弃用,关闭也将属于前一类。
换句话说,在 PHP 8 中,引擎将盲目地假设$this闭包中的任何引用实际上都是一个对象,而不是 null。
因此,不推荐使用的特定场景是,您有一个提到 的闭包$this,然后您将其解除绑定,因此$this根本不会设置为任何内容。只要您为 提供新值$this,您就应该不受影响,因为$this永远不会受到影响null。