Problem/Motivation
The `ProxyBuilder` class generates invalid PHP code when a method has `static` as return type (PHP 8+ feature). It incorrectly outputs `\static` instead of `static`, causing a PHP Fatal error:
PHP Fatal error: '\static' is an invalid class name in .../ProxyClass/Hook/ContentHooks.php on line 73
In `core/lib/Drupal/Component/ProxyBuilder/ProxyBuilder.php`, lines 239-242, the code checks if the return type is not built-in and prepends a backslash:
php
if (!$return_type->isBuiltin()) {
// The parameter is a class or interface.
$signature_line .= '\\';
}The `static` return type is not a built-in type (`isBuiltin()` returns `false`), but it's also not a class/interface - it's a PHP keyword that should not have a backslash prefix. The code already handles `self` specially (line 244-246), but `static` was not considered.
Steps to reproduce
1. Have a service class that implements `ContainerInjectionInterface` with the `create()` method using `static` return type:
php
class ContentHooks implements ContainerInjectionInterface {
public static function create(ContainerInterface $container): static {
return new static();
}
}2. Mark this service as lazy in `*.services.yml`
3. Run the proxy class generator:
bash
php core/scripts/generate-proxy-class.php 'Drupal\eca_content\Hook\ContentHooks' "modules/contrib/eca/modules/content/src"
4. Try to clear cache with `drush cr` - PHP Fatal error occurs
**Environment:**
- Drupal 11.3.2
- PHP 8.4.16
- Debian GNU/Linux 13 (trixie)
- Apache/2.4.66
**Affected module:** ECA 3.0.10 (eca_content submodule)
Proposed resolution
Add a check for `static` return type similar to how `self` is handled:
diff
if ($reflection_method->hasReturnType()) {
$signature_line .= ': ';
$return_type = $reflection_method->getReturnType();
+ $return_type_name = $return_type->getName();
if ($return_type->allowsNull()) {
$signature_line .= '?';
}
- if (!$return_type->isBuiltin()) {
- // The parameter is a class or interface.
+ if (!$return_type->isBuiltin() && $return_type_name !== 'static') {
+ // The return type is a class or interface.
+ // Note: 'static' is not built-in but also not a class, it's a PHP keyword.
$signature_line .= '\\';
}
- $return_type_name = $return_type->getName();
if ($return_type_name === 'self') {
Remaining tasks
- Review and commit patch
- Add test case for `static` return type in `ProxyBuilderTest.php`
- Regenerate affected core proxy classes (if any)
User interface changes
None.
Introduced terminology
None.
API changes
None. This is a bug fix - the API remains the same, but now correctly handles `static` return types.
Data model changes
None.
Release notes snippet
Fixed a bug where the ProxyBuilder would generate invalid PHP code (`\static` instead of `static`) for methods with `static` return type, causing a PHP Fatal error when using lazy services with `ContainerInjectionInterface::create()` on PHP 8+.
| Comment | File | Size | Author |
|---|---|---|---|
| proxybuilder-static-return-type.patch | 1.11 KB | pimok3000 |
Comments
Comment #2
liam morlandComment #3
quietone commentedChanging tags per Issue tags field and Issue tags -- special tags
Hi, Issues for Drupal core should be targeted to the 'main' branch, our primary development branch. Changes are made on the main branch first, and are then back ported as needed according to the Core change policies. The version the problem was discovered on should be stated in the issue summary Problem/Motivation section. Thanks.