TypeError при рендеринге панели навигации в Symfony 4

У меня есть TypeError в конструкторе TraceableVoter в проекте Симфони 4.2.2 при отображении индексной страницы с добавленной пользовательской панелью навигации. Файл Security.yaml прикреплен к этому вопросу ниже.

Весь исходный код проекта является полной копией курса Symfony 4 от Udemy.
. TypeError имеет следующую трассировку:

Argument 4 passed to Symfony\Component\Security\Core\Event\VoteEvent::__construct() must be of the type integer, null given, called in /home/vagrant/symfony-01/vendor/symfony/security-core/Authorization/Voter/TraceableVoter.php on line 40 Twig_Environment->render('micro-post/index.html.twig', array('posts' => array(object(MicroPost), object(MicroPost), object(MicroPost), object(MicroPost), object(MicroPost), object(MicroPost), object(MicroPost), object(MicroPost), object(MicroPost), object(MicroPost)))) in src/Controller/MicroPostController.php (line 81)

панель навигации из intex.html


<nav class = "navbar navbar-dark navbar-expand-md sticky-top bg-dark p-0">
    <a class = "navbar-brand col-sm-3 col-md-2 mr-0"
       href = "{{ path('micro_post_index') }}">Micro Post App</a>
    <div class = "w-100 order-1 order-md-0">
        <ul class = "navbar-nav px-3">
            {% if is_granted('ROLE_USER') %}
                <li class = "nav-item text-nowrap">
                    <a class = "nav-link" href = "{{ path('micro_post_add') }}">Add new</a>
                </li>
            {% endif %}
        </ul>
    </div>

    <div class = "order-2 order-md-1">
        <ul class = "navbar-nav px-3">
            {% if is_granted('ROLE_USER') %}
                <li class = "nav-item text-nowrap">
                    <a class = "nav-link"
                       href = "#">{{ app.user.fullName }}</a>
                </li>
                <li class = "nav-item text-nowrap">
                    <a class = "nav-link"
                       href = "{{ path('security_logout') }}">Sign out</a>
                </li>
            {% else %}
                <li class = "nav-item text-nowrap">
                    <a class = "nav-link"
                       href = "{{ path('security_login') }}">Sign in</a>
                </li>
            {% endif %}
        </ul>
    </div>
</nav>

Обработка индексной страницы в MicroPostController.php

    /**
     * @Route("/", name = "micro_post_index")
     * */
    public function index()
    {
        $html = $this->twig->render('micro-post/index.html.twig', ['posts' => $this->microPostRepository->findAll()]);
        return new Response($html);
    }

безопасность.yaml

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
        app_user_provider:
            entity:
                class: App\Entity\User
                property: username
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
            pattern: ^/
            form_login:
                check_path: security_login
                login_path: security_login
                csrf_token_generator: security.csrf.token_manager
                default_target_path: micro_post_index
            logout:
                path: security_logout
                target: micro_post_index
    access_control:
        - { path: ^/micro-post, roles: ROLE_USER }

Это не дублирующий вопрос. преобразование ролей toArray()не решает мою проблему. Вот полная трассировка стека:

TypeError:
Argument 4 passed to Symfony\Component\Security\Core\Event\VoteEvent::__construct() must be of the type integer, null given, called in /home/vagrant/symfony-01/vendor/symfony/security-core/Authorization/Voter/TraceableVoter.php on line 40

  at vendor/symfony/security-core/Event/VoteEvent.php:31
  at Symfony\Component\Security\Core\Event\VoteEvent->__construct(object(ExampleVoter), object(Request), array('ROLE_USER'), null)
     (vendor/symfony/security-core/Authorization/Voter/TraceableVoter.php:40)
  at Symfony\Component\Security\Core\Authorization\Voter\TraceableVoter->vote(object(AnonymousToken), object(Request), array('ROLE_USER'))
     (vendor/symfony/security-core/Authorization/AccessDecisionManager.php:73)
  at Symfony\Component\Security\Core\Authorization\AccessDecisionManager->decideAffirmative(object(AnonymousToken), array('ROLE_USER'), object(Request))
     (vendor/symfony/security-core/Authorization/AccessDecisionManager.php:60)
  at Symfony\Component\Security\Core\Authorization\AccessDecisionManager->decide(object(AnonymousToken), array('ROLE_USER'), object(Request))
     (vendor/symfony/security-core/Authorization/TraceableAccessDecisionManager.php:61)
  at Symfony\Component\Security\Core\Authorization\TraceableAccessDecisionManager->decide(object(AnonymousToken), array('ROLE_USER'), object(Request))
     (vendor/symfony/security-http/Firewall/AccessListener.php:67)
  at Symfony\Component\Security\Http\Firewall\AccessListener->handle(object(GetResponseEvent))
     (vendor/symfony/security-bundle/Debug/WrappedListener.php:46)
  at Symfony\Bundle\SecurityBundle\Debug\WrappedListener->handle(object(GetResponseEvent))
     (vendor/symfony/security-bundle/Debug/TraceableFirewallListener.php:35)
  at Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener->handleRequest(object(GetResponseEvent), object(Generator))
     (vendor/symfony/security-http/Firewall.php:90)
  at Symfony\Component\Security\Http\Firewall->onKernelRequest(object(GetResponseEvent))
     (vendor/symfony/security-bundle/EventListener/FirewallListener.php:48)
  at Symfony\Bundle\SecurityBundle\EventListener\FirewallListener->onKernelRequest(object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
     (vendor/symfony/event-dispatcher/Debug/WrappedListener.php:111)
  at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(GetResponseEvent), 'kernel.request', object(EventDispatcher))
     (vendor/symfony/event-dispatcher/EventDispatcher.php:212)
  at Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.request', object(GetResponseEvent))
     (vendor/symfony/event-dispatcher/EventDispatcher.php:44)
  at Symfony\Component\EventDispatcher\EventDispatcher->dispatch('kernel.request', object(GetResponseEvent))
     (vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:145)
  at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch('kernel.request', object(GetResponseEvent))
     (vendor/symfony/http-kernel/HttpKernel.php:126)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:67)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:198)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (public/index.php:25)

