0
votes

I'm creating a CRUD app sample where i need to connect my ZF3 app to my database

My Models Post.php and PostTable.php respectively

namespace Post\Model;

    /**
     * 
     */
    class Post
    {

        protected $id;
        protected $title;
        protected $description;
        protected $category;
        public function exchangeArray($data){
            $this->id = $data['id'];
            $this->title = $data['title'];
            $this->description = $data['description'];
            $this->category = $data['category'];
        }
        public function getId(){
            return $this->id;
        }
        public function getTitle(){
            return $this->titile;
        }
        public function getDescription(){
            return $this->description;
        }
        public function getCategory(){
            return $this->category;
        }
    }

namespace Post\Model;

    use Zend\Db\TableGateway\TableGatewayInterface;
    /**
     * 
     */
    class PostTable
    {

        function __construct(TableGatewayInterface $tableGateway)
        {
            # code...
            $this->tableGateway = $tableGateway;

        }

        public function fetchAll(){
            return $tableGateway->select();
        }

    } 

Module.config.php


namespace Post;

use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;

return [
    'router' => [
        'routes' => [
            'home' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/',
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'application' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/post[/:action]',
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
        ],
    ],
    'controllers' => [
        'factories' => [
            Controller\IndexController::class => InvokableFactory::class,
        ],
    ],
    'view_manager' => [
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'doctype'                  => 'HTML5',
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',
        'template_map' => [
            'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
            'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
            'error/404'               => __DIR__ . '/../view/error/404.phtml',
            'error/index'             => __DIR__ . '/../view/error/index.phtml',
        ],
        'template_path_stack' => [
            __DIR__ . '/../view',
        ],
    ],
];

My Module.php

namespace Post;
use Zend\Db\AdapterInterface;
use Zend\Db\TableGateway;
use Zend\Db\ResultSet\ResultSet;
use Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module implements ConfigProviderInterface
{
    const VERSION = '3.0.3-dev';

    public function getConfig()
    {
        return include __DIR__ . '/../config/module.config.php';
    }
    public function getServiceConfig(){
        return [
            'factories' => [
                Model\PostTable::class => function($container){
                    $tableGateway = $container->get(Model\PostTableGateway::class);
                    return new Model\PostTable($tableGateway);
                },
                Model\PostTableGateway::class => function($container){
                    $adapter = $container->get(AdapterInterface::class);
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Model\Post);
                    return new tableGateway('post',$adapter,null,$resultSetPrototype);
                }
            ],

        ];
    }

    public function getControllerConfig(){
        return [
            'factories' => [
                controller\IndexController::class => function($container){
                    return new Controller\IndexController($controller->get(Model\PostTable::class));

                }
            ]
        ];
    }
}

IndexController.php

namespace Post\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class IndexController extends AbstractActionController
{
    public function __construct($table){
        $this->table = $table;
    }
    public function indexAction()
    {
        return new ViewModel();
    }
}

my ArgumentCountError exception Too few arguments to function Post\Controller\IndexController::__construct(), 0 passed in F:\Path\to\Project\vendor\zendframework\zend-servicemanager\src\Factory\InvokableFactory.php on line 30 and exactly 1 expected F:\Path\to\Project\module\Post\src\Controller\IndexController.php:15 The line 15

public function __construct($table){
        $this->table = $table;
    }

I expect to get a Result Set from the database. But the Constructor outputs an Argument Count Error exception

1

1 Answers

0
votes

There are two errors in your code.

First one is inside module.config.php, under the key controllers you must remove the old IndexController definition:

'router' => [
    ...
],
'controllers' => [
    'factories' => [
        // This one is obsolete, and you must remove it.
        // Controller\IndexController::class => InvokableFactory::class,
    ],
],
'view_manager' => [
    ...
],

Since you are declaring controllers inside Module.php class, controllers key in module.config.php is not necessary anymore, and you could remove it:

'router' => [
    ...
],
'view_manager' => [
    ...
],

Second one: there is a (double) mistake in IndexController factory (in Module.php).

  • The first is a wrongly typed namespace, controller instead of Controller.
  • The second one is that you use $controller instead of $container to retrieve the PostTable instance.
public function getControllerConfig() {
    return [
        'factories' => [
            Controller\IndexController::class => function($container) {
                return new Controller\IndexController($container->get(Model\PostTable::class));
            }
        ]
    ];
}