![](/img/trans.png)
[英]Zend 3 error: Argument to AlbumController::__construct() must be an instance of Album\Model\AlbumTable, none given
[英]Catchable fatal error: Argument 1 passed to Album\Controller\AlbumController::__construct() must be an instance of Album\Model\AlbumTable, none given
我刚刚在文档的帮助下安装了项目; 我收到此错误:
错误
可捕获的致命错误:传递给 Album\Controller\AlbumController::__construct() 的参数 1 必须是 Album\Model\AlbumTable 的实例,未给出,在 C:\wamp64\www\myalbums\vendor\zendframework\zend-servicemanager 中调用第 30 行的 \src\Factory\InvokableFactory.php 并在第 15 行的 C:\wamp64\www\myalbums\module\Album\src\Controller\AlbumController.php 中定义
模块.config.php
<?php
namespace Album;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'controllers' => [
'factories' => [
Controller\AlbumController::class => InvokableFactory::class,
],
],
// The following section is new and should be added to your file:
'router' => [
'routes' => [
'album' => [
'type' => Segment::class,
'options' => [
'route' => '/album[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\AlbumController::class,
'action' => 'index',
],
],
],
],
],
'view_manager' => [
'template_path_stack' => [
'album' => __DIR__ . '/../view',
],
],
];
相册表.php
namespace Album\Model;
use RuntimeException;
use Zend\Db\TableGateway\TableGatewayInterface;
class AlbumTable
{
private $tableGateway;
public function __construct(TableGatewayInterface $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
return $this->tableGateway->select();
}
public function getAlbum($id)
{
$id = (int) $id;
$rowset = $this->tableGateway->select(['id' => $id]);
$row = $rowset->current();
if (! $row) {
throw new RuntimeException(sprintf(
'Could not find row with identifier %d',
$id
));
}
return $row;
}
public function saveAlbum(Album $album)
{
$data = [
'artist' => $album->artist,
'title' => $album->title,
];
$id = (int) $album->id;
if ($id === 0) {
$this->tableGateway->insert($data);
return;
}
if (! $this->getAlbum($id)) {
throw new RuntimeException(sprintf(
'Cannot update album with identifier %d; does not exist',
$id
));
}
$this->tableGateway->update($data, ['id' => $id]);
}
public function deleteAlbum($id)
{
$this->tableGateway->delete(['id' => (int) $id]);
}
}
专辑控制器.php
namespace Album\Controller;
use Album\Model\AlbumTable;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class AlbumController extends AbstractActionController
{
// Add this property:
private $table;
// Add this constructor:
public function __construct(AlbumTable $table)
{
$this->table = $table;
}
public function indexAction()
{
return new ViewModel([
'albums' => $this->table->fetchAll(),
]);
}
public function addAction()
{
}
public function editAction()
{
}
public function deleteAction()
{
}
}
该错误来自 AlbumController 构造函数,该构造函数期望在创建前者时注入 AlbumTable 对象。
控制器创建于
Controller\AlbumController::class => InvokableFactory::class,
使用没有构造函数参数的标准工厂。
您需要将其更改为:
Controller\AlbumController::class => function($container) {
return new Controller\AlbumController(
$container->get(\Album\Model\AlbumTable::class)
);
},
以便为工厂提供依赖项(AlbumTable)。
AlbumTable 也应该有自己的工厂(也许你的配置中已经有了):
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
'service_manager' => [
'factories' => [
\Album\Model\AlbumTable::class => function($sm) {
$tableGateway = $sm->get('AlbumTableGateway');
$table = new \Album\Model\AlbumTable($tableGateway);
return $table;
},
'AlbumTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
]
],
其中TableGateway('album')
的 'album' 是您的数据库表名。
Controller\AlbumController::class => InvokableFactory::class,
改成
Controller\AlbumController::class => Controller\AlbumControllerFactory::class,
然后在 Controller 目录中创建 AlbumControllerFactory 类
namespace Album\Controller;
use Album\Controller\AlbumController;
use Zend\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
use Album\Model\AlbumTable;
class AlbumControllerFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName, array $options = null){
$model = $container->get(AlbumTable::class);
return new AlbumController($model);
}
}
此外,如果您没有 AlbumModel 的工厂,您可以以相同的方式创建它,这样您的 modlue.config.php 看起来就像例如。
....
'controllers' => [
'factories' => [
Controller\AlbumController::class => Controller\AlbumControllerFactory::class,
],
],
'service_manager' => [
'factories' => [
Model\AlbumModel::class => Model\AlbumModelFactory::class,
],
],
....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.