ZEND FRAMEWORK FOUNDATIONS CHUCK REEVES @MANCHUCK
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 WHAT WE WILL COVER ▸ Intro to Zend Framework 2 ▸ Modules ▸ Service Locator ▸ Event Manager ▸ MVC ▸ Forms ▸ Database ▸ Logging 2INTRO TO ZEND FRAMEWORK 2
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 http://framework.zend.com/manual/current/en/index.html https://github.com/manchuck/phpworld-zf2
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 BASICS
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 INTRO TO ZEND FRAMEWORK 2 ▸ Release in Fall 2012 ▸ Updated modules from Zend Framework 1 ▸ Collection of Individual components ▸ PSR-0 Compliant SOME BASICS 5
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 INTRO TO ZEND FRAMEWORK 2 GETTING STARTED ▸ Using the skeleton app cd my/project/dir
 git clone git://github.com/zendframework/ZendSkeletonApplication.git
 cd ZendSkeletonApplication
 php composer.phar install ▸ God Mode (aka Composer): "require": {
 "zendframework/zendframework": "~2.5"
 } 6
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 FILE STRUCTURE ▸ config - stores global config options ▸ data - cache, logs, session files ▸ module - your custom modules ▸ public - HTML, CSS, JS, Images ▸ test - Integration tests and test bootstrap INTRO TO ZEND FRAMEWORK 2 7
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 INTRO TO ZEND FRAMEWORK 2 APPLICATION BASICS ▸ At its core, ZF2 applications have 6 dependancies: 1. ZendConfig - a Traversable object containing merged config 2. ZendServiceManager - A Service Locator for loading/creating objects 3. ZendEventManager - An Event dispatcher for controlling application flow 4. ZendModuleManager - Used for loading/finding configured modules 5. Request - Helper for managing the incoming request 6. Response - Helper for returning a response 8
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MODULES
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MODULES FILE STRUCTURE ▸ config - holds the config(s) ▸ language - PO language files (or other I18N translations) ▸ src - source code for the modules ▸ test - module specific tests ▸ view - view scripts and layout ▸ autoload_classmap - maps classes to files ▸ Module.php - bootstrap for the module 10
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MODULES BOOTSTRAPPING MODULES ‣ The ModuleManager brokers loading files using the EventManager ‣ Allows initializing 3rd party libraries ‣ Three methods for bootstrapping: ‣ init ‣ modulesLoaded ‣ onBootstrap 11
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MODULES THE ONLY THING A MODULE NEEDS 12 
 use ZendModuleManagerFeatureAutoloaderProviderInterface;
 use ZendModuleManagerFeatureConfigProviderInterface;
 
 class Module implements ConfigProviderInterface, AutoloaderProviderInterface
 {
 public function getConfig()
 {
 return include __DIR__ . '/config/module.config.php';
 }
 public function getAutoloaderConfig()
 {
 return array(
 'ZendLoaderClassMapAutoloader' => array(
 __DIR__ . '/autoload_classmap.php',
 ),
 'ZendLoaderStandardAutoloader' => array(
 'namespaces' => array(
 __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
 ),
 ),
 );
 }
 }
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DEPENDENCY INJECTION - FOR THOSE WHO DON'T KNOW ▸ Instead of creating all the objects needed by a class, you "inject" a created object that the class knows how to interact with it ▸ Makes testing easier (you are writing tests correct?) ▸ Code changes are a breeze ▸ Reduces class coupling 14
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DEPENDENCY INJECTION - METHOD class MapService {
 public function getLatLong(
 GoogleMaps $map,
 $street,
 $city, 
 $state
 ) {
 return $map->getLatLong($street . ' ' . $city . ' ' . $state);
 }
 } 15
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DEPENDENCY INJECTION - __CONSTRUCT class MapService 
 {
 protected $map;
 public function __construct(GoogleMaps $map) {
 $this->$map = $map;
 }
 
 public function getLatLong($street, $city, $state ) {
 return $this->map->getLatLong($street . ' ' . $city . ' ' . $state);
 }
 } 16
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DEPENDENCY INJECTION - SETTERS class MapService
 {
 protected $map;
 public function setMap(GoogleMaps $map) {
 $this->$map = $map;
 }
 
 public function getMap() {
 return $this->map;
 }
 
 public function getLatLong($street, $city, $state ) {
 return $this->getMap()->getLatLong($street . ' ' . $city . ' ' . $state);
 }
 } 17
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER WHAT IS A SERVICE LOCATOR ▸ Purpose - "To implement a loosely coupled architecture in order to get better testable, maintainable and extendable code. DI pattern and Service Locator pattern are an implementation of the Inverse of Control pattern." * ▸ Keeps DI Simple and clean ▸ Only has two methods: get() and has() 18 * https://github.com/domnikl/DesignPatternsPHP/tree/master/More/ServiceLocator
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER WHAT IS IN THE SERVICE MANAGER ▸ Invokables - Objects that can just be called via "new <class_name>" ▸ Factories - a class that creates another (follows the factory pattern) ▸ Abstract Factories - Factories that create many objects using a config ▸ Initializers - Used to add additional dependancies after the object is created (ex. adding logging to classes with out having a huge dependency list) ▸ Delegators - wrappers that adds more functionality to existing objects ▸ Aliases - simpler names for services 19
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - CONFIG 'service_manager' => [
 'abstract_factories' => [
 'ZendLogLoggerAbstractServiceFactory',
 ],
 'factories' => [
 'MyModuleMyService' => 'MyModuleMyServiceFactory'
 ],
 'invokables' => [
 'FooBar' => 'stdClass'
 ],
 'delgators' => [
 'MyModuleMyService' => [
 'MyModuleMyServiceDelegator'
 ]
 ],
 'alises' => [
 'MyService' => 'MyModuleMyService'
 ]
 ] 20
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - THE WRONG WAY! 'factories' => [
 'MyModuleMyService' => function ($sm) {
 // do crazy things to build
 // this class and slow down // your application 
 return $service;
 }
 ], 21
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - THE WRONG WAY! ▸ SERIOUSLY DON'T USE CLOSURES TO REGISTER SERVICES ▸ YOU MIGHT AS WELL USE TABS ▸ LIKE EVER 22
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - CONCRETE OBJECT use ZendServiceManagerServiceManager;
 
 $serviceManager = new ServiceManager();
 
 //sets the created object instead of having the SM buildone
 $fooBar = new stdClass();
 $serviceManager->setService('FooBar', $fooBar); 23
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - IN CODE use ZendServiceManagerServiceManager;
 
 $serviceManager = new ServiceManager();
 
 $serviceManager->setFactory('MyModuleMyService', 'MyModuleMyServiceFactory'); 
 $serviceManager->setInvokableClass('FooBar', 'stdClass');
 $serviceManager->addAbstractFactory('ZendLogLoggerAbstractServiceFactory');
 $serviceManager->addDelegator('MyModuleMyService', 'MyModuleMyServiceDelegator');
 $serviceManager->setAlias('MyService', 'MyModuleMyService'); 24
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER FACTORIES ▸ Contains the code to build the object ▸ The ServiceManager is passed in to the create function ▸ can either implement ZendServiceManagerFactoryInterface or just implement __invoke 25
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER ABSTRACT FACTORIES ▸ Allows one factory that builds multiple objects based on a config ▸ Prevents writing multiple factories that do similar functions based on a config ▸ MUST Implement ZendServiceManagerAbstractFactoryInterface ▸ defines canCreateServiceWithName() and createServiceWithName() 26
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER ABSTRACT FACTORIES use ZendDbTableGatewayTableGateway;
 use ZendServiceManagerFactoryInterface;
 use ZendServiceManagerServiceLocatorInterface;
 
 class ProjectsTableFactory implements FactoryInterface {
 public function createService(ServiceLocatorInterface $serviceLocator) {
 $adapter = new $serviceLocator->get('ZendDbAdapterAdapter');
 return new TableGateway('projects', $adapter);
 }
 }
 
 class CategoriesTableFactory implements FactoryInterface {
 public function createService(ServiceLocatorInterface $serviceLocator) {
 $adapter = new $serviceLocator->get('ZendDbAdapterAdapter');
 return new TableGateway('categories', $adapter);
 }
 } 27
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER ABSTRACT FACTORIES use ZendDbTableGatewayTableGateway;
 use ZendServiceManagerAbstractFactoryInterface;
 use ZendServiceManagerServiceLocatorInterface;
 
 class TableAbstractFactory implements AbstractFactoryInterface {
 public function canCreateServiceWithName(ServiceLocatorInterface $sl, $name, $requestedName) {
 return preg_match("/Table$/", $requestedName);
 }
 
 public function createServiceWithName(ServiceLocatorInterface $sl, $name, $requestedName) {
 $adapter = $sl->get('ZendDbAdapterAdapter');
 $tableName = str_replace('Table', '', $requestedName);
 $tableName = strtolower($tableName);
 
 return new TableGateway($tableName, $adapter);
 }
 } 28
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER INITIALIZERS ▸ Applied to every object that the ServiceManager created ▸ Useful to inject other dependancies ▸ Do not over use them (50 Initializers with 300 objects means 15,000 calls) 29
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DELEGATORS ▸ Add functionality to a class ▸ Transfers process to another object based on conditions ▸ Technically ZF2 delegators are decorators ▸ https://en.wikipedia.org/wiki/Delegation_pattern 30
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DELEGATORS - HOW THEY WORK ▸ A delegator factory (MUST implement ZendServiceManager DelegatorFactoryInterface) ▸ FactoryClass MUST BE registered as separate service in the ServiceManager ▸ Note: the delegator will not be passed through initializers 31
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER OTHER SERVICE MANAGERS ▸ ZF2 builds other service managers that will be injected with the main service manager ▸ ControllerManager, InputFilterManager, RouterPluginManager, and FormElementManager are just some 32
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER EVENT MANAGER ▸ Aspect Oriented Programming (AOP) ▸ What it is useful for: ▸ Logging ▸ Caching ▸ Authorization ▸ Sanitizing ▸ Auditing ▸ Notifying the user when something happens (or fails) 34
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER ASPECT ORIENTED PROGRAMMING 101 - TERMS ▸ Aspect - The object being interacted with ▸ Advice - What should be done with each method of the aspect ▸ Joinpoint - Places where Advice can be created ▸ Pointcut - Matches Joinpoint to an Advice 35
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER ASPECT ORIENTED PROGRAMMING 101 - ADVICE TYPES ▸ Before advice - Applied before the advice is called ▸ After returning advice - Applied after the advice is called ▸ After throwing advice - Applied when an error happens ▸ Around advice - combines the Before and After returning advice* 36 http://www.sitepoint.com/explore-aspect-oriented-programming-with-codeigniter-1/
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER HOW IT WORKS IN ZF2 ▸ Events chain until no more listeners are registered or a listener stops propagation of events ▸ Listeners are called in order of priority. From the higher number to lower number ▸ Responses from each listener is stored in a collection and returned back to the calling code 37
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER REGISTERING EVENTS - CALLBACKS use ZendEventManagerEventManager;
 use ZendEventManagerEvent;
 use ZendLogLogger;
 
 $log = new Logger(['writers' => [['name' => 'noop']]]);
 $events = new EventManager();
 $events->attach('my_event', function (Event $event) use ($log) {
 $event = $event->getName();
 $target = get_class($event->getTarget());
 $params = json_encode($event->getParams());
 
 $log->info(sprintf(
 '%s called on %s, using params %s',
 $event,
 $target,
 $params
 ));
 });
 
 $target = new stdClass();
 $params = ['foo' => 'bar'];
 $events->trigger('my_event', $target, $params); 38
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER REGISTERING EVENTS - AGGREGATE class Listener implements ListenerAggregateInterface, LoggerAwareInterface
 {
 use LoggerAwareTrait;
 
 protected $listeners = [];
 
 public function attach(EventManagerInterface $events) {
 $this->listeners[] = $events->attach('my_event', [$this, 'logEvent'], 1000);
 }
 
 public function detach(EventManagerInterface $events) {
 foreach ($this->listeners as $index => $callback) {
 if ($events->detach($callback)) {
 unset($this->listeners[$index]);
 }
 }
 }
 }
 
 $events->attach(new Listener()); 39
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER REGISTERING EVENTS - OTHER ▸ Register a listener to multiple events using an array $events->attach(['my_event_1', 'my_event_2'], [$this, 'logEvent']); ▸ Or using a wildcard $events->attach('*', [$this, 'logEvent']); 40
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER SHARED EVENT MANAGER ▸ Segregates events from other classes that could interfere with the listeners ▸ JIT loading of listeners to keep the event manager lightweight 41
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER SHARED EVENT MANAGER - REGISTERING LISTENERS public function setEventManager(EventManagerInterface $eventManager)
 {
 $eventManager->addIdentifiers(array(
 get_called_class()
 ));
 
 $this->eventManager = $eventManager;
 } 43
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER SHARED EVENT MANAGER - REGISTERING LISTENERS public function onBootstrap(MvcEvent $event)
 {
 $eventManager = $event->getApplication()- >getEventManager();
 $sharedEventManager = $eventManager->getSharedManager();
 
 $sharedEventManager->attach('MyService', 'my_event', function($e) {
 var_dump($e);
 }, 100);
 } 44
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC MODELS ▸ Nothing special they are just classes 46
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC MVC_EVENT ▸ Created during application bootstrap ▸ Provides helpers to access the Application, Request, Response, Router, and the View. (all these are injected during the bootstrap event 47
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC MVC_EVENT - EVENTS ▸ MvcEvent::EVENT_BOOTSTRAP - Prepares the application ▸ MvcEvent::EVENT_ROUTE - Matches the request to a controller ▸ MvcEvent::EVENT_DISPATCH - Call the matched controller ▸ MvcEvent::EVENT_DISPATCH_ERROR - Error happens during dispatch ▸ MvcEvent::EVENT_RENDER - Prepares the data to be rendered ▸ MvcEvent::EVENT_RENDER_ERROR - Error during rendering ▸ MvcEvent::EVENT_FINISH - Finial task 48
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC ROUTING ▸ Provides a means to match a request to a controller ▸ Matching can be made on any part of the URL ▸ Three router types: ConsoleSimpleRouteStack, HttpSimpleRouterStack and HttpTreeRouterStack 49
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC CONTROLLERS ▸ Controllers are dispatched from a Router ▸ A Controller just needs to implement ZendStdlibDispatchableInterface ▸ Other common interfaces for controllers: ▸ ZendMvcInjectApplicationEventInterface ▸ ZendServiceManagerServiceLocatorAwareInterface ▸ ZendEventManagerEventManagerAwareInterface 50
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC CONTROLLERS - DEFAULT ▸ ZendMvcControllerAbstractController ▸ ZendMvcControllerAbstractActionController ▸ ZendMvcControllerAbstractRestfulController ▸ ZendMvcControllerAbstractConsoleController 51
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC CONTROLLERS - PLUGINS ▸ Provides helper functions to controllers ▸ Default Plugins (More to come later) ▸ FlashMessenger ▸ Forward ▸ Params ▸ PostRedirectGet ▸ Redirect ▸ Url 52
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC CONTROLLER PLUGINS - CUSTOM PLUGINS IN 3 STEPS ▸ Create plugin ▸ Register in config ▸ Call in controller 53
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC VIEWS ▸ Views incorporate multiple levels to render a response ▸ By default uses the PHP template system (but can use your templating system of choice) ▸ Layouts are also possible since ViewModels can be nested ▸ Your controllers do not need to return a ViewModel 54
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC VIEW - ONE VIEW MANY LAYERS ▸ Containers - holds variables and or callbacks (typically a model or the array representation of the model) ▸ View Model - Connects the Container to a template (if applicable) ▸ Renders - Takes the Model and returns the representation of the model (Three are included by default: PhpRenderer, JsonRenderer, FeedRenderer) ▸ Resolvers - Uses a strategy to resolve a template for the renderer ▸ Rendering Strategies - Decides which renderer to use ▸ Response Strategies - Handles setting the headers responses 55
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC VIEWS - HOW TO USE ▸ From controller: $view = new ViewModel(array(
 'message' => 'Hello world',
 ));
 $view->setTemplate('my/template');
 return $view; ▸ Or return array(
 'message' => 'Hello world',
 ); 56
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC VIEW - HELPERS ▸ Used with the PhpRenderer ▸ Handles common functions within a view ▸ Check out the manual for complete list visit: http://framework.zend.com/ manual/current/en/modules/zend.view.helpers.html 57
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC VIEW - CREATING CUSTOM HELPERS ▸ Have your helper implement ZendViewHelperHelperInterface ▸ or just extend ZendViewHelperAbstractHelper ▸ Register the helper ▸ in the config under 'view_helpers' ▸ in the module by implementing ZendModuleManagerFeature ViewHelperProviderInterface 58
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC REQUEST AND RESPONSE ▸ Abstracts the HTTP (or console) Request and response ▸ Can also be used with the ZendHttp when you need to make CURL requests ▸ ViewModels can also understand the response based on different PHP runtimes (console or web requests) 59
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC RESPONSE use ZendHttpResponse; $response = new Response();
 $response->setStatusCode(Response::STATUS_CODE_200);
 $response->getHeaders()->addHeaders(array(
 'HeaderField1' => 'header-field-value',
 'HeaderField2' => 'header-field-value2',
 ));
 $response->setContent("Hello Word"); 60
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC REQUEST use ZendHttpRequest;
 
 $request = new Request();
 $request->setMethod(Request::METHOD_POST);
 $request->setUri('/foo');
 $request->getHeaders()->addHeaders(array(
 'HeaderField1' => 'header-field-value1',
 'HeaderField2' => 'header-field-value2',
 ));
 $request->getPost()->set('foo', 'bar'); 61
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 MVC ACCESSING FROM THE CONTROLLER ▸ God Mode: $this->getEvent()->getRequest(); $this->getEvent()->getResponse(); ▸ The easy way: $this->getRequest(); $this->getResponse(); 62
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS FORMS ▸ Used to bridge Views to Models (epically useful when following DOM) ▸ Takes elements, filters and validators to ensure data integrity. ▸ Creates element objects just-in-time to help keep for classes light 64
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS INPUTFILTERS ▸ Filters and validates sets of data by using filters and validators ▸ Can be independent objects, specified in the config or built on the fly in code ▸ Passed by reference, keeps data from being munged elsewhere 65
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS FILTERS AND VALIDATORS ▸ Transform data (trim, uppercase, lowercase etc) ▸ Filters are applied before validation ▸ Multiple filters and validators can be applied for each field ▸ Validators get passed the full data set to help validate 66
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS RENDERING FORMS ▸ View helpers for each filed type ▸ or simply use the formElement view helper ▸ setting values to the form will display the value by the user 67
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 DATABASE
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 DATABASE OVERVIEW ▸ ZendDb provides simple abstraction for working with RDBMS ▸ Can be used as an ORM ▸ Can use PDO or basic drivers 69
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 DATABASE STATEMENTS ▸ Used to Programmatically create SQL statements ▸ Agnostic towards different systems ▸ Normalizes out queries (as best they can) to handle the differences between RDBMS ▸ Returns Results Statements which can create your models using a hydrator 70
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 DATABASE HYDRATORS ▸ Transform an object to an array ▸ Take and array and set those values on the object (or hydrates an object) ▸ ArraySerializable ▸ ClassMethods ▸ Can also filter values before passing into the object 71
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 DATABASE TABLE/ROW GATEWAY ▸ Represents a row or table in the database ▸ Does all the heavy lifting for building a SQL query. ▸ A Must have when following the Active Record pattern ▸ Definition of the row and table is defined using the ZendDbMetadata* classes 72
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 LOGGING
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 LOGGING BASICS ▸ Allows writing to multiple log locations ▸ Allows filtering out log levels or text ▸ Can be used to log PHP errors and exceptions ▸ Complies with RFC-3164 ▸ Not PSR-3 compliant! (but you can use this module) 74
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 LOGGING HOW IT WORKS ▸ ZendLogLogger is constructed with writers ▸ Writers can get formatters to format the message to your hearts desire ▸ Messages are normally written during shutdown ▸ Logger can also take a filter which messages are logged ▸ Log Level ▸ Regex ▸ Following a Filter or Validator 75
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 LOGGING USING LOGS $logger = new ZendLogLogger;
 $writer = new ZendLogWriterStream('php://output');
 
 $logger->addWriter($writer);
 
 $logger->info('This is an info'); 76
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 QUESTIONS?
Zend Framework Foundations, Chuck Reeves @manchuck PHP[world] 2015 THANK YOU THANK YOU ▸ Documentation - http://framework.zend.com/manual/current/en/index.html ▸ Marco Pivetta Blogs - http://ocramius.github.io/ ▸ Mathew Weier O'Phinney - https://mwop.net/ ▸ Design Patterns in PHP - https://github.com/domnikl/DesignPatternsPHP ▸ Images: The internet 78

Zend Framework Foundations

  • 1.
  • 2.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 WHAT WE WILL COVER ▸ Intro to Zend Framework 2 ▸ Modules ▸ Service Locator ▸ Event Manager ▸ MVC ▸ Forms ▸ Database ▸ Logging 2INTRO TO ZEND FRAMEWORK 2
  • 3.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 http://framework.zend.com/manual/current/en/index.html https://github.com/manchuck/phpworld-zf2
  • 4.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 BASICS
  • 5.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 INTRO TO ZEND FRAMEWORK 2 ▸ Release in Fall 2012 ▸ Updated modules from Zend Framework 1 ▸ Collection of Individual components ▸ PSR-0 Compliant SOME BASICS 5
  • 6.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 INTRO TO ZEND FRAMEWORK 2 GETTING STARTED ▸ Using the skeleton app cd my/project/dir
 git clone git://github.com/zendframework/ZendSkeletonApplication.git
 cd ZendSkeletonApplication
 php composer.phar install ▸ God Mode (aka Composer): "require": {
 "zendframework/zendframework": "~2.5"
 } 6
  • 7.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 FILE STRUCTURE ▸ config - stores global config options ▸ data - cache, logs, session files ▸ module - your custom modules ▸ public - HTML, CSS, JS, Images ▸ test - Integration tests and test bootstrap INTRO TO ZEND FRAMEWORK 2 7
  • 8.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 INTRO TO ZEND FRAMEWORK 2 APPLICATION BASICS ▸ At its core, ZF2 applications have 6 dependancies: 1. ZendConfig - a Traversable object containing merged config 2. ZendServiceManager - A Service Locator for loading/creating objects 3. ZendEventManager - An Event dispatcher for controlling application flow 4. ZendModuleManager - Used for loading/finding configured modules 5. Request - Helper for managing the incoming request 6. Response - Helper for returning a response 8
  • 9.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MODULES
  • 10.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MODULES FILE STRUCTURE ▸ config - holds the config(s) ▸ language - PO language files (or other I18N translations) ▸ src - source code for the modules ▸ test - module specific tests ▸ view - view scripts and layout ▸ autoload_classmap - maps classes to files ▸ Module.php - bootstrap for the module 10
  • 11.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MODULES BOOTSTRAPPING MODULES ‣ The ModuleManager brokers loading files using the EventManager ‣ Allows initializing 3rd party libraries ‣ Three methods for bootstrapping: ‣ init ‣ modulesLoaded ‣ onBootstrap 11
  • 12.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MODULES THE ONLY THING A MODULE NEEDS 12 
 use ZendModuleManagerFeatureAutoloaderProviderInterface;
 use ZendModuleManagerFeatureConfigProviderInterface;
 
 class Module implements ConfigProviderInterface, AutoloaderProviderInterface
 {
 public function getConfig()
 {
 return include __DIR__ . '/config/module.config.php';
 }
 public function getAutoloaderConfig()
 {
 return array(
 'ZendLoaderClassMapAutoloader' => array(
 __DIR__ . '/autoload_classmap.php',
 ),
 'ZendLoaderStandardAutoloader' => array(
 'namespaces' => array(
 __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
 ),
 ),
 );
 }
 }
  • 13.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER
  • 14.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DEPENDENCY INJECTION - FOR THOSE WHO DON'T KNOW ▸ Instead of creating all the objects needed by a class, you "inject" a created object that the class knows how to interact with it ▸ Makes testing easier (you are writing tests correct?) ▸ Code changes are a breeze ▸ Reduces class coupling 14
  • 15.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DEPENDENCY INJECTION - METHOD class MapService {
 public function getLatLong(
 GoogleMaps $map,
 $street,
 $city, 
 $state
 ) {
 return $map->getLatLong($street . ' ' . $city . ' ' . $state);
 }
 } 15
  • 16.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DEPENDENCY INJECTION - __CONSTRUCT class MapService 
 {
 protected $map;
 public function __construct(GoogleMaps $map) {
 $this->$map = $map;
 }
 
 public function getLatLong($street, $city, $state ) {
 return $this->map->getLatLong($street . ' ' . $city . ' ' . $state);
 }
 } 16
  • 17.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DEPENDENCY INJECTION - SETTERS class MapService
 {
 protected $map;
 public function setMap(GoogleMaps $map) {
 $this->$map = $map;
 }
 
 public function getMap() {
 return $this->map;
 }
 
 public function getLatLong($street, $city, $state ) {
 return $this->getMap()->getLatLong($street . ' ' . $city . ' ' . $state);
 }
 } 17
  • 18.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER WHAT IS A SERVICE LOCATOR ▸ Purpose - "To implement a loosely coupled architecture in order to get better testable, maintainable and extendable code. DI pattern and Service Locator pattern are an implementation of the Inverse of Control pattern." * ▸ Keeps DI Simple and clean ▸ Only has two methods: get() and has() 18 * https://github.com/domnikl/DesignPatternsPHP/tree/master/More/ServiceLocator
  • 19.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER WHAT IS IN THE SERVICE MANAGER ▸ Invokables - Objects that can just be called via "new <class_name>" ▸ Factories - a class that creates another (follows the factory pattern) ▸ Abstract Factories - Factories that create many objects using a config ▸ Initializers - Used to add additional dependancies after the object is created (ex. adding logging to classes with out having a huge dependency list) ▸ Delegators - wrappers that adds more functionality to existing objects ▸ Aliases - simpler names for services 19
  • 20.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - CONFIG 'service_manager' => [
 'abstract_factories' => [
 'ZendLogLoggerAbstractServiceFactory',
 ],
 'factories' => [
 'MyModuleMyService' => 'MyModuleMyServiceFactory'
 ],
 'invokables' => [
 'FooBar' => 'stdClass'
 ],
 'delgators' => [
 'MyModuleMyService' => [
 'MyModuleMyServiceDelegator'
 ]
 ],
 'alises' => [
 'MyService' => 'MyModuleMyService'
 ]
 ] 20
  • 21.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - THE WRONG WAY! 'factories' => [
 'MyModuleMyService' => function ($sm) {
 // do crazy things to build
 // this class and slow down // your application 
 return $service;
 }
 ], 21
  • 22.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - THE WRONG WAY! ▸ SERIOUSLY DON'T USE CLOSURES TO REGISTER SERVICES ▸ YOU MIGHT AS WELL USE TABS ▸ LIKE EVER 22
  • 23.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - CONCRETE OBJECT use ZendServiceManagerServiceManager;
 
 $serviceManager = new ServiceManager();
 
 //sets the created object instead of having the SM buildone
 $fooBar = new stdClass();
 $serviceManager->setService('FooBar', $fooBar); 23
  • 24.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER REGISTERING SERVICES - IN CODE use ZendServiceManagerServiceManager;
 
 $serviceManager = new ServiceManager();
 
 $serviceManager->setFactory('MyModuleMyService', 'MyModuleMyServiceFactory'); 
 $serviceManager->setInvokableClass('FooBar', 'stdClass');
 $serviceManager->addAbstractFactory('ZendLogLoggerAbstractServiceFactory');
 $serviceManager->addDelegator('MyModuleMyService', 'MyModuleMyServiceDelegator');
 $serviceManager->setAlias('MyService', 'MyModuleMyService'); 24
  • 25.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER FACTORIES ▸ Contains the code to build the object ▸ The ServiceManager is passed in to the create function ▸ can either implement ZendServiceManagerFactoryInterface or just implement __invoke 25
  • 26.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER ABSTRACT FACTORIES ▸ Allows one factory that builds multiple objects based on a config ▸ Prevents writing multiple factories that do similar functions based on a config ▸ MUST Implement ZendServiceManagerAbstractFactoryInterface ▸ defines canCreateServiceWithName() and createServiceWithName() 26
  • 27.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER ABSTRACT FACTORIES use ZendDbTableGatewayTableGateway;
 use ZendServiceManagerFactoryInterface;
 use ZendServiceManagerServiceLocatorInterface;
 
 class ProjectsTableFactory implements FactoryInterface {
 public function createService(ServiceLocatorInterface $serviceLocator) {
 $adapter = new $serviceLocator->get('ZendDbAdapterAdapter');
 return new TableGateway('projects', $adapter);
 }
 }
 
 class CategoriesTableFactory implements FactoryInterface {
 public function createService(ServiceLocatorInterface $serviceLocator) {
 $adapter = new $serviceLocator->get('ZendDbAdapterAdapter');
 return new TableGateway('categories', $adapter);
 }
 } 27
  • 28.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER ABSTRACT FACTORIES use ZendDbTableGatewayTableGateway;
 use ZendServiceManagerAbstractFactoryInterface;
 use ZendServiceManagerServiceLocatorInterface;
 
 class TableAbstractFactory implements AbstractFactoryInterface {
 public function canCreateServiceWithName(ServiceLocatorInterface $sl, $name, $requestedName) {
 return preg_match("/Table$/", $requestedName);
 }
 
 public function createServiceWithName(ServiceLocatorInterface $sl, $name, $requestedName) {
 $adapter = $sl->get('ZendDbAdapterAdapter');
 $tableName = str_replace('Table', '', $requestedName);
 $tableName = strtolower($tableName);
 
 return new TableGateway($tableName, $adapter);
 }
 } 28
  • 29.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER INITIALIZERS ▸ Applied to every object that the ServiceManager created ▸ Useful to inject other dependancies ▸ Do not over use them (50 Initializers with 300 objects means 15,000 calls) 29
  • 30.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DELEGATORS ▸ Add functionality to a class ▸ Transfers process to another object based on conditions ▸ Technically ZF2 delegators are decorators ▸ https://en.wikipedia.org/wiki/Delegation_pattern 30
  • 31.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER DELEGATORS - HOW THEY WORK ▸ A delegator factory (MUST implement ZendServiceManager DelegatorFactoryInterface) ▸ FactoryClass MUST BE registered as separate service in the ServiceManager ▸ Note: the delegator will not be passed through initializers 31
  • 32.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 SERVICE MANAGER OTHER SERVICE MANAGERS ▸ ZF2 builds other service managers that will be injected with the main service manager ▸ ControllerManager, InputFilterManager, RouterPluginManager, and FormElementManager are just some 32
  • 33.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER
  • 34.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER EVENT MANAGER ▸ Aspect Oriented Programming (AOP) ▸ What it is useful for: ▸ Logging ▸ Caching ▸ Authorization ▸ Sanitizing ▸ Auditing ▸ Notifying the user when something happens (or fails) 34
  • 35.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER ASPECT ORIENTED PROGRAMMING 101 - TERMS ▸ Aspect - The object being interacted with ▸ Advice - What should be done with each method of the aspect ▸ Joinpoint - Places where Advice can be created ▸ Pointcut - Matches Joinpoint to an Advice 35
  • 36.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER ASPECT ORIENTED PROGRAMMING 101 - ADVICE TYPES ▸ Before advice - Applied before the advice is called ▸ After returning advice - Applied after the advice is called ▸ After throwing advice - Applied when an error happens ▸ Around advice - combines the Before and After returning advice* 36 http://www.sitepoint.com/explore-aspect-oriented-programming-with-codeigniter-1/
  • 37.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER HOW IT WORKS IN ZF2 ▸ Events chain until no more listeners are registered or a listener stops propagation of events ▸ Listeners are called in order of priority. From the higher number to lower number ▸ Responses from each listener is stored in a collection and returned back to the calling code 37
  • 38.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER REGISTERING EVENTS - CALLBACKS use ZendEventManagerEventManager;
 use ZendEventManagerEvent;
 use ZendLogLogger;
 
 $log = new Logger(['writers' => [['name' => 'noop']]]);
 $events = new EventManager();
 $events->attach('my_event', function (Event $event) use ($log) {
 $event = $event->getName();
 $target = get_class($event->getTarget());
 $params = json_encode($event->getParams());
 
 $log->info(sprintf(
 '%s called on %s, using params %s',
 $event,
 $target,
 $params
 ));
 });
 
 $target = new stdClass();
 $params = ['foo' => 'bar'];
 $events->trigger('my_event', $target, $params); 38
  • 39.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER REGISTERING EVENTS - AGGREGATE class Listener implements ListenerAggregateInterface, LoggerAwareInterface
 {
 use LoggerAwareTrait;
 
 protected $listeners = [];
 
 public function attach(EventManagerInterface $events) {
 $this->listeners[] = $events->attach('my_event', [$this, 'logEvent'], 1000);
 }
 
 public function detach(EventManagerInterface $events) {
 foreach ($this->listeners as $index => $callback) {
 if ($events->detach($callback)) {
 unset($this->listeners[$index]);
 }
 }
 }
 }
 
 $events->attach(new Listener()); 39
  • 40.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER REGISTERING EVENTS - OTHER ▸ Register a listener to multiple events using an array $events->attach(['my_event_1', 'my_event_2'], [$this, 'logEvent']); ▸ Or using a wildcard $events->attach('*', [$this, 'logEvent']); 40
  • 41.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER SHARED EVENT MANAGER ▸ Segregates events from other classes that could interfere with the listeners ▸ JIT loading of listeners to keep the event manager lightweight 41
  • 42.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015
  • 43.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER SHARED EVENT MANAGER - REGISTERING LISTENERS public function setEventManager(EventManagerInterface $eventManager)
 {
 $eventManager->addIdentifiers(array(
 get_called_class()
 ));
 
 $this->eventManager = $eventManager;
 } 43
  • 44.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 EVENT MANAGER SHARED EVENT MANAGER - REGISTERING LISTENERS public function onBootstrap(MvcEvent $event)
 {
 $eventManager = $event->getApplication()- >getEventManager();
 $sharedEventManager = $eventManager->getSharedManager();
 
 $sharedEventManager->attach('MyService', 'my_event', function($e) {
 var_dump($e);
 }, 100);
 } 44
  • 45.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC
  • 46.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC MODELS ▸ Nothing special they are just classes 46
  • 47.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC MVC_EVENT ▸ Created during application bootstrap ▸ Provides helpers to access the Application, Request, Response, Router, and the View. (all these are injected during the bootstrap event 47
  • 48.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC MVC_EVENT - EVENTS ▸ MvcEvent::EVENT_BOOTSTRAP - Prepares the application ▸ MvcEvent::EVENT_ROUTE - Matches the request to a controller ▸ MvcEvent::EVENT_DISPATCH - Call the matched controller ▸ MvcEvent::EVENT_DISPATCH_ERROR - Error happens during dispatch ▸ MvcEvent::EVENT_RENDER - Prepares the data to be rendered ▸ MvcEvent::EVENT_RENDER_ERROR - Error during rendering ▸ MvcEvent::EVENT_FINISH - Finial task 48
  • 49.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC ROUTING ▸ Provides a means to match a request to a controller ▸ Matching can be made on any part of the URL ▸ Three router types: ConsoleSimpleRouteStack, HttpSimpleRouterStack and HttpTreeRouterStack 49
  • 50.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC CONTROLLERS ▸ Controllers are dispatched from a Router ▸ A Controller just needs to implement ZendStdlibDispatchableInterface ▸ Other common interfaces for controllers: ▸ ZendMvcInjectApplicationEventInterface ▸ ZendServiceManagerServiceLocatorAwareInterface ▸ ZendEventManagerEventManagerAwareInterface 50
  • 51.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC CONTROLLERS - DEFAULT ▸ ZendMvcControllerAbstractController ▸ ZendMvcControllerAbstractActionController ▸ ZendMvcControllerAbstractRestfulController ▸ ZendMvcControllerAbstractConsoleController 51
  • 52.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC CONTROLLERS - PLUGINS ▸ Provides helper functions to controllers ▸ Default Plugins (More to come later) ▸ FlashMessenger ▸ Forward ▸ Params ▸ PostRedirectGet ▸ Redirect ▸ Url 52
  • 53.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC CONTROLLER PLUGINS - CUSTOM PLUGINS IN 3 STEPS ▸ Create plugin ▸ Register in config ▸ Call in controller 53
  • 54.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC VIEWS ▸ Views incorporate multiple levels to render a response ▸ By default uses the PHP template system (but can use your templating system of choice) ▸ Layouts are also possible since ViewModels can be nested ▸ Your controllers do not need to return a ViewModel 54
  • 55.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC VIEW - ONE VIEW MANY LAYERS ▸ Containers - holds variables and or callbacks (typically a model or the array representation of the model) ▸ View Model - Connects the Container to a template (if applicable) ▸ Renders - Takes the Model and returns the representation of the model (Three are included by default: PhpRenderer, JsonRenderer, FeedRenderer) ▸ Resolvers - Uses a strategy to resolve a template for the renderer ▸ Rendering Strategies - Decides which renderer to use ▸ Response Strategies - Handles setting the headers responses 55
  • 56.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC VIEWS - HOW TO USE ▸ From controller: $view = new ViewModel(array(
 'message' => 'Hello world',
 ));
 $view->setTemplate('my/template');
 return $view; ▸ Or return array(
 'message' => 'Hello world',
 ); 56
  • 57.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC VIEW - HELPERS ▸ Used with the PhpRenderer ▸ Handles common functions within a view ▸ Check out the manual for complete list visit: http://framework.zend.com/ manual/current/en/modules/zend.view.helpers.html 57
  • 58.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC VIEW - CREATING CUSTOM HELPERS ▸ Have your helper implement ZendViewHelperHelperInterface ▸ or just extend ZendViewHelperAbstractHelper ▸ Register the helper ▸ in the config under 'view_helpers' ▸ in the module by implementing ZendModuleManagerFeature ViewHelperProviderInterface 58
  • 59.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC REQUEST AND RESPONSE ▸ Abstracts the HTTP (or console) Request and response ▸ Can also be used with the ZendHttp when you need to make CURL requests ▸ ViewModels can also understand the response based on different PHP runtimes (console or web requests) 59
  • 60.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC RESPONSE use ZendHttpResponse; $response = new Response();
 $response->setStatusCode(Response::STATUS_CODE_200);
 $response->getHeaders()->addHeaders(array(
 'HeaderField1' => 'header-field-value',
 'HeaderField2' => 'header-field-value2',
 ));
 $response->setContent("Hello Word"); 60
  • 61.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC REQUEST use ZendHttpRequest;
 
 $request = new Request();
 $request->setMethod(Request::METHOD_POST);
 $request->setUri('/foo');
 $request->getHeaders()->addHeaders(array(
 'HeaderField1' => 'header-field-value1',
 'HeaderField2' => 'header-field-value2',
 ));
 $request->getPost()->set('foo', 'bar'); 61
  • 62.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 MVC ACCESSING FROM THE CONTROLLER ▸ God Mode: $this->getEvent()->getRequest(); $this->getEvent()->getResponse(); ▸ The easy way: $this->getRequest(); $this->getResponse(); 62
  • 63.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS
  • 64.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS FORMS ▸ Used to bridge Views to Models (epically useful when following DOM) ▸ Takes elements, filters and validators to ensure data integrity. ▸ Creates element objects just-in-time to help keep for classes light 64
  • 65.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS INPUTFILTERS ▸ Filters and validates sets of data by using filters and validators ▸ Can be independent objects, specified in the config or built on the fly in code ▸ Passed by reference, keeps data from being munged elsewhere 65
  • 66.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS FILTERS AND VALIDATORS ▸ Transform data (trim, uppercase, lowercase etc) ▸ Filters are applied before validation ▸ Multiple filters and validators can be applied for each field ▸ Validators get passed the full data set to help validate 66
  • 67.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 FORMS, VALIDATORS AND INPUTFILTERS RENDERING FORMS ▸ View helpers for each filed type ▸ or simply use the formElement view helper ▸ setting values to the form will display the value by the user 67
  • 68.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 DATABASE
  • 69.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 DATABASE OVERVIEW ▸ ZendDb provides simple abstraction for working with RDBMS ▸ Can be used as an ORM ▸ Can use PDO or basic drivers 69
  • 70.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 DATABASE STATEMENTS ▸ Used to Programmatically create SQL statements ▸ Agnostic towards different systems ▸ Normalizes out queries (as best they can) to handle the differences between RDBMS ▸ Returns Results Statements which can create your models using a hydrator 70
  • 71.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 DATABASE HYDRATORS ▸ Transform an object to an array ▸ Take and array and set those values on the object (or hydrates an object) ▸ ArraySerializable ▸ ClassMethods ▸ Can also filter values before passing into the object 71
  • 72.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 DATABASE TABLE/ROW GATEWAY ▸ Represents a row or table in the database ▸ Does all the heavy lifting for building a SQL query. ▸ A Must have when following the Active Record pattern ▸ Definition of the row and table is defined using the ZendDbMetadata* classes 72
  • 73.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 LOGGING
  • 74.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 LOGGING BASICS ▸ Allows writing to multiple log locations ▸ Allows filtering out log levels or text ▸ Can be used to log PHP errors and exceptions ▸ Complies with RFC-3164 ▸ Not PSR-3 compliant! (but you can use this module) 74
  • 75.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 LOGGING HOW IT WORKS ▸ ZendLogLogger is constructed with writers ▸ Writers can get formatters to format the message to your hearts desire ▸ Messages are normally written during shutdown ▸ Logger can also take a filter which messages are logged ▸ Log Level ▸ Regex ▸ Following a Filter or Validator 75
  • 76.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 LOGGING USING LOGS $logger = new ZendLogLogger;
 $writer = new ZendLogWriterStream('php://output');
 
 $logger->addWriter($writer);
 
 $logger->info('This is an info'); 76
  • 77.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 QUESTIONS?
  • 78.
    Zend Framework Foundations,Chuck Reeves @manchuck PHP[world] 2015 THANK YOU THANK YOU ▸ Documentation - http://framework.zend.com/manual/current/en/index.html ▸ Marco Pivetta Blogs - http://ocramius.github.io/ ▸ Mathew Weier O'Phinney - https://mwop.net/ ▸ Design Patterns in PHP - https://github.com/domnikl/DesignPatternsPHP ▸ Images: The internet 78