আগামী ১৫ ডিসেম্বর -২০১৭ তারিখ থেকে শুরু হচ্ছে পাঁচ মাস ব্যাপী Professional Web Design and Development with HTML, CSS PHP,MySQL,JavaScript, AJAX, JQUERY, Bootstrap and Live Project কোর্সের ৮৭ তম ব্যাচ এবং ২৬ ডিসেম্বর-২০১৭ তারিখ থেকে শুরু হচ্ছে চার মাস ব্যাপী Zend PHP-7 Certified PHP Engineering (Advance PHP) কোর্সের ৩৫ তম ব্যাচ। প্রত্যেকটি কোর্স এর ফী নির্ধারণ করা হয়েছে ৩০,০০০/= আগ্রহীদেরকে অতিসত্বর মাসুদ আলম স্যার এর সাথে যোগাযোগ করতে অনুরোধ করা যাচ্ছে। স্যার এর মোবাইল: 01722 81 75 91

CRUD with Zend Framework 2 Part-1: Show Users List From Database

Introduction

In this tutorial We are going to create a CRUD system with “Zend Framework 2”. The main page will list of users and allow us to add, edit and delete users. I assume you have completed the Part-1, Part2 and Part-3 a lot of the steps I already explained in there. Now We are going to need four pages in our website:

Page Description
List of users This will display the list of users and provide links to edit and delete them. Also, a link to enable adding new usres will be provided.
Add new users This page will provide a form for adding a new user.
Edit users This page will provide a form for editing an user.
Delete users This page will confirm that we want to delete an user and then delete it.

 Now, we will be creating a database called “zf2_test” and table called “users” in MySQL database for save and retrieve data using this table. Run Below SQL Query in Your Favourite MySQL Tools e.g phpmyadmin,sqlyog

 CREATE TABLE IF NOT EXISTS `users` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(50) NOT NULL,

`email` varchar(100) NOT NULL,

`address` varchar(255) NOT NULL,

`mobile` varchar(15) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=21 ;

--

-- Dumping data for table `users`

--

INSERT INTO `users` (`id`, `name`, `email`, `address`, `mobile`) VALUES

(16, 'Ezaj Karim', '[email protected]', 'Lahore, Pakistan', '01722875491'),

(17, 'Arefin Newaj', '[email protected]', 'Dhaka,Bangladesh', '01899876543'),

(18, 'Privish Krishna', '[email protected]', 'Katmondu,Nepal', '01877991122'),

(19, 'Bprokash Dash', '[email protected]', 'Delhi,India', '098765432'),

(20, 'Lasith Mehanga', '[email protected]', 'Colombo,Srilanka', '324567891');

Zend Framework 2 uses a modular system now we create a new module, which we’ll call “Users”. Let’s first create the configuration files of the module:

Let’s Go …

Creating the Structure Module

  1. First Create a new folder called “Users” within the “directory zf2/module . Inside the “Users“, create 3 folders: “config“, “src” and “view“. Also create a file called ” Module.php “, and leave it blank for now.
  2. Inside the “src” folder, create another folder called “Users” (Capitalized same, because the namespace)
  3. Inside the “src/Users” Create a Folder called “Controller” (Capitalized same, because the namespace), and also create “UsersController.php” file within the “src/Users/Controller” folder.
  4. Inside the “view” folder, create another folder called “users” (this lowercase).
  5. Finally, create a file called “module.config.php ” in the folder “config“, blank for now.

Note that the structure will look like this:

Zend Framework 2 Crud Folder and File Structure

For now these are the directories and files that need. Come to the most important part of this process: The configuration of this module.

 Informing the application about our new module

 The first step is to enable the module . In Zend Framework is all explicit, so if we create a module, we configure it properly and do not set this module is active, it will not run. To activate it, open the file ” zf2/config/application.config.php “and add the module name in this array there.See:

<?php

return array (

'Modules' => array (

'Application',
 'Users',   // This line was added to activate the module

)

'Module_listener_options' => array (

'Module_paths' => array (

'. / Module',
 '. / Vendor',
 )

'Config_glob_paths' => array (

'Config / autoload / {*.} {Global, local}. Php',
 )

)

);

Setup Routing

Create the necessary views and modify the module’s  “/zf2/module/Users/config/module.config.php” file. We will add a route for our users actions. Add the following code:

<?php

