Getting Started with Zend Framework 2
Agenda
- Framework Overview
- Benefits of using Framework
- Getting Started
- Installation (Skeleton App)
- File/Code Structure
- Modules
- Controllers, Views, Routing
- Database and Models
- Filters
- Service Manager
- Factory based instantiation
- Session Container
- Dependency Injection
What is a Framework?
“A Framework is a universal, reusable software platform to develop software applications, products and solutions. In other words, we can say it is some kind of library, a piece of software, which provide web developers with code base and consistent standardized ways of creating web applications”.
Benefits of using Framework
- Code and File Organization
- Enforcing of Good Coding Standards
- Utilities and Libraries
- Less Code & Faster Development
- Community Support
- Security
-
Modular, use what you need, ignore what you don’t
-
Strong use of OOP and Design Patterns for Consistency
Getting Started
Tutorial: https://docs.zendframework.com/tutorials/getting-started/overview/
Routing: https://docs.zendframework.com/tutorials/in-depth-guide/understanding-routing/
Input Filters: https://framework.zend.com/manual/2.4/en/modules/zend.input-filter.intro.html
Session Container: https://framework.zend.com/manual/2.4/en/modules/zend.session.container.html
Modules
A module is a software component or part of a program that contains one or more routines. One or more independently developed modules make up a program. An enterprise-level software application may contain several different modules, and each module serves unique and separate business operations.
Creating a Module
// SAMPLE Module.php file
namespace Album;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
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';
}
}
1. Create directory for the module
2. create sub directories(src, config, view)
3. create Module.php under src/ directory
4. create config/module.config.php
5. Register module to application.config.php
6. Update composer.json, add module to autoload
7. run composer dump-autoload
Creating a Controller
namespace Album\Controller;
class AlbumController extends AbstractActionController { public function __construct() { } }
1. Create controller under src/Controller/AlbumController.php directory
2. Controller class should extend AbstractActionController
3. Create a Factory for the controller under src/ServiceFactory/Controller/ (AlbumControllerFactory.php)
<?php namespace Album\ServiceFactory\Controller; use Psr\Container\ContainerInterface; class AlbumControllerFactory { public function __invoke(ContainerInterface $container) { $container = $container->getServiceLocator(); // remove if zf3 // $AlbumTable = $container->get(AlbumTable::class); // sample call for getting services from service manager return new AlbumController(); } }
Creating a Controller
'controllers' => array( 'factories' => array( AlbumController::class => AlbumControllerFactory::class ) ),
4. Register controller in config/module.config.php
Routing
'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', ], ], ], 'home' => [ 'type' => Literal::class, 'options' => [ 'route' => '/', 'defaults' => [ 'controller' => IndexController::class, 'action' => 'index', ] ] ] ], ],
Route configuration is placed inside module.config.php file
Sample Segment and Literal Route Configuration
Models and Tables
namespace Album\Model; class Album { public $id; public $artist; public $title; public function exchangeArray(array $data) { $this->id = !empty($data['id']) ? $data['id'] : null; $this->artist = !empty($data['artist']) ? $data['artist'] : null; $this->title = !empty($data['title']) ? $data['title'] : null; } }
Models and Table classes are placed under src/Model directory.
Sample Model:
Models and Tables
namespace Album\Model; use Zend\Db\TableGateway\TableGateway; class AlbumTable { private $tableGateway; public function __construct(TableGateway $tableGateway) { $this->tableGateway = $tableGateway; } }
Sample Table class
Models and Tables
namespace Album\ServiceFactory\Model; use Album\Model\Album; use Album\Model\AlbumTable; use Psr\Container\ContainerInterface; use Zend\Db\ResultSet\ResultSet; use Zend\Db\TableGateway\TableGateway; class AlbumTableFactory { public function __invoke(ContainerInterface $container) { // Creation for table gateway instance $dbAdapter = $container->get('test'); $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Album()); // create TableGateway instance $tableGateway = new TableGateway( 'album', $dbAdapter, null, $resultSetPrototype ); // Create AlbumTable instance return new AlbumTable($tableGateway); } }
Create a Factory for AlbumTable class under src/ServiceFactory/Model directory
Models and Tables
'service_manager' => array( 'factories' => array( AlbumTable::class => AlbumTableFactory::class, 'Album\Storage\AlbumSessionContainer' => AlbumSessionContainerFactory::class, ), 'invokables' => array( AlbumFilter::class => AlbumFilter::class, ) ),
Register AlbumTable in module.config.php service manager factories
Models and Tables
return array( 'service_manager' => array( 'abstract_factories' => array( 'Zend\Db\Adapter\AdapterAbstractServiceFactory', ), ), 'db' => array( 'adapters' => array( 'test' => array( 'driver' => 'Pdo_Mysql', 'driver_options' => array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' ) ), ), ), );
Add Database Adapters by updating global.php config file
Add Database Connection Configuration in local.php config file
return array( 'db' => array( 'adapters' => array( 'test' => array( 'dsn' => 'mysql:dbname=test;host=mysql-57', 'username' => 'root', 'password' => 'root' ), ), ), );
Models and Tables
public function selectWithJoin() { $select = $this->tableGateway->getSql()->select(); $select->columns(array("artist")); $select->join( array("a" => "artists"), "a.artist_id = album.artist_id", array("*"),"LEFT" ); // query to fetch specific column $resultSet = $this->tableGateway->selectWith($select)->getDataSource(); // this will return columns that are not specified in the query, // but values are null $resultSet = $this->tableGateway->selectWith($select); foreach ($resultSet as $row) { \Zend\Debug\Debug::dump($row); exit; } // dump sql query /// echo $this->tableGateway->getSql()->getSqlStringForSqlObject($select); }
Sample select with joins
Input Filters
namespace Album\Filter; use Zend\InputFilter\InputFilter; use Zend\Validator\NotEmpty; class AlbumFilter extends InputFilter { public function __construct() { $this->add(array( 'name' => 'artist', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array( 'name' => 'StringTrim', ), ), 'validators' => array( array( 'name' => 'StringLength', 'options' => array( 'min' => 1, 'max' => 35, 'messages' => array( 'stringLengthTooShort' => 'Artist is too short.', 'stringLengthTooLong' => 'Artist is too long.' ), ), ), ), )); }
Create Filters under src/Filter directory.
Then register in service manager as invokables if there are no dependencies, otherwise create Factory for your filter class then register in service manager factories
Session Manager
public function onBootstrap(MvcEvent $e) { .... Some codes here .... /** * This method will handle the setting of session sharing configurations * and also starting the session manager. */ $sm = $e->getApplication()->getServiceManager(); $config = $sm->get('Configuration'); $sessionConfig = new SessionConfig(); $sessionConfig->setOptions($config['session_config']); $sessionManager = new SessionManager($sessionConfig); $sessionManager->start(); }
Configure and Start Session Manager
1. Edit Application/src/Module.php and update onBootstrap method
2. Add session configuration in local.php
'session_config' => array( 'remember_me_seconds' => 2419200, 'use_cookies' => true, 'cookie_domain' => '.zftraining.com', // 'php_save_handler' => 'memcache', // 'save_path' => 'tcp://memcached-session:11211', ),
Factory Design Pattern
Dependency Injection
Dependency injection (Di) is a design pattern which purpose is to reduce the coupling between software components.

Service Manager
- Allow to programmatically configure dependencies.
- Use to easily apply Inversion Of Control.
- Creates and stores instances of your objects: an instance manager.
Getting Started with
By pgamilde
Getting Started with
- 728