3
votes

I am currently working through the Zend 3 tutorial. The only difference is I am using an Examples table/class instead of Albums. Everything appears to be as per spec except I am getting the following error every time I try to access the dev server:

Fatal error: Uncaught exception 'Zend\ServiceManager\Exception\ServiceNotFoundException' with message 'A plugin by the name "Example\Segment" was not found in the plugin manager Zend\Router\RoutePluginManager' in C:\Websites\ZEND2\vendor\zendframework\zend-servicemanager\src\AbstractPluginManager.php:133 Stack trace: #0 C:\Websites\ZEND2\vendor\zendframework\zend-router\src\SimpleRouteStack.php(280): Zend\ServiceManager\AbstractPluginManager->get('Example\Segment', Array) #1 C:\Websites\ZEND2\vendor\zendframework\zend-router\src\Http\TreeRouteStack.php(201): Zend\Router\SimpleRouteStack->routeFromArray(Array) #2 C:\Websites\ZEND2\vendor\zendframework\zend-router\src\Http\TreeRouteStack.php(151): Zend\Router\Http\TreeRouteStack->routeFromArray(Array) #3 C:\Websites\ZEND2\vendor\zendframework\zend-router\src\SimpleRouteStack.php(142): Zend\Router\Http\TreeRouteStack->addRoute('example', Array) #4 C:\Websites\ZEND2\vendor\zendframework\zend-router\src\SimpleRouteStack.php(86): Zend\Router\SimpleRouteStack->addRoutes(Array) in C:\Websites\ZEND2\vendor\zendframework\zend-servicemanager\src\AbstractPluginManager.php on line 133

ExampleController.php

namespace Example\Controller;

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

class ExampleController extends AbstractActionController
{
    private $table;

    public function indexAction()
    {
        return new ViewModel([
            'examples' => $this->table->fetchAll(),
        ]);
    }

    public function addAction()
    {
    }

    public function editAction()
    {
    }

    public function deleteAction()
    {
    }

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

ExampleTable.php

<?php 

namespace Example\Model;

use RuntimeException;
use Zend\Db\TableGateway\TableGatewayInterface;

class ExampleTable
{
    private $tableGateway;

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

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

    public function getExample($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 saveExample(Example $example)
    {
        $data = [
            'name' => $example->name,
            'description'  => $example->description,
            'web_url'  => $example->web_url,
        ];

        $id = (int) $example->id;

        if ($id === 0) {
            $this->tableGateway->insert($data);
            return;
        }

        if (! $this->getExample($id)) {
            throw new RuntimeException(sprintf(
                'Cannot update example with identifier %d; does not exist',
                $id
            ));
        }

        $this->tableGateway->update($data, ['id' => $id]);
    }

    public function deleteExample($id)
    {
        $this->tableGateway->delete(['id' => (int) $id]);
    }
}

module.config.php

<?php

namespace Example;

return [

    // The following section is new and should be added to your file:
    'router' => [
        'routes' => [
            'example' => [
                'type'    => Segment::class,
                'options' => [
                    'route' => '/example[/:action[/:id]]',
                    'constraints' => [
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'id'     => '[0-9]+',
                    ],
                    'defaults' => [
                        'controller' => Controller\ExampleController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
        ],
    ],

    'view_manager' => [
        'template_path_stack' => [
            'example' => __DIR__ . '/../view',
        ],
    ],
];

Module.php

<?php

namespace Example;

use Zend\Db\Adapter\Adapter;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module implements ConfigProviderInterface
{
    public function getConfig()
    {
        return include __DIR__ . '\config\module.config.php';
    }

    // Add this method:
    public function getServiceConfig()
    {
        return [
            'factories' => [
                Model\ExampleTable::class => function($container) {
                    $tableGateway = $container->get(Model\ExampleTableGateway::class);
                    return new Model\ExampleTable($tableGateway);
                },
                Model\ExampleTableGateway::class => function ($container) {
                    $dbAdapter = $container->get(AdapterInterface::class);
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Model\Example());
                    return new TableGateway('example', $dbAdapter, null, $resultSetPrototype);
                },
            ],
        ];
    }

     public function getControllerConfig()
    {
        return [
            'factories' => [
                Controller\ExampleController::class => function($container) {
                    return new Controller\ExampleController(
                        $container->get(Model\ExampleTable::class)
                    );
                },
            ],
        ];
    }
}

Example.php

namespace Example\Model;

class Example
{
    public $id;
    public $name;
    public $description;
    public $web_url

    public function exchangeArray(array $data)
    {
        $this->id     = !empty($data['id']) ? $data['id'] : null;
        $this->name = !empty($data['name']) ? $data['name'] : null;
        $this->description  = !empty($data['description']) ? $data['description'] : null;
        $this->web_url  = !empty($data['web_url']) ? $data['web_url'] : null;
    }
}

modules.config.php

<?php
/**
 * @link      http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
 * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

/**
 * List of enabled modules for this application.
 *
 * This should be an array of module namespaces used in the application.
 */
return [
    'Zend\Form',
    'Zend\Db',
    'Zend\Router',
    'Zend\Validator',
    'Application',
    'Example',
];

I have included everything as iam really not sure where the problem is. Any help will be greatly appreciated.

1
Please only include the code necessary to fix the issue. See the Stack Overflow guidelines hereCharlie Fish
In your module.config.php write 'segment' in place of Segment::classRavi Kant Mishra

1 Answers

15
votes

Your module.config.php file needs a:

use Zend\Router\Http\Segment;

declaration near the top to create the Segment alias that you use later on in the file. At the moment, because this doesn't exist, PHP is looking for that class in your declared namespace (so Example\Segment), which doesn't exist.