return array(
    'controllers' => array(
        'invokables' => array(
            'Users\Controller\Users' => 'Users\Controller\UsersController',
        ),
    ),
    // The following section is new and should be added to your file
    'router' => array(
        'routes' => array(
            'users' => array(
                'type' => 'segment',
                'options' => array(
                    'route' => '/users[/:action][/:id]',
                    'constraints' => array(
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'id' => '[0-9]+',
                    ),
                    'defaults' => array(
                        'controller' => 'Users\Controller\Users',
                        'action' => 'index',
                    ),
                ),
            ),
        ),
    ),
    'view_manager' => array(
        'template_path_stack' => array(
            'users' => __DIR__ . '/../view',
        ),
    ),
);

 The name of the route is ‘users’ and has a type of ‘segment’. The segment route allows us to specify placeholders in the URL pattern (route) that will be mapped to named parameters in the matched route. In this case, the route is “/users[/:action][/:id]“ which will match any URL that starts with /users. The next segment will be an optional action name, and then finally the next segment will be mapped to an optional id. The square brackets indicate that a segment is optional. The constraints section allows us to ensure that the characters within a segment are as expected, so we have limited actions to starting with a letter and then subsequent characters only being alphanumeric, underscore or hyphen. We also limit the id to a number.

This route allows us to have the following URLs:

URL Page Action
/users Home (list of users) index
/users/add Add new user add
/users/edit/2 Edit user with an id of 2 edit
/users/delete/4 Delete user with an id of 4 delete

Create the controller

Now we need to create our controller class UsersController.php at zf2/module/Users/src/Users/Controller :

<?php

namespace Users\Controller;

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

class UsersController extends AbstractActionController {

    public function indexAction() {
        
    }

    public function addAction() {
        
    }

    public function editAction() {
        
    }

    public function deleteAction() {
        
    }

}

Create the views:

Now we need to Create view files within the directory ” / zf2/module/Users/view/users / “a new directory called” users “.This refers to the folder Controller “UsersController” . Now inside the directory ” / zf2/module/Users/view/users/users “, Create these four empty files now:

 module/Users/view/users/users/index.phtml

module/Users/view/users/users/add.phtml

module/Users/view/users/users/edit.phtml

module/Users/view/users/users/delete.phtml

Creating Model

We can now start filling everything in, starting with our database and models.

Create a new model for the User class. This needs to be created under src/Users/Model/Users.php.

 

<?php

namespace Users\Model;

class Users {

    public $id;
    public $name;
    public $email;
    public $mobile;
    public $address;

    public function exchangeArray($data) {

        $this->id = (!empty($data['id'])) ? $data['id'] : null;

        $this->name = (!empty($data['name'])) ? $data['name'] : null;

        $this->email = (!empty($data['email'])) ? $data['email'] : null;

        $this->mobile = (!empty($data['mobile'])) ? $data['mobile'] : null;

        $this->address = (!empty($data['address'])) ? $data['address'] : null;
    }

}
 

The User model will define the exchangeArray() method:

the exchangeArray() method; This method simply copies the data from the passed in array to our entity’s properties

Next, we create our UsersTable.php file in module/Users/src/Users/Model directory like this:

<?php

namespace Users\Model;

use Zend\Db\TableGateway\TableGateway;

class UsersTable {

    protected $tableGateway;

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

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

}

Above code we set the protected property $tableGateway to the TableGateway instance passed in the constructor. We will use this to perform operations on the database table for our users. Then we create a helper method fetchAll() that retrieves all users rows from the database as a ResultSet

 Zend Framework 2 ServiceManager to configure the users gateway and inject into the UsersTable

 The ZF2 ServiceManager implements the service locator design pattern. The service locator is a service/object locator used for retrieving other objects. The ServiceManager configurations are classified into six main categories; your application/module configuration will fall under one or more of the categories listed in the following table:

Configuration type Description
abstract_factories Used to define an array of abstract classes.
aliases

Used to define an associative array of alias name / target name pairs.

factories

Used to define an array of service name / factory class name pairs. The factory classes defined here should either implement Zend/ServiceManager/FactoryInterface or invokable classes.

invokables

Used to define an array of service name / class name pairs. The classes listed here may be directly instantiated without any constructor arguments.

services

Used to define an array of service name / object pairs. The service is basically an instance of a class. Services can be used to register classes which are already initialized.

shared

Used to define an array of service name / Boolean pairs, indicating whether or not a service should be shared. All services are shared by default; this ServiceManager option can be used to disable sharing on specific services.

