diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php index 7adf2ed27e77c..dfecac9ee6862 100644 --- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php +++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php @@ -294,6 +294,17 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa return $a == $b ? 0 : 1; }); + // force string for an object. See https://bugs.php.net/bug.php?id=66966 + foreach ($extra as $paramName => $param) { + if (!\is_object($param)) { + continue; + } + if (!\is_callable([$param, '__toString'])) { + throw new InvalidParameterException(sprintf('Error when generating an URL for "%s". Cannot convert object of type "%s" to string for parameter "%s".', $name, get_debug_type($param), $paramName)); + } + $extra[$paramName] = (string) $param; + } + // extract fragment $fragment = $defaults['_fragment'] ?? ''; diff --git a/src/Symfony/Component/Routing/Tests/Generator/StringableStub.php b/src/Symfony/Component/Routing/Tests/Generator/StringableStub.php new file mode 100644 index 0000000000000..47ea8583b3c08 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/Generator/StringableStub.php @@ -0,0 +1,11 @@ +assertEquals('/app.php/testing#fragment', $url); } + public function testNonStringableObjectParameterCannotBeConvertedToString() + { + $object = new \stdClass(); + $routes = $this->getRoutes('test', new Route('/testing')); + $this->expectException(InvalidParameterException::class); + $this->getGenerator($routes)->generate('test', ['param' => $object]); + } + + public function testStringableObjectParameterIsConvertedToString() + { + $object = new StringableStub(); + $routes = $this->getRoutes('test', new Route('/testing')); + $url = $this->getGenerator($routes)->generate('test', ['param' => $object]); + + $this->assertEquals('/app.php/testing?param=dummy', $url); + } + /** * @dataProvider provideLookAroundRequirementsInPath */