Zend Service Manager - 尝试使用 phpdebugbar 时未发现服务异常
Zend Service Manager - Service not found exception when trying to use phpdebugbar
我正在尝试在干净的 Zend Expressive Skeleton 应用程序中使用 https://github.com/php-middleware/phpdebugbar。
我知道此页面上的说明建议使用此 DI 配置(如果使用疙瘩):
$container[Psr\Http\Message\ResponseInterface::class] = new Zend\Diactoros\ResponseFactory();
$container[Psr\Http\Message\StreamFactoryInterface] = new Zend\Diactoros\StreamFactory();
所以我尝试使用这个(我正在使用 zend 服务管理器):
return [
'dependencies' => [
'factories' => [
Psr\Http\Message\ResponseInterface::class => new Zend\Diactoros\ResponseFactory(),
'Psr\Http\Message\StreamFactoryInterface' => new Zend\Diactoros\StreamFactory(),
],
],
];
但我 运行 遇到以下错误:
PHP Fatal error: Uncaught Zend\ServiceManager\Exception\ServiceNotFoundException: Unable to resolve service "Psr\Http\Message\ResponseInterface" to a factory; are you certain you provided it during configuration? in /www/develop.expressive.centralsemi.com/htdocs/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:687
我也试过这个:
return [
'dependencies' => [
'factories' => [
Psr\Http\Message\ResponseInterface::class => new Zend\Diactoros\ResponseFactory(),
Psr\Http\Message\StreamFactoryInterface::class => new Zend\Diactoros\StreamFactory(),
],
],
];
还有这个:
return [
'dependencies' => [
'factories' => [
Psr\Http\Message\ResponseInterface::class => Zend\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Zend\Diactoros\StreamFactory::class,
],
],
];
但还是没有运气。
诚然,我对Zend/Diactoros不熟悉,但我不明白Zend\Diactoros\ResponseFactory
怎么可以是工厂,它没有__invoke()
方法。所以我觉得这是我问题的核心。我应该为此创建自己的工厂吗?我觉得这不是执行此操作的预期方式。
请注意,我也尝试按照这些说明进行操作。虽然没有错误,但它似乎根本没有出现:
https://docs.zendframework.com/zend-expressive/v3/cookbook/debug-toolbars/
我确信我遗漏了一些关键部分,但我遗漏了什么?
我的composer.json:
{
"name": "zendframework/zend-expressive-skeleton",
"description": "Zend expressive skeleton. Begin developing PSR-15 middleware applications in seconds!",
"type": "project",
"homepage": "https://github.com/zendframework/zend-expressive-skeleton",
"license": "BSD-3-Clause",
"keywords": [
"skeleton",
"middleware",
"psr",
"psr-7",
"psr-11",
"psr-15",
"zf",
"zendframework",
"zend-expressive"
],
"config": {
"sort-packages": true
},
"extra": {
"zf": {
"component-whitelist": [
"zendframework/zend-expressive",
"zendframework/zend-expressive-helpers",
"zendframework/zend-expressive-router",
"zendframework/zend-httphandlerrunner",
"zendframework/zend-expressive-fastroute",
"zendframework/zend-expressive-twigrenderer"
]
}
},
"support": {
"issues": "https://github.com/zendframework/zend-expressive-skeleton/issues",
"source": "https://github.com/zendframework/zend-expressive-skeleton",
"rss": "https://github.com/zendframework/zend-expressive-skeleton/releases.atom",
"slack": "https://zendframework-slack.herokuapp.com",
"forum": "https://discourse.zendframework.com/c/questions/expressive"
},
"require": {
"php": "^7.1",
"zendframework/zend-component-installer": "^2.1.1",
"zendframework/zend-config-aggregator": "^1.0",
"zendframework/zend-diactoros": "^1.7.1 || ^2.0",
"zendframework/zend-expressive": "^3.0.1",
"zendframework/zend-expressive-helpers": "^5.0",
"zendframework/zend-stdlib": "^3.1",
"zendframework/zend-servicemanager": "^3.3",
"zendframework/zend-expressive-fastroute": "^3.0",
"zendframework/zend-expressive-twigrenderer": "^2.0"
},
"require-dev": {
"filp/whoops": "^2.1.12",
"php-middleware/php-debug-bar": "^3.0",
"phpunit/phpunit": "^7.0.1",
"roave/security-advisories": "dev-master",
"squizlabs/php_codesniffer": "^2.9.1",
"zendframework/zend-expressive-tooling": "^1.0",
"zfcampus/zf-development-mode": "^3.1"
},
"autoload": {
"psr-4": {
"App\": "src/App/src/",
"PhpDebugBar\": "src/PhpDebugBar/src/"
}
},
"autoload-dev": {
"psr-4": {
"AppTest\": "test/AppTest/"
}
},
"scripts": {
"post-create-project-cmd": [
"@development-enable"
],
"development-disable": "zf-development-mode disable",
"development-enable": "zf-development-mode enable",
"development-status": "zf-development-mode status",
"expressive": "expressive --ansi",
"check": [
"@cs-check",
"@test"
],
"clear-config-cache": "php bin/clear-config-cache.php",
"cs-check": "phpcs",
"cs-fix": "phpcbf",
"serve": "php -S 0.0.0.0:8080 -t public/",
"test": "phpunit --colors=always",
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml"
}
}
先尝试创建别名,然后将其提供给工厂
return [
'dependencies' => [
'factories' => [
Psr\Http\Message\ResponseInterface::class => Zend\Diactoros\ResponseFactory::class,
'Psr\Http\Message\StreamFactoryInterface' => Zend\Diactoros\StreamFactory::class,
],
'aliases' => [
ClassThatImplementsResponseInterface::class => Psr\Http\Message\ResponseInterface::class,
ClassThatImplementsStreamFactoryInterface::class => 'Psr\Http\Message\StreamFactoryInterface',
]
],
];
更新:
正如@d.lanza38 发现的那样,这是赖特配置
return [
'dependencies' => [
'invokables' => [
Zend\Diactoros\ResponseFactory::class => Zend\Diactoros\ResponseFactory::class,
Zend\Diactoros\StreamFactory::class => Zend\Diactoros\StreamFactory::class,
],
'aliases' => [
Psr\Http\Message\ResponseFactoryInterface::class => Zend\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Zend\Diactoros\StreamFactory::class,
]
],
];
我正在写另一个答案,因为它更容易阅读。
好的。我刚刚全新安装了 Zend Expressive 3 和 https://github.com/php-middleware/phpdebugbar:
- 作曲家要求 --dev php-middleware/php-debug-bar
- 作曲家转储自动加载
- 已创建 /config/autoload/debugbar.local.php
return array_merge(PhpMiddleware\PhpDebugBar\ConfigProvider::getConfig(), [
'phpmiddleware' => [
'phpdebugbar' => [
'javascript_renderer' => [
'base_url' => '/razvan.ionascu/ze-api/public',
],
'collectors' => [
DebugBar\DataCollector\ConfigCollector::class, // Service names of collectors
],
'storage' => null, // Service name of storage
],
],
'dependencies' => [
'factories' => [
\PhpMiddleware\PhpDebugBar\PhpDebugBarMiddleware::class => \PhpMiddleware\PhpDebugBar\PhpDebugBarMiddlewareFactory::class,
\DebugBar\DataCollector\ConfigCollector::class => \PhpMiddleware\PhpDebugBar\ConfigCollectorFactory::class,
\PhpMiddleware\PhpDebugBar\ConfigProvider::class => \PhpMiddleware\PhpDebugBar\ConfigProvider::class,
\DebugBar\DebugBar::class => \PhpMiddleware\PhpDebugBar\StandardDebugBarFactory::class,
JavascriptRenderer::class => NewJavascriptRendererFactory::class,
],
],
]);
为此,您需要创建一个新的 JavascriptRendererFactory。当前搜索错误的配置键,ConfigProvider::class 而不是 'config' :
class NewJavascriptRendererFactory
{
public function __invoke(ContainerInterface $container): JavascriptRenderer
{
$debugbar = $container->get(DebugBar::class);
$config = $container->get('config');
$rendererOptions = $config['phpmiddleware']['phpdebugbar']['javascript_renderer'];
$renderer = new JavascriptRenderer($debugbar);
$renderer->setOptions($rendererOptions);
return $renderer;
}
}
- 将以下别名和工厂添加到 /confog/atuoload/dependencies。global.php
'aliases' => [
\Psr\Http\Message\ResponseFactoryInterface::class => ResponseFactory::class,
\Psr\Http\Message\StreamFactoryInterface::class => StreamFactory::class,
],
'factories' => [
...
\DebugBar\JavascriptRenderer::class => JavascriptRendererFactory::class,
...
],
- 向 /config/pipeline 添加了新管道。php
//only works in development mode
if (!empty($container->get('config')['debug'])) {
$app->pipe(\PhpMiddleware\PhpDebugBar\PhpDebugBarMiddleware::class);
}
正如我在之前的评论中提到的,我还配置了 https://docs.zendframework.com/zend-servicemanager/reflection-abstract-factory/ ,因此我不需要为每个服务创建一个工厂()
See the working debug bar here
我明白了。 https://docs.zendframework.com/zend-expressive/v3/cookbook/debug-toolbars/ 处的说明是正确的。唯一需要的额外步骤是向配置添加 invokables
和 aliases
条目。
我的在 /config/autoload/zend-expressive-tooling-factories.global.php
:
return [
'dependencies' => [
'invokables' => [
Zend\Diactoros\ResponseFactory::class => Zend\Diactoros\ResponseFactory::class,
Zend\Diactoros\StreamFactory::class => Zend\Diactoros\StreamFactory::class,
],
'aliases' => [
Psr\Http\Message\ResponseFactoryInterface::class => Zend\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Zend\Diactoros\StreamFactory::class,
]
],
];
我最初只有 aliases
部分而不是 invokables
部分。添加后,一切正常。
我正在尝试在干净的 Zend Expressive Skeleton 应用程序中使用 https://github.com/php-middleware/phpdebugbar。
我知道此页面上的说明建议使用此 DI 配置(如果使用疙瘩):
$container[Psr\Http\Message\ResponseInterface::class] = new Zend\Diactoros\ResponseFactory();
$container[Psr\Http\Message\StreamFactoryInterface] = new Zend\Diactoros\StreamFactory();
所以我尝试使用这个(我正在使用 zend 服务管理器):
return [
'dependencies' => [
'factories' => [
Psr\Http\Message\ResponseInterface::class => new Zend\Diactoros\ResponseFactory(),
'Psr\Http\Message\StreamFactoryInterface' => new Zend\Diactoros\StreamFactory(),
],
],
];
但我 运行 遇到以下错误:
PHP Fatal error: Uncaught Zend\ServiceManager\Exception\ServiceNotFoundException: Unable to resolve service "Psr\Http\Message\ResponseInterface" to a factory; are you certain you provided it during configuration? in /www/develop.expressive.centralsemi.com/htdocs/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:687
我也试过这个:
return [
'dependencies' => [
'factories' => [
Psr\Http\Message\ResponseInterface::class => new Zend\Diactoros\ResponseFactory(),
Psr\Http\Message\StreamFactoryInterface::class => new Zend\Diactoros\StreamFactory(),
],
],
];
还有这个:
return [
'dependencies' => [
'factories' => [
Psr\Http\Message\ResponseInterface::class => Zend\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Zend\Diactoros\StreamFactory::class,
],
],
];
但还是没有运气。
诚然,我对Zend/Diactoros不熟悉,但我不明白Zend\Diactoros\ResponseFactory
怎么可以是工厂,它没有__invoke()
方法。所以我觉得这是我问题的核心。我应该为此创建自己的工厂吗?我觉得这不是执行此操作的预期方式。
请注意,我也尝试按照这些说明进行操作。虽然没有错误,但它似乎根本没有出现: https://docs.zendframework.com/zend-expressive/v3/cookbook/debug-toolbars/
我确信我遗漏了一些关键部分,但我遗漏了什么?
我的composer.json:
{
"name": "zendframework/zend-expressive-skeleton",
"description": "Zend expressive skeleton. Begin developing PSR-15 middleware applications in seconds!",
"type": "project",
"homepage": "https://github.com/zendframework/zend-expressive-skeleton",
"license": "BSD-3-Clause",
"keywords": [
"skeleton",
"middleware",
"psr",
"psr-7",
"psr-11",
"psr-15",
"zf",
"zendframework",
"zend-expressive"
],
"config": {
"sort-packages": true
},
"extra": {
"zf": {
"component-whitelist": [
"zendframework/zend-expressive",
"zendframework/zend-expressive-helpers",
"zendframework/zend-expressive-router",
"zendframework/zend-httphandlerrunner",
"zendframework/zend-expressive-fastroute",
"zendframework/zend-expressive-twigrenderer"
]
}
},
"support": {
"issues": "https://github.com/zendframework/zend-expressive-skeleton/issues",
"source": "https://github.com/zendframework/zend-expressive-skeleton",
"rss": "https://github.com/zendframework/zend-expressive-skeleton/releases.atom",
"slack": "https://zendframework-slack.herokuapp.com",
"forum": "https://discourse.zendframework.com/c/questions/expressive"
},
"require": {
"php": "^7.1",
"zendframework/zend-component-installer": "^2.1.1",
"zendframework/zend-config-aggregator": "^1.0",
"zendframework/zend-diactoros": "^1.7.1 || ^2.0",
"zendframework/zend-expressive": "^3.0.1",
"zendframework/zend-expressive-helpers": "^5.0",
"zendframework/zend-stdlib": "^3.1",
"zendframework/zend-servicemanager": "^3.3",
"zendframework/zend-expressive-fastroute": "^3.0",
"zendframework/zend-expressive-twigrenderer": "^2.0"
},
"require-dev": {
"filp/whoops": "^2.1.12",
"php-middleware/php-debug-bar": "^3.0",
"phpunit/phpunit": "^7.0.1",
"roave/security-advisories": "dev-master",
"squizlabs/php_codesniffer": "^2.9.1",
"zendframework/zend-expressive-tooling": "^1.0",
"zfcampus/zf-development-mode": "^3.1"
},
"autoload": {
"psr-4": {
"App\": "src/App/src/",
"PhpDebugBar\": "src/PhpDebugBar/src/"
}
},
"autoload-dev": {
"psr-4": {
"AppTest\": "test/AppTest/"
}
},
"scripts": {
"post-create-project-cmd": [
"@development-enable"
],
"development-disable": "zf-development-mode disable",
"development-enable": "zf-development-mode enable",
"development-status": "zf-development-mode status",
"expressive": "expressive --ansi",
"check": [
"@cs-check",
"@test"
],
"clear-config-cache": "php bin/clear-config-cache.php",
"cs-check": "phpcs",
"cs-fix": "phpcbf",
"serve": "php -S 0.0.0.0:8080 -t public/",
"test": "phpunit --colors=always",
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml"
}
}
先尝试创建别名,然后将其提供给工厂
return [
'dependencies' => [
'factories' => [
Psr\Http\Message\ResponseInterface::class => Zend\Diactoros\ResponseFactory::class,
'Psr\Http\Message\StreamFactoryInterface' => Zend\Diactoros\StreamFactory::class,
],
'aliases' => [
ClassThatImplementsResponseInterface::class => Psr\Http\Message\ResponseInterface::class,
ClassThatImplementsStreamFactoryInterface::class => 'Psr\Http\Message\StreamFactoryInterface',
]
],
];
更新: 正如@d.lanza38 发现的那样,这是赖特配置
return [
'dependencies' => [
'invokables' => [
Zend\Diactoros\ResponseFactory::class => Zend\Diactoros\ResponseFactory::class,
Zend\Diactoros\StreamFactory::class => Zend\Diactoros\StreamFactory::class,
],
'aliases' => [
Psr\Http\Message\ResponseFactoryInterface::class => Zend\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Zend\Diactoros\StreamFactory::class,
]
],
];
我正在写另一个答案,因为它更容易阅读。 好的。我刚刚全新安装了 Zend Expressive 3 和 https://github.com/php-middleware/phpdebugbar:
- 作曲家要求 --dev php-middleware/php-debug-bar
- 作曲家转储自动加载
- 已创建 /config/autoload/debugbar.local.php
return array_merge(PhpMiddleware\PhpDebugBar\ConfigProvider::getConfig(), [
'phpmiddleware' => [
'phpdebugbar' => [
'javascript_renderer' => [
'base_url' => '/razvan.ionascu/ze-api/public',
],
'collectors' => [
DebugBar\DataCollector\ConfigCollector::class, // Service names of collectors
],
'storage' => null, // Service name of storage
],
],
'dependencies' => [
'factories' => [
\PhpMiddleware\PhpDebugBar\PhpDebugBarMiddleware::class => \PhpMiddleware\PhpDebugBar\PhpDebugBarMiddlewareFactory::class,
\DebugBar\DataCollector\ConfigCollector::class => \PhpMiddleware\PhpDebugBar\ConfigCollectorFactory::class,
\PhpMiddleware\PhpDebugBar\ConfigProvider::class => \PhpMiddleware\PhpDebugBar\ConfigProvider::class,
\DebugBar\DebugBar::class => \PhpMiddleware\PhpDebugBar\StandardDebugBarFactory::class,
JavascriptRenderer::class => NewJavascriptRendererFactory::class,
],
],
]);
为此,您需要创建一个新的 JavascriptRendererFactory。当前搜索错误的配置键,ConfigProvider::class 而不是 'config' :
class NewJavascriptRendererFactory
{
public function __invoke(ContainerInterface $container): JavascriptRenderer
{
$debugbar = $container->get(DebugBar::class);
$config = $container->get('config');
$rendererOptions = $config['phpmiddleware']['phpdebugbar']['javascript_renderer'];
$renderer = new JavascriptRenderer($debugbar);
$renderer->setOptions($rendererOptions);
return $renderer;
}
}
- 将以下别名和工厂添加到 /confog/atuoload/dependencies。global.php
'aliases' => [
\Psr\Http\Message\ResponseFactoryInterface::class => ResponseFactory::class,
\Psr\Http\Message\StreamFactoryInterface::class => StreamFactory::class,
],
'factories' => [
...
\DebugBar\JavascriptRenderer::class => JavascriptRendererFactory::class,
...
],
- 向 /config/pipeline 添加了新管道。php
//only works in development mode
if (!empty($container->get('config')['debug'])) {
$app->pipe(\PhpMiddleware\PhpDebugBar\PhpDebugBarMiddleware::class);
}
正如我在之前的评论中提到的,我还配置了 https://docs.zendframework.com/zend-servicemanager/reflection-abstract-factory/ ,因此我不需要为每个服务创建一个工厂()
See the working debug bar here
我明白了。 https://docs.zendframework.com/zend-expressive/v3/cookbook/debug-toolbars/ 处的说明是正确的。唯一需要的额外步骤是向配置添加 invokables
和 aliases
条目。
我的在 /config/autoload/zend-expressive-tooling-factories.global.php
:
return [
'dependencies' => [
'invokables' => [
Zend\Diactoros\ResponseFactory::class => Zend\Diactoros\ResponseFactory::class,
Zend\Diactoros\StreamFactory::class => Zend\Diactoros\StreamFactory::class,
],
'aliases' => [
Psr\Http\Message\ResponseFactoryInterface::class => Zend\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Zend\Diactoros\StreamFactory::class,
]
],
];
我最初只有 aliases
部分而不是 invokables
部分。添加后,一切正常。