The ServiceManager configuration can be stored either in the application configuration or in the module configuration; this can be chosen according to the needs, application, or module.

 Now we configure the ServiceManager, we can either supply the name of the class to be instantiated or a factory (closure or callback) that instantiates the object when the ServiceManager needs it. We start by implementing getServiceConfig() to provide a factory that creates an UsersTable. Add this method to the bottom of the Module.php file in module/Users.

 <?php

namespace Users;

use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Users\Model\Users;
use Users\Model\UsersTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;

class Module {

    public function onBootstrap(MvcEvent $e) {

        $eventManager        = $e->getApplication()->getEventManager();

        $moduleRouteListener = new ModuleRouteListener();

        $moduleRouteListener->attach($eventManager);
    }

    public function getConfig() {

        return include __DIR__ . '/config/module.config.php';
    }

    public function getAutoloaderConfig() {

        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

    public function getServiceConfig() {

        return array(

        'factories' => array(

        'Users\Model\UsersTable' =>   function($sm) {

        $tableGateway = $sm->get('UsersTableGateway');

        $table = new UsersTable($tableGateway);

        return $table;

        },
        'UsersTableGateway' => function ($sm) {

        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');

        $resultSetPrototype = new ResultSet();

        $resultSetPrototype->setArrayObjectPrototype(new Users());

        return new TableGateway('users', $dbAdapter, null, $resultSetPrototype);

        },
        ),
        );
    }

}

This method returns an array of factories that are all merged together by the ModuleManager before passing to the ServiceManager. The factory for  Users\Model\UsersTable uses the ServiceManager to create an UsersTableGateway to pass to the UsersTable. We also tell the ServiceManager that an UsersTableGateway is created by getting a Zend\Db\Adapter\Adapter (also from the ServiceManager) and using it to create a TableGateway object.

The TableGateway is told to use an Users object whenever it creates a new result row. The UsersGateway classes use the prototype pattern for creation of result sets and entities.

Now we need to configure the ServiceManager so that it knows how to get a Zend\Db\Adapter\Adapter.

This is done using a factory called Zend\Db\Adapter\AdapterServiceFactory which we can configure within the merged config system. Zend Framework 2’s ModuleManager merges all the configuration from each module’s module.config.php file and then merges in the files in config/autoload (*.global.php and then *.local.php files).

We’ll add our database configuration information to global.php which you should commit to your version control system. You can use local.php (outside of the VCS) to store the credentials for your database if you want.

Modify config/autoload/global.php (in the Zend Skeleton root, not inside the users module) with following code:

<?php

return array(
    'db' => array(
        'driver' => 'Pdo',
        'dsn' => 'mysql:dbname=zf2_test;host=localhost',
        'username' => 'root',
        'password' => '',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),
    ),
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter'
            => 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
    ),
);

Back to the controller

Now that the ServiceManager can create an UsersTable instance for us, we can add a method to the controller to retrieve it. Add getUsersTable() to the UsersController class:

// module/Users/src/Users/Controller/UsersController.php:

public function getUsersTable() {

    if (!$this->usersTable) {

        $sm = $this->getServiceLocator();

        $this->usersTable = $sm->get('Users\Model\UsersTable');
    }

    return $this->usersTable;
}

You should also add:

protected $usersTable;

to the top of the class.

We can now call getUsersTable() from within our controller whenever we need to interact with our model.

If the service locator was configured correctly in Module.php, then we should get an instance of Users\Model\UsersTable when calling getUsersTable().

Listing users

In order to list the users, we need to retrieve them from the model and pass them to the view. To do this, we fill in indexAction()within UsersController. Update the UsersController’s indexAction() like this:

<?php

namespace Users\Controller;

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

class UsersController extends AbstractActionController {

    protected $usersTable;

    public function indexAction() {

        return new ViewModel(array(
            'users' => $this->getUsersTable()->fetchAll(),
        ));
    }

    public function addAction() {
        
    }

    public function editAction() {
        
    }

    public function deleteAction() {
        
    }

// module/Users/src/Users/Controller/UsersController.php:

    public function getUsersTable() {

        if (!$this->usersTable) {

            $sm = $this->getServiceLocator();

            $this->usersTable = $sm->get('Users\Model\UsersTable');
        }

        return $this->usersTable;
    }

}

Finally We can now fill in the index.phtml view script:

