PHP从5.6.30升级到7.0.20后,Symfony 2.8上复杂表单的SQL问题

时间:2017-06-16 23:01:08

标签: symfony symfony-2.8

我在Symfony 2.8中使用PHP 5.6成功使用了一个应用程序。在我升级到PHP 7.0.20之后,我遇到了使用一对多关系绑定/提交复杂表单的问题。

产生的错误是:

  

request.CRITICAL:未捕获的PHP异常   Doctrine \ ORM \ Query \ QueryException:“[语法错误]第0行,第63栏:   错误:预期文字,得到'订购'   .... / Symfony的/供应商/教义/ ORM / LIB /学说/ ORM /查询/ QueryException.php   第44行{“例外”:“[对象]   (Doctrine \ ORM \ Query \ QueryException(代码:0):[语法错误]第0行,   第63栏:错误:预期文字,得到'订购'   .... / Symfony的/供应商/教义/ ORM / LIB /学说/ ORM /查询/ QueryException.php:44,   Doctrine \ ORM \ Query \ QueryException(代码:0):SELECT s1 FROM   Prfuk \ WebquotaBundle \ Entity \ Workplace s1在哪里订购s1.nazev   ASC在   .... / Symfony的/供应商/教义/ ORM / LIB /学说/ ORM /查询/ QueryException.php:39)“}   []

WHEREORDER BY之间缺少部分。奇怪的是列表数据是好的,填充表单字段来编辑记录也是好的,问题只是在将POST请求与当前表单数据合并时,我认为SQL中缺少部分是由学说产生的。

与其他表没有关系的简单表单可以正常工作。

我正在使用最新的2.8.x Symfony版本,我能够通过composer更新的最新版本是2.3.6-dev,这是相当古老的,但它似乎是最新的支持/兼容。

这是一个已知问题吗? Symfony 2.8与PHP 7.0兼容吗? 你能给我一些关于如何解决这个问题的建议吗?

我的表格类型:

$qb = array(
    'class' => 'Prfuk\\WebquotaBundle\\Entity\\Workplace',
    'property' => 'nazev',
    'query_builder' => function(\Prfuk\WebquotaBundle\Entity\WorkplaceRepository $repository) {
        return $repository
            ->createQueryBuilder('s1')
            ->add('orderBy', 's1.nazev ASC');
    },
    'attr' => array(
        "class" => "input_text_nazev"),
        'label' => "Pracoviště",
    );
$builder->add('pracoviste', 'entity', $qb);

我的控制器:

