Symfony既指用于构建Web应用程序的PHP框架,也指构建框架的一组组件。此标记指的是当前支持的主要版本2.x,3.x和4.x.或者,您可以使用相应的标记指定确切的版本。此标记不应用于有关Symfony 1.x的问题。请改用Symfony1标签。
Symfony 测试我的命令需要将参数传递给构造函数。为什么?
交响乐 6 教义3 php单元 我的原始命令正在正常运行。没什么特别的。现在我想写一个测试用例。但我得到的只是: 运行: php bin/phpunittests/Command/
我正在尝试在运行 phpunit 测试时从 php 代码运行固定命令。 最终出现以下错误: Symfony\Component\Console\Exception\CommandNotFoundException] 没有
假设我有一个父实体: #[ORM\Entity(repositoryClass: EventRepository::class)] 事件实体类 { ... #[ORM\ManyToOne(targetEntity: EventStatusEntity::class)] #[ORM\JoinColumn...
我正在为 Laravel 集成 Azure 通信服务电子邮件,当然我已经创建了帐户、添加了域、验证了 SPF 和 DKIM,在此添加到我的配置/se 中之后...
我不明白为什么某些约束在验证后不会在错误消息中插入属性名称。我有这个实体类: 我不明白为什么某些约束在验证后不会在错误消息中插入属性名称。我有这个实体类: <?php namespace AC\OperaBundle\Entity; use Doctrine\ORM\Mapping as ORM; use AC\UserBundle\Entity\Utente; use Symfony\Component\Validator\Constraints as Assert; /** * Class Episodio * @package AC\OperaBundle\Entity * @ORM\Entity(repositoryClass="AC\OperaBundle\Repository\EpisodioRepository") * * @ORM\Table( * name="ac_Episodio", * uniqueConstraints={@ORM\UniqueConstraint(name="unique_idx", columns={"opera", "numero_episodio", "extra"})}, * indexes={ @ORM\Index(name="opera_idx", columns={"opera"}), * @ORM\Index(name="numero_episodio_idx", columns={"numero_episodio"}), * @ORM\Index(name="extra_idx", columns={"extra"}), * @ORM\Index(name="attivo_idx", columns={"attivo"}) }) */ class Episodio { /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @var Opera * * @ORM\ManyToOne(targetEntity="AC\OperaBundle\Entity\Opera", inversedBy="episodi") * @ORM\JoinColumn(name="opera", referencedColumnName="id", nullable=false) */ protected $opera; /** * @var string * * @ORM\Column(name="numero_episodio", type="string", length=5, nullable=false) */ protected $numero_episodio; /** * @var string * * @ORM\Column(name="extra", type="string", length=30, nullable=false) */ protected $extra; /** * @var string * * @ORM\Column(name="titolo_italiano", type="string", length=150, nullable=false) * @Assert\NotBlank() */ protected $titolo_italiano; /** * @var string * * @ORM\Column(name="titolo_originale", type="string", length=150, nullable=false) * @Assert\NotBlank() */ protected $titolo_originale; /** * @var \DateTime * * @ORM\Column(name="data_ita", type="date", nullable=true) * @Assert\Date() */ protected $data_ita; /** * @var \DateTime * * @ORM\Column(name="data_jap", type="date", nullable=true) * @Assert\Date() */ protected $data_jap; /** * @var int * * @ORM\Column(name="durata", type="smallint", nullable=false, options={"default" = 0}) */ protected $durata; /** * @var string * * @ORM\Column(name="trama", type="text", nullable=false) */ protected $trama; /** * @var int * * @ORM\Column(name="ordine", type="smallint", nullable=false, options={"default" = 0}) */ protected $ordine; /** * @var int * * @ORM\Column(name="promosso", type="integer", nullable=false, options={"default" = 0}) */ protected $promosso; /** * @var int * * @ORM\Column(name="rimandato", type="integer", nullable=false, options={"default" = 0}) */ protected $rimandato; /** * @var int * * @ORM\Column(name="bocciato", type="integer", nullable=false, options={"default" = 0}) */ protected $bocciato; /** * @var boolean * * @ORM\Column(name="fansub", type="boolean", nullable=false) */ protected $fansub; /** * @var boolean * * @ORM\Column(name="attivo", type="boolean", nullable=false) */ protected $attivo; /** * @var \DateTime * * @ORM\Column(name="data_aggiornamento", type="date") */ protected $data_aggiornamento; /** * @var Utente * * @ORM\ManyToOne(targetEntity="AC\UserBundle\Entity\Utente") * @ORM\JoinColumn(name="utente_aggiornamento", referencedColumnName="id", nullable=true) */ protected $utente_aggiornamento; /** * @param boolean $attivo */ public function setAttivo($attivo) { $this->attivo = $attivo; } /** * @return boolean */ public function getAttivo() { return $this->attivo; } /** * @param int $bocciato */ public function setBocciato($bocciato) { $this->bocciato = $bocciato; } /** * @return int */ public function getBocciato() { return $this->bocciato; } /** * @param \DateTime $data_aggiornamento */ public function setDataAggiornamento($data_aggiornamento) { $this->data_aggiornamento = $data_aggiornamento; } /** * @return \DateTime */ public function getDataAggiornamento() { return $this->data_aggiornamento; } /** * @param \DateTime $data_ita */ public function setDataIta($data_ita) { $this->data_ita = $data_ita; } /** * @return \DateTime */ public function getDataIta() { return $this->data_ita; } /** * @param \DateTime $data_jap */ public function setDataJap($data_jap) { $this->data_jap = $data_jap; } /** * @return \DateTime */ public function getDataJap() { return $this->data_jap; } /** * @param int $durata */ public function setDurata($durata) { $this->durata = $durata; } /** * @return int */ public function getDurata() { return $this->durata; } /** * @param string $extra */ public function setExtra($extra) { $this->extra = $extra; } /** * @return string */ public function getExtra() { return $this->extra; } /** * @param boolean $fansub */ public function setFansub($fansub) { $this->fansub = $fansub; } /** * @return boolean */ public function getFansub() { return $this->fansub; } /** * @param int $id */ public function setId($id) { $this->id = $id; } /** * @return int */ public function getId() { return $this->id; } /** * @param string $numero_episodio */ public function setNumeroEpisodio($numero_episodio) { $this->numero_episodio = $numero_episodio; } /** * @return string */ public function getNumeroEpisodio() { return $this->numero_episodio; } /** * @param \AC\OperaBundle\Entity\Opera $opera */ public function setOpera($opera) { $this->opera = $opera; } /** * @return \AC\OperaBundle\Entity\Opera */ public function getOpera() { return $this->opera; } /** * @param int $ordine */ public function setOrdine($ordine) { $this->ordine = $ordine; } /** * @return int */ public function getOrdine() { return $this->ordine; } /** * @param int $promosso */ public function setPromosso($promosso) { $this->promosso = $promosso; } /** * @return int */ public function getPromosso() { return $this->promosso; } /** * @param int $rimandato */ public function setRimandato($rimandato) { $this->rimandato = $rimandato; } /** * @return int */ public function getRimandato() { return $this->rimandato; } /** * @param string $titolo_italiano */ public function setTitoloItaliano($titolo_italiano) { $this->titolo_italiano = $titolo_italiano; } /** * @return string */ public function getTitoloItaliano() { return $this->titolo_italiano; } /** * @param string $titolo_originale */ public function setTitoloOriginale($titolo_originale) { $this->titolo_originale = $titolo_originale; } /** * @return string */ public function getTitoloOriginale() { return $this->titolo_originale; } /** * @param string $trama */ public function setTrama($trama) { $this->trama = $trama; } /** * @return string */ public function getTrama() { return $this->trama; } /** * @param \AC\UserBundle\Entity\Utente $utente_aggiornamento */ public function setUtenteAggiornamento($utente_aggiornamento) { $this->utente_aggiornamento = $utente_aggiornamento; } /** * @return \AC\UserBundle\Entity\Utente */ public function getUtenteAggiornamento() { return $this->utente_aggiornamento; } } 在控制器中,在 $form->isValid() 方法中执行 classi 调用以检查验证。如果出现错误,我会致电 $form->getErrorsAsString(),结果如下: ERROR: This value should not be blank. ERROR: This value should not be blank. numeroEpisodio: No errors titoloItaliano: No errors titoloOriginale: No errors dataIta: ERROR: This value is not valid. dataJap: ERROR: This value is not valid. durata: No errors trama: No errors extra: No errors fansub: No errors 使用@Assert\NotBlank()的属性不要将属性名称放入错误消息中!因此,我有前两个错误行与 e generic: ERROR: This value should not be blank. ERROR: This value should not be blank. 我不知道验证失败的属性是谁。我查看了 Symfony 组件的源代码,发现非空白约束: /** * @author Bernhard Schussek <[email protected]> * * @api */ class NotBlankValidator extends ConstraintValidator { /** * {@inheritdoc} */ public function validate($value, Constraint $constraint) { if (!$constraint instanceof NotBlank) { throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\NotBlank'); } if (false === $value || (empty($value) && '0' != $value)) { $this->context->addViolation($constraint->message); } } } 对于数据约束: /** * @author Bernhard Schussek <[email protected]> * * @api */ class DateValidator extends ConstraintValidator { const PATTERN = '/^(\d{4})-(\d{2})-(\d{2})$/'; /** * {@inheritdoc} */ public function validate($value, Constraint $constraint) { if (!$constraint instanceof Date) { throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Date'); } if (null === $value || '' === $value || $value instanceof \DateTime) { return; } if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) { throw new UnexpectedTypeException($value, 'string'); } $value = (string) $value; if (!preg_match(static::PATTERN, $value, $matches) || !checkdate($matches[2], $matches[3], $matches[1])) { $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); } } } 重要的区别是 $this->context->addViolation($constraint->message); VS $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); 为什么? 这是控制器的核心部分 if ($request->getMethod() == 'POST') { try { $form->handleRequest($request); if ($form->isValid()) { /* @var $item Episodio */ $item = $form->getData(); $em->persist($item); $em->flush(); $msg = new Message(true, Message::OK_MESSAGE); } else { $msg = new Message(false, Message::KO_MESSAGE); $errors = Utility::getErrorMessages($form); $msg->setData($errors); } } catch (\Exception $ex) { $msg = new Message(false, $ex->getMessage()); } return new Response($this->get('jms_serializer')->serialize($msg, 'json')); } 这是从表单获取错误的实用程序类 class Utility { static function getErrorMessages(\Symfony\Component\Form\Form $form) { $errors = array(); foreach ($form->getErrors() as $key => $error) { $template = $error->getMessageTemplate(); $parameters = $error->getMessageParameters(); foreach($parameters as $var => $value){ $template = str_replace($var, $value, $template); } $errors[$key] = $template; } //if ($form->hasChildren()) { foreach ($form->all() as $child) { if (!$child->isValid()) { $errors[$child->getName()] = Utility::getErrorMessages($child); } } //} return $errors; } } 表格类 class EpisodioForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('numeroEpisodio', 'text'); $builder->add('titoloItaliano', 'text',array()); $builder->add('titoloOriginale', 'text'); $builder->add('dataIta', 'date', array('widget' => 'single_text', 'format' => 'dd/MM/yyyy')); $builder->add('dataJap', 'date', array('widget' => 'single_text', 'format' => 'dd/MM/yyyy')); $builder->add('durata', 'text'); $builder->add('trama', 'textarea'); $builder->add('extra', 'text'); $builder->add('fansub', 'checkbox'); } /** * Returns the name of this type. * * @return string The name of this type */ public function getName() { return "episodio_form"; } } 框架版本是Symfony 2.4 为什么$this->context->addViolation($constraint->message); VS $this->context->addViolation($constraint->message, array('{{ value }}' => $value));? 这是因为日期约束验证器在错误消息中显示了验证失败的值,例如 45.04.2014 is not a valid date. 而 NotBlank 约束验证器则不需要,因为导致错误的值始终为空。 将属性名称放入错误消息中 这可以实现: 将实体中约束的注释更改为: class Episodio { /** * @Assert\NotBlank(message="'titolo_italiano' should not be blank.") */ protected $titolo_italiano; /** * @Assert\NotBlank(message="'titolo_originale' should not be blank.") */ protected $titolo_originale; } 为了便于阅读,我省略了实体中的列定义和其他字段。 或者通过定义自定义验证器将属性名称传递给错误消息: 约束: class MyCustomNotBlank extends NotBlank { public $message = "'{{ propertyName }}' should not be blank."; } 验证者: use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; class MyCustomNotBlankValidator extends ConstraintValidator { public function validate($value, Constraint $constraint) { if (!$value) { $this->context->addViolation( $constraint->message, array('{{ propertyName}}' => $this->context->getPropertyPath()) ); } } } 这向您展示了如何定义自定义验证约束: http://symfony.com/doc/current/cookbook/validation/custom_constraint.html 获取带有属性名称和错误消息的键值数组 Afaik,Symfony2 的表单组件中没有函数可以做到这一点,所以必须实现它。 请参阅https://stackoverflow.com/a/13763053/277106。您可以将该函数添加到服务中以实现可重用性。在您的 (AJAX) 控制器中您可以执行以下操作: public function someAction(Request $request) { $errors = array(); $form = $this->createForm(new MyType); if (!$form->bindRequest($request)->isValid()) { $errors = $this->myFormService->getErrorMessages($form); } else { // save the entity } return JsonResponse($errors); }
如何对 symfony/console 应用程序命令进行单元测试?
我仅使用 symfony/console 库来创建一个小型 cli 应用程序。 我想按原样对命令进行单元测试,但单元测试没有提供输出。 这是我的单元测试设置: 班级
我面临着一个非常烦人的问题。我有一个 Recipe 实体,其中包含一些具有多对多关系的成分(带有一个 Ingredient 实体)和一个用于映射的 RecipeIngredient 实体。 ...
大家好,当我更改树枝视图中的某些内容并再次发送电子邮件时,我的电子邮件模板出现问题,我始终处于第一个视图状态,我不知道为什么更改没有保存。 我我们...
使用 api 平台为 Symfony 自定义控制器生成 OpenAPI
我刚刚开始使用 Symfony (7.1) 并创建了一个控制器。 现在我想为控制器端点生成 OpenAPI 描述,我已经找到了 api_platform (4.0)。 (https://api-
我在正确安排服务方面遇到了问题。我想创建一个生成器,感谢提供者,它将通过工厂方法创建相应的生成器对象。在我的m...
在我使用 Doctrine ORM 2.7.0 的 Symfony 4 应用程序中,我得到了一个实体产品,它是外部包/系统(Akeneo 5)的一部分,我不能只是修改。由于我需要向其中添加属性(股票),所以我...
请帮助我,因为我不敢相信自己的眼睛。 我拒绝使用某些第三方插件进行文件上传,并拒绝为文件/文档创建单独的实体。我只想要简单的文件...
我花了几个小时浏览独白文档..但我只是无法弄清楚这个基本问题:独白中如何定义通道?我得到了这个 symfony2 项目,其中有这个...
这是我的控制器 公共函数index2Action($name) { $em = $this->getDoctrine()->getEntityManager(); $test = $em->getRepository('RestWebServiceBundle:Test')->findall(...
我正在运行 symfony 6 服务器/php 8.0.8,google ads api V22.0.0。获得了开发令牌/刷新令牌以及所有其他信息,并且无法运行来自谷歌的简单示例,我不确定我做错了什么。哈...
在我的 Symfony 5 项目中,我需要有两个不同的 AWS_S3 配置。 我到目前为止所做的步骤: 创建了扩展基类文件系统的“NewFileSystem”类。 在我的 Symfony 5 项目中,我需要有两个不同的 AWS_S3 配置。 我到目前为止所做的步骤: 创建了扩展基类 FileSystem 的类“NewFileSystem”。 <?php namespace App\Factory; use League\Flysystem\Filesystem; class NewFileSystem extends Filesystem { } 在 services.yaml 中添加配置 services: usr_data.s3_client: class: Aws\S3\S3Client arguments: - version: 'latest' region: "%env(AWS_S3_REGION)%" credentials: key: "%env(AWS_S3_KEY)%" secret: "%env(AWS_S3_SECRET)%" usr_data.s3_legacy_client: class: Aws\S3\S3Client arguments: - version: 'latest' region: "%env(AWS_S3_LEGACY_REGION)%" credentials: key: "%env(AWS_S3_LEGACY_KEY)%" secret: "%env(AWS_S3_LEGACY_SECRET)%" League\Flysystem\Filesystem: "@oneup_flysystem.s3_filesystem_filesystem" App\Factory\NewFileSystem: "@oneup_flysystem.s3_legacy_filesystem" 在oneup_flysystem.yaml中添加配置 oneup_flysystem: adapters: default_adapter: local: directory: '%kernel.root_dir%/../data/invoice-attachment' tutorial_adapter: local: directory: '%kernel.root_dir%/../public/assets/tutorial' permissions_adapter: local: directory: '%kernel.root_dir%/../public/assets/permissions' images_adapter: local: directory: '%kernel.root_dir%/../public/assets/images' awsS3_adapter_usr_data: awss3v3: client: usr_data.s3_client bucket: "%env(AWS_S3_UPLOAD_BUCKET)%" prefix: ~ awsS3_legacy_usr_data: awss3v3: client: usr_data.s3_legacy_client bucket: "%env(AWS_S3_LEGACY_UPLOAD_BUCKET)%" prefix: ~ filesystems: default_filesystem: adapter: default_adapter alias: my_filesystem tutorial_filesystem: adapter: tutorial_adapter permissions_filesystem: adapter: permissions_adapter images_filesystem: adapter: images_adapter s3_filesystem: adapter: awsS3_adapter_usr_data alias: League\Flysystem\Filesystem s3_legacy: adapter: awsS3_legacy_usr_data alias: App\Factory\NewFileSystem 通过控制器中的依赖注入来注入新类 public function createAction(Request $request, NewFileSystem $fileSystem): BaseOutput { dd($fileSystem); } 我有以下错误。 参数 2 传递给 应用\控制器\Api\迁移\ProcessController::createAction() 必须是 App\Factory\NewFileSystem 的实例, 给出联盟\Flysystem\文件系统 为什么系统不想注入类“NewFileSystem”。 我还应该配置什么才能拥有具有不同 s3 配置的新类。 谢谢你。 我认为你尝试将文件系统注入控制器的方式有点混乱。 根据 TheLeague 文档 以及 OneUp 文档,并假设您使用自动装配: 你的服务定义应该改为: oneup_flysystem: adapters: default_adapter: local: directory: '%kernel.root_dir%/../data/invoice-attachment' tutorial_adapter: local: directory: '%kernel.root_dir%/../public/assets/tutorial' permissions_adapter: local: directory: '%kernel.root_dir%/../public/assets/permissions' images_adapter: local: directory: '%kernel.root_dir%/../public/assets/images' awsS3_adapter_usr_data: awss3v3: client: usr_data.s3_client bucket: "%env(AWS_S3_UPLOAD_BUCKET)%" prefix: ~ awsS3_legacy_usr_data: awss3v3: client: usr_data.s3_legacy_client bucket: "%env(AWS_S3_LEGACY_UPLOAD_BUCKET)%" prefix: ~ filesystems: default_filesystem: adapter: default_adapter alias: my_filesystem tutorial_filesystem: adapter: tutorial_adapter permissions_filesystem: adapter: permissions_adapter images_filesystem: adapter: images_adapter s3_filesystem: adapter: awsS3_adapter_usr_data alias: League\Flysystem\Filesystem s3_legacy: adapter: awsS3_legacy_usr_data # mind the change here <<<<<<<<<<<<<< alias: s3_legacy_filesystem 你的控制器的代码应该如下所示: use League\Flysystem\FilesystemOperator; { //... // The variable name $s3LegacyFilesystem matters public function createAction(Request $request, FilesystemOperator $s3LegacyFilesystem) { // ... } } 现在您不再需要整个 NewFileSystem 类。
我在 Symfony 2.4 项目中有一个 Util 类,可以从书中获取 slug。 slug 不能重复。每个蛞蝓必须是唯一的。我有以下代码形成生成 slug 的类。我...
Symfony Doctrine Fixture 意外的空值
我无法弄清楚为什么此代码发送空值而不是对另一个对象实体/记录的实际引用。这是我在生成灯具时在控制台中收到的消息: 有人吗
当我使用 symfony 6.4 序列化器 6.4.11 时,有些事情很奇怪。我的序列化日期用双引号引起来...我怀疑该值编码了两次,但为什么? 这是代码: $tmp = $值->
有没有办法找出 Symfony Mailer 发送电子邮件后使用的传输方式?
我正在尝试找到一种方法来确定邮件程序发送消息后使用哪种传输来发送消息。 我的 Symfony 配置在 config/packages/mailer.yaml 中定义了 3 个传输: 邮寄者: ...