PhpStorm 中的 "Add #[Pure] attribute" 检查是为了什么?

What is the "Add #[Pure] attribute" inspection in PhpStorm checking for?

我在 Laravel 项目中有一个非常简单的 FormRequest class。两种方法,两者都是 return 一个由方法部分填充的简单数组,但 IDE 对它们的处理方式不同。

<?php

namespace App\Http\Requests;

class VerifyPhoneNumber extends FormRequest {
    use Support\ValidatesPhoneNumbers;

    public function authorize(): bool {
        return true;
    }

    public function rules(): array {
        return [
            "phone_number" => $this->getPhoneNumberRules(),
            "verify_code" => ["required", "numeric", "max:999999"],
        ];
    }

    public function messages(): array {
        return [
            "phone_number.regex" => $this->getPhoneNumberMessage(),
        ];
    }
}

以及非常基本的特征方法:

<?php

namespace App\Http\Requests\Support;

trait ValidatesPhoneNumbers {
    protected function getPhoneNumberMessage(): string {
        return __("Some localized error message");
    }

    protected function getPhoneNumberRules(): array {
        return ["regex:/^\+?1?[2-9][0-9]{5,14}$/", "max:16"];
    }
}

我感到困惑的是 IDE 检查抱怨我应该将 JetBrains\PhpStorm\Pure 属性添加到 rules() 方法,而不是 messages()方法。

the class definition中的评论说:

The attribute marks the function that has no impact on the program state or passed parameters used after the function execution. This means that a function call that resolves to such a function can be safely removed if the execution result is not used in code afterwards.

这并没有真正给我任何线索,说明为什么它以不同的方式对待这两种方法。如果我对第二句话的理解正确,当“纯”方法的结果未被使用时,IDE 会将该方法的使用标记为未使用并建议将其删除。

用于确定何时需要此属性的逻辑是什么?

如果一个函数只依赖于其他纯函数,那么它也是纯函数。由于 getPhoneNumberRules() 只是 return 一个固定数组,它是纯数组,所以 rules() 也是纯数组。

但是 messages() 调用 getPhoneNumberMessage(),它调用 __() 函数,如果位置状态发生变化,该函数可以 return 不同的本地化消息,因此它不是纯粹的。

rules() 方法有 固定(最好说 “无副作用”)结果——它使用固定值只要。当然,它从特征调用 getPhoneNumberRules() 但它也 returns 固定数组(总是相同的)。它不会在其他任何地方(内部状态或外部存储)进行更改。

messages() 方法从调用 __() 的特征中调用一个方法来获取翻译后的消息...可能来自不同的来源(数据库、文件),因此可能如果存储 (file/DB) 不可读,则抛出异常。 IDE 不确定 __() 是否对 file/DB 进行了更改——它没有被注释为 pure 并且 PhpStorm 无法根据它使用的方法做出这样的决定。


P.S. 如果这个检查让你烦恼(我能理解)那么我建议你忽略这样的检查并在 PhpStorm 设置中将其严重性降低到“否”突出显示,仅修复" (Settings (Preferences on macOS) | Editor | Inspections | PHP | Attributes | '#[Pure]' attribute can be added)

Use this attribute for functions that do not produce any side effects. All such PHP internal functions are already marked in PhpStorm.

#[Pure]
function compare(Foo $a, Foo $b): int
{
    return $a->a <=> $b->b;
}

来源:https://github.com/JetBrains/phpstorm-attributes#pure

由于此函数仅在其自身内部执行某些操作,因此可以将其称为#[Pure] 函数,因此您可以通过 PhpStorm 了解这一点。