У меня есть конструктор и маршрут в моем настраиваемом 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;
}
}
Спасибо.
Ага, только что добавил. Спасибо.






Просто используйте в своем шаблоне веточки:
{{ 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.
Хороший совет по поводу змеиного дела, спасибо. Погодите, значит, я должен использовать в своей ветке методы, а не переменные?
Если вы используете такую переменную, как my_variable yes, легче получить доступ к подобному значению, потому что вам придется использовать странное имя для ваших геттеров / сеттеров для доступа к этому частному свойству в Twig. Или используйте переменную вроде myVariable
Я не думаю, что вам следует встраивать 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, я подумал, что начиная с Symfony 3.3 вы должны использовать инъекцию зависимостей. Я ошибся?
Да, это то, что он делает с подсказками типа услуги. Он вставляет службу в конструктор контроллера, чтобы ее можно было использовать.
@Franck Gamess прав, но вы также можете избавиться от get.
Если вы напишете {{ user.firstName }}, twig автоматически свяжет это с вашим методом getFirstName().
Я не знаю, почему вы пишете свои свойства с помощью snake_case, но вы можете изменить его на camelCase и получить доступ к своим свойствам через их «настоящее» имя.
Можете ли вы показать свою сущность пользователя?