Вы проверяли это? stackoverflow.com/questions/24009476/… Это может быть та же проблема, можете ли вы показать свою сущность пользователя?

Bernard Pagoaga 30.01.2019 17:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
883
6

Ответы 6

У вас есть некоторые замечания о вашем MicroPostController.php (действия индекса),

  • Когда вы визуализируете представление шаблона, вам нужно просто сделать $this->render('path_to_template); вместо $this->twig->render('path_to_template)
  • Вам не нужно передавать представление Twig какой-либо переменной и возвращать Response()

  • Если вы хотите использовать Репозиторий сущностей в Symfony 4.x, используйте Внедрение зависимостей, чтобы ваш показатель принимал такие параметры, как public

function index(MicroPostRepository $microPostRepository) {}

Тогда ваш контроллер должен быть таким

/**
 * @Route("/", name = "micro_post_index")
 * */
public function index(MicroPostRepository $microPostRepository)
{
    return $this->render('micro-post/index.html.twig', [
        'posts' => $microPostRepository->findAll()
    ]);
}

Наконец, чтобы решить проблему, проверьте свой Пользовательская сущность и замените свой Получатели ролей на

public function getRoles()
{
    return $this->roles->toArray();
}

Лучше всего создавать User Entity с помощью Набор создателя и избегать этой ошибки.

php bin/console make:user

К сожалению, это не работает. Во-первых, return $this->roles->toArray(); не влияет на эту ошибку, потому что $roles уже имеет тип ArrayCollection. И $microPostRepository является атрибутом MicroPostController, поэтому я передаю его как $this->$microPostRepository

user10640506 01.02.2019 09:02

Указан неверный путь к app.js — build\js\app.js. Решается добавлением действительного пути app.js к базовому шаблону:

base.html.twig

...

{% block javascripts %}
    <script src = "{{ asset('build/app.js') }}"></script>
{% endblock %}

</body>

У меня такая же проблема. В методе $result есть переменная TraceableVoter->vote. Он должен возвращать целое число. Я сбросил эту переменную, и там действительно был int 0. Но по некоторым причинам класс VoteEvent принимает это значение как нулевое. Поэтому после 38-й строки в TraceableVoter я добавил intval($result);.

public function vote(TokenInterface $token, $subject, array $attributes)
{
    $result = $this->voter->vote($token, $subject, $attributes);

    $result = intval($result);//here

    $this->eventDispatcher->dispatch('debug.security.authorization.vote', new VoteEvent($this->voter, $subject, $attributes, $result));

    return $result;
}

Я новичок в symfony, поэтому не знаю, было ли мое решение правильным, но оно работает.

Убедитесь, что вы нет Voter с функцией внутри этого не имеет возврата.

Эта ошибка возникает, когда ваш процесс голосования имеет нулевой результат.

Я думаю, что Alex_B прав. и проблема была в том, что Voter возвращает null. Если вы находитесь на уроке 43 (is_granted), у вас должен быть ExampleVoter с пустым голосованием за метод. Итак, я только что сделал это, чтобы вернуть 0 из false следующим образом:

Приложение\Безопасность\ExampleVoter.php

namespace App\Security;

use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class ExampleVoter implements VoterInterface
{

  public function vote(TokenInterface $token, $subject, array $attributes)
  {

  return false;

  }
}

и все приходит в норму. Я также новичок в Symfony и надеюсь, что это решит вашу проблему.

В настройках Symfony по умолчанию может быть переопределение для VoterInterface, и вы можете найти его в src/Security/ExampleVoter.php

public function vote(TokenInterface $token, $subject, array $attributes)
    {
        // TODO: Implement vote() method.
    }

Вот проблема либо вернуть 0; или удалите папку, чтобы остановить переопределение.

Другие вопросы по теме