【问题标题】:Making a Doctrine migration adhere to ContainerAwareInterface使 Doctrine 迁移遵循 ContainerAwareInterface
【发布时间】:2018-07-09 05:19:53
【问题描述】:

我有一个看起来像这样的 Doctrine 迁移:

<?php

namespace Application\Migrations;

use Doctrine\ORM\Mapping\PushNotification;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Doctrine\DBAL\Schema\Schema;

/**
 * Auto-generated Migration: Please modify to your needs!
 */
class Version20180123103147 extends AbstractMigration implements ContainerAwareInterface
{
    private $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    /**
     * @param Schema $schema
     */
    public function up(Schema $schema)
    {
        $em = $this->container->getDoctrine()->getManager();
        $tableName = $em->getClassMetadata('AppBundle:PushNotification')->getTableName();

        $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');

        $this->addSql('ALTER TABLE '.$tableName.' ADD COLUMN   last_offset int(11) ');
        $this->addSql('ALTER TABLE '.$tableName.' ADD COLUMN   failure_count int(11) ');
        $this->addSql('ALTER TABLE '.$tableName.' ADD COLUMN   is_sent int(11) ');
        $this->addSql('ALTER TABLE '.$tableName.' ADD COLUMN   send_date datetime ');


    }

    /**
     * @param Schema $schema
     */
    public function down(Schema $schema)
    {

        $em = $this->container->getDoctrine()->getManager();
        $tableName = $em->getClassMetadata('AppBundle:PushNotification')->getTableName();

        $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');

        $this->addSql('ALTER TABLE '.$tableName.' DROP COLUMN   last_offset ');
        $this->addSql('ALTER TABLE '.$tableName.' DROP COLUMN   failure_count ');
        $this->addSql('ALTER TABLE '.$tableName.' DROP COLUMN   is_sent ');
        $this->addSql('ALTER TABLE '.$tableName.' DROP COLUMN   send_date ');

    }
}

...在运行迁移时,我收到一条错误消息,指出 Declaration of Application\Migrations\Version20180123103147::setContainer() must be compatible with Symfony\Component\DependencyInjection\ContainerAwareInterface::setContainer(Symfony\Component\DependencyInjection\ContainerInterface $container = NULL)

这个错误似乎不合适,因为我直接从相关接口复制了方法签名。

这里有没有明显遗漏的代码?

【问题讨论】:

  • 错误是抱怨方法签名,从我看到你没有导入 ContainerInterface 因此类型不匹配

标签: php symfony doctrine database-migration


【解决方案1】:

您似乎正试图将container 注入另一个服务,这通常是非常不鼓励的。相反,您可以注入 EntityManagerInterface 并使用它。

但是,我确实看到这是一个迁移文件。在您给定的代码中没有理由为什么应该在这里,而只是像这样硬编码表名:

$this->addSql('ALTER TABLE push_notification ADD COLUMN  last_offset int(11)');

所以总结一下,您收到该错误的原因是因为迁移需要将容器的实例传递给您的迁移,但是,由于您没有将迁移注册为服务,因此永远不会发生这种情况。

(sidenote: never register a migration as a service)

【讨论】:

  • 好点在这里。注入 EntityManagerInterface 不会也涉及将迁移注册为服务吗?
  • 如摘要中所述,是的。
  • 啊——我明白你的意思了。谢谢。
  • 如果仅此而已,请随意将问题标记为“已解决”:)
  • 您不需要将迁移声明为服务,正如here所解释的那样
【解决方案2】:

我认为你错误的原因只是因为你没有放在使用部分

use Symfony\Component\DependencyInjection\ContainerInterface;

其实它和没有使用的接口不是同一个原型(不为ContainerInterface引用同一个类)

尽管如此,上一个答案的评论也是正确的!

【讨论】:

    猜你喜欢
    • 2018-08-01
    • 2014-06-13
    • 1970-01-01
    • 2023-03-18
    • 2015-07-04
    • 1970-01-01
    • 2011-08-08
    • 2020-06-28
    • 1970-01-01
    相关资源
    最近更新 更多