在WordPress Sage Blade模板中使用单例服务报错排查
问题:DDEV+Bedrock+Sage开发WordPress主题时,Blade模板调用单例服务报错"Target class [TestService] does not exist"
我在使用DDEV + Bedrock + Sage开发WordPress主题时,在Blade模板中使用单例类遇到以下错误:
Target class [TestService] does not exist. (View: /var/www/html/web/app/themes/theme/resources/views/test-page.blade.php)
相关代码如下:
单例服务类TestService
final class TestService { public static string $name = "TestService"; private static ?TestService $instance = null; public static function getInstance(): TestService { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } private function __construct() { } private function __clone() { } public function __wakeup() { throw new Exception("Cannot unserialize singleton"); } public function testMethod() { return true; } }
服务提供者TestServiceProvider
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use App\Services\TestService; class TestServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // Register services in ServiceProviderOne $this->app->singleton("TestService", function () { return TestService::getInstance(); }); } /** * Bootstrap services. * * @return void */ public function boot() { // } }
调用服务的Blade页面模板
@php $testService = app("TestService"); $isTest = $testService->testMethod(); @endphp @extends('layouts.app') @section('content') @while(have_posts()) @php(the_post()) @includeFirst(['partials.content-page', 'partials.content']) @endwhile @endsection
请问我的单例和服务提供者设置是否有误?或是遗漏了某些配置?
解决方案
1. 补全单例类的命名空间
TestService类缺少命名空间,但服务提供者中引用的是App\Services\TestService,这是类找不到的核心原因。给TestService添加正确的命名空间:
<?php namespace App\Services; final class TestService { // 原有代码保持不变 }
同时确保文件存放路径为web/app/themes/你的主题名/app/Services/TestService.php,符合Sage的目录结构规范。
2. 注册服务提供者到Sage容器
Sage基于Illuminate容器,必须手动注册自定义服务提供者才能被容器识别。打开主题根目录下的app/config/app.php,在providers数组中添加你的服务提供者:
'providers' => [ // 保留原有默认提供者 App\Providers\TestServiceProvider::class, ],
3. 优化单例绑定逻辑
你同时实现了手动单例模式和Laravel容器单例绑定,存在冗余,可二选一:
- 方案一:保留手动单例
直接在模板中调用单例方法,无需通过容器:@php $testService = \App\Services\TestService::getInstance(); $isTest = $testService->testMethod(); @endphp - 方案二:用Laravel容器管理单例
去掉TestService中的手动单例逻辑,修改服务提供者的register方法:
模板中通过类名调用:public function register() { $this->app->singleton(\App\Services\TestService::class, function ($app) { return new \App\Services\TestService(); }); }@php $testService = app(\App\Services\TestService::class); $isTest = $testService->testMethod(); @endphp
4. 清除自动加载缓存
修改命名空间或文件结构后,执行以下命令更新Composer自动加载规则:
ddev composer dump-autoload
内容的提问来源于stack exchange,提问作者Vario
相关产品推荐
相关产品推荐

