Я отслеживаю странную ошибку в приложении Symfony 2, и мне хотелось бы знать, есть ли способ распечатать сообщения журнала из файла PHP репозитория. Например:
class OrderEntityRepository extends EntityRepository
{
/**
*
* @param mixed $filter
* @return type
*/
public function findByCriteria($filter) {
[...]
/* I'D LIKE TO LOG SOME VARIABLES FROM HERE */
}
}
Я пробовал использовать error_log(), но ничего не получается.
Это возможно? Заранее спасибо,
Настройте службу регистратора для репозитория, а затем вызовите ее ($this->logger->info($my, $vars)). Или используйте VarDumper от dump(). Если у вас есть print_r или еще что-то и ничего не происходит, скорее всего, вам не звонят.






Это возможно, но обычно это не очень хорошая практика. Хорошо, что нужно отправить обратно результат репозитория вашему контроллеру или службе, и вы регистрируете от них ошибку или что-то еще.
Но если вы все еще хотите это сделать, репозиторий похож на службы (когда вы реализуете ServiceEntityRepositoryсм. этот слайд для получения дополнительной информации). Если вы хотите зарегистрировать что-то конкретное внутри, вам нужно ввести LoggerInterface в конфигурацию вашего репозитория (как вы это делаете с сервисом).
В вашем service.yml (или xml), если вы не используете autowire:
Your\Repository:
arguments: ['@logger']
В вашем классе репозитория:
/**
* @var LoggerInterface
*/
protected $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
Привет, я изменил файлы Resources/config/service.yml и файл класса репозитория, следуя вашим инструкциям, и получаю эту ошибку: Catchable fatal error: Argument 1 passed to Master\StoreBundle\Entity\Repository\OrderEntityRepository::__construct() must be an instance of Master\StoreBundle\Entity\Repository\LoggerInterface, instance of Doctrine\ORM\EntityManager given. Нужно ли мне что-то менять, чтобы это работало?
@Fel Основная проблема заключается в том, что исходный вопрос не дает понять, что вы используете репозиторий Doctrine. Так что этот ответ менее полезен. Просто посмотрите, как использовать фабрику для создания службы репозитория и как использовать сеттеры для внедрения регистратора.
@Cerad Я прочитал комментарий, который вы оставили к моему сообщению, но вы решили его удалить, но мне очень интересно, что вы сказали на мой вопрос выше. Это потому, что если я что-то пропущу, я хотел бы знать. Спасибо
Спасибо всем за комментарии. Я не мог заставить его работать, но я нашел обходной путь, используя echo и распечатывая то, что мне нужно, в вывод HTML. Это не решает вопрос, но я продолжу исследовать и обновлю его, когда найду что-нибудь актуальное.
На symfony 3.8 у меня есть
class BlahRepository extends ServiceEntityRepository
{
/* @var ContainerInterface $container */
private $container;
/* @var LoggerInterface $logger */
private $logger;
public function __construct(RegistryInterface $registry, ContainerInterface $container, LoggerInterface $logger)
{
parent::__construct($registry, Blah::class);
$this->container = $container;
$this->logger = $logger;
}
}
и я могу использовать $this->logger->info("text")
Я думаю, что уловка может заключаться в расширении ServiceEntityRepository
Чтобы использовать внедрение зависимостей для репозиториев сущностей Doctrine, вы можете создать собственный RepositoryFactory.
Проверено на Symfony 3.4.
<?php
namespace AppBundle\Doctrine;
use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
use Doctrine\ORM\Repository\RepositoryFactory as RepositoryFactoryInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
class RepositoryFactory implements RepositoryFactoryInterface, LoggerAwareInterface
{
/** @var DefaultRepositoryFactory */
protected $defaultRepositoryFactory;
/** @var LoggerInterface */
private $logger;
/**
* @required (for autowiring)
* @param LoggerInterface $logger (Monolog will be the default one)
*/
public function setLogger(LoggerInterface $logger): void
{
$this->logger = $logger;
}
/**
* @see Configuration::getRepositoryFactory()
*/
public function __construct()
{
$this->defaultRepositoryFactory = new DefaultRepositoryFactory();
}
/**
* Gets the repository for an entity class.
*
* @param EntityManagerInterface $entityManager
* @param string $entityName The name of the entity.
* @return ObjectRepository
*/
public function getRepository(EntityManagerInterface $entityManager, $entityName): ObjectRepository
{
$repository = $this->defaultRepositoryFactory->getRepository($entityManager, $entityName);
if ($repository instanceof LoggerAwareInterface && $this->logger !== null) {
$repository->setLogger($this->logger);
}
return $repository;
}
}
Объявите это в конфигурации Doctrine.
# app/config.yml
doctrine:
# ...
orm:
repository_factory: AppBundle\Doctrine\RepositoryFactory
И, наконец, сделайте так, чтобы ваш класс репозитория реализовал LoggerAwareInterface.
class OrderEntityRepository extends EntityRepository implements LoggerAwareInterface
{
/** @var LoggerInterface */
private $logger;
/**
* @param LoggerInterface $logger
*/
public function setLogger(LoggerInterface $logger): void
{
$this->logger = $logger;
}
/**
* @param mixed $filter
* @return type
*/
public function findByCriteria($filter) {
//[...]
$this->logger->alert('message');
}
}
Вы также можете создать черту LoggerAwareTrait, чтобы избежать дублирования кода.
Я не уверен, но вы хотели бы попробовать PHPUnit