【问题标题】:Impossible to access an attribute on a null variable无法访问空变量的属性
【发布时间】:2022-07-07 13:45:17
【问题描述】:

我目前正在使用 Symfony 为一个学校项目开发一个在线学习网站。 课程(编队)有部分,部分有课程。我正在展示课程。 当您单击编队目录时,您会看到一个带有侧边栏菜单的页面,其中显示了所有部分和课程,您可以单击它们。 问题是,当您单击课程时,会出现错误:Impossible to access an attribute ("title") on a null variable.

我猜从初始形成页面传递值存在问题,在该页面中一切正常,但我不知道如何让它们“跟随”。单击课程链接时,我得到了控制器中定义的正确路线,但错误似乎来自原始页面(formation.html.twig)。

FormationsController 中的代码,用于形成页面和课程页面:

#[Route('/formations/consulter-{id}', name: 'app_formations_see')]
    public function see($id): Response
    {
        $formation = $this->doctrine->getRepository(Formation::class)->findOneById($id);
        $section  = $this->doctrine->getRepository(Section::class)->findAll();
        $lesson = $this->doctrine->getRepository(Lesson::class)->findAll();
        return $this->render('formations/formation.html.twig', [
            'formation' => $formation,
            'sections' => $section,
            'lessons' => $lesson
        ]);
    }

     #[Route('/formations/consulter-lecon-{id}', name: 'app_formations_lesson')]
    public function seeLesson($id): Response
    {
        $lesson = $this->doctrine->getRepository(Lesson::class)->findOneById($id);
        return $this->render('formations/lesson.html.twig', [
            'lesson' => $lesson
        ]);
    }

在formation.html.twig中:

{% extends 'base.html.twig' %}
{% block title %}{{ formation.title }}{% endblock %}
{% block content %}
    <div class="formationcontainer text-center">
        <nav class="flex-shrink-0flex-shrink-0 p-3 bg-white sidenav">
            <button class="btn btn-success" id="sidenav-btn" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarCollapse" aria-expanded="false" aria-controls="collapseOne">
                Sommaire
            </button>
            <div class="list-unstyled ps-0 ul-custom navbar-collapse collapse show" id="sidebarCollapse" aria-expanded="true">
                <li class="mb-1">
                    {% for section in formation.sections %}
                    <ul class="list-unstyled align-items-center rounded fw-normal">
                        <li>{{ section.name }}</li>
                    </ul>
                    <div>
                        {% for lesson in section.lessons %}
                        <ul class="list-unstyled fw-normal pb-1 small">
                            <li><a href="{{ path('app_formations_lesson', {'id':lesson.id}) }}" class="link-dark rounded">{{ lesson.title }}</a></li>
                        </ul>
                        {% endfor %}
                    </div>
                    {% endfor %}
                </li>
                <li class="border-top my-3"></li>
                <li class="mb-1">
                    <ul class="list-unstyled fw-normal pb-1 small">
                        <li><a href="{{path('app_formations')}}" class="link-dark rounded">retour à la liste des formations</a></li>
                    </ul>
                </li>
            </div>
        </nav>
        <h1>{{ formation.title }} par {{ formation.user.firstname }} {{ formation.user.lastname }}</h1>
        {{ formation.description }}
        <hr>
        <h2>Sommaire</h2>
        <div class="tableau">
            <table class="table">
                {% for section in formation.sections %}
                    <thead class="table-success">
                    <tr>
                        <th scope="col">{{ section.name }}</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for lesson in section.lessons %}
                        <tr>
                            <td>{{ lesson.title }}</td>
                        </tr>
                    {% endfor %}
                    </tbody>
                {% endfor %}
            </table>
        </div>
    </div>
{% endblock %}

lesson.html.twig 基本上是相同的代码,但内容会发生变化并显示课程内容,而不是所有部分和课程的摘要

编辑:添加了 course.html.twig

