【问题标题】:Psalm: How to handle dedicated view files?诗篇:如何处理专用视图文件?
【发布时间】:2021-06-10 13:13:44
【问题描述】:

我的设置包括一个带有类的 lib 文件夹和一个带有 PHP 文件的 view 文件夹,它们会产生输出。视图被导入到类似于这样的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' =&gt; 'bar']。然而,Psalm 并没有赶上这一点,并报告了很多 UndefinedGlobalVariable 问题。

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

【问题讨论】:

  • 从技术上讲,您的视图只是一个接受一堆变量并返回一个字符串的方法。那么为什么不把它变成像psalm.dev/r/66898ee87f 这样的方法呢?
  • 谢谢你的想法!是的,从技术上讲,这对我有用。我有点犹豫,因为它看起来像很多 OOP 样板,而我想要的只是一些好的老式标签汤 PHP 和 include_once "partial/component.php"; 以某种可控的方式。我想,诗篇是检查观点的错误工具吗?不过,它就像一个魅力,检查我的代码的 OOP 部分。但也许我尝试用螺丝刀来处理钉子......
  • 想一想,也许我可以用普通函数最小化样板文件......像function part1(string $foo, int $bar) { ?&gt; html ... &lt;?php part2($bar) ?&gt; ... html &lt;?php } 这样的东西可能符合要求,比普通文件更复杂。放在一个命名空间中,一些自动加载,那么这可能是一个很好的“PHP 作为模板引擎”的解决方案......我将不得不尝试一下。同时:如果您愿意,可以将您的评论复制到答案中,然后我至少可以投票。

标签: php testing model-view-controller types psalm-php


【解决方案1】:

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

或者,您可以将模板包装成最小的方法/函数,因为从技术上讲,它只是一个接受一堆变量并返回字符串的函数: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,但不限于)都能够理解它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 2021-09-30
    • 2020-02-18
    • 2021-12-14
    • 2021-11-21
    • 1970-01-01
    • 2020-09-14
    相关资源
    最近更新 更多