Symfony创建Twig扩展函数报错:Call to a member function getRepository() on null
解决Twig扩展中
getRepository()调用null的问题 看起来你遇到的核心问题是Doctrine的ManagerRegistry没有被正确注入到Twig扩展类中,所以调用getRepository()时才会出现"Call to a member function on null"的错误。既然返回字符串正常,说明你的Twig扩展本身已经被正确注册了,只是依赖注入环节出了问题。下面一步步帮你修复:
1. 修正OrderExtension类的依赖注入
首先确保你的扩展类构造函数正确接收ManagerRegistry,并将其存为类属性:
<?php namespace App\Twig; use Doctrine\Persistence\ManagerRegistry; use App\Entity\Order; // 替换成你实际的订单实体命名空间 use Twig\Extension\AbstractExtension; use Twig\TwigFunction; class OrderExtension extends AbstractExtension { private $managerRegistry; // 关键:通过构造函数注入ManagerRegistry,必须加上类型提示 public function __construct(ManagerRegistry $managerRegistry) { $this->managerRegistry = $managerRegistry; } // 注册Twig函数,这里用`get_all_orders`作为函数名,你也可以直接用`orders` public function getFunctions(): array { return [ new TwigFunction('get_all_orders', [$this, 'getAllOrders']), ]; } public function getAllOrders() { // 现在调用getRepository就不会是null了 return $this->managerRegistry->getRepository(Order::class)->findAll(); } }
2. 确保服务被Symfony容器正确注册
Symfony 4+默认会自动注册src/目录下的所有类作为服务,但如果你的项目有自定义配置,需要检查config/services.yaml,确保扩展类被正确识别并注入依赖:
# config/services.yaml services: # 默认自动注册配置,确保没被注释或修改 App\: resource: '../src/' exclude: - '../src/DependencyInjection/' - '../src/Entity/' - '../src/Kernel.php' - '../src/Tests/' # 如果自动注册没生效,手动注册扩展类(可选) App\Twig\OrderExtension: arguments: ['@doctrine'] # @doctrine就是ManagerRegistry的服务ID tags: ['twig.extension'] # 必须加这个标签,Symfony才会把它当成Twig扩展
3. 调整Twig全局变量的配置
你之前把orders设为@App\Twig\OrderExtension,这其实是把服务实例本身作为全局变量,而不是订单数组。如果想直接在模板里用{{ orders }}拿到订单数组,需要用Twig的表达式语言调用扩展的方法:
# config/twig.yaml twig: # 其他原有配置... globals: orders: '@=service("App\Twig\OrderExtension").getAllOrders()'
或者,你也可以直接在模板里调用Twig函数:
{# 在模板中调用函数获取订单数组 #} {% set orders = get_all_orders() %} {% for order in orders %} {{ order.id }} - {{ order.customerName }} {% endfor %}
4. 额外排查点
- 检查你的订单实体
Order的命名空间是否正确,比如是不是App\Entity\Order,不要写错。 - 确认Doctrine配置正常,数据库连接没问题,可以通过
bin/console doctrine:query:sql "SELECT * FROM orders"测试连接。
按照上面的步骤调整后,应该就能正常获取到订单数组了。
内容的提问来源于stack exchange,提问作者Clément HUBERT
相关产品推荐
相关产品推荐

