0

我的设置包括一个lib带有类的view文件夹和一个带有 PHP 文件的文件夹,它们会产生输出。视图被导入到View与此类似的类中:

class View {

    public function render(string $basename, Array $params) : string {
        extract($params, EXTR_PREFIX_INVALID, 'v');
        ob_start();
        include sprintf('%s/views/%s.php', dirname(__DIR__), $basename);
        $out = ob_get_contents();
        ob_end_clean();
        return $out;
    }

}

在这种情况下,我基本上对 Psalm 有两个问题:

  1. 因为View::render它报告了一个UnresolvableInclude. 我什至可以用类似的$basename东西输入

     @param "view1"|"view2"|"about" $basename
    

    没有效果。无法解决的包含仍然存在。

  2. extract()的内容放在$params包含视图文件的本地范围内。这让我有

     <?=escape($foo)?>
    

    我的视图文件中的“标签”带有$params === ['foo' => 'bar']. 然而,Psalm 并没有赶上这一点,并报告了很多UndefinedGlobalVariable问题。

我的问题:如何告诉 psalm 有关视图文件和变量的信息?或者,我如何重新构建此代码以便 psalm 可以为我测试它?

4

1 回答 1

1

在 Psalm 的 repo 中有一个演示TemlateChecker 插件,它似乎做了类似的事情:它查看视图文件中的 docblock 中的标签,@variablesfrom ClassName::method并使其在模板文件中可用。或者只是该方法中变量的属性$this,不确定。Psalm 文档中也提到了这一点:检查非 PHP 文件

或者,您可以将模板包装成最小的方法/函数,因为从技术上讲,它只是一个接受一堆变量并返回字符串的函数:https ://psalm.dev/r/66898ee87f

<?php class HomePageView {  // view starts here
    /** @param list<string> $sections */
    public function render(
        string $title,
        array $sections
    ): string { ob_start();
?>
<html>
    <head>
       <title><?=$title?></title>
    </head>
    <body>
    <?php foreach ($sections as $section): ?>
        <section><?=$section?></section>
    <?php endforeach; ?>
    </body>
</html>

<?php return ob_get_contents(); }} // view ends here ?>

这样任何分析代码的工具(包括 Psalm,但不限于)都能够理解它。

于 2021-03-23T10:17:39.480 回答