$form = $this->createForm(new FolderType($this->getDoctrine()->getEntityManager()), $folder);
if ($request->isMethod('POST')) {
    //print_r($form->getData()); // works here
    $form->bind($request); // throws an exception

ORM:

Prfuk\WebquotaBundle\Entity\Folder:
    type: entity
    table: null
    repositoryClass: Prfuk\WebquotaBundle\Entity\FolderRepository
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
        nazev:
            type: string
            length: '255'
        cesta:
            type: string
            length: '255'
        kvota:
            type: integer
        uzivatel:
            type: string
            length: '255'
        poznamka:
            type: text
        vyuziti_mb:
            type: integer
            options:
                default: 0
    manyToOne:
        pracoviste:
            targetEntity: Workplace
            inversedBy: pracoviste
            joinColumn:
                name: pracoviste
                referencedColumnName: id
        db:
            targetEntity: DatabaseInfo
            inversedBy: db
            joinColumn:
                name: db
                referencedColumnName: id
        skupina:
            targetEntity: GroupInfo
            inversedBy: skupina
            joinColumn:
                name: skupina
                referencedColumnName: id
        webhost:
            targetEntity: WebhostInfo
            inversedBy: webhost
            joinColumn:
                name: webhost
                referencedColumnName: id
    lifecycleCallbacks: {  }

编辑:stacktrace(文件路径已编辑):

[1] Doctrine\ORM\Query\QueryException: [Syntax Error] line 0, col 63: Error: Expected Literal, got 'ORDER'
    at n/a
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php line 44

    at Doctrine\ORM\Query\QueryException::syntaxError('line 0, col 63: Error: Expected Literal, got 'ORDER'', object(QueryException))
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 396

    at Doctrine\ORM\Query\Parser->syntaxError('Literal')
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2363

    at Doctrine\ORM\Query\Parser->Literal()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2550

    at Doctrine\ORM\Query\Parser->ArithmeticPrimary()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2485

    at Doctrine\ORM\Query\Parser->ArithmeticFactor()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2453

    at Doctrine\ORM\Query\Parser->ArithmeticTerm()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2427

    at Doctrine\ORM\Query\Parser->SimpleArithmeticExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2414

    at Doctrine\ORM\Query\Parser->ArithmeticExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2749

    at Doctrine\ORM\Query\Parser->ComparisonExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2277

    at Doctrine\ORM\Query\Parser->SimpleConditionalExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2177

    at Doctrine\ORM\Query\Parser->ConditionalPrimary()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2153

    at Doctrine\ORM\Query\Parser->ConditionalFactor()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2121

    at Doctrine\ORM\Query\Parser->ConditionalTerm()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2096

    at Doctrine\ORM\Query\Parser->ConditionalExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 1209

    at Doctrine\ORM\Query\Parser->WhereClause()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 759

    at Doctrine\ORM\Query\Parser->SelectStatement()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 726

    at Doctrine\ORM\Query\Parser->QueryLanguage()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 229

    at Doctrine\ORM\Query\Parser->getAST()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 304

    at Doctrine\ORM\Query\Parser->parse()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php line 233

    at Doctrine\ORM\Query->_parse()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php line 245

    at Doctrine\ORM\Query->_doExecute()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php line 753

    at Doctrine\ORM\AbstractQuery->execute(null, '1')
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php line 542

    at Doctrine\ORM\AbstractQuery->getResult()
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php line 126

    at Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader->getEntitiesByIds('id', array('27'))
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php line 153

    at Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader->loadChoicesForValues(array('27'), array(object(IdReader), 'getIdValue'))
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/ChoiceList/LazyChoiceList.php line 122

    at Symfony\Component\Form\ChoiceList\LazyChoiceList->getChoicesForValues(array('27'))
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php line 46

    at Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer->reverseTransform('27')
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 1190

    at Symfony\Component\Form\Form->viewToNorm('27')
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 639

    at Symfony\Component\Form\Form->submit('27', true)
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 579

    at Symfony\Component\Form\Form->submit(array('pracoviste' => '27', 'cesta' => 'simonju_botazah', 'kvota' => '100', 'uzivatel' => 'simonju', 'skupina' => '', 'poznamka' => 'fake záznam pro člena skupiny www-botazah', 'db' => '', 'webhost' => '', 'vyuziti_mb' => '0'))
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 692

    at Symfony\Component\Form\Form->bind(object(Request))
        in /..../Symfony/src/Prfuk/WebquotaBundle/Controller/FolderController.php line 90

    at Prfuk\WebquotaBundle\Controller\FolderController->editAction(object(Request), '650')
        in  line 

    at call_user_func_array(array(object(FolderController), 'editAction'), array(object(Request), '650'))
        in /..../Symfony/app/bootstrap.php.cache line 3247

    at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
        in /..../Symfony/app/bootstrap.php.cache line 3206

    at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
        in /..../Symfony/app/bootstrap.php.cache line 3360

    at Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(object(Request), '1', true)
        in /..../Symfony/app/bootstrap.php.cache line 2562

    at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
        in /..../Symfony/web/app_dev.php line 28

[2] Doctrine\ORM\Query\QueryException: SELECT s1 FROM Prfuk\WebquotaBundle\Entity\Workplace s1 WHERE  ORDER BY s1.nazev ASC
    at n/a
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php line 39

    at Doctrine\ORM\Query\QueryException::dqlError('SELECT s1 FROM Prfuk\WebquotaBundle\Entity\Workplace s1 WHERE  ORDER BY s1.nazev ASC')
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 396

    at Doctrine\ORM\Query\Parser->syntaxError('Literal')
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2363

    at Doctrine\ORM\Query\Parser->Literal()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2550

    at Doctrine\ORM\Query\Parser->ArithmeticPrimary()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2485

    at Doctrine\ORM\Query\Parser->ArithmeticFactor()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2453

    at Doctrine\ORM\Query\Parser->ArithmeticTerm()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2427

    at Doctrine\ORM\Query\Parser->SimpleArithmeticExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2414

    at Doctrine\ORM\Query\Parser->ArithmeticExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2749

    at Doctrine\ORM\Query\Parser->ComparisonExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2277

    at Doctrine\ORM\Query\Parser->SimpleConditionalExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2177

    at Doctrine\ORM\Query\Parser->ConditionalPrimary()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2153

    at Doctrine\ORM\Query\Parser->ConditionalFactor()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2121

    at Doctrine\ORM\Query\Parser->ConditionalTerm()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 2096

    at Doctrine\ORM\Query\Parser->ConditionalExpression()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 1209

    at Doctrine\ORM\Query\Parser->WhereClause()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 759

    at Doctrine\ORM\Query\Parser->SelectStatement()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 726

    at Doctrine\ORM\Query\Parser->QueryLanguage()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 229

    at Doctrine\ORM\Query\Parser->getAST()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php line 304

    at Doctrine\ORM\Query\Parser->parse()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php line 233

    at Doctrine\ORM\Query->_parse()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Query.php line 245

    at Doctrine\ORM\Query->_doExecute()
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php line 753

    at Doctrine\ORM\AbstractQuery->execute(null, '1')
        in /..../Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php line 542

    at Doctrine\ORM\AbstractQuery->getResult()
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php line 126

    at Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader->getEntitiesByIds('id', array('27'))
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php line 153

    at Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader->loadChoicesForValues(array('27'), array(object(IdReader), 'getIdValue'))
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/ChoiceList/LazyChoiceList.php line 122

    at Symfony\Component\Form\ChoiceList\LazyChoiceList->getChoicesForValues(array('27'))
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php line 46

    at Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer->reverseTransform('27')
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 1190

    at Symfony\Component\Form\Form->viewToNorm('27')
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 639

    at Symfony\Component\Form\Form->submit('27', true)
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 579

    at Symfony\Component\Form\Form->submit(array('pracoviste' => '27', 'cesta' => 'simonju_botazah', 'kvota' => '100', 'uzivatel' => 'simonju', 'skupina' => '', 'poznamka' => 'fake záznam pro člena skupiny www-botazah', 'db' => '', 'webhost' => '', 'vyuziti_mb' => '0'))
        in /..../Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 692

    at Symfony\Component\Form\Form->bind(object(Request))
        in /..../Symfony/src/Prfuk/WebquotaBundle/Controller/FolderController.php line 90

    at Prfuk\WebquotaBundle\Controller\FolderController->editAction(object(Request), '650')
        in  line 

    at call_user_func_array(array(object(FolderController), 'editAction'), array(object(Request), '650'))
        in /..../Symfony/app/bootstrap.php.cache line 3247

    at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
        in /..../Symfony/app/bootstrap.php.cache line 3206

    at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
        in /..../Symfony/app/bootstrap.php.cache line 3360

    at Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(object(Request), '1', true)
        in /..../Symfony/app/bootstrap.php.cache line 2562

    at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
        in /..../Symfony/web/app_dev.php line 28

2 个答案:

答案 0 :(得分:1)

我终于解决了这个问题:

  1. 旧的学说包(2.3.x)由于某种原因在2月份我将Symfony升级到2.8时没有更新(只要作曲家很开心,我甚至都不知道)。

    < / LI>
  2. 在app_dev.php生成的backtrace的帮助下,我将错误缩小到Symfony / vendor / doctrine / orm / lib / Doctrine / ORM / QueryBuilder.php的andWhere()方法:

    public function andWhere($where)
    {
        $where = $this->getDQLPart('where');
        $args  = func_get_args();
        if ($where instanceof Expr\Andx) {
            $where->addMultiple($args);
        } else {
            array_unshift($args, $where);
            $where = new Expr\Andx($args);
        }
        return $this->add('where', $where, true);
    }
    
  3. 自PHP 7.0.0起,func_get_args()的行为发生了变化:

      

    此函数仅返回传递的参数的副本,并且确实如此   不考虑默认(未通过)参数。

         

    如果参数通过引用传递,则对参数进行任何更改   将反映在此函数返回的值中。从PHP 7开始   如果传递参数,也将返回当前值   按价值。

    短期解决方案是在此方法中交换前两行代码。但是代码中有更多的地方使用相同的逻辑模式,所以我必须找到一种方法来升级教条。

    1. 升级学说对我来说是一项艰巨的任务,但我成功了。这是我现在拥有的最终composer.json:

      {
          "name": "symfony/framework-standard-edition",
          "license": "MIT",
          "type": "project",
          "description": "The \"Symfony Standard Edition\" distribution",
          "autoload": {
              "psr-0": { "": "src/" }
          },
          "require": {
              "php": ">=5.3.9",
              "symfony/symfony": "2.8.*",
              "doctrine/common": "2.5.*",
              "doctrine/dbal": "2.5.*",
              "doctrine/orm": "~2.5.0",
              "doctrine/doctrine-bundle": "~1.4.0",
              "twig/extensions": "1.0.*",
              "symfony/assetic-bundle": "2.3.*",
              "symfony/swiftmailer-bundle": "2.3.*",
              "symfony/monolog-bundle": "2.3.*",
              "sensio/distribution-bundle": "4.0.*",
              "sensio/framework-extra-bundle": "3.0.*",
              "sensio/generator-bundle": "2.4.*",
              "jms/security-extra-bundle": "1.6.*",
              "jms/di-extra-bundle": "1.4.*",
              "incenteev/composer-parameter-handler": "~2.0"
          },
          "minimum-stability": "stable",
          "scripts": {
              "post-install-cmd": [
                  "Incenteev\\ParameterHandler       \\ScriptHandler::buildParameters",
                  "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
                  "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
                  "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
                  "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
              ],
              "post-update-cmd": [
                  "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
                  "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
                  "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
                  "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
                  "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
              ]
          },
          "config": {
              "bin-dir": "bin"
          },
          "extra": {
              "symfony-app-dir": "app",
              "symfony-web-dir": "web",
              "incenteev-parameters": {
                   "file": "app/config/parameters.yml"
              }
          }
      }
      
    2. 凭借新知识,我很乐意在网上找到更多相关信息,即 https://github.com/doctrine/doctrine2/issues/4712

    3. 谢谢所有回复的人。

答案 1 :(得分:0)

试试这个:

OtherClass.operation(scanner.nextLine());   // In case method is static

new OtherClass().operation(scanner.nextLine());   // In case method is not static