Sonata Admin Bundle - RouteCompiler 错误,因为占位符长于 32 个字符
Sonata Admin Bundle - RouteCompiler error because of placeholder longer than 32 char
我刚刚使用 composer 更新了我的包,然后 Symfony 抛出了一个错误。在更新之前,我的应用程序 运行 没问题。
错误:
Variable name "childChildChildChildChildChildChildId" cannot be longer than 32 characters in route pattern "/admin/project/rest/member/{id}/shelves_member/{childId}/contributor/{childChildId}/series/{childChildChildId}/shelves_series/{childChildChildChildId}/post/{childChildChildChildChildId}/tag/{childChildChildChildChildChildId}/event/{childChildChildChildChildChildChildId}/edit". Please use a shorter name.
解释:
管理员似乎在 admin.yml 中嵌套得很深,这使得动态生成的 'childchild...' 占位符超过 32 个字符,这又会引发错误,因为 [=41] =] 来自 Symfony 的占位符限制由常量 VARIABLE_MAXIMUM_LENGTH 定义为 32 个字符。
我没有在奏鸣曲文档中找到任何关于自定义占位符或为其设置最大长度的内容。
现在,我发现让应用程序在更新后运行的唯一方法是将此常量更改为 64 个字符,但我很确定这不是一个好主意,因为它可能会破坏其他地方。
(编辑:添加堆栈跟踪)
堆栈跟踪
in vendor/symfony/symfony/src/Symfony/Component/Routing/RouteCompiler.php at line 116 -
}
if (strlen($varName) > self::VARIABLE_MAXIMUM_LENGTH) {
throw new \DomainException(sprintf('Variable name "%s" cannot be longer than %s characters in route pattern "%s". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern));
}
if ($isSeparator && strlen($precedingText) > 1) {
at RouteCompiler ::compilePattern (object(Route), '/admin/project/rest/member/{id}/shelves_member/{childId}/contributor/{childChildId}/series/{childChildChildId}/shelves_series/{childChildChildChildId}/post/{childChildChildChildChildId}/tag/{childChildChildChildChildChildId}/event/{childChildChildChildChildChildChildId}/edit', false)
in vendor/symfony/symfony/src/Symfony/Component/Routing/RouteCompiler.php at line 65 +
at RouteCompiler ::compile (object(Route))
in vendor/symfony/symfony/src/Symfony/Component/Routing/Route.php at line 594 +
at Route ->compile ()
in vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php at line 387 +
at PhpMatcherDumper ->groupRoutesByHostRegex (object(RouteCollection))
in vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php at line 125 +
at PhpMatcherDumper ->compileRoutes (object(RouteCollection), true)
in vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php at line 96 +
at PhpMatcherDumper ->generateMatchMethod (true)
in vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php at line 76 +
at PhpMatcherDumper ->dump (array('class' => 'appDevDebugProjectContainerUrlMatcher', 'base_class' => 'Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher'))
in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php at line 306 +
at Router ->Symfony\Component\Routing\{closure} (object(ResourceCheckerConfigCache))
at call_user_func (object(Closure), object(ResourceCheckerConfigCache))
in vendor/symfony/symfony/src/Symfony/Component/Config/ResourceCheckerConfigCacheFactory.php at line 46 +
at ResourceCheckerConfigCacheFactory ->cache ('/var/www/serverv2/app/cache/dev/appDevDebugProjectContainerUrlMatcher.php', object(Closure))
in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php at line 308 +
at Router ->getMatcher ()
in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php at line 256 +
at Router ->matchRequest (object(Request))
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php at line 157 +
at RouterListener ->onKernelRequest (object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
at call_user_func (array(object(RouterListener), 'onKernelRequest'), object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php at line 61 +
at WrappedListener ->__invoke (object(GetResponseEvent), 'kernel.request', object(ContainerAwareEventDispatcher))
at call_user_func (object(WrappedListener), object(GetResponseEvent), 'kernel.request', object(ContainerAwareEventDispatcher))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php at line 184 +
at EventDispatcher ->doDispatch (array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.request', object(GetResponseEvent))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php at line 46 +
at EventDispatcher ->dispatch ('kernel.request', object(GetResponseEvent))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php at line 133 +
at TraceableEventDispatcher ->dispatch ('kernel.request', object(GetResponseEvent))
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 116 +
at HttpKernel ->handleRaw (object(Request), '1')
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 57 +
at HttpKernel ->handle (object(Request), '1', true)
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php at line 67 +
at ContainerAwareHttpKernel ->handle (object(Request), '1', true)
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php at line 183 +
at Kernel ->handle (object(Request))
in web/app_dev.php at line 32 +
奏鸣曲包
$ composer show --latest 'sonata-project/*'
sonata-project/admin-bundle 3.34.1 3.34.1 The missing Symfony Admin Generator
sonata-project/block-bundle 3.12.1 3.12.1 Symfony SonataBlockBundle
sonata-project/cache 1.0.7 1.0.7 Cache library
sonata-project/core-bundle 3.9.1 3.9.1 Symfony SonataCoreBundle
sonata-project/datagrid-bundle 2.3.1 2.3.1 Symfony SonataDatagridBundle
sonata-project/doctrine-extensions 1.0.2 1.0.2 Doctrine2 behavioral extensions
sonata-project/doctrine-mongodb-admin-bundle 3.1.1 3.1.1 Symfony Sonata / Integrate Doctrine MongoDB ODM into the SonataAdminBundle
sonata-project/easy-extends-bundle 2.5.0 2.5.0 Symfony SonataEasyExtendsBundle
sonata-project/exporter 1.8.0 1.8.0 Lightweight Exporter library
sonata-project/formatter-bundle 3.4.1 3.4.1 Symfony SonataFormatterBundle
sonata-project/google-authenticator 1.1.0 1.1.0 Library to integrate Google Authenticator into a PHP project
sonata-project/user-bundle 3.6.0 3.6.0 Symfony SonataUserBundle
Symfony 包
$ composer show --latest 'symfony*'
symfony/monolog-bundle 2.11.1 v3.2.0 Symfony MonologBundle
symfony/phpunit-bridge v3.1.5 v4.0.8 Symfony PHPUnit Bridge
symfony/polyfill-apcu v1.7.0 v1.7.0 Symfony polyfill backporting apcu_* functions to lower PHP versions
symfony/polyfill-intl-icu v1.7.0 v1.7.0 Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring v1.7.0 v1.7.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php54 v1.7.0 v1.7.0 Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions
symfony/polyfill-php55 v1.7.0 v1.7.0 Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions
symfony/polyfill-php56 v1.7.0 v1.7.0 Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions
symfony/polyfill-php70 v1.7.0 v1.7.0 Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-util v1.7.0 v1.7.0 Symfony utilities for portability of PHP codes
symfony/security-acl v3.0.1 v3.0.1 Symfony Security Component - ACL (Access Control List)
symfony/swiftmailer-bundle v2.3.11 v3.0.3 Symfony SwiftmailerBundle
symfony/symfony v2.8.38 v3.4.8 The Symfony PHP framework
PHP 版本
$ php -v
PHP 5.6.33-0+deb8u1 (cli) (built: Jan 5 2018 15:46:26)
感谢您的帮助!
我 运行 遇到了同样的问题,在阅读了您添加到 github 的问题后,我解决了这个问题如下:
首先,我创建了自己的 AbstractAdmin
来扩展奏鸣曲的
我所有的奏鸣曲管理员 类 然后扩展我的抽象管理员。
在我的 AbstractAdmin
中,我覆盖了 getIdParameter()
方法以强制 Sonata 使用较短的占位符 - 'c' 而不是 'child':
<?php
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin as SonataAbstractAdmin;
abstract class AbstractAdmin extends SonataAbstractAdmin
{
public function getIdParameter()
{
$parameter = 'id';
for ($i = 0; $i < $this->getChildDepth(); ++$i) {
$parameter = sprintf('c%s', ucfirst($parameter));
}
return $parameter;
}
}
请注意,这不允许无限嵌套 - 只是为了更多。
无法绕过 Symfony 规定的每个占位符 32 个字符的总体限制。
正如您自己指出的那样,它是一个可以被覆盖的常量,但这可能不是一个好主意。
供参考:https://github.com/sonata-project/SonataAdminBundle/issues/5072
我刚刚使用 composer 更新了我的包,然后 Symfony 抛出了一个错误。在更新之前,我的应用程序 运行 没问题。
错误:
Variable name "childChildChildChildChildChildChildId" cannot be longer than 32 characters in route pattern "/admin/project/rest/member/{id}/shelves_member/{childId}/contributor/{childChildId}/series/{childChildChildId}/shelves_series/{childChildChildChildId}/post/{childChildChildChildChildId}/tag/{childChildChildChildChildChildId}/event/{childChildChildChildChildChildChildId}/edit". Please use a shorter name.
解释:
管理员似乎在 admin.yml 中嵌套得很深,这使得动态生成的 'childchild...' 占位符超过 32 个字符,这又会引发错误,因为 [=41] =] 来自 Symfony 的占位符限制由常量 VARIABLE_MAXIMUM_LENGTH 定义为 32 个字符。
我没有在奏鸣曲文档中找到任何关于自定义占位符或为其设置最大长度的内容。
现在,我发现让应用程序在更新后运行的唯一方法是将此常量更改为 64 个字符,但我很确定这不是一个好主意,因为它可能会破坏其他地方。
(编辑:添加堆栈跟踪)
堆栈跟踪
in vendor/symfony/symfony/src/Symfony/Component/Routing/RouteCompiler.php at line 116 -
}
if (strlen($varName) > self::VARIABLE_MAXIMUM_LENGTH) {
throw new \DomainException(sprintf('Variable name "%s" cannot be longer than %s characters in route pattern "%s". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern));
}
if ($isSeparator && strlen($precedingText) > 1) {
at RouteCompiler ::compilePattern (object(Route), '/admin/project/rest/member/{id}/shelves_member/{childId}/contributor/{childChildId}/series/{childChildChildId}/shelves_series/{childChildChildChildId}/post/{childChildChildChildChildId}/tag/{childChildChildChildChildChildId}/event/{childChildChildChildChildChildChildId}/edit', false)
in vendor/symfony/symfony/src/Symfony/Component/Routing/RouteCompiler.php at line 65 +
at RouteCompiler ::compile (object(Route))
in vendor/symfony/symfony/src/Symfony/Component/Routing/Route.php at line 594 +
at Route ->compile ()
in vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php at line 387 +
at PhpMatcherDumper ->groupRoutesByHostRegex (object(RouteCollection))
in vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php at line 125 +
at PhpMatcherDumper ->compileRoutes (object(RouteCollection), true)
in vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php at line 96 +
at PhpMatcherDumper ->generateMatchMethod (true)
in vendor/symfony/symfony/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php at line 76 +
at PhpMatcherDumper ->dump (array('class' => 'appDevDebugProjectContainerUrlMatcher', 'base_class' => 'Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher'))
in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php at line 306 +
at Router ->Symfony\Component\Routing\{closure} (object(ResourceCheckerConfigCache))
at call_user_func (object(Closure), object(ResourceCheckerConfigCache))
in vendor/symfony/symfony/src/Symfony/Component/Config/ResourceCheckerConfigCacheFactory.php at line 46 +
at ResourceCheckerConfigCacheFactory ->cache ('/var/www/serverv2/app/cache/dev/appDevDebugProjectContainerUrlMatcher.php', object(Closure))
in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php at line 308 +
at Router ->getMatcher ()
in vendor/symfony/symfony/src/Symfony/Component/Routing/Router.php at line 256 +
at Router ->matchRequest (object(Request))
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php at line 157 +
at RouterListener ->onKernelRequest (object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
at call_user_func (array(object(RouterListener), 'onKernelRequest'), object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php at line 61 +
at WrappedListener ->__invoke (object(GetResponseEvent), 'kernel.request', object(ContainerAwareEventDispatcher))
at call_user_func (object(WrappedListener), object(GetResponseEvent), 'kernel.request', object(ContainerAwareEventDispatcher))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php at line 184 +
at EventDispatcher ->doDispatch (array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.request', object(GetResponseEvent))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php at line 46 +
at EventDispatcher ->dispatch ('kernel.request', object(GetResponseEvent))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php at line 133 +
at TraceableEventDispatcher ->dispatch ('kernel.request', object(GetResponseEvent))
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 116 +
at HttpKernel ->handleRaw (object(Request), '1')
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 57 +
at HttpKernel ->handle (object(Request), '1', true)
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php at line 67 +
at ContainerAwareHttpKernel ->handle (object(Request), '1', true)
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php at line 183 +
at Kernel ->handle (object(Request))
in web/app_dev.php at line 32 +
奏鸣曲包
$ composer show --latest 'sonata-project/*'
sonata-project/admin-bundle 3.34.1 3.34.1 The missing Symfony Admin Generator
sonata-project/block-bundle 3.12.1 3.12.1 Symfony SonataBlockBundle
sonata-project/cache 1.0.7 1.0.7 Cache library
sonata-project/core-bundle 3.9.1 3.9.1 Symfony SonataCoreBundle
sonata-project/datagrid-bundle 2.3.1 2.3.1 Symfony SonataDatagridBundle
sonata-project/doctrine-extensions 1.0.2 1.0.2 Doctrine2 behavioral extensions
sonata-project/doctrine-mongodb-admin-bundle 3.1.1 3.1.1 Symfony Sonata / Integrate Doctrine MongoDB ODM into the SonataAdminBundle
sonata-project/easy-extends-bundle 2.5.0 2.5.0 Symfony SonataEasyExtendsBundle
sonata-project/exporter 1.8.0 1.8.0 Lightweight Exporter library
sonata-project/formatter-bundle 3.4.1 3.4.1 Symfony SonataFormatterBundle
sonata-project/google-authenticator 1.1.0 1.1.0 Library to integrate Google Authenticator into a PHP project
sonata-project/user-bundle 3.6.0 3.6.0 Symfony SonataUserBundle
$ composer show --latest 'symfony*'
symfony/monolog-bundle 2.11.1 v3.2.0 Symfony MonologBundle
symfony/phpunit-bridge v3.1.5 v4.0.8 Symfony PHPUnit Bridge
symfony/polyfill-apcu v1.7.0 v1.7.0 Symfony polyfill backporting apcu_* functions to lower PHP versions
symfony/polyfill-intl-icu v1.7.0 v1.7.0 Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring v1.7.0 v1.7.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php54 v1.7.0 v1.7.0 Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions
symfony/polyfill-php55 v1.7.0 v1.7.0 Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions
symfony/polyfill-php56 v1.7.0 v1.7.0 Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions
symfony/polyfill-php70 v1.7.0 v1.7.0 Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-util v1.7.0 v1.7.0 Symfony utilities for portability of PHP codes
symfony/security-acl v3.0.1 v3.0.1 Symfony Security Component - ACL (Access Control List)
symfony/swiftmailer-bundle v2.3.11 v3.0.3 Symfony SwiftmailerBundle
symfony/symfony v2.8.38 v3.4.8 The Symfony PHP framework
$ php -v
PHP 5.6.33-0+deb8u1 (cli) (built: Jan 5 2018 15:46:26)
感谢您的帮助!
我 运行 遇到了同样的问题,在阅读了您添加到 github 的问题后,我解决了这个问题如下:
首先,我创建了自己的 AbstractAdmin
来扩展奏鸣曲的
我所有的奏鸣曲管理员 类 然后扩展我的抽象管理员。
在我的 AbstractAdmin
中,我覆盖了 getIdParameter()
方法以强制 Sonata 使用较短的占位符 - 'c' 而不是 'child':
<?php
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin as SonataAbstractAdmin;
abstract class AbstractAdmin extends SonataAbstractAdmin
{
public function getIdParameter()
{
$parameter = 'id';
for ($i = 0; $i < $this->getChildDepth(); ++$i) {
$parameter = sprintf('c%s', ucfirst($parameter));
}
return $parameter;
}
}
请注意,这不允许无限嵌套 - 只是为了更多。
无法绕过 Symfony 规定的每个占位符 32 个字符的总体限制。
正如您自己指出的那样,它是一个可以被覆盖的常量,但这可能不是一个好主意。
供参考:https://github.com/sonata-project/SonataAdminBundle/issues/5072