Symfony 4 - FOSUserBundle - Отображает информацию о пользователе на настраиваемом маршруте

У меня есть конструктор и маршрут в моем настраиваемом ProfileController

private $userManager;

public function __construct(UserManagerInterface $userManager)
{
    $this->userManager = $userManager;
}

/**
 * @Route("/profile/bookings", name = "profile_bookings")
 */
public function bookings()
{

    $user = $this->getUser();

    return $this->render('profile/bookings/bookings.html.twig', array('user'=>$user));
}

И в моем шаблоне я ссылаюсь

{{user.first_name}}

Но получаю ошибку:

Внутренняя ошибка сервера HTTP 500 Ни свойство «first_name», ни один из методов «first_name ()», «getfirst_name ()» / «isfirst_name ()» / «hasfirst_name ()» или «__call ()» не существуют и не имеют общего доступа в классе «App \ Сущность \ Пользователь ".

Как получить информацию о пользователе из базы данных и отобразить на дополнительных страницах профиля?

Обновлено: Пользовательский объект ...

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;

/**
 * @ORM\Entity
 * @ORM\Table(name = "`user`")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
     * @ORM\Column(type = "integer")
     */
    protected $id;

    /**
     * @ORM\Column(type = "string", length=190)
     */
    private $first_name;

    /**
     * @ORM\Column(type = "string", length=190)
     */
    private $last_name;

    /**
     * @ORM\Column(type = "string", length=190, nullable=true)
     */
    private $phone_number;

    /**
     * @ORM\Column(type = "integer", nullable=true)
     */
    private $profile_height;

    /**
     * @ORM\Column(type = "integer", nullable=true)
     */
    private $profile_weight;

    /**
     * @ORM\Column(type = "date", nullable=true)
     */
    private $profile_dob;

    /**
     * @ORM\Column(type = "string", length=190, nullable=true)
     */
    private $profile_gender;

    /**
     * @ORM\OneToMany(targetEntity = "App\Entity\Booking", mappedBy = "user")
     */
    private $bookings;

    public function __construct()
    {
        parent::__construct();
        $this->bookings = new ArrayCollection();
    }

    /**
     * Overridde setEmail method so that username is now optional
     *
     * @param string $email
     * @return User
     */
    public function setEmail($email)
    {
        $this->setUsername($email);

        return parent::setEmail($email);
    }

    public function getFirstName()
    {
        return $this->first_name;
    }

    public function setFirstName($first_name)
    {
        $this->first_name = $first_name;
    }

    public function getLastName()
    {
        return $this->last_name;
    }

    public function setLastName($last_name)
    {
        $this->last_name = $last_name;
    }

    public function getPhoneNumber(): ?string
    {
        return $this->phone_number;
    }

    public function setPhoneNumber(string $phone_number): self
    {
        $this->phone_number = $phone_number;

        return $this;
    }

    public function getProfileHeight(): ?int
    {
        return $this->profile_height;
    }

    public function setProfileHeight(?int $profile_height): self
    {
        $this->profile_height = $profile_height;

        return $this;
    }

    public function getProfileDob(): ?\DateTimeInterface
    {
        return $this->profile_dob;
    }

    public function setProfileDob(?\DateTimeInterface $profile_dob): self
    {
        $this->profile_dob = $profile_dob;

        return $this;
    }

    public function getProfileWeight(): ?int
    {
        return $this->profile_weight;
    }

    public function setProfileWeight(?int $profile_weight): self
    {
        $this->profile_weight = $profile_weight;

        return $this;
    }

    public function getProfileGender(): ?string
    {
        return $this->profile_gender;
    }

    public function setProfileGender(?string $profile_gender): self
    {
        $this->profile_gender = $profile_gender;

        return $this;
    }

    /**
     * @return Collection|Booking[]
     */
    public function getBookings(): Collection
    {
        return $this->bookings;
    }

    public function addBooking(Booking $booking): self
    {
        if (!$this->bookings->contains($booking)) {
            $this->bookings[] = $booking;
            $booking->setUser($this);
        }

        return $this;
    }

    public function removeBooking(Booking $booking): self
    {
        if ($this->bookings->contains($booking)) {
            $this->bookings->removeElement($booking);
            // set the owning side to null (unless already changed)
            if ($booking->getUser() === $this) {
                $booking->setUser(null);
            }
        }

        return $this;
    }

}

Спасибо.

Можете ли вы показать свою сущность пользователя?

fgamess 05.12.2018 06:34

Ага, только что добавил. Спасибо.

TimothyAURA 05.12.2018 06:52
Стоит ли изучать 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
246
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Просто используйте в своем шаблоне веточки:

{{ user.getFirstName }}

Работает нормально. Обычно то, что делает Twig на уровне PHP, довольно просто:

check if user is an array and first_name a valid element;
if not, and if user is an object, check that first_name is a valid property;
if not, and if user is an object, check that first_name is a valid method (even if first_name is the constructor - use __construct() instead);
if not, and if user is an object, check that getfirst_name is a valid method;
if not, and if user is an object, check that isfirst_name is a valid method;
if not, and if user is an object, check that hasfirst_name is a valid method;
if not, return a null value.

См. Переменные Twig.

Кстати, вы должны следовать Стандарт кодирования Symfony для своей переменной, потому что для twig может быть сложно найти значение свойств, записанных в snake_case.

Хороший совет по поводу змеиного дела, спасибо. Погодите, значит, я должен использовать в своей ветке методы, а не переменные?

TimothyAURA 05.12.2018 07:22

Если вы используете такую ​​переменную, как my_variable yes, легче получить доступ к подобному значению, потому что вам придется использовать странное имя для ваших геттеров / сеттеров для доступа к этому частному свойству в Twig. Или используйте переменную вроде myVariable

fgamess 05.12.2018 07:24

Я не думаю, что вам следует встраивать UserManagerInterface в свой контроллер. Кроме того, как говорит Франк, по возможности используйте стандарт кодирования, это сэкономит много времени и сэкономит нервы в будущем!

Вот контроллер, который я использую в проекте Symfony 4:

namespace App\Controller;

use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

/**
 * @Route("/profile/bookings", name = "profile_bookings")
 */
public function bookings()
{
    $user = $this->getUser();
    if (!is_object($user) || !$user instanceof UserInterface) {
        throw new AccessDeniedException('This user does not have access to this section.');
    }

    return $this->render('profile/bookings/bookings.html.twig', array(
        'user' => $user,
    ));
    }
} 

Я не согласен с вами, когда вы говорите, что он не должен «создавать» UserManager в контроллере. Во многих случаях на моем контроллере я использую какой-то метод Manager / service, поэтому я вставляю его в __construct и могу получить к нему доступ во всем контроллере.

Etshy 13.12.2018 14:59

@Etshy, я подумал, что начиная с Symfony 3.3 вы должны использовать инъекцию зависимостей. Я ошибся?

Dirk J. Faber 13.12.2018 16:47

Да, это то, что он делает с подсказками типа услуги. Он вставляет службу в конструктор контроллера, чтобы ее можно было использовать.

Etshy 13.12.2018 17:00
Ответ принят как подходящий

@Franck Gamess прав, но вы также можете избавиться от get. Если вы напишете {{ user.firstName }}, twig автоматически свяжет это с вашим методом getFirstName().

Я не знаю, почему вы пишете свои свойства с помощью snake_case, но вы можете изменить его на camelCase и получить доступ к своим свойствам через их «настоящее» имя.

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