<?php
$title = 'Users Management';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>

<table class="table table-bordered table-striped table-hover">
    <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Mobile</th>
        <th>Address</th>
        <th>&nbsp;</th>
    </tr>
    <?php foreach ($users as $user) : ?>
        <tr>
            <td><?php echo $this->escapeHtml($user->name); ?></td>
            <td><?php echo $this->escapeHtml($user->email); ?></td>
            <td><?php echo $this->escapeHtml($user->mobile); ?></td>
            <td><?php echo $this->escapeHtml($user->address); ?></td>
            <td>
                <a class="btn btn-info" href="<?php echo $this->url('users', array('action' => 'edit', 'id' => $user->id));
                ?>"><span class="glyphicon glyphicon-pencil"></span>&nbsp;Edit</a>
                <a class="btn btn-danger" href="<?php echo $this->url('users', array('action' => 'delete', 'id' => $user->id));
    ?>"><span class="glyphicon glyphicon-trash"></span>&nbsp;Delete</a>
            </td>
        </tr>
    <?php endforeach; ?>
    <tr>
        <td colspan="5">  <a class="btn btn-success pull-right" href="<?php echo $this->url('users', array('action' => 'add')); ?>"><span class="glyphicon glyphicon-plus-sign"></span>&nbsp;
                Add new User&nbsp;<span class="glyphicon glyphicon-user"></span></a></td>
    </tr>
</table>

  • The first thing we do is to set the title for the page (used in the layout) and also set the title for the  <head> section using the headTitle() view helper which will display in the browser’s title bar. We then create a link to add a new users.
  • The url() view helper is provided by Zend Framework 2 and is used to create the links we need. The first parameter to url() is the route name we wish to use for construction of the URL, and the second parameter is an array of all the variables to fit into the placeholders to use. In this case we use our ‘users’ route which is set up to accept two placeholder variables: action and id.
  • We iterate over the $users that we assigned from the controller action. The Zend Framework 2 view system automatically ensures that these variables are extracted into the scope of the view script, so that we don’t have to worry about prefixing them with $this-> as we used to have to do with Zend Framework 1; however you can do so if you wish.
  • We then create a table to display each users’s title and artist, and provide links to allow for editing and deleting the record. A standard foreach: loop is used to iterate over the list of userss, and we use the alternate form using a colon and endforeach; as it is easier to scan than to try and match up braces. Again, the url() view helper is used to create the edit and delete links.

If you open http://zf2/users  you should see this:

Show Users List From Database Using Zend Framework 2

Warmest regards and until next time.

CRUD with Zend Framework 2 Part-1

Hi, My name is Masud Alam, love to work with Open Source Technologies, living in Dhaka, Bangladesh. I’m a Certified Engineer on ZEND PHP 5.3, I served my first five years a number of leadership positions at Winux Soft Ltd, SSL Wireless Ltd, Canadian International Development Agency (CIDA), World Vision, Care Bangladesh, Helen Keller, US AID and MAX Group where I worked on ERP software and web development., but now i’m a founder and CEO of TechBeeo Software Company Ltd. I’m also a Course Instructor of ZCPE PHP 7 Certification and professional web development course at w3programmers Training Institute – a leading Training Institute in the country.

7 comments on “CRUD with Zend Framework 2 Part-1: Show Users List From Database
  1. get error..
    File:

    D:\webserver\htdocs\zf2crud\vendor\zendframework\zendframework\library\Zend\View\Renderer\PhpRenderer.php:499

    Message:

    Zend\View\Renderer\PhpRenderer::render: Unable to render template “users/users/index”; resolver could not resolve to a file

    Stack trace:

    #0 D:\webserver\htdocs\zf2crud\vendor\zendframework\zendframework\library\Zend\View\View.php(205): Zend\View\Renderer\PhpRenderer->render(Object(Zend\View\Model\ViewModel)) ….

    why?

  2. Hello Masud Alam,
    facing a problem
    “Namespace declaration statement has to be the very first statement in the script in C:\xampp\htdocs\TestZf\module\Users\Module.php on line 3”
    Thanks

    • Please go to Module.php and do not copy the code form the site, you should just write in netbeens. Then restart your server again and try……

  3. j’ai ce probleme ( ! ) Fatal error: Namespace declaration statement has to be the very first statement in the script in C:\wamp\www\zf2\module\Users\module.php on line 2

Leave a Reply

Your email address will not be published. Required fields are marked *