{% extends 'base.html.twig' %}
{% block title %}titre de la leçon{% endblock %}
{% block content %}
    <div class="formationcontainer text-center">
        <nav class="flex-shrink-0flex-shrink-0 p-3 bg-white sidenav">
            <button class="btn btn-success" id="sidenav-btn" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarCollapse" aria-expanded="false" aria-controls="collapseOne">
                Sommaire
            </button>
            <div class="list-unstyled ps-0 ul-custom navbar-collapse collapse show" id="sidebarCollapse" aria-expanded="true">
                <li class="mb-1">
                    {% for section in formation.sections %}
                        <ul class="list-unstyled align-items-center rounded fw-normal">
                            <li>{{ section.name }}</li>
                        </ul>
                        <div>
                            {% for lesson in section.lessons %}
                                <ul class="list-unstyled fw-normal pb-1 small">
                                    <li><a href="#" class="link-dark rounded">{{ lesson.title }}</a></li>
                                </ul>
                            {% endfor %}
                        </div>
                    {% endfor %}
                </li>
                <li class="border-top my-3"></li>
                <li class="mb-1">
                    <ul class="list-unstyled fw-normal pb-1 small">
                        <li><a href="{{path('app_formations')}}" class="link-dark rounded">retour à la liste des formations</a></li>
                    </ul>
                </li>
            </div>
        </nav>
        <h1>Nom de la leçon</h1>
        <hr>
        <h2>Vidéo</h2>
        <h2>Contenu</h2>
    </div>
{% endblock %}

【问题讨论】:

  • 在哪个文件和行中抛出错误?你为什么写{% for lesson in section.lessons %}而不是{% for lesson in lessons %},因为你把整个课程列表都传给了树枝!!
  • 请将课程模板发布为formation.html.twig与手头的问题无关
  • formation.html.twig 的第 2 行抛出错误,问题似乎出在 {{formation.title }} 上。我写了section.lessons,因为我不想得到一个包含所有课程的菜单,只有那些与课程相匹配的部分。我添加了课程模板,但它基本上是同一个文件,只是内容发生了变化,而且还没有任何内容,因为我首先无法访问该页面。
  • 点击课时出现错误对吧?您没有将任何变量 formation 从控制器传递到该部分中的视图
  • 是的,当我点击课程时会发生这种情况!我应该直接在控制器中设置变量吗?如果是,我如何获取当前值以传递它?非常感谢

标签: symfony twig


【解决方案1】:

我遇到了类似的问题,最终在数小时后发现了罪魁祸首。当您确定有数据时,这是一个棘手的问题,因此您确定变量不可能为空。

在我的情况下,链接实际上是指向不同的路线,而不是预期的路线。然后该路线被视为{id},因此没有具有这种id的记录。这导致没有找到任何记录,因此为空。

链接是如何转到非目标路由的?我有这样的:

路线 1:

#[Route('/formations/{id}', name: 'app_formations_see')]

路线 2:

#[Route('/formations/consulter', name: 'app_formations_see')]

所以每次我点击一个链接去路由 2(/formations/consulter) 时,它都会转到路由 1(/formations/{id}),它在代码中的路由 2 之前,因此首先找到. 问题是当链接错误地转到路由 1 而不是路由 2 时,'consulter' 被视为路由 1(/formations/{id}) 的 {id}。在数据库中,您不会找到编队记录具有 id 'consulter',因此是 null 变量的原因。

这失败了:

$formation = $this->doctrine->getRepository(Formation::class)->findOneById($id);

因为 ($id) 将被替换为:

$formation = $this->doctrine->getRepository(Formation::class)->findOneById(consulter);

最终,我确保没有其他路线的位置直接与 {id} 匹配,或者在 {id} 路线之后。例如,路线 2 在路线 1 之前。 或者我在路由 1 中添加一个额外的步骤,例如:

路线 1:

#[Route('/formations/forms/{id}', name: 'app_formations_see')]

路线 2:

#[Route('/formations/consulter', name: 'app_formations_see')]

Otherwise you can add a check for the null variable in your twig template:

关注straightupcraft's article:

{# 空测试 null 测试将告诉您变量是否为 null,但在测试空数组或对象时可能会给您带来不希望的结果,因为它们将被视为非 null #} {% if variable is not null %} ... {% endif %}

{# 空测试 如果您不知道变量可能具有什么类型的值,则测试变量是否为空会很有帮助。如果 foo 变量为 null、false、空数组或空字符串,则空测试评估为 true #} {% 如果变量不为空 %} ... {% endif %}

但这意味着如果您仍然走错路线,是的,错误将得到处理,并且您可能会显示有用的消息,但随后应用程序将无法运行,因为它将丢失应呈现的数据。

因此,我建议您按照顶部的说明处理路由结构,以避免来自 {id} 部分的路由冲突

【讨论】:

    猜你喜欢
    • 2020-01-05
    • 2017-11-17
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多