【问题标题】:Psalm possibly null value provided with request->get()随 request->get() 提供的诗篇可能为空值
【发布时间】:2025-11-30 03:15:01
【问题描述】:

我有以下代码:

$request->headers->get('Accept-Language', 'en');

我提供了一个默认值,但 Psalm 认为它可能为 null,因为 ->get() 声明返回一个可为空的字符串:

// vendor/symfony/http-foundation/HeaderBag.php
/**
 * Returns a header value by name.
 *
 * @return string|null The first header value or default value
 */
public function get(string $key, string $default = null) { /* */ }

如何解决这个问题,让 psalm 知道它不为空?

【问题讨论】:

  • 如果你明确告诉类型它不起作用? /** @var string $yourVarName */

标签: php symfony static-analysis psalm-php


【解决方案1】:

由于您无法控制上游库中的注释,因此您必须在自己的代码中向 Psalm 提供缺失的信息。

几种方法:

转换为字符串,因此 Psalm 毫无疑问 get() 会为您提供什么类型:

$a = (string) $request->headers->get('Accept-Language', 'en');

是的,演员表是多余的,但清晰简洁。我通常这样做只是为了经济。

您可以显式声明此get() 调用结果的变量是一个字符串:

/** @var string $acceptLanguage **/
$acceptLanguage = $request->headers->get('Accept-Language', 'en');

最后,您可以在任何需要的地方简单地取消 PossiblyNullArgument

/** @psalm-suppress PossiblyNullArgument */
iWantAString($request->headers->get('Accept-Language', 'en'));

查看所有这些工作here

您还可以将上面的一些方法与您自己的包装器方法结合起来,以处理从请求中获取值,确保始终返回字符串。如果你这样做,你可能应该throw一个异常,如果没有找到参数。

【讨论】:

    【解决方案2】:

    除了 @yivi 的回答向您展示如何覆盖类型推断或抑制错误之外,您还可以通过使用 conditional types 直接在源代码(如果你可以控制的话)或stub file

    /**
     * Returns a header value by name.
     *
     * @psalm-return ($default is null ? (string|null) : string)
     */
    public function get(string $key, string $default = null) { /* */ }
    

    https://psalm.dev/r/41b8471847

    【讨论】:

      最近更新 更多