为什么引用set_error_handler函数闭包时使用的变量未定义?

时间:2019-10-01 16:55:19

标签: php laravel symfony closures pass-by-reference

在阅读Laravel框架源代码时,我偶然发现了这段代码

set_error_handler(function ($type, $msg) use (&$error) {
    $error = $msg;
});

在Laravel使用Heremove()包的UploadedFile类的symfony/http-foundation类的set_error_handler函数中

VSCode上的Intelephense扩展引发警告

  

未定义变量'$ error'

对代码的屏幕截图深表歉意(以防万一这是扩展程序中的错误,并且您无法复制,请告诉我)。

enter image description here

在研究此问题时,我发现this answer将闭包用法传递给$that = $this; set_error_handler( function() use ($that) { $that->customErrorHandler(); } );

customErrorHandler()

我的理解是UploadedFile是同一类或上下文中的一个函数,必须在调用之外定义

在官方文档中搜索类似的示例会产生相同的结果,see here

但是Symfony的$error类仅定义了该类全局的私有属性$error = $this->error; set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); ,所以不是这样吗?

$error

此代码如何知道从属性中获取$error变量而不进行定义?*

*那是从那里得到的,否则...

undefined在这里如何传递? String content = "-----"; BufferedReader reader = null; HttpsURLConnection connection = null; String returnValue = ""; URL url = new URL(CredentialDto.getTockenurl()); connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setRequestProperty("Authorization", "Basic " + CredentialDto.getAuthentication()); connection.setRequestProperty("Content-Type", "application/x-www-form- urlencoded"); connection.setRequestProperty("Accept", "application/json"); PrintStream os = new PrintStream(connection.getOutputStream()); os.print(content); os.close(); reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line = null; StringWriter out = new StringWriter(connection.getContentLength() > 0 ? connection.getContentLength() : 2048); while((line = reader.readLine()) != null) { out.append(line); } accessToken = out.toString(); Matcher matcher = PAT.matcher(retuenValue); if(matcher.matches() && matcher.groupCount() > 0) { accessToken = matcher.group(1); } 的警告合法性是什么?给定代码确实有效(很好奇)

1 个答案:

答案 0 :(得分:1)

&$error使代码正常工作。基本上,当您传递可调用对象时,它会将$error变量分配为null,然后在内部将其设置为错误消息,然后使用。

set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
$moved = move_uploaded_file($this->getPathname(), $target);
restore_error_handler();

然后,如果移动失败,它将使用$error变量:

if (!$moved) {
    throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error)));
}

与以下相同:

$error = null;
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });

如果没有&,它将引发未定义的变量通知。

并且没有$error变量与error属性无关。

您可以以以下代码为例:

function executeCallback($callable) {
    $callable();   
}

executeCallback(function () use (&$error) {
    $error = 'This is the error message.';
});

echo $error;

$error变量在use (&$error)中定义,随后使用。 echo的输出为:

  

这是错误消息。