You are on page 1of 1217

Zend Framework 2 Documentation

Release 2.0.6

Zend Technologies Ltd.

January 27, 2013

CONTENTS

1 2 3

Overview Installation Getting Started with Zend Framework 2 3.1 Some assumptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 The tutorial application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting started: A skeleton application 4.1 Virtual host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unit Testing 5.1 Setting up the tests directory 5.2 Bootstrapping your tests . . 5.3 Your first Controller test . . 5.4 Testing . . . . . . . . . . .

1 3 5 5 5 7 8 9 9 9 12 13 15 15 16 17 19 20 25 25 25 28 30 33 33 35 37 37 42 45 47

4

5

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

6

Modules 6.1 Setting up the Album module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Informing the application about our new module . . . . . . . . . . . . . . . . . . . . . . . . . . . . Routing and controllers 7.1 Create the controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Database and models 8.1 The database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 The model files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3 Using ServiceManager to configure the table gateway and inject into the AlbumTable . 8.4 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5 Back to the controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6 Listing albums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Styling and Translations

7

8

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

9

10 Forms and actions 10.1 Adding new albums . . . . . . . . . . . . . . . . . . . 10.2 Editing an album . . . . . . . . . . . . . . . . . . . . . 10.3 Deleting an album . . . . . . . . . . . . . . . . . . . . 10.4 Ensuring that the home page displays the list of albums .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

i

11 Conclusion 12 Learning Dependency Injection 12.1 Very brief introduction to Di. . . . . . . . . . . . . . . 12.2 Very brief introduction to Di Container. . . . . . . . . . 12.3 Simplest usage case (2 classes, one consumes the other) 12.4 Simplest Usage Case Without Type-hints . . . . . . . . 12.5 Simplest usage case with Compiled Definition . . . . . 12.6 Creating a precompiled definition for others to use . . . 12.7 Using Multiple Definitions From Multiple Sources . . . 12.8 Generating Service Locators . . . . . . . . . . . . . . . 13 Introduction 13.1 Adapters . . . . . . 13.2 Results . . . . . . . 13.3 Identity Persistence . 13.4 Usage . . . . . . . .

49 51 51 51 51 53 55 56 56 57 61 61 62 63 66 69 69 69 71 75 75 75 75 77 77 77 77 78 79 81 81 81 83 84 86 86 89 91 91 92 93 95 95 97 99 99

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

14 Database Table Authentication 14.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14.2 Basic Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14.3 Advanced Usage: Persisting a DbTable Result Object . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Digest Authentication 15.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.2 Specifics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.3 Identity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 HTTP Authentication Adapter 16.1 Introduction . . . . . . . 16.2 Design Overview . . . . . 16.3 Configuration Options . . 16.4 Resolvers . . . . . . . . . 16.5 Basic Usage . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

17 LDAP Authentication 17.1 Introduction . . . . . . . . . . . . . 17.2 Usage . . . . . . . . . . . . . . . . . 17.3 The API . . . . . . . . . . . . . . . 17.4 Server Options . . . . . . . . . . . . 17.5 Collecting Debugging Messages . . . 17.6 Common Options for Specific Servers 18 Introduction

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

19 Barcode creation using Zend\Barcode\Barcode class 19.1 Using Zend\Barcode\Barcode::factory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19.2 Drawing a barcode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19.3 Renderering a barcode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Zend\Barcode\Barcode Objects 20.1 Common Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2 Common Additional Getters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Description of shipped barcodes 21.1 Zend\Barcode\Object\Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii

21.2 21.3 21.4 21.5 21.6 21.7 21.8 21.9 21.10 21.11 21.12 21.13 21.14 21.15 21.16 21.17 21.18

Zend\Barcode\Object\Code128 . . . . . Zend\Barcode\Object\Codabar . . . . . . Zend\Barcode\Object\Code25 . . . . . . Zend\Barcode\Object\Code25interleaved Zend\Barcode\Object\Ean2 . . . . . . . Zend\Barcode\Object\Ean5 . . . . . . . Zend\Barcode\Object\Ean8 . . . . . . . Zend\Barcode\Object\Ean13 . . . . . . . Zend\Barcode\Object\Code39 . . . . . . Zend\Barcode\Object\Identcode . . . . . Zend\Barcode\Object\Itf14 . . . . . . . . Zend\Barcode\Object\Leitcode . . . . . . Zend\Barcode\Object\Planet . . . . . . . Zend\Barcode\Object\Postnet . . . . . . Zend\Barcode\Object\Royalmail . . . . . Zend\Barcode\Object\Upca . . . . . . . Zend\Barcode\Object\Upce . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

99 99 100 100 100 101 101 101 102 102 102 103 103 103 104 104 104

22 Zend\Barcode Renderers 107 22.1 Common Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 22.2 Zend\Barcode\Renderer\Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 22.3 Zend\Barcode\Renderer\Pdf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 23 Zend\Cache\Storage\Adapter 23.1 Overview . . . . . . . . . . . . . . . 23.2 Quick Start . . . . . . . . . . . . . . 23.3 Basic Configuration Options . . . . . 23.4 The StorageInterface . . . . . . . . . 23.5 The AvailableSpaceCapableInterface 23.6 The TotalSpaceCapableInterface . . . 23.7 The ClearByNamespaceInterface . . 23.8 The ClearByPrefixInterface . . . . . 23.9 The ClearExpiredInterface . . . . . . 23.10 The FlushableInterface . . . . . . . . 23.11 The IterableInterface . . . . . . . . . 23.12 The OptimizableInterface . . . . . . 23.13 The TaggableInterface . . . . . . . . 23.14 The Apc Adapter . . . . . . . . . . . 23.15 The Dba Adapter . . . . . . . . . . . 23.16 The Filesystem Adapter . . . . . . . 23.17 The Memcached Adapter . . . . . . 23.18 The Memory Adapter . . . . . . . . 23.19 The WinCache Adapter . . . . . . . 23.20 The ZendServerDisk Adapter . . . . 23.21 The ZendServerShm Adapter . . . . 23.22 Examples . . . . . . . . . . . . . . . 109 109 109 110 110 112 112 112 113 113 113 113 113 114 114 115 116 117 118 119 120 120 121 123 123 123 125

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

24 Zend\Cache\Storage\Capabilities 24.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24.2 Available Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24.3 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25 Zend\Cache\Storage\Plugin 127 25.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 25.2 Quick Start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 iii

25.3 25.4 25.5 25.6 25.7 25.8 25.9

The ClearExpiredByFactor Plugin The ExceptionHandler Plugin . . The IgnoreUserAbort Plugin . . . The OptimizeByFactor Plugin . . The Serializer Plugin . . . . . . . Available Methods . . . . . . . . Examples . . . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

128 128 128 128 129 129 130

26 Zend\Cache\Pattern 131 26.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 26.2 Quick Start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 26.3 Available Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 27 Zend\Cache\Pattern\CallbackCache 27.1 Overview . . . . . . . . . . . . 27.2 Quick Start . . . . . . . . . . . 27.3 Configuration Options . . . . . 27.4 Available Methods . . . . . . . 27.5 Examples . . . . . . . . . . . . 28 Zend\Cache\Pattern\ClassCache 28.1 Overview . . . . . . . . . . 28.2 Quick Start . . . . . . . . . 28.3 Configuration Options . . . 28.4 Available Methods . . . . . 28.5 Examples . . . . . . . . . . 133 133 133 133 134 134 135 135 135 135 135 136 139 139 139 139 140 140 143 143 143 143 143 144 145 145 145 145 146 146 147 149

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

29 Zend\Cache\Pattern\ObjectCache 29.1 Overview . . . . . . . . . . . 29.2 Quick Start . . . . . . . . . . 29.3 Configuration Options . . . . 29.4 Available Methods . . . . . . 29.5 Examples . . . . . . . . . . . 30 Zend\Cache\Pattern\OutputCache 30.1 Overview . . . . . . . . . . . 30.2 Quick Start . . . . . . . . . . 30.3 Configuration Options . . . . 30.4 Available Methods . . . . . . 30.5 Examples . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

31 Zend\Cache\Pattern\CaptureCache 31.1 Overview . . . . . . . . . . . . 31.2 Quick Start . . . . . . . . . . . 31.3 Configuration Options . . . . . 31.4 Available Methods . . . . . . . 31.5 Examples . . . . . . . . . . . . 32 Introduction 33 Captcha Operation

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

34 CAPTCHA Adapters 151 34.1 Zend\Captcha\AbstractWord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 34.2 Zend\Captcha\Dumb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152

iv

34.3 Zend\Captcha\Figlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 34.4 Zend\Captcha\Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 34.5 Zend\Captcha\ReCaptcha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 35 Introduction 155 35.1 Using Zend\Config\Config with a Reader Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 35.2 Using Zend\Config\Config with a PHP Configuration File . . . . . . . . . . . . . . . . . . . . . . . 156 36 Theory of Operation 37 Zend\Config\Reader 37.1 Zend\Config\Reader\Ini . 37.2 Zend\Config\Reader\Xml 37.3 Zend\Config\Reader\Json 37.4 Zend\Config\Reader\Yaml 157 159 159 160 161 162 165 165 166 167 167 168 171 171 171 172 172 173

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

38 Zend\Config\Writer 38.1 Zend\Config\Writer\Ini . . . . 38.2 Zend\Config\Writer\Xml . . . 38.3 Zend\Config\Writer\PhpArray 38.4 Zend\Config\Writer\Json . . . 38.5 Zend\Config\Writer\Yaml . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

39 Zend\Config\Processor 39.1 Zend\Config\Processor\Constant . 39.2 Zend\Config\Processor\Filter . . 39.3 Zend\Config\Processor\Queue . . 39.4 Zend\Config\Processor\Token . . 39.5 Zend\Config\Processor\Translator

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

40 The Factory 175 40.1 Loading configuration file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 40.2 Storing configuration file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 41 Introduction 177 41.1 Writing console routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 41.2 Handling console requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 41.3 Adding console usage info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 42 Console routes and routing 42.1 Router configuration . . . 42.2 Basic route . . . . . . . . 42.3 Catchall route . . . . . . . 42.4 Console routes cheat-sheet 183 183 184 188 189

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

43 Console-aware modules 191 43.1 Application banner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 43.2 Usage information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 44 Console-aware action controllers 44.1 Handling console requests . . . . . . . . 44.2 Sending output to console . . . . . . . . 44.3 Are we in a console? . . . . . . . . . . . 44.4 Reading values from console parameters 197 197 199 199 201

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

v

45 Console adapters 205 45.1 Retreving console adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 45.2 Using console adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 46 Console prompts 46.1 Confirm . . 46.2 Line . . . . 46.3 Char . . . 46.4 Select . . . 47 Introduction 48 Encrypt/decrypt using block ciphers 209 209 210 210 211 213 215

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

49 Key derivation function 217 49.1 Pbkdf2 adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 49.2 SaltedS2k adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 50 Secure Password Storing 219

51 Public key cryptography 221 51.1 Diffie-Hellman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 51.2 RSA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 52 Zend\Db\Adapter 52.1 Creating an Adapter - Quickstart . . . . . . . . . . . . . . . . . 52.2 Creating an Adapter Using Dependency Injection . . . . . . . . 52.3 Query Preparation Through Zend\Db\Adapter\Adapter::query() 52.4 Query Execution Through Zend\Db\Adapter\Adapter::query() . 52.5 Creating Statements . . . . . . . . . . . . . . . . . . . . . . . 52.6 Using the Driver Object . . . . . . . . . . . . . . . . . . . . . 52.7 Using The Platform Object . . . . . . . . . . . . . . . . . . . . 52.8 Using The Parameter Container . . . . . . . . . . . . . . . . . 52.9 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 225 226 226 227 227 227 229 230 231 233 233 234 234 237 237 238 238 241 242 242 242

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

53 Zend\Db\ResultSet 53.1 Quickstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53.2 Zend\Db\ResultSet\ResultSet and Zend\Db\ResultSet\AbstractResultSet . . . . . . . . . . . . . . . . 53.3 Zend\Db\ResultSet\HydratingResultSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 Zend\Db\Sql 54.1 Zend\Db\Sql\Sql (Quickstart) . . . . . . . . . . 54.2 Zend\Db\Sql’s Select, Insert, Update and Delete 54.3 Zend\Db\Sql\Select . . . . . . . . . . . . . . . . 54.4 Zend\Db\Sql\Insert . . . . . . . . . . . . . . . . 54.5 Zend\Db\Sql\Update . . . . . . . . . . . . . . . 54.6 Zend\Db\Sql\Delete . . . . . . . . . . . . . . . 54.7 Zend\Db\Sql\Where & Zend\Db\Sql\Having . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

55 Zend\Db\TableGateway 247 55.1 Basic Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 55.2 TableGateway Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 56 Zend\Db\RowGateway 251 56.1 Quickstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

vi

57 Zend\Db\Metadata 253 57.1 Basic Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 58 Introduction to Zend\Di 257 58.1 Dependency Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 58.2 Dependency Injection Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 59 Zend\Di Quickstart 60 Zend\Di Definition 60.1 DefinitionList . . . 60.2 RuntimeDefinition 60.3 CompilerDefinition 60.4 ClassDefinition . . 259 263 263 263 264 265 267 267 268 269 271

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

61 Zend\Di InstanceManager 61.1 Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.2 Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.3 Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Zend\Di Configuration

63 Zend\Di Debugging & Complex Use Cases 273 63.1 Debugging a DiC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 63.2 Complex Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 64 Introduction 277

65 Zend\Dom\Query 279 65.1 Theory of Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 65.2 Methods Available . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 66 The EventManager 66.1 Overview . . . . . . . 66.2 Quick Start . . . . . . 66.3 Configuration Options 66.4 Available Methods . . 66.5 Examples . . . . . . . 67 Introduction 283 283 283 286 286 288 293

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

68 Importing Feeds 295 68.1 Dumping the contents of a feed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 69 Retrieving Feeds from Web Pages 70 Consuming an RSS Feed 71 Consuming an Atom Feed 72 Consuming a Single Atom Entry 297 299 301 303

73 Zend\Feed and Security 305 73.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 73.2 Filtering data using HTMLPurifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 73.3 Escaping data using Zend\Escaper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307

vii

74 Zend\Feed\Reader\Reader 74.1 Introduction . . . . . . . . . . . . . . . . . . 74.2 Importing Feeds . . . . . . . . . . . . . . . . 74.3 Retrieving Underlying Feed and Entry Sources 74.4 Cache Support and Intelligent Requests . . . . 74.5 Locating Feed URIs from Websites . . . . . . 74.6 Attribute Collections . . . . . . . . . . . . . . 74.7 Retrieving Feed Information . . . . . . . . . . 74.8 Retrieving Entry/Item Information . . . . . . . 74.9 Extending Feed and Entry APIs . . . . . . . . 75 Zend\Feed\Writer\Writer 75.1 Introduction . . . . . . . 75.2 Architecture . . . . . . . 75.3 Getting Started . . . . . . 75.4 Setting Feed Data Points . 75.5 Setting Entry Data Points

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

309 309 309 310 311 312 313 313 316 317 323 323 323 324 326 328 331 331 331 332 333

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

76 Zend\Feed\PubSubHubbub 76.1 What is PubSubHubbub? . . . . . . . . 76.2 Architecture . . . . . . . . . . . . . . 76.3 Zend\Feed\PubSubHubbub\Publisher . 76.4 Zend\Feed\PubSubHubbub\Subscriber

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

77 Introduction 339 77.1 What is a filter? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 77.2 Basic usage of filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 78 Using the StaticFilter 341 78.1 Double filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 79 Standard Filter Classes 79.1 Alnum . . . . . . . . . . . 79.2 Alpha . . . . . . . . . . . . 79.3 BaseName . . . . . . . . . 79.4 Boolean . . . . . . . . . . . 79.5 Callback . . . . . . . . . . 79.6 Compress and Decompress . 79.7 Digits . . . . . . . . . . . . 79.8 Dir . . . . . . . . . . . . . 79.9 Encrypt and Decrypt . . . . 79.10 HtmlEntities . . . . . . . . 79.11 Int . . . . . . . . . . . . . . 79.12 Null . . . . . . . . . . . . . 79.13 NumberFormat . . . . . . . 79.14 PregReplace . . . . . . . . 79.15 RealPath . . . . . . . . . . 79.16 StringToLower . . . . . . . 79.17 StringToUpper . . . . . . . 79.18 StringTrim . . . . . . . . . 79.19 StripNewLines . . . . . . . 79.20 StripTags . . . . . . . . . . 343 343 344 344 345 347 349 354 355 355 361 363 363 364 365 366 367 367 368 369 369

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

80 Word Filters 371 80.1 CamelCaseToDash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371

viii

80.2 80.3 80.4 80.5 80.6 80.7 80.8 80.9 80.10 80.11 80.12

CamelCaseToSeparator . CamelCaseToUnderscore DashToCamelCase . . . . DashToSeparator . . . . . DashToUnderscore . . . . SeparatorToCamelCase . SeparatorToDash . . . . . SeparatorToSeparator . . UnderscoreToCamelCase UnderscoreToSeparator . UnderscoreToDash . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

371 372 372 373 373 374 374 375 376 376 377

81 Filter Chains 379 81.1 Setting Filter Chain Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 81.2 Using the Plugin Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 82 Zend\Filter\Inflector 82.1 Operation . . . . . . . . . . . . . . . . . . . . . . . . . . 82.2 Using Custom Filters . . . . . . . . . . . . . . . . . . . . 82.3 Setting the Inflector Target . . . . . . . . . . . . . . . . . 82.4 Inflection Rules . . . . . . . . . . . . . . . . . . . . . . . 82.5 Utility Methods . . . . . . . . . . . . . . . . . . . . . . . 82.6 Using a Traversable or an array with Zend\Filter\Inflector 83 Writing Filters 84 Introduction to Zend\Form 85 Form Quick Start 85.1 Programmatic Form Creation . 85.2 Creation via Factory . . . . . . 85.3 Factory-backed Form Extension 85.4 Validating Forms . . . . . . . . 85.5 Hinting to the Input Filter . . . 85.6 Binding an object . . . . . . . . 85.7 Rendering . . . . . . . . . . . 85.8 Validation Groups . . . . . . . 85.9 Using Annotations . . . . . . . 381 381 382 382 383 385 385 387 389 391 391 392 395 397 398 400 401 404 404 407 410 414 415 415 416 418 421 421 421 423 436

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

86 Form Collections 86.1 Creating Fieldsets . . . . . . . . . . . . . . 86.2 The Form Element . . . . . . . . . . . . . . 86.3 The Controller . . . . . . . . . . . . . . . . 86.4 The View . . . . . . . . . . . . . . . . . . . 86.5 Adding New Elements Dynamically . . . . . 86.6 Validation groups for fieldsets and collection 87 Form Elements 87.1 Introduction . . . . 87.2 Element Base Class 87.3 Standard Elements . 87.4 HTML5 Elements .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

88 Form View Helpers 449 88.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449

ix

88.2 Standard Helpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 88.3 HTML5 Helpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460 89 Overview of Zend\Http 465 89.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 89.2 Zend\Http Request, Response and Headers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 90 The Request Class 90.1 Overview . . . . . . . 90.2 Quick Start . . . . . . 90.3 Configuration Options 90.4 Available Methods . . 90.5 Examples . . . . . . . 91 The Response Class 91.1 Overview . . . . . . . 91.2 Quick Start . . . . . . 91.3 Configuration Options 91.4 Available Methods . . 91.5 Examples . . . . . . . 467 467 467 468 468 471 473 473 473 474 474 476 479 479 479 480 480 482 482 483 487 487 487 488 488 491 495 495 495 498 499 500 502 505 505 505 507 507 508 509 509 510

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

92 The Headers Class 92.1 Overview . . . . . . . . . . . . . . 92.2 Quick Start . . . . . . . . . . . . . 92.3 Configuration Options . . . . . . . 92.4 Available Methods . . . . . . . . . 92.5 Zend\Http\Header\* Base Methods 92.6 List of HTTP Header Types . . . . 92.7 Examples . . . . . . . . . . . . . . 93 HTTP Client - Overview 93.1 Overview . . . . . . . 93.2 Quick Start . . . . . . 93.3 Configuration Options 93.4 Available Methods . . 93.5 Examples . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

94 HTTP Client - Connection Adapters 94.1 Overview . . . . . . . . . . . . . . . . 94.2 The Socket Adapter . . . . . . . . . . 94.3 The Proxy Adapter . . . . . . . . . . . 94.4 The cURL Adapter . . . . . . . . . . . 94.5 The Test Adapter . . . . . . . . . . . . 94.6 Creating your own connection adapters

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

95 HTTP Client - Advanced Usage 95.1 HTTP Redirections . . . . . . . . . . . . . . . . 95.2 Adding Cookies and Using Cookie Persistence . 95.3 Setting Custom Request Headers . . . . . . . . 95.4 File Uploads . . . . . . . . . . . . . . . . . . . 95.5 Sending Raw POST Data . . . . . . . . . . . . 95.6 HTTP Authentication . . . . . . . . . . . . . . 95.7 Sending Multiple Requests With the Same Client 95.8 Data Streaming . . . . . . . . . . . . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

x

96 HTTP Client - Static Usage 96.1 Overview . . . . . . . 96.2 Quick Start . . . . . . 96.3 Configuration Options 96.4 Available Methods . . 97 Translating 97.1 Adding translations . 97.2 Supported formats . 97.3 Setting a locale . . . 97.4 Translating messages 97.5 Caching . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

513 513 513 513 514 515 515 516 516 516 516 517 517 517 518 519 520 520 521

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

98 I18n View Helpers 98.1 Introduction . . . . . . . 98.2 CurrencyFormat Helper . 98.3 DateFormat Helper . . . . 98.4 NumberFormat Helper . . 98.5 Translate Helper . . . . . 98.6 TranslatePlural Helper . . 98.7 Abstract Translator Helper

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

99 I18n Filters 523 99.1 Alnum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 99.2 Alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524 99.3 NumberFormat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524 100I18n Validators 527

101Float 529 101.1 Supported options for Zend\I18n\Validator\Float . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529 101.2 Simple float validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529 101.3 Localized float validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529 102Int 531 102.1 Supported options for Zend\I18n\Validator\Int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 102.2 Simple integer validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 102.3 Localized integer validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 103Introduction 104Introduction 533 537

105Basic Usage 539 105.1 Pretty-printing JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 106Advanced Usage of Zend\Json 106.1 JSON Objects . . . . . . 106.2 Encoding PHP objects . . 106.3 Internal Encoder/Decoder 106.4 JSON Expressions . . . . 107XML to JSON conversion 541 541 541 542 542 543

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

108Zend\Json\Server - JSON-RPC server 545 108.1 Advanced Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547

xi

109Introduction 553 109.1 Theory of operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553 110API overview 557 110.1 Configuration / options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557 110.2 API Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558 111Zend\Ldap\Ldap 559 111.1 Zend\Ldap\Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560 112Zend\Ldap\Attribute 113Zend\Ldap\Converter\Converter 114Zend\Ldap\Dn 115Zend\Ldap\Filter 116Zend\Ldap\Node 561 563 565 567 569

117Zend\Ldap\Node\RootDse 571 117.1 OpenLDAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573 117.2 ActiveDirectory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573 117.3 eDirectory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574 118Zend\Ldap\Node\Schema 577 118.1 OpenLDAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579 118.2 ActiveDirectory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580 119Zend\Ldap\Ldif\Encoder 581

120Usage Scenarios 583 120.1 Authentication scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 120.2 Basic CRUD operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 120.3 Extended operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585 121Tools 121.1 Creation and modification of DN strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.2 Using the filter API to create search filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.3 Modify LDAP entries using the Attribute API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122Object oriented access to the LDAP tree using Zend\Ldap\Node 122.1 Basic CRUD operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.2 Extended operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.3 Tree traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587 587 587 587 589 589 589 589

123Getting information from the LDAP server 591 123.1 RootDSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 123.2 Schema Browsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 124Serializing LDAP data to and from LDIF 593 124.1 Serialize a LDAP entry to LDIF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593 124.2 Deserialize a LDIF string into a LDAP entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594 125The AutoloaderFactory 597 125.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 125.2 Quick Start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 xii

125.3 Configuration Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598 125.4 Available Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598 125.5 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598 126The StandardAutoloader 126.1 Overview . . . . . . . 126.2 Quick Start . . . . . . 126.3 Configuration Options 126.4 Available Methods . . 126.5 Examples . . . . . . . 127The ClassMapAutoloader 127.1 Overview . . . . . . . 127.2 Quick Start . . . . . . 127.3 Configuration Options 127.4 Available Methods . . 127.5 Examples . . . . . . . 128The ModuleAutoloader 128.1 Overview . . . . . . . 128.2 Quickstart . . . . . . 128.3 Configuration Options 128.4 Available Methods . . 128.5 Examples . . . . . . . 599 599 600 601 601 602 603 603 603 603 604 605 607 607 607 607 608 608 609 609 609 610 610 611 613 613 613 614 614 615 619 619 619 619 620 620 621 621 621 621 621 622

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

129The SplAutoloader Interface 129.1 Overview . . . . . . . . 129.2 Quick Start . . . . . . . 129.3 Configuration Options . 129.4 Available Methods . . . 129.5 Examples . . . . . . . . 130The PluginClassLoader 130.1 Overview . . . . . . . 130.2 Quick Start . . . . . . 130.3 Configuration Options 130.4 Available Methods . . 130.5 Examples . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

131The ShortNameLocator Interface 131.1 Overview . . . . . . . . . . . 131.2 Quick Start . . . . . . . . . . 131.3 Configuration Options . . . . 131.4 Available Methods . . . . . . 131.5 Examples . . . . . . . . . . . 132The PluginClassLocator interface 132.1 Overview . . . . . . . . . . . 132.2 Quick Start . . . . . . . . . . 132.3 Configuration Options . . . . 132.4 Available Methods . . . . . . 132.5 Examples . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

133The Class Map Generator utility: bin/classmap_generator.php 623 133.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623

xiii

133.2 Quick Start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623 133.3 Configuration Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623 134Overview 134.1 Creating a Log . . . . . . 134.2 Logging Messages . . . . 134.3 Destroying a Log . . . . . 134.4 Using Built-in Priorities . 134.5 Understanding Log Events 134.6 Log PHP Errors . . . . . 135Writers 135.1 Writing to Streams . . . 135.2 Writing to Databases . . 135.3 Writing to FirePHP . . . 135.4 Stubbing Out the Writer 135.5 Testing with the Mock . 135.6 Compositing Writers . . 625 625 626 626 626 627 627 629 629 630 630 631 631 631

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

136Filters 633 136.1 Available filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633 137Formatters 137.1 Simple Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137.2 Formatting to XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137.3 Formatting to FirePhp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635 635 635 636

138Introduction 637 138.1 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637 138.2 Configuring the default sendmail transport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638 139Zend\Mail\Message 139.1 Overview . . . . . . . 139.2 Quick Start . . . . . . 139.3 Configuration Options 139.4 Available Methods . . 139.5 Examples . . . . . . . 140Zend\Mail\Transport 140.1 Overview . . . . . . . 140.2 Quick Start . . . . . . 140.3 Configuration Options 140.4 Available Methods . . 140.5 Examples . . . . . . . 639 639 639 641 641 644 645 645 645 646 646 647 649 649 649 651 651 652

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

141Zend\Mail\Transport\SmtpOptions 141.1 Overview . . . . . . . . . . . . 141.2 Quick Start . . . . . . . . . . . 141.3 Configuration Options . . . . . 141.4 Available Methods . . . . . . . 141.5 Examples . . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

142Zend\Mail\Transport\FileOptions 653 142.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653 142.2 Quick Start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653

xiv

142.3 Configuration Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653 142.4 Available Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654 142.5 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654 143Introduction 655 143.1 Random number generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655 143.2 Big integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 656 144Zend\Mime 659 144.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659 144.2 Static Methods and Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659 144.3 Instantiating Zend\Mime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660 145Zend\Mime\Message 145.1 Introduction . . . . . . . . . . . . . . . . . . . . . . 145.2 Instantiation . . . . . . . . . . . . . . . . . . . . . . 145.3 Adding MIME Parts . . . . . . . . . . . . . . . . . . 145.4 Boundary handling . . . . . . . . . . . . . . . . . . . 145.5 Parsing a string to create a Zend\Mime\Message object 145.6 Available methods . . . . . . . . . . . . . . . . . . . 146Zend\Mime\Part 146.1 Introduction . . . . . . . . . . . . . . . . . . . . 146.2 Instantiation . . . . . . . . . . . . . . . . . . . . 146.3 Methods for rendering the message part to a string 146.4 Available methods . . . . . . . . . . . . . . . . . 661 661 661 661 661 662 662 663 663 663 663 664

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

147Introduction to the Module System 665 147.1 The autoload_*.php Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 666 148The Module Manager 667 148.1 Module Manager Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667 148.2 Module Manager Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667 149The Module Class 149.1 A Minimal Module . . . . . . . 149.2 A Typical Module Class . . . . 149.3 The “loadModules.post” Event 149.4 The MVC “bootstrap” Event . . 671 671 671 672 673

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

150The Module Autoloader 675 150.1 Module Autoloader Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 675 150.2 Non-Standard / Explicit Module Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676 150.3 Packaging Modules with Phar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677 151Best Practices when Creating Modules 152Introduction to the MVC Layer 152.1 Basic Application Structure . . . . . 152.2 Basic Module Structure . . . . . . . 152.3 Bootstrapping an Application . . . . 152.4 Bootstrapping a Modular Application 152.5 Conclusion . . . . . . . . . . . . . . 679 681 681 682 684 685 686

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

153Quick Start 687 153.1 Install the Zend Skeleton Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687 xv

153.2 153.3 153.4 153.5 153.6 153.7 153.8

Create a New Module . . . . . . . . . Update the Module Class . . . . . . . . Create a Controller . . . . . . . . . . . Create a View Script . . . . . . . . . . Create a Route . . . . . . . . . . . . . Tell the Application About our Module Test it Out! . . . . . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

688 688 689 690 690 692 692 695 695 695 698 699 700 703 705 705 711 713 715

154Default Services 154.1 Theory of Operation . . . . . . . . 154.2 ServiceManager . . . . . . . . . . 154.3 ViewManager . . . . . . . . . . . . 154.4 Application Configuration Options 154.5 Default Configuration Options . . . 155Routing 155.1 Router Types . . . . . . . 155.2 HTTP Route Types . . . . 155.3 HTTP Routing Examples 155.4 Console Route Types . . . 156The MvcEvent

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

157Available Controllers 717 157.1 Common Interfaces Used With Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717 157.2 The AbstractActionController . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719 157.3 The AbstractRestfulController . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 720 158Controller Plugins 158.1 The FlashMessenger . . . . . 158.2 The Forward Plugin . . . . . 158.3 The Layout Plugin . . . . . . 158.4 The Params Plugin . . . . . . 158.5 The Post/Redirect/Get Plugin 158.6 The Redirect Plugin . . . . . 158.7 The Url Plugin . . . . . . . . 723 723 724 725 725 725 726 727

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

159Examples 729 159.1 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729 159.2 Bootstrapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730 160Introduction 731 160.1 Pages and Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731 160.2 Separation of data (model) and rendering (view) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731 161Zend\Navigation Quick Start 162Pages 163Common page features 164Zend\Navigation\Page\Mvc 165Zend\Navigation\Page\Uri 166Creating custom page types 733 735 737 739 743 745

xvi

167Creating pages using the page factory 168Containers 168.1 Creating containers 168.2 Adding pages . . . 168.3 Removing pages . 168.4 Finding pages . . . 168.5 Iterating containers 168.6 Other operations . 169Introduction 170Usage 170.1 Paginating data collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170.2 The DbSelect adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170.3 Rendering pages with view scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171Configuration 172Advanced usage 172.1 Custom data source adapters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.2 Custom scrolling styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.3 Caching features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173Introduction 173.1 Resources . . . . . . . . . . . . . 173.2 Roles . . . . . . . . . . . . . . . 173.3 Creating the Access Control List . 173.4 Registering Roles . . . . . . . . . 173.5 Defining Access Controls . . . . 173.6 Querying an ACL . . . . . . . .

747 749 749 755 756 757 759 760 763 765 765 766 767 773 775 775 775 776 779 779 780 781 781 782 783

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

174Refining Access Controls 785 174.1 Precise Access Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 785 174.2 Removing Access Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786 175Advanced Usage 789 175.1 Storing ACL Data for Persistence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789 175.2 Writing Conditional ACL Rules with Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789 176Introduction 791 176.1 Roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791 176.2 Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791 176.3 Dynamic Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791 177Methods 793

178Examples 795 178.1 Roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 795 178.2 Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796 178.3 Dynamic Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796 179Introduction to Zend\Serializer 179.1 Quick Start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179.2 Basic configuration Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179.3 Available Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799 799 800 800

xvii

180Zend\Serializer\Adapter 180.1 The PhpSerialize Adapter 180.2 The IgBinary Adapter . . 180.3 The Wddx Adapter . . . . 180.4 The Json Adapter . . . . . 180.5 The PythonPickle Adapter 180.6 The PhpCode Adapter . . 181Introduction

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

803 803 803 803 804 804 805 807

182Zend\Server\Reflection 809 182.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809 182.2 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809 183Zend\ServiceManager 811

184Zend\ServiceManager Quick Start 813 184.1 Using Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 813 184.2 Modules as Service Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814 184.3 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814 185Zend\Soap\Server 185.1 Zend\Soap\Server constructor . . . . . 185.2 Methods to define Web Service API . . 185.3 Request and response objects handling 185.4 Document/Literal WSDL Handling . . 819 819 820 821 823

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

186Zend\Soap\Client 825 186.1 Zend\Soap\Client Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 825 186.2 Performing SOAP Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826 187WSDL Accessor 187.1 Zend\Soap\Wsdl constructor . . 187.2 addMessage() method . . . . . 187.3 addPortType() method . . . . . 187.4 addPortOperation() method . . 187.5 addBinding() method . . . . . . 187.6 addBindingOperation() method 187.7 addSoapBinding() method . . . 187.8 addSoapOperation() method . . 187.9 addService() method . . . . . . 187.10Type mapping . . . . . . . . . 187.11addDocumentation() method . . 187.12Get finalized WSDL document 188AutoDiscovery 188.1 AutoDiscovery Introduction 188.2 Class autodiscovering . . . 188.3 Functions autodiscovering . 188.4 Autodiscovering Datatypes . 188.5 WSDL Binding Styles . . . 829 829 829 830 830 830 831 831 831 831 832 833 834 835 835 836 837 837 837

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

189Zend\Stdlib\Hydrator 839 189.1 HydratorInterface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839 189.2 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839

xviii

189.3 Available Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 840 190Zend\Stdlib\Hydrator\Strategy 190.1 Adding strategies to the hydrators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190.2 Available implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190.3 Writing custom strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191Introduction 841 841 842 842 845

192Creating tag clouds with Zend\Tag\Cloud 847 192.1 Decorators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848 193Zend\Text\Figlet 194Zend\Text\Table 195Zend\Uri 195.1 Overview . . . . . . . . . . . 195.2 Creating a New URI . . . . . 195.3 Manipulating an Existing URI 195.4 Common Instance Methods . 196Introduction 196.1 What is a validator? . . 196.2 Basic usage of validators 196.3 Customizing messages . 196.4 Translating messages . . 197Standard Validation Classes 198Alnum 198.1 Supported options for Zend\Validator\Alnum 198.2 Basic usage . . . . . . . . . . . . . . . . . . 198.3 Using whitespaces . . . . . . . . . . . . . . 198.4 Using different languages . . . . . . . . . . 199Alpha 199.1 Supported options for Zend\Validator\Alpha 199.2 Basic usage . . . . . . . . . . . . . . . . . . 199.3 Using whitespaces . . . . . . . . . . . . . . 199.4 Using different languages . . . . . . . . . . 851 853 855 855 855 856 856 861 861 861 862 863 865 867 867 867 867 868 869 869 869 869 870 871 873 873 874 874

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

200Barcode 200.1 Supported options for Zend\Validator\Barcode 200.2 Basic usage . . . . . . . . . . . . . . . . . . . 200.3 Optional checksum . . . . . . . . . . . . . . . 200.4 Writing custom adapters . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

201Between 877 201.1 Supported options for Zend\Validator\Between . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 877 201.2 Default behaviour for Zend\Validator\Between . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 877 201.3 Validation exclusive the border values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 877 202Callback 879 202.1 Supported options for Zend\Validator\Callback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 879 202.2 Basic usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 879

xix

202.3 Usage with closures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 879 202.4 Usage with class-based callbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 880 202.5 Adding options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 881 203CreditCard 203.1 Supported options for Zend\Validator\CreditCard 203.2 Basic usage . . . . . . . . . . . . . . . . . . . . 203.3 Accepting defined credit cards . . . . . . . . . . 203.4 Validation by using foreign APIs . . . . . . . . 203.5 Ccnum . . . . . . . . . . . . . . . . . . . . . . 204Date 204.1 204.2 204.3 204.4 883 884 884 884 885 886 887 887 887 887 888 889 889 889 890 891 891

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

Supported options for Zend\Validator\Date Default date validation . . . . . . . . . . . Localized date validation . . . . . . . . . . Self defined date validation . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

205Db\RecordExists and Db\NoRecordExists 205.1 Supported options for Zend\Validator\Db\* 205.2 Basic usage . . . . . . . . . . . . . . . . . 205.3 Excluding records . . . . . . . . . . . . . 205.4 Database Adapters . . . . . . . . . . . . . 205.5 Database Schemas . . . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

206Digits 893 206.1 Supported options for Zend\Validator\Digits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893 206.2 Validating digits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893 207EmailAddress 207.1 Basic usage . . . . . . . . . . . . . . . . . . . . 207.2 Options for validating Email Addresses . . . . . 207.3 Complex local parts . . . . . . . . . . . . . . . 207.4 Validating only the local part . . . . . . . . . . . 207.5 Validating different types of hostnames . . . . . 207.6 Checking if the hostname actually accepts email 207.7 Validating International Domains Names . . . . 207.8 Validating Top Level Domains . . . . . . . . . . 207.9 Setting messages . . . . . . . . . . . . . . . . . 895 895 895 896 896 896 896 897 898 898 899 899 899 899

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

208GreaterThan 208.1 Supported options for Zend\Validator\GreaterThan . . . . . . . . . . . . . . . . . . . . . . . . . . . 208.2 Basic usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208.3 Validation inclusive the border value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209Hex 209.1 Supported options for Zend\Validator\Hex

901 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901 903 903 903 903 904 905 907

210Hostname 210.1 Supported options for Zend\Validator\Hostname 210.2 Basic usage . . . . . . . . . . . . . . . . . . . . 210.3 Validating different types of hostnames . . . . . 210.4 Validating International Domains Names . . . . 210.5 Validating Top Level Domains . . . . . . . . . . 211Iban

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

xx

211.1 Supported options for Zend\Validator\Iban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 907 211.2 IBAN validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 907 212Identical 212.1 Supported options for Zend\Validator\Identical 212.2 Basic usage . . . . . . . . . . . . . . . . . . . 212.3 Identical objects . . . . . . . . . . . . . . . . 212.4 Form elements . . . . . . . . . . . . . . . . . 212.5 Strict validation . . . . . . . . . . . . . . . . . 212.6 Configuration . . . . . . . . . . . . . . . . . . 213InArray 213.1 Supported options for Zend\Validator\InArray 213.2 Simple array validation . . . . . . . . . . . . . 213.3 Array validation modes . . . . . . . . . . . . 213.4 Recursive array validation . . . . . . . . . . . 909 909 909 909 910 910 910 913 913 913 914 915 917 917 917 918 919 919 919 919 920

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

214Ip 214.1 Supported options for Zend\Validator\Ip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.2 Basic usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.3 Validate IPv4 or IPV6 alone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215Isbn 215.1 215.2 215.3 215.4

Supported options for Zend\Validator\Isbn Basic usage . . . . . . . . . . . . . . . . . Setting an explicit ISBN validation type . . Specifying a separator restriction . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

216LessThan 921 216.1 Supported options for Zend\Validator\LessThan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921 216.2 Basic usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921 216.3 Validation inclusive the border value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921 217NotEmpty 217.1 Supported options for Zend\Validator\NotEmpty . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217.2 Default behaviour for Zend\Validator\NotEmpty . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217.3 Changing behaviour for Zend\Validator\NotEmpty . . . . . . . . . . . . . . . . . . . . . . . . . . . 923 923 923 923

218PostCode 925 218.1 Constructor options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 926 218.2 Supported options for Zend\Validator\PostCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 926 219Regex 219.1 Supported options for Zend\Validator\Regex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219.2 Validation with Zend\Validator\Regex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219.3 Pattern handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220Sitemap Validators 220.1 Sitemap\Changefreq . . . . . . . . . . . . . . . 220.2 Sitemap\Lastmod . . . . . . . . . . . . . . . . . 220.3 Sitemap\Loc . . . . . . . . . . . . . . . . . . . 220.4 Sitemap\Priority . . . . . . . . . . . . . . . . . 220.5 Supported options for Zend\Validator\Sitemap_* 927 927 927 927 929 929 929 929 930 930

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

221Step 931 221.1 Supported options for Zend\Validator\Step . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931 xxi

221.2 Basic usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931 221.3 Using floating-point values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931 222StringLength 222.1 Supported options for Zend\Validator\StringLength 222.2 Default behaviour for Zend\Validator\StringLength 222.3 Limiting the maximum allowed length of a string . 222.4 Limiting the minimal required length of a string . 222.5 Limiting a string on both sides . . . . . . . . . . . 222.6 Encoding of values . . . . . . . . . . . . . . . . . 223Validator Chains 224Writing Validators 933 933 933 933 934 934 934 937 939

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

225Validation Messages 943 225.1 Using pre-translated validation messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 943 225.2 Limit the size of a validation message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944 226Getting the Zend Framework Version 227Zend\View Quick Start 228Overview 229Usage 229.1 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229.2 Controllers and View Models . . . . . . . . . . . . . . . . . . . . . . 229.3 Nesting View Models . . . . . . . . . . . . . . . . . . . . . . . . . . 229.4 Dealing with Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . 229.5 Creating and Registering Alternate Rendering and Response Strategies 945 947 949 951 951 952 953 955 958

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

230The PhpRenderer 963 230.1 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 963 230.2 Options and Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 967 230.3 Additional Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 967 231PhpRenderer View Scripts 969 231.1 Escaping Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 970 232View Helpers 233Included Helpers 233.1 URL Helper . . . . . 233.2 HtmlList Helper . . . 233.3 BasePath Helper . . . 233.4 Cycle Helper . . . . . 233.5 Partial Helper . . . . . 233.6 Placeholder Helper . . 233.7 Doctype Helper . . . . 233.8 HeadLink Helper . . . 233.9 HeadMeta Helper . . . 233.10HeadScript Helper . . 233.11HeadStyle Helper . . . 233.12HeadTitle Helper . . . 233.13HTML Object Helpers 971 973 973 974 976 976 977 979 982 983 984 986 989 990 991

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

xxii

. . . . . . . . . . . . . . . . . . . . . 239. . . . . . . . . . 237. .233. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 Anatomy of a webservice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12Performance optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 Submitting false positives (ham) 238. . . . . 239. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Registering Concrete Helpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Looking up a Specific Amazon Item by ASIN . . . . . . . . . . . . . . . . . . . . . . . . . .1 Quick Start . . . . . . . . . . . . . . . . . . . . .6 Utilizing Namespaces . . . 238. . . . . . . . . . . . . . . . . . 1020 234. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 Writing Custom Helpers . . . . . . .5 Error Handling . . . . . 238. . . 237. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11Usage Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239. . . . . . . . . . . . . . .1 Introduction . . . . . . . . . . . . . . . . . . . . . . 236. 236. . . . . . . . . . . . . . . . 1021 235Introduction 1023 235. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237. . . 993 234Advanced usage of helpers 1019 234. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237. . . . . .3 Types and Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993 233. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 Conventions . . . . .3 Check for spam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239. . . . 236. . . . . . .3 Server Structure . . . . . . . .2 Country Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 Submitting known spam . . . . . . . . 237. 1019 234. . . . . . . . . . . . . . . . . . . . . . . . 1023 236Zend\XmlRpc\Client 236. . . . . . 238ZendServiceAkismet 238. . . . . . . . . . . . . . . . . . . . .1 Introduction . . . . . . . . . . . . . . . . . . 237. . . . . . . . . . . . . . . . . . 1053 xxiii . . . . .8 HTTP Client and Testing . . . . . . . . . . . . . . . . . . . . . . .2 Users . .16Navigation Helpers . . . . . . . . . . . . . . . . . . . . .8 Custom Responses . . . . . . . . . . . . . . . . 1053 240. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239ZendServiceAmazon 239. . . . . . . . . .6 Server Introspection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Introduction . . . . . . . . . . . . . . . . . . . . .1 Registering Helpers . . . . . . . . . . . . . . . . . . . 238. . . 1025 1025 1025 1026 1027 1028 1029 1030 1030 1031 1031 1031 1031 1032 1032 1033 1033 1034 1034 1034 1035 1039 1041 1041 1041 1041 1042 1043 1043 1045 1045 1046 1046 1047 1047 1048 . . . . . . . . .2 Method Calls . . . . . . . .7 Custom Request Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 Handling Exceptions via Faults . . . . . . . . .2 Basic Usage . . . . 240ZendServiceAudioscrobbler 1053 240. . . . .2 Verify an API key . . . . . . . . . . . . . . . . . .14InlineScript Helper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 Server Proxy Object . . . . . . . . . . . . . . . .7 From Request to Response 236. . . . . . . . . . . . . . . . . . . . . . . 237. . . . . . . . . . . . . . . . . . . . . . . . . .5 Using the Alternative Query API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992 233. . 238. . . . . 236. . . . . . . . .10Caching Server Definitions Between Requests 237. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239. . . .6 ZendServiceAmazon Classes . . . . .4 Performing Amazon Item Searches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15JSON Helper . . .6 Zend-specific Methods . . .1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . 236. . . . . . . . . . . . . . . . . . . . . . . . . . . 237. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Introduction . 237Zend\XmlRpc\Server 237. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237.

. . . . . . . . . .9 Public data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Introduction .3 ZendServiceDeliciousPostList 241. . . . . . . . . . . . . .1 Introduction to DeveloperGarden 242. . 241. . . . . . . . 246Zend\Service\Rackspace 246. .3 Finding photos From a Group Pool . . . . . . . . .4 Cloud Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243ZendServiceFlickr 243. . . 245. . . . . . . . . . . . . . . . . . . . . . . . . .5 240. 242Zend_Service_DeveloperGarden 242. . . . . . . . . . .4 Local Search . . . 242. . . . . . . . . 242. . . . . . . . . . .9 Performance and Caching . .4 Retrieving Flickr Image Details . . . . . . . . . . . . . . . .1 Introduction to LiveDocx . . . . . . . . . . . . . . . . . .1 Introduction . . . . . 245. . . . . . . . . . . . . . . . 242. . . . . . . . . . . . . . . . . . . . . . . . 1075 244. . . . . . . . . 245. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Groups Forums . . . . . . . . . . . . . . . . . . . . . . . . . 241. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 Tags .7 Artists Tracks Tags . .8 Handling Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243. . . . . . . . . . . . . . . . . . .8 Bundles . . . . . . . . . . . . . . . . . 241. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1077 245ZendServiceNirvanix 245. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 Features . . . . . . . . . . . . .5 Deleting posts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 Send SMS . . . 242. . . .7 Examining Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 IP Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245. . . . . . . . . . 241. . . . . . . . . . . . . . . . . . .3 API Documentation . .2 Registering with Rackspace 246. . . . . . . . . . . . . . . . . . . . . . .6 240. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 Adding new posts . 243. . . . . . . . . . . . . . . . . . . . . . . . . . . 242. . . . . . . . . . .2 Registering with Nirvanix 245. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 Editing posts . . . . . . . . . . . . . . . . . . . . . . . . .1 Introduction . . . . . .2 ZendService\LiveDocx\MailMerge . . . . 243. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 Retrieving posts . . . . . . . .2 Finding Flickr Users’ Photos and Information 243. . . . . . . . . . . . . . . . . . . .5 Getting Started . . . . . . . . . . . 245. . . . . . . .3 Cloud Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242. . . . . . . . . . . . . 241. . . . . . . . . . .10HTTP client . . . . . . . . . . . . . . . . . . . . . . . . .6 Understanding the Proxy . . . . .7 Voice Call . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241. . . . 1089 1089 1089 1089 1089 1090 1090 1091 1092 1093 1093 1093 1093 1094 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 SMS Validation . . . . . . . 246. . . . . . . . . . . . . . . . . . . . 241. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 240. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv . . . . . . . . . . . . . .2 BaseUserService . . . . .8 ConferenceCall . . . . . . . . . . .5 ZendServiceFlickr Result Classes . . . . . .240. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244ZendService\LiveDocx 1075 244. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1055 1055 1056 1056 1056 1057 1057 1057 1058 1059 1059 1060 1060 1061 1061 1062 1063 1063 1064 1065 1066 1066 1067 1067 1068 1070 1071 1071 1071 1072 1072 1072 241ZendServiceDelicious 241. . .4 240. . . . . . 241. . . . . . . . . . . . . . . . . . . . .

. . . . .4 Making Your First Query . . . . . . . . . . . . . . . . . .1 Introduction . . . . 248. . . . . . . . . . . . 248. . . . . . . . . . . . . . . . . . .2 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 ZendServiceTechnorati Classes . . . .2 Installing the Windows Azure SDK . . . . .8 Favorite Methods . . . . . . . . . . . .1 Introduction . . . . . . . . . 1137 xxv . .4 Consuming Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250. . . . . . . . . . . . . . . . . . . . . . . . . . . 248. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 ZendServiceSlideShare Caching policies . . . . . . . . . . . . . . . . 250ZendServiceTechnorati 250. . . . . . . . . . . . . . . . . . .3 Account Methods . . . . . . . . . . . . . . . . . . . . . . . . . 1094 247ZendServiceReCaptcha 1097 247. . . . . . . . . . . .2 Twitter Trends . . . . . . . . . . . . . . . 251. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 Block Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1098 248ZendServiceSlideShare 248. . . . . . . 1137 253. . . . .6 Handling Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1137 253. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 Friendship Methods . . . . . . . . . . . .6 Direct Message Methods 251. . . . . . . . . . . . . . . . . . . . . . .3 API Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250. . . . . . . .2 The SlideShow object . . . . . . . . . . . . . 250. . . . . . .1 Getting Started with ZendServiceSlideShare 248. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 Simplest use . . . . .6 Checking Your API Key Daily Usage 250. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 Changing the behavior of the HTTP Client . 248. . . . .5 Handling Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 Available Methods . . 251. . .5 Examining Results . . . . . . . . . . . . . . . . .1 Overview . . . . . . . . . . . . . . . . . . . . . . . .3 Retrieving a single slide show . . .1 Introduction . . . . . . . . . . . . . . . . . . 250. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251ZendServiceTwitter 251. . . . . . . . . . . . . . . . . . . . . 250. 249ZendServiceStrikeIron 249. . . . . . . . . . 249. . . . . . . . . . . . . . 249. . . . 252. . . .7 Available Technorati Queries . . .3 Making Your First Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 Registering with StrikeIron 249. . . . . . . . . . . . . . . . 249. . . . . 253ZendServiceWindowsAzure 1137 253. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249. . . . . . . .3 Searching Twitter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097 247. . . . . . . . . . 252ZendServiceTwitterSearch 252. . . . . . . . 251.246. . . . . . . . . . . . . . . . . . . . . . . . . . .4 Status Methods . . . . . . . . . . 252. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251. . . . . . . . . . . . . . . . . . . . 251. . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Hiding email addresses . . . . . . . . . . . . . . . . . . .4 Retrieving Groups of Slide Shows . . . . . . . . . . . . . . . . . .2 Authentication . . . . . . . . .4 Zend-specific Accessor Methods . . . . . . . . . . . . 1097 247. . . . . . . . . . . . . . . . . .7 Checking Your Subscription 1101 1101 1101 1104 1104 1105 1105 1107 1107 1107 1108 1108 1109 1110 1110 1113 1113 1113 1113 1114 1115 1116 1116 1120 1125 1125 1125 1126 1127 1129 1130 1131 1132 1133 1135 1135 1135 1135 1136 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249. .1 Introduction . . .3 Getting Started . . . . . . . . 251. . . . . . . . . . . . . . . . . . . .5 User Methods . . . . . . . . . . . . . . . . . 251. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . .4 Usage . . using the PHAR file 257. . . . . . . . . . . . . . . . . . . . .19Zend\Ldap . . . . . 1145 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253. . . . . . . .3 Table storage session handler . . . . . . . . . . . . . . 263. . . . . 263. . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1155 257Zend Framework Tool (ZFTool) 257. . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255. . .17Zend\InputFilter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . 1139 1139 1141 1141 1142 . . . . . . . . . . . . . . .5 Zend\Config . . . .7 Zend\Crypt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 Zend\Captcha . 263. . . . . . . . . . . . . . . .1 Operations on tables . . . . . . . . . . . 263. 257. . . . . . . . . .10Zend\Dom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . .5 Architecture .3 Without installation. . . . . . . . 263. 1152 256ZendServiceWindowsAzureStorageQueue 1155 256. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Zend\Authentication . . . .22Zend\Mail . . . . . . . . . . . . . . . . .9 Zend\Di . . . . . . . . . . 1145 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 Shared Access Signature . . . .21Zend\Log . . . . .6 Zend\Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12Zend\Feed . . . . . . . . .3 Zend\Cache . . .3 Blob storage stream wrapper . . . . .1 API Examples . 254. . . . . 263. . . . . . .20Zend\Loader . . . . . . . . . . . . . .15Zend\Http . . . . . . . . . 254. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 Zend\Db . . . . . . . . . . . . . . . .2 Manual installation .1 API Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254. . . . .18Zend\Json . . . . 1137 253. . . . . . . . . . . . . . . . . 1138 254ZendServiceWindowsAzureStorageBlob 254. . . . . .1 Installation using Composer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 Root container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1146 . 263. 258Copyright Information 259Introduction to Zend Framework 2 260User Guide 261Zend Framework Tool (ZFTool) 262Learning Zend Framework 2 263Zend Framework 2 Reference 263. . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . 263. . . . . . . . 255. . . . . . . . . . . . . . . . . 257. . .4 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . .11Zend\EventManager . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . xxvi 1159 1159 1159 1159 1160 1163 1165 1167 1169 1171 1173 1173 1173 1173 1174 1174 1174 1174 1174 1175 1175 1175 1175 1176 1176 1176 1176 1177 1177 1177 1177 1178 1178 . . . . . . . . . . . . . . . . 255ZendServiceWindowsAzureStorageTable 255. . . . . . . . . . . .2 Zend\Barcode . . . . . . . . . . . . . .2 Operations on entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16Zend\I18n . . . . . . . . . . . .13Zend\Filter . .14Zend\Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . 264. . . . . . . . . . . . . . . . 264. . . . . . . . . . . . . . . . . . . .5 ZendService\Developer Garden . 263. . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . 264. . 263. . . . .1 ZendService\Akismet . . . . .39Zend\Validator . . . . . . . . . . . . . . . . . . . . 264. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37Zend\Text . . . . .25Zend\ModuleManager . . . . . . .263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264. . . . . . .7 ZendService\Google\Gcm . . . . . . 263. . . . . . . . . . . . . .14ZendService\Technorati . . .40Zend\Version . . . .16ZendService\Windows Azure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33Zend\ServiceManager . .11ZendService\ReCaptcha . . . . . . . . . . . . .36Zend\Tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264. . . . . . . . . . . . . . . . . . . . . . . . . . . .8 ZendService\LiveDocx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .27Zend\Navigation . . . .42Zend\XmlRpc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35Zend\Stdlib . . .23Zend\Math . . . . . . . . . . . . . . . .4 ZendService\Del. . . . . . . . . . . . . .32Zend\Server .31Zend\Serializer . .41Zend\View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . 263. . . . . .6 ZendService\Flickr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .us . . . . . . . . . . . . . . .10ZendService\Rackspace . . . . . . . . . . . . . . . . . .13ZendService\StrikeIron . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 ZendService\Amazon . . . . . . . . . . . . . . . 264. . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . 264. . . . . . . . . . . . . . . . . . . . . . . . . . . . 264. . . . . . . . . . . . . . . . . . . . . . 1178 1178 1178 1178 1179 1179 1179 1179 1179 1180 1180 1180 1180 1180 1180 1180 1181 1181 1181 1181 1183 1183 1183 1183 1183 1183 1183 1183 1184 1184 1184 1184 1184 1184 1184 1184 1184 1185 1187 264Services for Zend Framework 2 Reference 264. . . . . . . . 263. . . . . . . . . . . . . . . . . . 263. . . . . . . xxvii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28Zend\Paginator . . . . . . 264. . . . . . . . . . . . . .9 ZendService\Nirvanix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26Zend\Mvc . . . . . . . . . . . . . .3 ZendService\Audioscrobbler . . . . . . . . . . . . . . . . . 263. . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . 264. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34Zend\Soap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38Zend\Uri . . . . . .29Zend\Permissions\Acl . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . . . .30Zend\Permissions\Rbac 263. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264. .icio. . . . . . . . . . . . . . . . . . . .24Zend\Mime . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263. . . . . . . . 263. . . . . . . . .12ZendService\SlideShare . . . . . . . . . . . . . . . . . . . . 265Copyright 266Indices and tables . . . . . . . . . . . . . . . . . . 264. . . . .15ZendService\Twitter . . . . . . .

xxviii .

a database abstraction that is simple to use. late static binding. Whatever question you have about Zend Framework 2.3+ implemented by the framework. Community members.CHAPTER ONE OVERVIEW Zend Framework 2 is an open source framework for developing web applications and services using PHP 5. further enhancing this design. Note: ZF2 is not backward compatible with ZF1. Still others. but many companies have contributed components or significant features to the framework. make themselves available on mailing lists. it offers a robust. The principal sponsor of the project ‘Zend Framework 2’ is Zend Technologies. This loosely coupled architecture allows developers to use whichever components they want. such as Zend\Authentication and Zend\Permissions\Acl. The component structure of Zend Framework 2 is unique. Zend Framework 2 uses 100% object-oriented code and utilises most of the new features of PHP 5. each component is designed with few dependencies on other components.3. ZF2 follows the SOLID object oriented design principle. IRC channels and other forums. and due to major rewrites of many components. While they can be used separately. Zend Framework 2 components in the standard library form a powerful and extensible web application framework when combined. namely namespaces. Zend Framework 2 evolved from Zend Framework 1. We use PHPUnit to test our code and Travis CI as a Continuous Integration service. you’re likely to find a Zend Framework 2 component that can be used to dramatically reduce development time with a thoroughly tested foundation. Also. a successful PHP framework with over 15 million downloads. Microsoft. lambda functions and closures.3+. object oriented interface. 1 . and StrikeIron have partnered with Zend to provide interfaces to web services and other technologies they wish to make available to Zend Framework 2 developers. Companies such as Google. implement client libraries to simply access the most popular web services available. Whatever your application needs are. Other components. Zend Framework 2 could not deliver and support all of these features without the help of the vibrant Zend Framework 2 community. because of the new features in PHP 5. with the ZendService namespace. including contributors. We support Pyrus and Composer as installation and dependency tracking mechanisms for the framework as a whole and for each component. high performance MVC implementation. the community is always available to address it. We call this a “use-at-will” design. provide user authentication and authorization against all common credential stores. validation. and filtering so that developers can consolidate all of these operations using one easy-to-use. and a forms component that implements HTML5 form rendering.

Overview .6 2 Chapter 1. Release 2.0.Zend Framework 2 Documentation.

3 . Consider using Git to get Zend Framework if you want to contribute back to the framework.’ To fix that. or need to upgrade your framework version more often than releases occur. Zend Framework is open source software.gz formats. i. Once you have a copy of Zend Framework available.zip and . • Brave.conf (or equivalent). Also.CHAPTER TWO INSTALLATION • New to Zend Framework? Download the latest stable release. Getting Started with Zend Framework 2. Run ‘php composer. There are several ways to achieve this. cutting edge? Download Zend Framework’s Git repository using a Git client.phar install‘ or define a ZF2_PATH environment variable. and the Git repository used for its development is publicly available on GitHub. Failing to find a Zend Framework 2 installation.e. you can add the Zend Framework’s library path to the PHP include_path. Other Zend Framework community members are actively working on expanding the tutorial. Rob Allen has kindly provided the community with an introductory tutorial. your application needs to be able to access the framework classes found in the library folder. the following error occurs: Fatal error: Uncaught exception ’RuntimeException’ with message ’Unable to load ZF2.tar. you should set an environment path named ‘ZF2_PATH’ in httpd. SetEnv ZF2_PATH /var/ZF2 running Linux. Available in .

Release 2. Installation .6 4 Chapter 2.0.Zend Framework 2 Documentation.

1 Some assumptions This tutorial assumes that you are running PHP 5. We will also need to store our data into a database. We will only need one table with these fields in it: 5 .CHAPTER THREE GETTING STARTED WITH ZEND FRAMEWORK 2 This tutorial is intended to give an introduction to using Zend Framework 2 by creating a simple database driven application using the Model-View-Controller paradigm.2 The tutorial application The application that we are going to build is a simple inventory system to display which albums we own.htaccess usage correctly. Check with your distribution’s documentation for exact details. This page will provide a form for editing an album. By the end you will have a working ZF2 application and you can then poke around the code to find out more about how it all works and fits together. Your Apache installation must have the mod_rewrite extension installed and configured. You will not be able to navigate to any page other than the home page in this tutorial if you have not configured mod_rewrite and .3 with the Apache web server and MySQL. This page will confirm that we want to delete an album and then delete it.3. This page will provide a form for adding a new album. We are going to need four pages in our website: Page List of albums Add new album Edit album Delete album Description This will display the list of albums and provide links to edit and delete them. Also. a link to enable adding new albums will be provided.conf file. edit and delete CDs.htaccess files. 3. accessible via the PDO extension. The main page will list our collection and allow us to add. This is usually done by changing the setting: AllowOverride None to AllowOverride FileInfo in your httpd. 3. You must also ensure that Apache is configured to support .

6 Field name id artist title Type integer varchar(100) varchar(100) Null? No No No Notes Primary key. Getting Started with Zend Framework 2 . Release 2.0.Zend Framework 2 Documentation. auto-increment 6 Chapter 3.

ZendSkeletonApplication is set up to use Composer (http://getcomposer.phar self-update php composer. Go to https://github.zendframework.0.org) to create a new project from scratch with Zend Framework: php composer. we will start with the ZendSkeletonApplication available on github. and composer timed out. In this case. This will download a file with a name zendframework-ZendSkeletonApplication-zfrelease-2. You should see an output like: Installing dependencies from lock file . To install Zend Framework 2 into our application we simply type: php composer.phar create-project --repository-url="http://packages.zip similar. the dependency is Zend Framework 2 itself.CHAPTER FOUR GETTING STARTED: A SKELETON APPLICATION In order to build our application.phar install from the zf2-tutorial folder.Installing zendframework/zendframework (dev-master) Cloning 18c8e223f070deb07c17543ed938b54542aa0ed8 Generating autoload files Note: If you see this message: [RuntimeException] The process timed out.com/zendframework/ZendSkeletonApplication click the “Zip” button. then your connection was too slow to download the entire package in time.com" zendframework/s Note: Another way to install the ZendSkeletonApplication is to github.0beta5-2-gc2c7315. use and like or Unzip this file into the directory where you keep all your vhosts and rename the resultant directory to zf2-tutorial. Use Composer (http://getcomposer.org) to resolve its dependencies.phar install 7 . instead of running: php composer. To avoid this. This takes a while.

1 zf2-tutorial.0. Setting up the virtual host is usually done within httpd. navigate to http://zf2-tutorial.localhost localhost Restart your web server.htaccess file is working.php from the zf2-tutorial/public directory.Zend Framework 2 Documentation.L] You now have a working skeleton application and we can start adding the specifics for our application.conf file. Some Linux distributions (ex: Ubuntu) package Apache so that configuration files are stored in /etc/apache2 and create one file per virtual host inside folder /etc/apache2/sites-enabled.localhost/1234 and you should see this: If you see a standard Apache 404 error. 4.deny Allow from all </Directory> </VirtualHost> Make sure that you update your /etc/hosts or c:\windows\system32\drivers\etc\hosts file so that zf2-tutorial.localhost DocumentRoot /path/to/zf2-tutorial/public SetEnv APPLICATION_ENV "development" <Directory /path/to/zf2-tutorial/public> DirectoryIndex index.localhost is mapped to 127.*$ index.php [NC. 8 Chapter 4.phar install We can now move on to the virtual host.0. you should see something like this: To test that your .conf or extra/httpd-vhosts. and then define a virtual host along these lines: <VirtualHost *:80> ServerName zf2-tutorial.1. In this case. you would place the virtual host block below into the file /etc/apache2/sites-enabled/zf2-tutorial. then you need to fix .6 run instead: COMPOSER_PROCESS_TIMEOUT=5000 php composer. If you are using httpd-vhosts. ensure that this file is included by your main httpd.0. Release 2. The website can then be accessed using http://zf2tutorial.php AllowOverride All Order allow.localhost will serve index. If you’re are using IIS with the URL Rewrite Module. 127. import the following: RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^.htaccess usage before continuing.localhost. Getting started: A skeleton application .conf.0.0.conf. Ensure that NameVirtualHost is defined and set to “*:80” or similar. If you’ve done it right.1 Virtual host You now need to create an Apache virtual host for the application and edit your hosts file so that http://zf2tutorial.

also under zf-tutorial/module/Application/test: This is a Bootstrap written by Evan Coury which can just be dropped in. 9 . Your unit tests will help alleviate that by automatically testing your application’s components and alerting you when something is not working the same way it was when you wrote your tests. The Zend Framework 2 API uses PHPUnit.2 Bootstrapping your tests Next. 5. especially those with many people involved. This tutorial assumes that you already have PHPUnit installed. create a file called phpunit.php.0" encoding="UTF-8"?> <phpunit bootstrap="Bootstrap. so we will only provide sample tests for the components in the pages that follow. and so does this tutorial application. 5.dist under zf2-tutorial/module/Application/test: <?xml version="1. and it will allow you to keep your tests well-organized and easy to find.1 Setting up the tests directory Start by creating a directory called test in zf2-tutorial\module\Application with the following subdirectories: zf2-tutorial/ /module /Application /test /ApplicationTest /Controller The structure of the test directory matches exactly with that of the module’s source files.php"> <testsuites> <testsuite name="zf2tutorial"> <directory>.xml. A detailed explanation of unit testing is beyond the scope of this tutorial. Going back and manually testing every individual component of an application after every change is impractical.CHAPTER FIVE UNIT TESTING A solid unit test suite is essential for ongoing development in large projects./ApplicationTest</directory> </testsuite> </testsuites> </phpunit> A file called Bootstrap. only the namespace needs changing.

protected static $bootstrap. Zend\Mvc\Service\ServiceManagerConfig. $zf2ModulePaths .= getenv(’ZF2_MODULES_TEST_PATHS’) ?: (defined(’ZF2_MODULES_TEST_PATHS’) ? Z static::initAutoloader(). public static function init() { // Load the user-defined test configuration file.php’)) { $testConfig = include __DIR__ . chdir(__DIR__).php. $serviceManager = new ServiceManager(new ServiceManagerConfig()). otherwise. ). $serviceManager->setService(’ApplicationConfig’. protected static $config.Zend Framework 2 Documentation. PATH_SEPARATOR. // use ModuleManager to load this module and it’s dependencies $baseConfig = array( ’module_listener_options’ => array( ’module_paths’ => explode(PATH_SEPARATOR. static::$config = $config. $serviceManager->get(’ModuleManager’)->loadModules(). Zend\ServiceManager\ServiceManager. error_reporting(E_ALL | E_STRICT). } else { $testConfig = include __DIR__ .dist’. Zend\Stdlib\ArrayUtils.//Change this namespace for your test use use use use use Zend\Loader\AutoloaderFactory. foreach ($modulePaths as $modulePath) { if (($path = static::findParentPath($modulePath)) ) { $zf2ModulePaths[] = $path.php’. if (isset($testConfig[’module_listener_options’][’module_paths’])) { $modulePaths = $testConfig[’module_listener_options’][’module_paths’]. ’/TestConfig. } $zf2ModulePaths = array(). ’/TestConfig. $config = ArrayUtils::merge($baseConfig. class Bootstrap { protected static $serviceManager. $testConfig). static::$serviceManager = $serviceManager.0. load if (is_readable(__DIR__ . Release 2. ). RuntimeException. $zf2ModulePaths). Unit Testing . $zf2ModulePaths) . if it exists. 10 Chapter 5. $config). ’/TestConfig. } } } $zf2ModulePaths = implode(PATH_SEPARATOR.6 <?php namespace ApplicationTest.

Bootstrapping your tests 11 . ’/’ . } } Bootstrap::init(). And a file called TestConfig. if (!$zf2Path) { throw new RuntimeException(’Unable to load ZF2. } public static function getConfig() { return static::$config. } protected static function initAutoloader() { $vendorPath = static::findParentPath(’vendor’). } protected static function findParentPath($path) { $dir = __DIR__.php’. __NAMESPACE__.2.php’. ). } else { $zf2Path = getenv(’ZF2_PATH’) ?: (defined(’ZF2_PATH’) ? ZF2_PATH : (is_dir($vendorPath .php. )). ’/Zend/Loader/AutoloaderFactory.dist <?php return array( 5. if (is_readable($vendorPath . ’/autoload. $previousDir = ’.Zend Framework 2 Documentation.6 } public static function getServiceManager() { return static::$serviceManager. if ($previousDir === $dir) return false. ’/’ . ’/’ . ’/autoload. Run ‘php composer. ). Release 2. } return $dir .’.php’)) { $loader = include $vendorPath .0. $path)) { $dir = dirname($dir). $previousDir = $dir. ’namespaces’ => array( __NAMESPACE__ => __DIR__ . $path. } AutoloaderFactory::factory(array( ’Zend\Loader\StandardAutoloader’ => array( ’autoregister_zf’ => true. while (!is_dir($dir .phar install‘ or de } include $zf2Path .

protected $routeMatch. ). Zend\Mvc\MvcEvent. use use use use use use use use ApplicationTest\Bootstrap. create IndexControllerTest.config. $this->controller = new IndexController(). class IndexControllerTest extends \PHPUnit_Framework_TestCase { protected $controller. $config = $serviceManager->get(’Config’).}{global. This is basically the same as config/application. $this->request = new Request(). PHPUnit_Framework_TestCase. ’module_listener_options’ => array( ’config_glob_paths’ => array( ’.php but we define only the modules which are required for this test 5. protected $request.. $this->event->setRouter($router)./. ’vendor’. protected $event.*.. Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter. )./. $this->event = new MvcEvent(). Zend\Http\Response. Unit Testing .. $routerConfig = isset($config[’router’]) ? $config[’router’] : array(). Zend\Http\Request.6 ’modules’ => array( ’Application’. 12 Chapter 5. $router = HttpRouter::factory($routerConfig).local}. Zend\Mvc\Router\RouteMatch. Release 2. ).php’. $this->routeMatch = new RouteMatch(array(’controller’ => ’index’)).0. Application\Controller\IndexController./config/autoload/{. $this->event->setRouteMatch($this->routeMatch). protected function setUp() { $serviceManager = Bootstrap::getServiceManager().Zend Framework 2 Documentation.3 Your first Controller test Next. ’module_paths’ => array( ’module’. ).php under zf-tutorial/module/Application/test/ApplicationTest/Con with the following contents: <?php namespace ApplicationTest\Controller. protected $response. ).

4 Testing Finally. } } Here. Now.4. we expand a bit on the setup in Tom Oram’s Unit Testing a ZF 2 Controller blog entry by initializing our application in the setUp() method and setting the EventManager and ServiceLocator directly on the controller. } The test is verifying that the homepage responds with HTTP status code 200. If you see something like this. ’index’). $response->getStatusCode()).75Mb OK (1 test. $this->controller->setServiceLocator($serviceManager). $this->assertEquals(200. then your application is ready for more tests! PHPUnit 3. Memory: 5.5.6 $this->controller->setEvent($this->event). Time: 0 seconds. Release 2.Zend Framework 2 Documentation. cd to zf-tutorial/module/Application/test/ and run phpunit. add the following function to the IndexControllerTest class: public function testIndexActionCanBeAccessed() { $this->routeMatch->setParam(’action’. This isn’t important right now.15 by Sebastian Bergmann. $result = $this->controller->dispatch($this->request). but we’ll need it later on when writing more advanced tests. Testing 13 . 5. 2 assertions) 5.0. $response = $this->controller->getResponse(). .

Release 2.6 14 Chapter 5.0. Unit Testing .Zend Framework 2 Documentation.

which is the directory name of the module. say. In order to load and configure a module. Zend Framework 2 has a ModuleManager. error and routing configuration to the whole application. This will look for Module.CHAPTER SIX MODULES Zend Framework 2 uses a module system and you organise your main application-specific code within each module. The Application module provided by the skeleton is used to provide bootstrapping. It is usually used to provide application level controllers for.php in the root of the module directory (module/Album) and expect to find a class called Album\Module within it. 6. That is.php in the Album zf2-tutorial/module/Album: module: Create a file called Module. The view directory also has a sub-folder called album for our module’s view scripts. We’ll also tweak the Application module as required.1 Setting up the Album module Start by creating a directory called Album under module with the following subdirectories to hold the module’s files: zf2-tutorial/ /module /Album /config /src /Album /Controller /Form /Model /view /album /album As you can see the Album module has separate directories for the different types of files we will have. the classes within a given module will have the namespace of the module’s name. but we are not going to use the default one provided in this tutorial as we want our album list to be the home page. Let’s start with the directories required.php under 15 . We are going to put all our code into the Album module which will contain our controllers. The PHP files that contain classes within the Album namespace live in the src/Album directory so that we can have multiple namespaces within our module should we require it. Create Module. along with configuration. forms and views. models. the home page of an application. which will live in our own module.

whenever the autoloader looks for a class within the Album namespace.6 <?php namespace Album. This method simply loads the config/module.Zend Framework 2 Documentation. let’s have a quick look at the getConfig() method in Album\Module.config. 6.php under zf2-tutorial/module/Album: <?php return array().1 Autoloading files Our getAutoloaderConfig() method returns an array that is compatible with ZF2’s AutoloaderFactory. 6. __NAMESPACE__. it will fall back to the to StandardAutoloader for us. then you need to run php composer. class Module { public function getAutoloaderConfig() { return array( ’Zend\Loader\ClassMapAutoloader’ => array( __DIR__ .php’. } } The ModuleManager will call getAutoloaderConfig() and getConfig() automatically for us. we don’t need to load files via the classmap. Modules .config. ’/config/module. ’/autoload_classmap. The standard autoloader requires a namespace and the path where to find the files for that namespace.php under zf2-tutorial/module/Album/config: 16 Chapter 6. so we provide an empty array for the classmap autoloader. As this is an empty array. Note: Note that as we are using Composer.phar update to update the composer autoloading files.config. It is PSR-0 compliant and so classes map directly to files as per the PSR-0 rules. If you go this way.json.1. ). ’/src/’ .php file. ).2 Configuration Having registered the autoloader. ). Create a file called autoload_classmap. } public function getConfig() { return include __DIR__ . ’Zend\Loader\StandardAutoloader’ => array( ’namespaces’ => array( __NAMESPACE__ => __DIR__ . Create a file called module. Release 2. you could not implement getAutoloaderConfig() and instead add "Application": "module/Application/src" to the psr-0 key in composer. ). We configure it so that we add a class map file to the ClassmapAutoloader and also add this module’s namespace to the StandardAutoloader. as an alternative.0. As we are in development.php’.

3. // <-.php file which is provided by the skeleton application. Within the view_manager section. ’view_manager’ => array( ’template_path_stack’ => array( ’album’ => __DIR__ . We will need one controller. ). ’module_listener_options’ => array( ’config_glob_paths’ => array( ’config/autoload/{.*.0. so we prefix it with our module name. As you can see.local}./view’. ). The controllers section provides a list of all the controllers provided by the module. ). ’.6 <?php return array( ’controllers’ => array( ’invokables’ => array( ’Album\Controller\Album’ => ’Album\Controller\AlbumController’. ’Album’. we add our view directory to the TemplatePathStack configuration. This is done in the application’s config/application. This will allow it to find the view scripts for the Album module that are stored in our view/ directory. ’/. ). ). We need two initial sections: controllers and view_manager. We have now set up the module ready for putting our custom code into it.Add this line ). ). ). which we’ll reference as Album\Controller\Album../module’. The controller key must be unique across all modules.config. Update this file so that its modules section contains the Album module as well.) <?php return array( ’modules’ => array( ’Application’.Zend Framework 2 Documentation.php’. 6. so the file now looks like this: (Changes required are highlighted using comments. 6. Informing the application about our new module 17 ./vendor’. we have added our Album module into the list of modules after the Application module. AlbumController. ). Release 2. ).3 Informing the application about our new module We now need to tell the ModuleManager that this new module exists. The config information is passed to the relevant components by the ServiceManager.}{global. ’module_paths’ => array( ’.

Zend Framework 2 Documentation. Modules . Release 2.0.6 18 Chapter 6.

This page will confirm that we want to delete an album and then delete it. you would generally group related actions into a controller. ). a link to enable adding new albums will be provided. ’options’ => array( 19 . Before we set up our files. This page will provide a form for editing an album. This is the updated module config file with the new code highlighted. This page will provide a form for adding a new album.CHAPTER SEVEN ROUTING AND CONTROLLERS We will build a very simple inventory system to display our album collection. it’s important to understand how the framework expects the pages to be organised. for instance. Hence the following pages are required: Page Home Add new album Edit album Delete album Description This will display the list of albums and provide links to edit and delete them. we will group them in a single controller AlbumController within our Album module as four actions. We will add a route for our album actions. edit and delete albums. Also. As we have four pages that all apply to albums. archived and view. The four actions will be: Page Home Add new album Edit album Delete album Controller AlbumController AlbumController AlbumController AlbumController Action index add edit delete The mapping of a URL to a particular action is done using routes that are defined in the module’s module.php file.config. // The following section is new and should be added to your file ’router’ => array( ’routes’ => array( ’album’ => array( ’type’ => ’segment’. <?php return array( ’controllers’ => array( ’invokables’ => array( ’Album\Controller\Album’ => ’Album\Controller\AlbumController’. a news controller might have actions of current. The home page will list our collection and allow us to add. ). Hence. Each page of the application is known as an action and actions are grouped into controllers within modules.

Zend Framework 2 Documentation, Release 2.0.6

’route’ => ’/album[/:action][/:id]’, ’constraints’ => array( ’action’ => ’[a-zA-Z][a-zA-Z0-9_-]*’, ’id’ => ’[0-9]+’, ), ’defaults’ => array( ’controller’ => ’Album\Controller\Album’, ’action’ => ’index’, ), ), ), ), ), ’view_manager’ => array( ’template_path_stack’ => array( ’album’ => __DIR__ . ’/../view’, ), ), );

The name of the route is ‘album’ 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 ‘‘/album[/:action][/:id]‘‘ which will match any URL that starts with /album. 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 /album /album/add /album/edit/2 /album/delete/4 Page Home (list of albums) Add new album Edit album with an id of 2 Delete album with an id of 4 Action index add edit delete

7.1 Create the controller
We are now ready to set up our controller. In Zend Framework 2, the controller is a class that is generally called {Controller name}Controller. Note that {Controller name} must start with a capital letter. This class lives in a file called {Controller name}Controller.php within the Controller directory for the module. In our case that is module/Album/src/Album/Controller. Each action is a public method within the controller class that is named {action name}Action. In this case {action name} should start with a lower case letter. Note: This is by convention. Zend Framework 2 doesn’t provide many restrictions on controllers other than that they must implement the Zend\Stdlib\Dispatchable interface. The framework provides two abstract classes that do this for us: Zend\Mvc\Controller\AbstractActionController and Zend\Mvc\Controller\AbstractRestfulController. We’ll be using the standard AbstractActionController, but if you’re intending to write a RESTful web service, AbstractRestfulController may be useful.

20

Chapter 7. Routing and controllers

Zend Framework 2 Documentation, Release 2.0.6

Let’s go ahead and create our controller class zf2-tutorials/module/Album/src/Album/Controller :
<?php namespace Album\Controller; use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; class AlbumController extends AbstractActionController { public function indexAction() { } public function addAction() { } public function editAction() { } public function deleteAction() { } }

AlbumController.php

at

Note: We have already informed the module about our controller in the ‘controller’ section of module/Album/config/module.config.php. We have now set up the four actions that we want to use. They won’t work yet until we set up the views. The URLs for each action are: URL http://zf2-tutorial.localhost/album http://zf2-tutorial.localhost/album/add http://zf2-tutorial.localhost/album/edit http://zf2-tutorial.localhost/album/delete Method called Album\Controller\AlbumController::indexAction Album\Controller\AlbumController::addAction Album\Controller\AlbumController::editAction Album\Controller\AlbumController::deleteAction

We now have a working router and the actions are set up for each page of our application. It’s time to build the view and the model layer.

7.1.1 Initialise the view scripts
To integrate the view into our application all we need to do is create some view script files. These files will be executed by the DefaultViewStrategy and will be passed any variables or view models that are returned from the controller action method. These view scripts are stored in our module’s views directory within a directory named after the controller. Create these four empty files now: • module/Album/view/album/album/index.phtml • module/Album/view/album/album/add.phtml • module/Album/view/album/album/edit.phtml • module/Album/view/album/album/delete.phtml

7.1. Create the controller

21

Zend Framework 2 Documentation, Release 2.0.6

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

7.1.2 Write the tests
Our Album controller doesn’t do much yet, so it should be easy to test. Create a directory structure like described in the previous section ing<http://framework.zend.com/manual/2.0/en/user-guide/routing-and-controllers.html/> Create the follwing subdirectories:
zf2-tutorial/ /module /Album /test /AlbumTest /Controller

‘Unit

Test-

Add the 3 files as described in unit Testing to module/Album/test * ‘‘Bootstrap.php * phpunit.xml.dist * TestConfig.php.dist Remember here to change the namespace in Bootstrap.php and change the Module Application to Album in the ‘‘TestConfig.php.dist. In phpunit.xml change the directory to point at AlbumTest Create zf2-tutorial/module/Album/test/AlbumTest/Controller/AlbumControllerTest.php‘ with the following contents:
<?php namespace AlbumTest\Controller; use use use use use use use use AlbumTest\Bootstrap; Album\Controller\AlbumController; Zend\Http\Request; Zend\Http\Response; Zend\Mvc\MvcEvent; Zend\Mvc\Router\RouteMatch; Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter; PHPUnit_Framework_TestCase;

class AlbumControllerTest extends PHPUnit_Framework_TestCase { protected $controller; protected $request; protected $response; protected $routeMatch; protected $event; protected function setUp() { $serviceManager = Bootstrap::getServiceManager(); $this->controller = new AlbumController(); $this->request = new Request(); $this->routeMatch = new RouteMatch(array(’controller’ => ’index’)); $this->event = new MvcEvent(); $config = $serviceManager->get(’Config’); $routerConfig = isset($config[’router’]) ? $config[’router’] : array(); $router = HttpRouter::factory($routerConfig); $this->event->setRouter($router); $this->event->setRouteMatch($this->routeMatch);

22

Chapter 7. Routing and controllers

Zend Framework 2 Documentation, Release 2.0.6

$this->controller->setEvent($this->event); $this->controller->setServiceLocator($serviceManager); } public function testAddActionCanBeAccessed() { $this->routeMatch->setParam(’action’, ’add’); $result = $this->controller->dispatch($this->request); $response = $this->controller->getResponse(); $this->assertEquals(200, $response->getStatusCode()); } public function testDeleteActionCanBeAccessed() { $this->routeMatch->setParam(’action’, ’delete’); $result = $this->controller->dispatch($this->request); $response = $this->controller->getResponse(); $this->assertEquals(200, $response->getStatusCode()); } public function testEditActionCanBeAccessed() { $this->routeMatch->setParam(’action’, ’edit’); $result = $this->controller->dispatch($this->request); $response = $this->controller->getResponse(); $this->assertEquals(200, $response->getStatusCode()); } public function testIndexActionCanBeAccessed() { $this->routeMatch->setParam(’action’, ’index’); $result = $this->controller->dispatch($this->request); $response = $this->controller->getResponse(); $this->assertEquals(200, $response->getStatusCode()); } }

And execute phpunit from module/Album/test.
PHPUnit 3.5.15 by Sebastian Bergmann. ..... Time: 0 seconds, Memory: 5.75Mb OK (5 tests, 10 assertions)

7.1. Create the controller

23

Zend Framework 2 Documentation, Release 2.0.6

24

Chapter 7. Routing and controllers

CHAPTER

EIGHT

DATABASE AND MODELS
8.1 The database
Now that we have the Album module set up with controller action methods and view scripts, it is time to look at the model section of our application. Remember that the model is the part that deals with the application’s core purpose (the so-called “business rules”) and, in our case, deals with the database. We will make use of the Zend Framework class Zend\Db\TableGateway\TableGateway which is used to find, insert, update and delete rows from a database table. We are going to use MySQL, via PHP’s PDO driver, so create a database called zf2tutorial, and run these SQL statements to create the album table with some data in it.
CREATE TABLE album ( id int(11) NOT NULL auto_increment, artist varchar(100) NOT NULL, title varchar(100) NOT NULL, PRIMARY KEY (id) ); INSERT INTO album (artist, title) VALUES (’The Military Wives’, ’In My Dreams’); INSERT INTO album (artist, title) VALUES (’Adele’, ’21’); INSERT INTO album (artist, title) VALUES (’Bruce Springsteen’, ’Wrecking Ball (Deluxe)’); INSERT INTO album (artist, title) VALUES (’Lana Del Rey’, ’Born To Die’); INSERT INTO album (artist, title) VALUES (’Gotye’, ’Making Mirrors’);

(The test data chosen happens to be the Bestsellers on Amazon UK at the time of writing!) We now have some data in a database and can write a very simple model for it.

8.2 The model files
Zend Framework does not provide a Zend\Model component as the model is your business logic and it’s up to you to decide how you want it to work. There are many components that you can use for this depending on your needs. One approach is to have model classes represent each entity in your application and then use mapper objects that load and save entities to the database. Another is to use an ORM like Doctrine or Propel. For this tutorial, we are going to create a very simple model by creating an AlbumTable class that uses the Zend\Db\TableGateway\TableGateway class in which each album object is an Album object (known as 25

Zend Framework 2 Documentation, Release 2.0.6

an entity). This is an implementation of the Table Data Gateway design pattern to allow for interfacing with data in a database table. Be aware though that the Table Data Gateway pattern can become limiting in larger systems. There is also a temptation to put database access code into controller action methods as these are exposed by Zend\Db\TableGateway\AbstractTableGateway. Don’t do this! Let’s start by creating a file called Album.php under module/Album/src/Album/Model:
<?php namespace Album\Model; class Album { public $id; public $artist; public $title; public function exchangeArray($data) { $this->id = (isset($data[’id’])) ? $data[’id’] : null; $this->artist = (isset($data[’artist’])) ? $data[’artist’] : null; $this->title = (isset($data[’title’])) ? $data[’title’] : null; } }

Our Album entity object is a simple PHP class. In order to work with Zend\Db’s TableGateway class, we need to implement the exchangeArray() method. This method simply copies the data from the passed in array to our entity’s properties. We will add an input filter for use with our form later. But first, does the Album model we have so far work the way we expect it to? Let’s write a few tests to be sure. Create a file called AlbumTest.php under module/Album/test/AlbumTest/Model:
namespace AlbumTest\Model; use Album\Model\Album; use PHPUnit_Framework_TestCase; class AlbumTest extends PHPUnit_Framework_TestCase { public function testAlbumInitialState() { $album = new Album(); $this->assertNull($album->artist, ’"artist" should initially be null’); $this->assertNull($album->id, ’"id" should initially be null’); $this->assertNull($album->title, ’"title" should initially be null’); } public function testExchangeArraySetsPropertiesCorrectly() { $album = new Album(); $data = array(’artist’ => ’some artist’, ’id’ => 123, ’title’ => ’some title’); $album->exchangeArray($data); $this->assertSame($data[’artist’], $album->artist, ’"artist" was not set correctly’); $this->assertSame($data[’id’], $album->id, ’"id" was not set correctly’); $this->assertSame($data[’title’], $album->title, ’"title" was not set correctly’);

26

Chapter 8. Database and models

Zend Framework 2 Documentation, Release 2.0.6

} public function testExchangeArraySetsPropertiesToNullIfKeysAreNotPresent() { $album = new Album(); $album->exchangeArray(array(’artist’ => ’some artist’, ’id’ => 123, ’title’ => ’some title’)); $album->exchangeArray(array()); $this->assertNull($album->artist, ’"artist" should have defaulted to null’); $this->assertNull($album->id, ’"id" should have defaulted to null’); $this->assertNull($album->title, ’"title" should have defaulted to null’); } }

We are testing for 3 things: 1. Are all of the Album’s properties initially set to NULL? 2. Will the Album’s properties be set correctly when we call exchangeArray()? 3. Will a default value of NULL be used for properties whose keys are not present in the $data array? If we run phpunit again, we’ll see that the answer to all three questions is “YES”:
PHPUnit 3.5.15 by Sebastian Bergmann. ........ Time: 0 seconds, Memory: 5.50Mb OK (8 tests, 19 assertions)

Next, we create our AlbumTable.php file in module/Album/src/Album/Model directory like this:
<?php namespace Album\Model; use Zend\Db\TableGateway\TableGateway; class AlbumTable { protected $tableGateway; public function __construct(TableGateway $tableGateway) { $this->tableGateway = $tableGateway; } public function fetchAll() { $resultSet = $this->tableGateway->select(); return $resultSet; } public function getAlbum($id) { $id = (int) $id;

8.2. The model files

27

Zend Framework 2 Documentation, Release 2.0.6

$rowset = $this->tableGateway->select(array(’id’ => $id)); $row = $rowset->current(); if (!$row) { throw new \Exception("Could not find row $id"); } return $row; } public function saveAlbum(Album $album) { $data = array( ’artist’ => $album->artist, ’title’ => $album->title, ); $id = (int)$album->id; if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getAlbum($id)) { $this->tableGateway->update($data, array(’id’ => $id)); } else { throw new \Exception(’Form id does not exist’); } } } public function deleteAlbum($id) { $this->tableGateway->delete(array(’id’ => $id)); } }

There’s a lot going on here. Firstly, 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 albums. We then create some helper methods that our application will use to interface with the table gateway. fetchAll() retrieves all albums rows from the database as a ResultSet, getAlbum() retrieves a single row as an Album object, saveAlbum() either creates a new row in the database or updates a row that already exists and deleteAlbum() removes the row completely. The code for each of these methods is, hopefully, self-explanatory.

8.3 Using ServiceManager to configure the table gateway and inject into the AlbumTable
In order to always use the same instance of our AlbumTable, we will use the ServiceManager to define how to create one. This is most easily done in the Module class where we create a method called getServiceConfig() which is automatically called by the ModuleManager and applied to the ServiceManager. We’ll then be able to retrieve it in our controller when we need it. To 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 AlbumTable. Add this method to the bottom of the Module.php file in module/Album.

28

Chapter 8. Database and models

Zend Framework 2 Documentation, Release 2.0.6

<?php namespace Album; // Add these import statements: use Album\Model\Album; use Album\Model\AlbumTable; use Zend\Db\ResultSet\ResultSet; use Zend\Db\TableGateway\TableGateway; class Module { // getAutoloaderConfig() and getConfig() methods here // Add this method: public function getServiceConfig() { return array( ’factories’ => array( ’Album\Model\AlbumTable’ => function($sm) { $tableGateway = $sm->get(’AlbumTableGateway’); $table = new AlbumTable($tableGateway); return $table; }, ’AlbumTableGateway’ => function ($sm) { $dbAdapter = $sm->get(’Zend\Db\Adapter\Adapter’); $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Album()); return new TableGateway(’album’, $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 Album\Model\AlbumTable uses the ServiceManager to create an AlbumTableGateway to pass to the AlbumTable. We also tell the ServiceManager that an AlbumTableGateway 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 Album object whenever it creates a new result row. The TableGateway classes use the prototype pattern for creation of result sets and entities. This means that instead of instantiating when required, the system clones a previously instantiated object. See PHP Constructor Best Practices and the Prototype Pattern for more details. Finally, 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 to. Modify config/autoload/global.php (in the Zend Skeleton root, not inside the Album module) with following code:
<?php return array( ’db’ => array( ’driver’ => ’Pdo’, ’dsn’ => ’mysql:dbname=zf2tutorial;host=localhost’, ’driver_options’ => array(

8.3. Using ServiceManager to configure the table gateway and inject into the AlbumTable

29

Zend Framework 2 Documentation, Release 2.0.6

PDO::MYSQL_ATTR_INIT_COMMAND => ’SET NAMES \’UTF8\’’ ), ), ’service_manager’ => array( ’factories’ => array( ’Zend\Db\Adapter\Adapter’ => ’Zend\Db\Adapter\AdapterServiceFactory’, ), ), );

You should put your database credentials in config/autoload/local.php so that they are not in the git repository (as local.php is ignored):
<?php return array( ’db’ => array( ’username’ => ’YOUR USERNAME HERE’, ’password’ => ’YOUR PASSWORD HERE’, ), );

8.4 Testing
Let’s write a few tests for all this code we’ve just written. First, we need to create a test class for the AlbumTable. Create a file AlbumTableTest.php in module/Album/test/AlbumTest/Model
<?php namespace AlbumTest\Model; use use use use Album\Model\AlbumTable; Album\Model\Album; Zend\Db\ResultSet\ResultSet; PHPUnit_Framework_TestCase;

class AlbumTableTest extends PHPUnit_Framework_TestCase { public function testFetchAllReturnsAllAlbums() { $resultSet = new ResultSet(); $mockTableGateway = $this->getMock(’Zend\Db\TableGateway\TableGateway’, array(’select’), array(), ’’, false); $mockTableGateway->expects($this->once()) ->method(’select’) ->with() ->will($this->returnValue($resultSet)); $albumTable = new AlbumTable($mockTableGateway); $this->assertSame($resultSet, $albumTable->fetchAll()); } }

In this test, we introduce the concept of Mock objects. A thorough explanation of what a Mock object is goes beyond the scope of this tutorial, but it’s basically an object that takes the place of another object and behaves in a predefined way. Since we are testing the AlbumTable here and NOT the TableGateway class (the Zend team has already

30

Chapter 8. Database and models

Zend Framework 2 Documentation, Release 2.0.6

tested the TableGateway class and we know it works), we just want to make sure that our AlbumTable class is interacting with the TableGatway class the way that we expect it to. Above, we’re testing to see if the fetchAll() method of AlbumTable will call the select() method of the $tableGateway property with no parameters. If it does, it should return a ResultSet object. Finally, we expect that this same ResultSet object will be returned to the calling method. This test should run fine, so now we can add the rest of the test methods:
public function testCanRetrieveAnAlbumByItsId() { $album = new Album(); $album->exchangeArray(array(’id’ => 123, ’artist’ => ’The Military Wives’, ’title’ => ’In My Dreams’)); $resultSet = new ResultSet(); $resultSet->setArrayObjectPrototype(new Album()); $resultSet->initialize(array($album));

$mockTableGateway = $this->getMock(’Zend\Db\TableGateway\TableGateway’, array(’select’), array(), $mockTableGateway->expects($this->once()) ->method(’select’) ->with(array(’id’ => 123)) ->will($this->returnValue($resultSet)); $albumTable = new AlbumTable($mockTableGateway); $this->assertSame($album, $albumTable->getAlbum(123)); }

public function testCanDeleteAnAlbumByItsId() { $mockTableGateway = $this->getMock(’Zend\Db\TableGateway\TableGateway’, array(’delete’), array(), $mockTableGateway->expects($this->once()) ->method(’delete’) ->with(array(’id’ => 123)); $albumTable = new AlbumTable($mockTableGateway); $albumTable->deleteAlbum(123); } public function testSaveAlbumWillInsertNewAlbumsIfTheyDontAlreadyHaveAnId() { $albumData = array(’artist’ => ’The Military Wives’, ’title’ => ’In My Dreams’); $album = new Album(); $album->exchangeArray($albumData);

$mockTableGateway = $this->getMock(’Zend\Db\TableGateway\TableGateway’, array(’insert’), array(), $mockTableGateway->expects($this->once()) ->method(’insert’) ->with($albumData); $albumTable = new AlbumTable($mockTableGateway); $albumTable->saveAlbum($album); } public function testSaveAlbumWillUpdateExistingAlbumsIfTheyAlreadyHaveAnId() { $albumData = array(’id’ => 123, ’artist’ => ’The Military Wives’, ’title’ => ’In My Dreams’); $album = new Album();

8.4. Testing

31

Zend Framework 2 Documentation, Release 2.0.6

$album->exchangeArray($albumData); $resultSet = new ResultSet(); $resultSet->setArrayObjectPrototype(new Album()); $resultSet->initialize(array($album)); $mockTableGateway = $this->getMock(’Zend\Db\TableGateway\TableGateway’, array(’select’, ’update’), array(), ’’, false); $mockTableGateway->expects($this->once()) ->method(’select’) ->with(array(’id’ => 123)) ->will($this->returnValue($resultSet)); $mockTableGateway->expects($this->once()) ->method(’update’) ->with(array(’artist’ => ’The Military Wives’, ’title’ => ’In My Dreams’), array(’id’ => 123)); $albumTable = new AlbumTable($mockTableGateway); $albumTable->saveAlbum($album); } public function testExceptionIsThrownWhenGettingNonexistentAlbum() { $resultSet = new ResultSet(); $resultSet->setArrayObjectPrototype(new Album()); $resultSet->initialize(array());

$mockTableGateway = $this->getMock(’Zend\Db\TableGateway\TableGateway’, array(’select’), array(), $mockTableGateway->expects($this->once()) ->method(’select’) ->with(array(’id’ => 123)) ->will($this->returnValue($resultSet)); $albumTable = new AlbumTable($mockTableGateway); try { $albumTable->getAlbum(123); } catch (\Exception $e) { $this->assertSame(’Could not find row 123’, $e->getMessage()); return; } $this->fail(’Expected exception was not thrown’); }

Let’s review our tests. We are testing that: 1. We can retrieve an individual album by its ID. 2. We can delete albums. 3. We can save new album. 4. We can update existing albums. 5. We will encounter an exception if we’re trying to retrieve an album that doesn’t exist. Great - our AlbumTable class is tested. Let’s move on! 32 Chapter 8. Database and models

Zend Framework 2 Documentation, Release 2.0.6

8.5 Back to the controller
Now that the ServiceManager can create an AlbumTable instance for us, we can add a method to the controller to retrieve it. Add getAlbumTable() to the AlbumController class:
// module/Album/src/Album/Controller/AlbumController.php: public function getAlbumTable() { if (!$this->albumTable) { $sm = $this->getServiceLocator(); $this->albumTable = $sm->get(’Album\Model\AlbumTable’); } return $this->albumTable; }

You should also add:
protected $albumTable;

to the top of the class. We can now call getAlbumTable() from within our controller whenever we need to interact with our model. Let’s make sure it works by writing a test. Add this test to your AlbumControllerTest class:
public function testGetAlbumTableReturnsAnInstanceOfAlbumTable() { $this->assertInstanceOf(’Album\Model\AlbumTable’, $this->controller->getAlbumTable()); }

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

8.6 Listing albums
In order to list the albums, we need to retrieve them from the model and pass them to the view. To do this, we fill in indexAction() within AlbumController. Update the AlbumController’s indexAction() like this:
// module/Album/src/Album/Controller/AlbumController.php: // ... public function indexAction() { return new ViewModel(array( ’albums’ => $this->getAlbumTable()->fetchAll(), )); } // ...

With Zend Framework 2, in order to set variables in the view, we return a ViewModel instance where the first parameter of the constructor is an array from the action containing data we need. These are then automatically passed to the view script. The ViewModel object also allows us to change the view script that is used, but the default is to use {controller name}/{action name}. We can now fill in the index.phtml view script:
<?php // module/Album/view/album/album/index.phtml:

8.5. Back to the controller

33

Zend Framework 2 Documentation, Release 2.0.6

$title = ’My albums’; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <p> <a href="<?php echo $this->url(’album’, array(’action’=>’add’));?>">Add new album</a> </p> <table class="table"> <tr> <th>Title</th> <th>Artist</th> <th>&nbsp;</th> </tr> <?php foreach ($albums as $album) : ?> <tr> <td><?php echo $this->escapeHtml($album->title);?></td> <td><?php echo $this->escapeHtml($album->artist);?></td> <td> <a href="<?php echo $this->url(’album’, array(’action’=>’edit’, ’id’ => $album->id));?>">Edit</a> <a href="<?php echo $this->url(’album’, array(’action’=>’delete’, ’id’ => $album->id));?>">Delete</a> </td> </tr> <?php endforeach; ?> </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 album. 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 ‘album’ route which is set up to accept two placeholder variables: action and id. We iterate over the $albums 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 album’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 albums, 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. Note: We always use the escapeHtml() view helper to help protect ourselves from XSS vulnerabilities. If you open http://zf2-tutorial.localhost/album you should see this:

34

Chapter 8. Database and models

CHAPTER

NINE

STYLING AND TRANSLATIONS
We’ve picked up the SkeletonApplication’s styling, which is fine, but we need to change the title and remove the copyright message. The ZendSkeletonApplication is set up to use Zend\I18n’s translation functionality for all the text. It uses .po files that live in Application/language, and you need to use poedit to change the text. Start poedit and open application/language/en_US.po. Click on “Skeleton Application” in the list of Original strings and then type in “Tutorial” as the translation. Press Save in the toolbar and poedit will create an en_US.mo file for us. If you find that no .mo file is generated, check Preferences -> Editor -> Behavior and see if the checkbox marked Automatically compile .mo file on save is checked. To remove the copyright message, we need to edit the Application module’s layout.phtml view script:
// module/Application/view/layout/layout.phtml: // Remove this line: <p>&copy; 2005 - 2012 by Zend Technologies Ltd. <?php echo $this->translate(’All rights reserved.’) ?></p>

The page now looks ever so slightly better now!

35

Zend Framework 2 Documentation, Release 2.0.6

36

Chapter 9. Styling and Translations

CHAPTER

TEN

FORMS AND ACTIONS
10.1 Adding new albums
We can now code up the functionality to add new albums. There are two bits to this part: • Display a form for user to provide details • Process the form submission and store to database We use Zend\Form to do this. The Zend\Form component manages the form and for validation, we add a Zend\InputFilter to our Album entity. We start by creating a new class Album\Form\AlbumForm that extends from Zend\Form\Form to define our form. Create a file called AlbumForm.php in module/Album/src/Album/Form:
<?php namespace Album\Form; use Zend\Form\Form; class AlbumForm extends Form { public function __construct($name = null) { // we want to ignore the name passed parent::__construct(’album’); $this->setAttribute(’method’, ’post’); $this->add(array( ’name’ => ’id’, ’attributes’ => array( ’type’ => ’hidden’, ), )); $this->add(array( ’name’ => ’artist’, ’attributes’ => array( ’type’ => ’text’, ), ’options’ => array( ’label’ => ’Artist’, ), )); $this->add(array( ’name’ => ’title’, ’attributes’ => array(

37

Zend Framework 2 Documentation, Release 2.0.6

’type’ => ’text’, ), ’options’ => array( ’label’ => ’Title’, ), )); $this->add(array( ’name’ => ’submit’, ’attributes’ => array( ’type’ => ’submit’, ’value’ => ’Go’, ’id’ => ’submitbutton’, ), )); } }

Within the constructor of AlbumForm, we set the name when we call the parent’s constructor and then set the method and then create four form elements for the id, artist, title, and submit button. For each item we set various attributes and options, including the label to be displayed. We also need to set up validation for this form. In Zend Framework 2 this is done using an input filter which can either be standalone or within any class that implements InputFilterAwareInterface, such as a model entity. We are going to add the input filter to our Album.php file in module/Album/src/Album/Model:
<?php namespace Album\Model; use use use use Zend\InputFilter\Factory as InputFactory; Zend\InputFilter\InputFilter; Zend\InputFilter\InputFilterAwareInterface; Zend\InputFilter\InputFilterInterface; // // // // <-<-<-<-Add Add Add Add this this this this import import import import

class Album implements InputFilterAwareInterface { public $id; public $artist; public $title; protected $inputFilter;

// <-- Add this variable

public function exchangeArray($data) { $this->id = (isset($data[’id’])) ? $data[’id’] : null; $this->artist = (isset($data[’artist’])) ? $data[’artist’] : null; $this->title = (isset($data[’title’])) ? $data[’title’] : null; } // Add content to this method: public function setInputFilter(InputFilterInterface $inputFilter) { throw new \Exception("Not used"); } public function getInputFilter() { if (!$this->inputFilter) { $inputFilter = new InputFilter(); $factory = new InputFactory();

38

Chapter 10. Forms and actions

Zend Framework 2 Documentation, Release 2.0.6

$inputFilter->add($factory->createInput(array( ’name’ => ’id’, ’required’ => true, ’filters’ => array( array(’name’ => ’Int’), ), ))); $inputFilter->add($factory->createInput(array( ’name’ => ’artist’, ’required’ => true, ’filters’ => array( array(’name’ => ’StripTags’), array(’name’ => ’StringTrim’), ), ’validators’ => array( array( ’name’ => ’StringLength’, ’options’ => array( ’encoding’ => ’UTF-8’, ’min’ => 1, ’max’ => 100, ), ), ), ))); $inputFilter->add($factory->createInput(array( ’name’ => ’title’, ’required’ => true, ’filters’ => array( array(’name’ => ’StripTags’), array(’name’ => ’StringTrim’), ), ’validators’ => array( array( ’name’ => ’StringLength’, ’options’ => array( ’encoding’ => ’UTF-8’, ’min’ => 1, ’max’ => 100, ), ), ), ))); $this->inputFilter = $inputFilter; } return $this->inputFilter; } }

The InputFilterAwareInterface defines two methods: setInputFilter() and getInputFilter(). We only need to implement getInputFilter() so we simply throw an exception in setInputFilter(). Within getInputFilter(), we instantiate an InputFilter and then add the inputs that we require. We add one input for each property that we wish to filter or validate. For the id field we add an Int filter as we only need

10.1. Adding new albums

39

Zend Framework 2 Documentation, Release 2.0.6

integers. For the text elements, we add two filters, StripTags and StringTrim to remove unwanted HTML and unnecessary white space. We also set them to be required and add a StringLength validator to ensure that the user doesn’t enter more characters than we can store into the database. We now need to get the form to display and then process it on submission. AlbumController’s addAction():
// module/Album/src/Album/Controller/AlbumController.php: //... use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; use Album\Model\Album; // <-- Add this import use Album\Form\AlbumForm; // <-- Add this import //... // Add content to this method: public function addAction() { $form = new AlbumForm(); $form->get(’submit’)->setValue(’Add’); $request = $this->getRequest(); if ($request->isPost()) { $album = new Album(); $form->setInputFilter($album->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) { $album->exchangeArray($form->getData()); $this->getAlbumTable()->saveAlbum($album); // Redirect to list of albums return $this->redirect()->toRoute(’album’); } } return array(’form’ => $form); } //...

This is done within the

After adding the AlbumForm to the use list, we implement addAction(). Let’s look at the addAction() code in a little more detail:
$form = new AlbumForm(); $form->get(’submit’)->setValue(’Add’);

We instantiate AlbumForm and set the label on the submit button to “Add”. We do this here as we’ll want to re-use the form when editing an album and will use a different label.
$request = $this->getRequest(); if ($request->isPost()) { $album = new Album(); $form->setInputFilter($album->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) {

If the Request object’s isPost() method is true, then the form has been submitted and so we set the form’s input filter from an album instance. We then set the posted data to the form and check to see if it is valid using the isValid() member function of the form.

40

Chapter 10. Forms and actions

Zend Framework 2 Documentation, Release 2.0.6

$album->exchangeArray($form->getData()); $this->getAlbumTable()->saveAlbum($album);

If the form is valid, then we grab the data from the form and store to the model using saveAlbum().
// Redirect to list of albums return $this->redirect()->toRoute(’album’);

After we have saved the new album row, we redirect back to the list of albums using the Redirect controller plugin.
return array(’form’ => $form);

Finally, we return the variables that we want assigned to the view. In this case, just the form object. Note that Zend Framework 2 also allows you to simply return an array containing the variables to be assigned to the view and it will create a ViewModel behind the scenes for you. This saves a little typing. We now need to render the form in the add.phtml view script:
<?php // module/Album/view/album/album/add.phtml: $title = ’Add new album’; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php $form = $this->form; $form->setAttribute(’action’, $this->url(’album’, array(’action’ => ’add’))); $form->prepare(); echo echo echo echo echo echo $this->form()->openTag($form); $this->formHidden($form->get(’id’)); $this->formRow($form->get(’title’)); $this->formRow($form->get(’artist’)); $this->formSubmit($form->get(’submit’)); $this->form()->closeTag();

Again, we display a title as before and then we render the form. Zend Framework provides some view helpers to make this a little easier. The form() view helper has an openTag() and closeTag() method which we use to open and close the form. Then for each element with a label, we can use formRow(), but for the two elements that are standalone, we use formHidden() and formSubmit(). Alternatively, the process of rendering the form can be simplified by using the bundled formCollection view helper. For example, in the view script above replace all the form-rendering echo statements with:
echo $this->formCollection($form);

This will iterate over the form structure, calling the appropriate label, element and error view helpers for each element, but you still have to wrap formCollection($form) with the open and close form tags. This helps reduce the complexity of your view script in situations where the default HTML rendering of the form is acceptable. You should now be able to use the “Add new album” link on the home page of the application to add a new album record. And execute phpunit from module/Album/test.
PHPUnit 3.5.15 by Sebastian Bergmann. ..............

10.1. Adding new albums

41

Zend Framework 2 Documentation, Release 2.0.6

Time: 1 seconds, Memory: 12.25Mb OK (14 tests, 23 assertions)

10.2 Editing an album
Editing an album is almost identical to adding one, so the code is very similar. This time we use editAction() in the AlbumController:
// module/Album/src/Album/Controller/AlbumController.php: //... // Add content to this method: public function editAction() { $id = (int) $this->params()->fromRoute(’id’, 0); if (!$id) { return $this->redirect()->toRoute(’album’, array( ’action’ => ’add’ )); } $album = $this->getAlbumTable()->getAlbum($id); $form = new AlbumForm(); $form->bind($album); $form->get(’submit’)->setAttribute(’value’, ’Edit’); $request = $this->getRequest(); if ($request->isPost()) { $form->setInputFilter($album->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) { $this->getAlbumTable()->saveAlbum($form->getData()); // Redirect to list of albums return $this->redirect()->toRoute(’album’); } } return array( ’id’ => $id, ’form’ => $form, ); } //...

This code should look comfortably familiar. Let’s look at the differences from adding an album. Firstly, we look for the id that is in the matched route and use it to load the album to be edited:
$id = (int) $this->params()->fromRoute(’id’, 0); if (!$id) { return $this->redirect()->toRoute(’album’, array( ’action’ => ’add’ )); }

42

Chapter 10. Forms and actions

Zend Framework 2 Documentation, Release 2.0.6

$album = $this->getAlbumTable()->getAlbum($id);

params is a controller plugin that provides a convenient way to retrieve parameters from the matched route. We use it to retrieve the id from the route we created in the modules’ module.config.php. If the id is zero, then we redirect to the add action, otherwise, we continue by getting the album entity from the database.
$form = new AlbumForm(); $form->bind($album); $form->get(’submit’)->setAttribute(’value’, ’Edit’);

The form’s bind() method attaches the model to the form. This is used in two ways: • When displaying the form, the initial values for each element are extracted from the model. • After successful validation in isValid(), the data from the form is put back into the model. These operations are done using a hydrator object. There are a number of hydrators, but the default one is Zend\Stdlib\Hydrator\ArraySerializable which expects to find two methods in the model: getArrayCopy() and exchangeArray(). We have already written exchangeArray() in our Album entity, so just need to write getArrayCopy():
// module/Album/src/Album/Model/Album.php: // ... public function exchangeArray($data) { $this->id = (isset($data[’id’])) ? $data[’id’] : null; $this->artist = (isset($data[’artist’])) ? $data[’artist’] : null; $this->title = (isset($data[’title’])) ? $data[’title’] : null; } // Add the following method: public function getArrayCopy() { return get_object_vars($this); } // ...

As a result of using bind() with its hydrator, we do not need to populate the form’s data back into the $album as that’s already been done, so we can just call the mappers’ saveAlbum() to store the changes back to the database. The view template, edit.phtml, looks very similar to the one for adding an album:
<?php // module/Album/view/album/album/edit.phtml: $title = ’Edit album’; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php $form = $this->form; $form->setAttribute(’action’, $this->url( ’album’, array( ’action’ => ’edit’, ’id’ => $this->id, ) )); $form->prepare();

10.2. Editing an album

43

$this->formRow($form->get(’title’)). Memory: 13.F..15 by Sebastian Bergmann... We need to change the test for edit ‘AlbumControllerTest’ in module/Album/test/AlbumTest/Controller : <?php . ’edit’). $this->formHidden($form->get(’id’)). Time: 1 second. Add the following also to 44 Chapter 10. ’add’). $response->getStatusCode()).Zend Framework 2 Documentation. $response = $this->controller->getResponse(). $this->formRow($form->get(’artist’)).. . } If we do not send any id parameter the Controller will redirect us to the album route which returns the HTTP Status Code 302 We will also add another test to check if the redirection works. Assertions: 23. $this->assertEquals(200..//Add this Row $result = $this->controller->dispatch($this->request). You should now be able to edit albums. $this->formSubmit($form->get(’submit’)). $result = $this->controller->dispatch($this->request). Release 2.6 echo echo echo echo echo echo $this->form()->openTag($form). $this->routeMatch->setParam(’id’. The only changes are to use the ‘Edit Album’ title and set the form’s action to the ‘edit’ action too. PHPUnit 3..00Mb There was 1 failure: 1) AlbumTest\Controller\AlbumControllerTest::testEditActionCanBeAccessed Failed asserting that 302 matches expected 200.php <?php ..0. And execute phpunit from module/Album/test. Forms and actions .. Failures: 1.... public function testAddActionCanBeAccessed() { $this->routeMatch->setParam(’action’..5. /var/www/tutorial/module/Album/test/AlbumTest/Controller/AlbumControllerTest. ’1’).. public function testEditActionRedirect() { $this->routeMatch->setParam(’action’.. AlbumControllerTest. $this->form()->closeTag().. $response = $this->controller->getResponse().php:65 FAILURES! Tests: 14..

} //.Zend Framework 2 Documentation. after all.. ’No’). This would be wrong. Release 2.15 by Sebastian Bergmann..00Mb OK (15 tests. } return array( ’id’ => $id. Let’s start with the action code in AlbumController::deleteAction(): // module/Album/src/Album/Controller/AlbumController.. we’ll code it directly into our view (Zend\Form is. } And execute phpunit from module/Album/test. Time: 1 second. . we need to add deletion. if ($request->isPost()) { $del = $request->getPost(’del’.0.3.. We use the table object to delete the row using the 10. 24 assertions) 10.5. 0). $response->getStatusCode()). We shall show a confirmation form when the user clicks delete and if they then click “yes”.php: //. As before.6 $this->assertEquals(302. we will do the deletion. Deleting an album 45 ... PHPUnit 3..... Memory: 13.3 Deleting an album To round out our application. // Add content to the following method: public function deleteAction() { $id = (int) $this->params()->fromRoute(’id’... As the form is trivial..and check the request object’s isPost() to determine whether to show the confirmation page or to delete the album... if (!$id) { return $this->redirect()->toRoute(’album’). We have a Delete link next to each album on our list page and the naïve approach would be to do a delete when it’s clicked. we get the id from the matched route.. optional!). we recall that you shouldn’t do an irreversible action using GET and should use POST instead. if ($del == ’Yes’) { $id = (int) $request->getPost(’id’).. $this->getAlbumTable()->deleteAlbum($id). } $request = $this->getRequest().. ’album’ => $this->getAlbumTable()->getAlbum($id) ). Remembering our HTTP spec. } // Redirect to list of albums return $this->redirect()->toRoute(’album’).

?> <h1><?php echo $this->escapeHtml($title). In the action. ?>" /> <input type="submit" name="del" value="Yes" /> <input type="submit" name="del" value="No" /> </div> </form> In this script. If the request is not a POST. ?> <form action="<?php echo $url. Forms and actions . ’delete’). ’1’). we display a confirmation message to the user and then a form with “Yes” and “No” buttons. ’id’ => $this->id. $response = $this->controller->getResponse().6 deleteAlbum() method and then redirect back the list of albums. we checked specifically for the “Yes” value when doing the deletion. $this->routeMatch->setParam(’id’.0. $response->getStatusCode()). $this->assertEquals(200. Release 2. $this->assertEquals(302. ?>" method="post"> <div> <input type="hidden" name="id" value="<?php echo (int) $album->id. ’delete’). ?>’ by ’<?php echo $this->escapeHtml($album->artist). ?>’? </p> <?php $url = $this->url(’album’.php in module/Album/test/AlbumTest/Controller: public function testDeleteActionCanBeAccessed() { $this->routeMatch->setParam(’action’. $result = $this->controller->dispatch($this->request). array( ’action’ => ’delete’.phtml: $title = ’Delete album’. then we retrieve the correct database record and assign to the view. $response = $this->controller->getResponse(). along with the id. The view script is a simple form: <?php // module/Album/view/album/album/delete. } public function testDeleteActionRedirect() { $this->routeMatch->setParam(’action’. Modify the tests in AlbumControllerTest. ?></h1> <p>Are you sure that you want to delete ’<?php echo $this->escapeHtml($album->title). $response->getStatusCode()).Zend Framework 2 Documentation. )). $result = $this->controller->dispatch($this->request). $this->headTitle($title). } 46 Chapter 10.

). Release 2. This is due to a route set up in the Application module’s module.0. module/Application/config/module. ’action’ => ’index’.php. That’s it .4 Ensuring that the home page displays the list of albums One final point.php and find the home route: ’home’ => array( ’type’ => ’Zend\Mvc\Router\Http\Literal’.localhost/ doesn’t display the list of albums.Zend Framework 2 Documentation. ). // <-. ). http://zf2-tutorial.change here ’action’ => ’index’. ).4. ). To change it. ’defaults’ => array( ’controller’ => ’Album\Controller\Album’. ’options’ => array( ’route’ => ’/’. At the moment.config. ’options’ => array( ’route’ => ’/’.config. ’defaults’ => array( ’controller’ => ’Application\Controller\Index’. ). Ensuring that the home page displays the list of albums 47 .you now have a fully working application! 10. open Change the controller from Application\Controller\Index to Album\Controller\Album: ’home’ => array( ’type’ => ’Zend\Mvc\Router\Http\Literal’. the home page.6 10.

0. Forms and actions .6 48 Chapter 10.Zend Framework 2 Documentation. Release 2.

but fully functional.CHAPTER ELEVEN CONCLUSION This concludes our brief look at building a simple. MVC application using Zend Framework 2. 49 .

0. Release 2. Conclusion .Zend Framework 2 Documentation.6 50 Chapter 11.

1 Very brief introduction to Di. one consumes the other) In the simplest use case. we’ll explain the act of injecting dependencies simply with this below code: 1 $b = new B(new A()). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 namespace My { class A { /* Some useful functionality */ } class B { protected $a = null. } } } 51 . this requires an object of type A be instantiated before an object of type B so that A can be injected into B. and A was injected into B. here are a couple of great reads: Matthew Weier O’Phinney’s Analogy. By having the dependency injected through the constructor.3 Simplest usage case (2 classes. 12. For the purposes of this quickstart. public function __construct(A $a) { $this->a = $a. 1 TBD. Dependency Injection is a concept that has been talked about in numerous places over the web. 12. Ralph Schindler’s Learning DI.CHAPTER TWELVE LEARNING DEPENDENCY INJECTION 12.2 Very brief introduction to Di Container. a developer might have one class (A) that is consumed by another class (B) through the constructor. If you are not familar with the concept of dependency injection. Above. A is a dependency of B. or Fabien Potencier’s Series on DI.

using a dependency injection container is one of these solutions.6 To create B by hand. one would use the Di::newInstance() method: 1 $b = $di->newInstance(’My\B’). the above use case can be taken care of with no configuration (provided all of your autoloading is already configured properly) with the following usage: 1 2 $di = new Zend\Di\Di.Zend Framework 2 Documentation. ’MyUsernameValue’). a developer would follow this work flow. by using the Di::get() method. To do this. To force new objects to be created on each and every request. 52 Chapter 12. With Zend’s dependency injection container Zend\Di\Di. or a similar workflow to this: 1 $b = new B(new A()). Learning Dependency Injection .0. While there are several ways to do this. public function __construct($username. Let’s assume for a moment that A requires some configuration before it can be created. Release 2. Our previous use case is expanded to this (we’ll throw a 3rd class in for good measure): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 namespace My { class A { protected $username = null. you are ensuring that the same exact object is returned on subsequent calls. this creates an opportunity where one might want to DRY up the code. ’password’. $di->getInstanceManager()->setProperty(’A’. ’username’. ’MyHardToGuessPassword%$#’). $password) { $this->username = $username. $this->password = $password. $b = $di->get(’My\B’). protected $password = null. $di->getInstanceManager()->setProperty(’A’. public function __construct(B $b) { $this->b = $b. we need to interact with the InstanceManager: 1 2 3 $di = new Zend\Di\Di. } } class C { protected $b = null. If this workflow becomes repeated throughout your application multiple times. } } class B { protected $a = null. // will produce a B object that is consuming an A object Moreover. } } } With the above. we need to ensure that our Di is capable of seeing the A class with a few configuration values (which are generally scalar in nature). public function __construct(A $a) { $this->a = $a.

of our B class now looking like this: 1 2 3 4 5 6 7 8 9 10 namespace My { class B { protected $a. and is followed by a capital letter. it will assume that all dependencies are scalar or required configuration parameters. such as interface injection and annotation based injection. Release 2. } } } Since the method is prefixed with set. Constructor injection is not the only supported type of injection. but you might find you need to describe your dependencies explicitly. we could do the following: 1 2 3 4 5 6 7 8 $parameters = array( ’username’ => ’MyUsernameValue’. Simple enough. To do this. Without type-hints. will once again know how to fill the dependencies when needed to create an object of type C. With no configuration. and our new goal is to have a C object that consumes B and in turn consumes A. the Di knows that this method is used for setter injection. // or $c = $di->newInstance(’My\C’). ). public function setA(A $a) { $this->a = $a. the default RuntimeDefinition.6 Now that our container has values it can use when creating A. The other most popular method of injection is also supported: setter injection. the map between classes. the use case $c = $di->get(’C’). 12. // or $c = $di->newInstance(’My\C’.4.Zend Framework 2 Documentation. 12. $parameters). for example. the usage scenario is still the same: 1 2 3 $c = $di->get(’My\C’). or in place of. $c = $di->get(’My\C’. $parameters).0. you can still use the Di. This particular definition is called the BuilderDefinition and can work with. Setter injection allows one to have a usage scenario that is the same as our previous example with the exception. you will need to interact with one of the definitions that is capable of letting a developer describe. and again. Definitions are a part of the Di that attempt to describe the relationship between classes so that Di::newInstance() and Di::get() can know what the dependencies are that need to be filled for a particular class/object. but what if we wanted to pass in these parameters at call time? Assuming a default Di object ($di = new Zend\Di\Di() without any configuration to the InstanceManager). Di will use the RuntimeDefinition which uses reflection and the type-hints in your code to determine the dependency map. Simplest Usage Case Without Type-hints 53 . Other methods are being created to determine what the wirings between classes are.4 Simplest Usage Case Without Type-hints If your code does not have type-hints or you are using 3rd party code that does not have type-hints but does practice dependency injection. with objects. ’password’ => ’MyHardToGuessPassword%$#’.

create C $parameters = array( ’username’ => ’MyUsernameValue’. use Zend\Di\Definition. } } } You’ll notice the only change is that setA now does not include any type-hinting information. ’My\A’). $im->addParameter(’a’. // Now make sure the Di understands it $di = new Di. $c = $di->get(’My\C’. allows you to programmatically describe the mappings with objects. public function setA($a) { $this->a = $a. Release 2. Learning Dependency Injection . // Describe this class: $builder = new Definition\BuilderDefinition. // Use both our Builder Definition as well as the default // RuntimeDefinition. 54 Chapter 12. $im->setName(’setA’). // and finally. Let’s say for example. ). it can be used in tandem with any definition by way of the AggregateDefinition). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 use Zend\Di\Di. $aDef->addDefinition(new Definition\RuntimeDefinition). ’password’ => ’MyHardToGuessPassword%$#’. This above usage scenario provides that whatever the code looks like. In an ideal world. $di->setDefinition($aDef). $parameters). which can be used in tandem with the RuntimeDefinition (technically. you can ensure that it works with the dependency injection container. $class->addInjectableMethod(($im = new Builder\InjectibleMethod)).0. were altered such that class B now looks like this: 1 2 3 4 5 6 7 8 9 10 namespace My { class B { protected $a. $class->setName(’My\B’). $aDef->addDefinition($builder). our above A/B/C usage scenario. use Zend\Di\Definition\Builder. all of your code would have the proper type hinting and/or would be using a mapping strategy that reduces the amount of bootstrapping work that needs to be done in order to have a full definition that is capable of instantiating all of the objects you might require.6 The BuilderDefinition.Zend Framework 2 Documentation. builder first $aDef = new Definition\AggregateDefinition. $builder->addClass(($class = new Builder\PhpClass)).

C scenario was actually a file per class on disk): 1 2 3 4 5 $di = new Zend\Di\Di. PHP at its core is not DI friendly. which is used by default. 12.Aggregates multiple definitions of various types. When this is not the case.php’. • Compiler. The rest of the Definition objects are capable of being aggregated and stored to disk in a very performant way.Creates a definition based on an object graph consisting of various Builder\PhpClass objects and Builder\InectionMethod objects that describe the mapping needs of the target codebase and . the Di uses a RuntimeDefinition which does all class map resolution via PHP’s Reflection extension. $di->getInstanceManager()->setProperty(’My\A’.Zend Framework 2 Documentation.php’) && $isProduction) { $compiler = new Zend\Di\Definition\Compiler(). The following is an example of producing a definition via a DirectoryScanner: 1 2 3 4 5 $compiler = new Zend\Di\Definition\Compiler(). but produces an ArrayDefinition based off of a code scanner (Zend\Code\Scanner\DirectoryScanner or Zend\Code\Scanner\FileScanner). Simplest usage case with Compiled Definition 55 . ’password’. .5. Out-of-the-box. B. ’/di-definition. Ideally. Release 2. It is worth noting that the RuntimeDefition. One strategy for persisting these compiled definitions would be the following: 1 2 3 4 5 6 7 8 if (!file_exists(__DIR__ . . $definition = $compiler->compile(). 3rd party code will ship with a pre-compiled Definition that will describe the various relationships and parameter/property needs of each class that is to be instantiated. is the only definition that does lookups on-demand.Net (where there is an application layer with in-memory object storage. it looks it up in the order the definitions were provided to this aggregate. Couple that with the fact that PHP does not have a true application layer capable of storing objects in-memory between requests. When looking for a class. Zend\Di has several features built in capable of pre-compiling the most expensive tasks that surround dependency injection. Here is a breakdown of the job of each definition type: • AggregateDefinition. as you might expect. $compiler->addCodeScannerDirectory( new Zend\Code\Scanner\ScannerDirectory(’path/to/library/My/’) ). $di->setDefinition($definition). ’username’. ’foo’). • ArrayDefinition.6 12.This is not actually a definition. This Definition would have been built as part of some deployment or packaging task by this 3rd party. This definition can then be directly used by the Di (assuming the above A. $di->getInstanceManager()->setProperty(’My\A’.0. $definition = $compiler->compile().This definition takes an array of information and exposes it via the interface provided by Zend\Di\Definition suitable for usage by Di or an AggregateDefinition • BuilderDefinition. ’bar’). $compiler->addCodeScannerDirectory( new Zend\Code\Scanner\ScannerDirectory(’path/to/library/My/’) ). ’/di-definition. you can create these Definitions via any of the Definition types provided with the exception of the RuntimeDefinition. and you get a recipe that is less performant than similar solutions you’ll find in Java and .5 Simplest usage case with Compiled Definition Without going into the gritty details. $c = $di->get(’My\C’). file_put_contents( __DIR__ .) To mitigate this shortcoming.

some other 3rd party code. To do this. true) . } else { $definition = new Zend\Di\Definition\ArrayDefinition( include __DIR__ . $class->setName(’DiDefinition’).6 9 10 11 12 13 14 15 16 17 18 ’<?php return ’ . Release 2. ’parent::__construct(’ .’ ). $class->setNamespaceName(’My’). Instead of writing the resulting array to disk. create a Definition class for this information $codeGenerator = new Zend\Code\Generator\FileGenerator(). 12. var_export($definition->toArray().’ ). } // $definition can now be used. in a production system it will be written // to disk.php’. Since Zend\Code\Scanner does not include files. $codeGenerator->setClass(($class = new Zend\Code\Generator\ClassGenerator())). file_put_contents(__DIR__ . ’/My/DiDefinition. ’/di-definition. and of course. or create it via the Compiler. you will be using code from multiple places. the classes contained within are not loaded into memory. your own code that makes up your application. Learning Dependency Injection .php’ ). Zend\Code\Scanner uses tokenization to determine the structure of your files. \Zend\Code\Generator\MethodGenerator::FLAG_PUBLIC. $definition = $compiler->toArrayDefinition(). Instead. Here is a method for consuming definitions from multiple places: 1 2 3 use Zend\Di\Di. // Now. ’. compile the information $compiler = new Zend\Di\Definition\CompilerDefinition(). use Zend\Di\Definition.0. by way of Zend\Code\Generator: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // First. 12. ’). $class->addMethod( ’__construct’. array().7 Using Multiple Definitions From Multiple Sources In all actuality. $codeGenerator->generate()). use the same technique as above. This makes this suitable to use this solution during development and within the same request as any one of your application’s dispatched actions. you would write the information into a definition directly. use Zend\Di\Definition\Builder. some Zend Framework code. true) . 56 Chapter 12.Zend Framework 2 Documentation.6 Creating a precompiled definition for others to use If you are a 3rd party code developer. $compiler->compile(). $class->setExtendedClass(’\Zend\Di\Definition\ArrayDefinition’). ’/My/’) ). var_export($definition->toArray(). $compiler->addDirectoryScanner( new Zend\Code\Scanner\DirectoryScanner(__DIR__ . it makes sense to produce a Definition file that describes your code so that others can utilize this Definition without having to Reflect it via the RuntimeDefintion.

for example $diDefAggregate->addDefinition(new ThirdParty\Dbal\DiDefinition()). $injectMethod->addParameter( ’implementation’. $injectMethod->setName(’injectImplementation’). and generates a service locator class for you from it. your application code $compiler = new Definition\Compiler() $compiler->addCodeScannerDirectory( new Zend\Code\Scanner\DirectoryScanner(__DIR__ . Generating Service Locators 57 .0.6 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 $di = new Di. consider the following: 12. while engineered for speed.8 Generating Service Locators In production. ’/App/’) ). // now. Methods on the Generator class allow you to specify the namespace and class for the generated Service Locator. ’password’ => ’somePassword’ ). as well as provide hard-coded. $appDefinition = $compiler->compile(). lazy-loading instantiation of instances. from which you can then write a class file with the new Service Locator. What if you could speed things up and remove those lookups? The Zend\Di\ServiceLocator\Generator component can do just that. // now. The Dependency Injection Container. Release 2. ’Zend\Controller\Helper\ContentType’ => array( ’default’ => ’xhtml5’ ). ’Class\For\Specific\Implementation’ ). $diDefAggregate->addDefinition($appDefinition). $class->addInjectionMethod( ($injectMethod = new Builder\InjectionMethod()) ).8. As an example. $diDefAggregate = new Definition\Aggregate(). pass in properties $im = $di->getInstanceManager(). It takes a configured DI instance. // for code that does not have TypeHints $builder = new Definition\BuilderDefinition().Zend Framework 2 Documentation. 12. still must do a fair bit of work resolving parameters and dependencies at runtime. you want things to be as fast as possible. The method getCodeGenerator() returns an instance of Zend\CodeGenerator\Php\PhpFile. $diDefAggregate->addDefinition(new Zend\Controller\DiDefinition()). // this could come from Zend\Config\Config::toArray $propertiesFromConfig = array( ’ThirdParty\Dbal\DbAdapter’ => array( ’username’ => ’someUsername’. $im->setProperties($propertiesFromConfig). That class will manage instances for you. $builder->addClass(($class = Builder\PhpClass)). // first add in provided Definitions. ).

php. } } public function getComposedClass() { if (isset($this->services[’My\ComposedClass’])) { return $this->services[’My\ComposedClass’]. ’/. $this->services[’My\ComposedClass’] = $object./Application/Context./Application/Context. $generator->setNamespace(’Application’) ->setContainerClass(’Context’). return $object. Learning Dependency Injection .. Release 2. default: return parent::get($name. The above code will write to . and that file will contain the class Application\Context. $params). } $object = new \My\Struct(). return $object. $file->write(). array $params = array()) { switch ($name) { case ’composed’: case ’My\ComposedClass’: return $this->getMyComposedClass(). class Context extends ServiceLocator { public function get($name.Zend Framework 2 Documentation. $this->services[’My\Struct’] = $object.php’). // $di is a fully configured DI instance $generator = new Generator($di). 58 Chapter 12. } public function getMyStruct() { if (isset($this->services[’My\Struct’])) { return $this->services[’My\Struct’]. case ’struct’: case ’My\Struct’: return $this->getMyStruct().6 1 2 3 4 5 6 7 8 9 10 use Zend\Di\ServiceLocator\Generator. That file might look like the following: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <?php namespace Application. $file = $generator->getCodeGenerator(). use Zend\Di\ServiceLocator. $file->setFilename(__DIR__ ..0. } $object = new \My\ComposedClass().

12. specify the container class to use. } } To use this class. } public function getStruct() { return $this->get(’My\Struct’). Generating Service Locators 59 .6 45 46 47 48 49 50 51 52 53 54 55 56 } public function getComposed() { return $this->get(’My\ComposedClass’). and then in your environment. Configuration is per-environment only at this time. Release 2. $struct = $container->get(’struct’). This means that you will need to generate a container per execution environment. // My\Struct instance One note about this functionality in its current incarnation.8. you simply consume it as you would a DI container: 1 2 3 $container = new Application\Context.Zend Framework 2 Documentation. Our recommendation is that you do so.0.

Zend Framework 2 Documentation. Learning Dependency Injection .6 60 Chapter 12. Release 2.0.

For more information about authorization and access control with Zend Framework. performing queries against the authentication service. other entities is outside the scope of Zend\Authentication. identification). 13. but some basic things are common among authentication adapters. Authorization. such as LDAP. that an adapter class must implement for performing an authentication query. Other details. have been omitted for brevity: 1 2 3 4 5 6 7 8 9 10 use Zend\Authentication\Adapter\AdapterInterface. class My\Auth\Adapter implements AdapterInterface { /** * Sets username and password for authentication * * @return void */ public function __construct($username.1 Adapters Zend\Authentication adapters are used to authenticate against a particular type of authentication service. or to perform operations upon. $password) 61 . authenticate().CHAPTER THIRTEEN INTRODUCTION The Zend\Authentication component provides an API for authentication and includes concrete authentication adapters for common use case scenarios. This interface defines one method. the process of deciding whether to allow an entity access to. or file-based storage. and returning results are common to Zend\Authentication adapters. RDBMS.g. such as how the authentication service is queried. based on some set of credentials. Each adapter class must be prepared prior to calling authenticate(). Each Zend\Authentication adapter class implements Zend\Authentication\Adapter\AdapterInterface. The following is an example authentication adapter that requires a username and password to be set for authentication.. please see the Zend\Permissions\Acl component. This class uses underlying authentication adapters and persistent storage backends.e. For example. Different adapters are likely to have vastly different options and behaviors. Such adapter preparation includes setting up credentials (e. Note: There is no Zend\Authentication\Authentication class.. username and password) and defining values for adapter-specific configuration options. Zend\Authentication is concerned only with authentication and not with authorization. Authentication is loosely defined as determining whether an entity actually is what it purports to be (i. instead the class Zend\Authentication\AuthenticationService is provided. such as database connection settings for a database table adapter. accepting authentication credentials (including a purported identity).

instead of a general authentication failure message. Some operations developers might find useful are locking accounts after too many unsuccessful password attempts..Zend Framework 2 Documentation. though developers are encouraged to consider the risks of providing such detailed reasons to users. 13..6 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 { // . authenticate() should throw an exception that derives from Zend\Authentication\Adapter\Exception\ExceptionInterface. } /** * Performs an authentication attempt * * @return \Zend\Authentication\Result * @throws \Zend\Authentication\Adapter\Exception\ExceptionInterface If authentication cannot be performed * / * public function authenticate() { // . This allows developers to maintain detailed authentication result statistics.2 Results Zend\Authentication adapters return an instance of Zend\Authentication\Result with authenticate() in order to represent the results of an authentication attempt. for example. and providing specific. Another use of this feature is to provide specific.0. If for some reason performing an authentication query is impossible. authenticate() must return an instance of Zend\Authentication\Result (or of a class derived from Zend\Authentication\Result).returns an array of messages regarding a failed authentication attempt A developer may wish to branch based on the type of authentication result in order to perform more specific operations. Result::SUCCESS Result::FAILURE Result::FAILURE_IDENTITY_NOT_FOUND Result::FAILURE_IDENTITY_AMBIGUOUS Result::FAILURE_CREDENTIAL_INVALID Result::FAILURE_UNCATEGORIZED The following example illustrates how a developer may branch on the result code: 62 Chapter 13. customized messages to users for usability reasons. } } As indicated in its docblock.returns the identity of the authentication attempt • getMessages().. so that the following four methods provide a basic set of user-facing operations that are common to the results of Zend\Authentication adapters: • isValid(). This may be used in situations where the developer wishes to distinguish among several authentication result types.returns a Zend\Authentication\Result constant identifier for determining the type of authentication failure or whether success has occurred. Release 2. see the notes below. Adapters populate the Zend\Authentication\Result object upon construction.returns TRUE if and only if the result represents a successful authentication attempt • getCode(). Introduction . customized authentication result messages to the user. flagging an IP address after too many nonexistent identities are attempted. • getIdentity(). The following result codes are available: 1 2 3 4 5 6 7 8 use Zend\Authentication\Result. For more information..

This namespace may be overridden by passing a different value to the constructor of Zend\Authentication\Storage\Session. This should occur before authentication is attempted.6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // inside of AuthController / loginAction $result = $this->auth->authenticate($adapter). uses Zend\Session. 13. and techniques such as cookies and sessions have been developed in order to facilitate maintaining state across multiple requests in server-side web applications. Zend\Authentication provides persistent storage of the identity from a successful authentication attempt using the PHP session. but it is also important to support maintaining the authenticated identity without having to present the authentication credentials with each request. Note: If automatic persistent storage of the identity is not appropriate for a particular use case. case Result::FAILURE_CREDENTIAL_INVALID: /** do stuff for invalid credential **/ break.3 Identity Persistence Authenticating a request that includes authentication credentials is useful per se. however.3. instead using an adapter class directly. Upon a successful authentication attempt. Identity Persistence 63 . case Result::SUCCESS: /** do stuff for successful authentication **/ break. since 13. switch ($result->getCode()) { case Result::FAILURE_IDENTITY_NOT_FOUND: /** do stuff for nonexistent identity **/ break. then developers may forego using the Zend\Authentication\AuthenticationService class altogether.1 Default Persistence in the PHP Session By default.3. Zend\Authentication\AuthenticationService uses a storage class named Zend\Authentication\Storage\Session. HTTP is a stateless protocol. A custom class may instead be used by providing an object that implements Zend\Authentication\Storage\StorageInterface to Zend\Authentication\AuthenticationService::setStorage(). default: /** do stuff for other failure **/ break. which. Modifying the Session Namespace Zend\Authentication\Storage\Session uses a session namespace of ‘Zend_Auth‘. Unless specified otherwise.Zend Framework 2 Documentation. and this value is internally passed along to the constructor of Zend\Session\Container. } 13. Zend\Authentication\AuthenticationService::authenticate() stores the identity from the authentication result into persistent storage.0. Release 2. in turn.

$auth = new AuthenticationService(). // Use ’someNamespace’ instead of ’Zend_Auth’ $auth->setStorage(new SessionStorage(’someNamespace’)). For such cases developers may simply implement Zend\Authentication\Storage\StorageInterface and supply an instance of the class to Zend\Authentication\AuthenticationService::setStorage().3. Using a Custom Storage Class In order to use an identity persistence storage class other than Zend\Authentication\Storage\Session.2 Implementing Customized Storage Sometimes developers may need to use a different identity storage mechanism than that provided by Zend\Authentication\Storage\Session.6 Zend\Authentication\AuthenticationService::authenticate() storage of the identity.0. and persisting the identity on // success $result = $auth->authenticate($authAdapter).Zend Framework 2 Documentation. * * @throws \Zend\Authentication\Exception\ExceptionInterface 64 Chapter 13. use Zend\Authentication\Storage\Session as SessionStorage. /** * @todo Set up the auth adapter. Introduction . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 performs the automatic use Zend\Authentication\AuthenticationService. saving the result. 13. Release 2. a developer implements Zend\Authentication\Storage\StorageInterface: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 use Zend\Authentication\Storage\StorageInterface. class My\Storage implements StorageInterface { /** * Returns true if and only if storage is empty * * @throws \Zend\Authentication\Exception\ExceptionInterface If it is impossible to * determine whether storage is empty * * @return boolean */ public function isEmpty() { /** * @todo implementation */ } /** * Returns the contents of storage * * Behavior is undefined when storage is empty. $authAdapter */ // Authenticate.

/** * @todo Set up the auth adapter. Release 2. $authAdapter */ // Authenticate.3. Zend\Authentication\AuthenticationService::setStorage() is invoked before an authentication query is attempted: 1 2 3 4 5 6 7 8 9 10 11 12 use Zend\Authentication\AuthenticationService. and persisting the identity on 13. saving the result. Identity Persistence 65 .Zend Framework 2 Documentation. // Instruct AuthenticationService to use the custom storage class $auth = new AuthenticationService().6 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 If reading contents from storage is impossible * * @return mixed */ public function read() { /** * @todo implementation */ } /** * Writes $contents to storage * * @param mixed $contents * @throws \Zend\Authentication\Exception\ExceptionInterface If writing $contents to storage is impossible * * @return void */ public function write($contents) { /** * @todo implementation */ } /** * Clears contents from storage * * @throws \Zend\Authentication\Exception\ExceptionInterface If clearing contents from storage is impossible * * @return void */ public function clear() { /** * @todo implementation */ } } In order to use this custom storage class. $auth->setStorage(new My\Storage()).0.

Introduction . through Zend\Authentication\AuthenticationService::authenticate() • directly. This typically would be used for implementing an application “logout” operation: 66 Chapter 13. /** * @todo Set up the auth adapter. as in the above example. print the reasons why foreach ($result->getMessages() as $message) { echo "$message\n".4 Usage There are two provided ways to use Zend\Authentication adapters: • indirectly. through the use of the Zend\Authentication\AuthenticationService class: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 use Zend\Authentication\AuthenticationService. } } else { // Authentication succeeded. get it $identity = $auth->getIdentity(). $auth = new AuthenticationService(). // Attempt authentication. // instantiate the authentication service $auth = new AuthenticationService(). the identity ($username) is stored // in the session // $result->getIdentity() === $auth->getIdentity() // $result->getIdentity() === $username } Once authentication has been attempted in a request. $password).Zend Framework 2 Documentation. it is a simple matter to check whether a successfully authenticated identity exists: 1 2 3 4 5 6 7 8 9 10 11 12 use Zend\Authentication\AuthenticationService. Release 2. through the adapter’s authenticate() method The following example illustrates how to use a Zend\Authentication adapter indirectly. simply use the clearIdentity() method. if (!$result->isValid()) { // Authentication failed.6 13 14 // success $result = $auth->authenticate($authAdapter). // Set up the authentication adapter $authAdapter = new My\Auth\Adapter($username. $authAdapter */ if ($auth->hasIdentity()) { // Identity exists. saving the result $result = $auth->authenticate($authAdapter).0. 13. } To remove an identity from persistent storage.

0. print the reasons why foreach ($result->getMessages() as $message) { echo "$message\n". using an adapter class directly. Usage 67 . $password). saving the result $result = $authAdapter->authenticate(). if (!$result->isValid()) { // Authentication failed. Direct use of an adapter class involves configuring and preparing an adapter object and then calling its authenticate() method.6 1 $auth->clearIdentity(). When the automatic use of persistent storage is inappropriate for a particular use case.Zend Framework 2 Documentation.4. } } else { // Authentication succeeded // $result->getIdentity() === $username } 13. Release 2. // Attempt authentication. The following example directly utilizes My\Auth\Adapter: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // Set up the authentication adapter $authAdapter = new My\Auth\Adapter($username. Adapter-specific details are discussed in the documentation for each adapter. a developer may simply bypass the use of the Zend\Authentication\AuthenticationService class.

6 68 Chapter 13. Release 2.0.Zend Framework 2 Documentation. Introduction .

salted or otherwise treated through some function or algorithm. the credential value corresponds to the password. passwords and other sensitive data are encrypted. By specifying a parameterized treatment string with this method. obscured. The available configuration options include: • tableName: This is the name of the database table that contains the authentication credentials. Because Zend\Authentication\Adapter\DbTable requires an instance of Zend\Db\Adapter\Adapter to be passed to its constructor. a developer may apply such arbitrary SQL upon input credential data. Other configuration options may be set through the constructor and through instance methods. Under a simple identity and password authentication scheme. See also the credentialTreatment option. • credentialColumn: This is the name of the database table column used to represent the credential. and inserts a row against which we can perform an authentication query later. such as a username or e-mail address. the database connection should be created. Since these functions are specific to the underlying RDBMS. // Create a SQLite database connection $dbAdapter = new DbAdapter(array( ’driver’ => ’Pdo_Sqlite’.1 Introduction Zend\Authentication\Adapter\DbTable provides the ability to authenticate against credentials stored in a database table.CHAPTER FOURTEEN DATABASE TABLE AUTHENTICATION 14. check the database manual for the availability of such functions for your database system. such as ‘MD5(?)‘ or ‘PASSWORD(?)‘. 69 . hashed. • identityColumn: This is the name of the database table column used to represent the identity. • credentialTreatment: In many cases. The following code creates an adapter for an in-memory database. creates a simple table schema. and against which the database authentication query is performed. First.2 Basic Usage As explained in the introduction. This example requires the PDO SQLite extension to be available: 1 2 3 4 5 use Zend\Db\Adapter\Adapter as DbAdapter. each instance is bound to a particular database connection. 14. encoded. The identity column must contain unique values. one for each option. the Zend\Authentication\Adapter\DbTable constructor requires an instance of Zend\Db\Adapter\Adapter that serves as the database connection to which the authentication adapter instance is bound.

// . At this point. the input credential values are passed to the adapter prior to calling the authenticate() method: 1 2 3 4 5 6 7 // Set the input credential values (e.6 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ’database’ => ’path/to/sqlite. // Create the authentication credentials table $dbAdapter->query($sqlCreate). In order to formulate an authentication query. // Perform the authentication query.Zend Framework 2 Documentation. With the database connection and table data available..db’ )). real_name) " . Zend\Authentication\Adapter\DbTable also supports retrieving the table row upon authentication success: 70 Chapter 14. from a login form) $authAdapter ->setIdentity(’my_username’) ->setCredential(’my_password’) . ’username’. // Insert the data $dbAdapter->query($sqlInsert). saving the result In addition to the availability of the getIdentity() method upon the authentication result object. an instance of Zend\Authentication\Adapter\DbTable may be created. // Build a simple table creation query $sqlCreate = ’CREATE TABLE [users] (’ . ’ . the authentication adapter instance is ready to accept authentication queries..or configure the instance with setter methods $authAdapter = new AuthAdapter($dbAdapter). "VALUES (’my_username’. ’[real_name] VARCHAR(150) NULL)’. ’ . ’My Real Name’)". ’users’. ’[username] VARCHAR(50) UNIQUE NOT NULL. ’ . ’my_password’. // Configure the instance with constructor parameters.0. password. $authAdapter ->setTableName(’users’) ->setIdentityColumn(’username’) ->setCredentialColumn(’password’) . Release 2. Configuration option values may be passed to the constructor or deferred as parameters to setter methods after instantiation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 use Zend\Authentication\Adapter\DbTable as AuthAdapter. $authAdapter = new AuthAdapter($dbAdapter.... ’[id] INTEGER NOT NULL PRIMARY KEY. ’password’ ).g. // Build a query to insert a row for which authentication may succeed $sqlInsert = "INSERT INTO users (username. ’[password] VARCHAR(32) NULL. Database Table Authentication .

3. /* Output: Array ( [id] => 1 [username] => my_username [real_name] => My Real Name ) */ $columnsToOmit = array(’password’). ’username’. Release 2. "\n\n". ’real_name’ ).0. or what columns to omit: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 $columnsToReturn = array( ’id’. When retrieving the result object. Another use case scenario. /* Output: my_username Array ( [id] => 1 [username] => my_username [password] => my_password [real_name] => My Real Name ) */ Since the table row contains the credential value.3 Advanced Usage: Persisting a DbTable Result Object By default.6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // Print the identity echo $result->getIdentity() . print_r($authAdapter->getResultRowObject(null. The following code snippet illustrates its use: 14. /* Output: Array ( [id] => 1 [username] => my_username [real_name] => My Real Name ) */ 14. Zend\Authentication\Adapter\DbTable returns the identity supplied back to the auth object upon successful authentication. it is important to secure the values against unintended access. we can either specify what columns to return. // Print the result row print_r($authAdapter->getResultRowObject()). where developers want to store to the persistent storage mechanism of Zend\Authentication an identity object containing other useful information. is solved by using the getResultRowObject() method to return a stdClass object. print_r($authAdapter->getResultRowObject($columnsToReturn)). Advanced Usage: Persisting a DbTable Result Object 71 .Zend Framework 2 Documentation. $columnsToOmit).

Zend\Authentication\Adapter\DbTable has some built in mechanisms that can be leveraged for additional checks at authentication time to solve some common user problems. */ } 14.. // The active field value of an account is equal to "TRUE" $adapter = new AuthAdapter($db. With that disclaimer out of the way. Salting is a term referring to a technique which 72 Chapter 14. it sometimes makes sense to solve what could look like an authorization problem within the authentication adapter.Zend Framework 2 Documentation.0.. // store the identity as an object where the password column has // been omitted $storage->write($adapter->getResultRowObject( null. ’users’. $storage->write($adapter->getResultRowObject(array( ’username’.3. // The status field value of an account is not equal to "compromised" $adapter = new AuthAdapter($db. if ($result->isValid()) { // store the identity as an object where only the username and // real_name have been returned $storage = $this->_auth->getStorage().. ’real_name’. ’MD5(?) AND active = "TRUE"’ ). ’MD5(?) AND status != "compromised"’ ). ’password’ )). there are a few instances and problems that toe the line between which domain they fit within. ))). ’username’. Another scenario can be the implementation of a salting mechanism.. /* .1 Advanced Usage By Example While the primary purpose of the Zend\Authentication component (and consequently Zend\Authentication\Adapter\DbTable) is primarily authentication and not authorization. ’username’. ’password’. ’users’.6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // authenticate with Zend\Authentication\Adapter\DbTable $result = $this->_auth->authenticate($adapter). */ } else { /* . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 use Zend\Authentication\Adapter\DbTable as AuthAdapter. Depending on how you’ve decided to explain your problem. Release 2. ’password’. Database Table Authentication .

"AFTER [password]". we need to modify our table to store our salt string: 1 2 3 $sqlAlter = "ALTER TABLE [users] " . password_salt))" ). This object will not have any of the identity or credential information in it as those values are placed into the select object at authenticate() time.0. Advanced Usage: Persisting a DbTable Result Object 73 . 126)). this ensures that users. Here’s a simple way to generate a salt string for every user at registration: 1 2 3 4 $dynamicSalt = ’’.6 can highly improve your application’s security. in other words to see if that user’s account is enabled. $i++) { $dynamicSalt . ?. 14. for ($i = 0. // get select object (by reference) $select = $adapter->getDbSelect(). "ADD COLUMN [password_salt] " .= chr(rand(33. ’username’. ’MD5(?)’ ). ’username’.active = TRUE $adapter->authenticate(). An example of a situation where one might want to use the getDbSelect() method would check the status of a user. Another alternative is to use the getDbSelect() method of the Zend\Authentication\Adapter\DbTable after the adapter has been constructed. "MD5(CONCAT(’staticSalt’. This method will return the Zend\Db\Sql\Select object instance it will use to complete the authenticate() routine. It is important to note that this method will always return the same object regardless if authenticate() has been called or not. // authenticate. by an SQL injection attack) but your web server is intact your data is still unusable for the attacker. g. $select->where(’active = "TRUE"’). $i < 50. Therefore. ’password’. Release 2. ’password’.3. Note: You can improve security even more by using a static salt value hard coded into your application. It’s based on the idea that concatenating a random string to every password makes it impossible to accomplish a successful brute force attack on the database using pre-computed hash values from a dictionary. ’users’. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // Continuing with the example from above $adapter = new AuthAdapter($db. ’users’. In the case that your database is compromised (e. } And now let’s build the adapter: 1 2 3 4 5 6 $adapter = new AuthAdapter($db.Zend Framework 2 Documentation.

Database Table Authentication .0.Zend Framework 2 Documentation.6 74 Chapter 14. Release 2.

requires several input parameters: • filename . such as “joe.2 Specifics The digest authentication adapter.user“ • realm.Digest authentication user • password . $adapter = new AuthAdapter($filename. as in the following example (in which the password is “somePassword”): 1 someUser:Some Realm:fde17b91c3a510ecbaf7dbd37f59d4f8 15. 1 2 3 use Zend\Authentication\Adapter\Digest as AuthAdapter. 15.1 Introduction Digest authentication is a method of HTTP authentication that improves upon Basic authentication by providing a way to authenticate without having to transmit the password in clear text across the network. such as “Administrative Area“ • MD5 hash of the username. realm. This adapter allows authentication against text files containing lines having the basic elements of Digest authentication: • username. which has been populated with the identity as an array having keys of realm and username. The respective array values associated with these keys correspond to the values set before authenticate() is called.3 Identity The digest authentication adapter returns a Zend\Authentication\Result object.CHAPTER FIFTEEN DIGEST AUTHENTICATION 15. and password. separated by colons The above elements are separated by colons.Filename against which authentication queries are performed • realm .Password for the user of the realm These parameters must be set prior to calling authenticate(). Zend\Authentication\Adapter\Digest. 75 .Digest authentication realm • username .

Zend Framework 2 Documentation.0. /* Array ( [realm] => Some Realm [username] => someUser ) */ 76 Chapter 15. Digest Authentication . $identity = $result->getIdentity(). $username. $result = $adapter->authenticate(). $password). Release 2. print_r($identity).6 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $realm.

Digest authentication is a method of HTTP authentication that improves upon Basic authentication by providing a way to authenticate without having to transmit the password in clear text across the network. It uses a Resolver to look up a client’s identity in some data store (text file by default). • Supports proxy authentication. or “auth-int”.” The HTTP authentication class encapsulates the logic for carrying out both Basic and Digest authentication. and some are required: 77 . and retrieve the credentials from the data store. such as databases.CHAPTER SIXTEEN HTTP AUTHENTICATION ADAPTER 16. 16. Major Features: • Supports both Basic and Digest authentication.2 Design Overview This adapter consists of two sub-components. and the so-called “Resolvers. which would allow for “stale” support. so client can respond with any scheme it supports. • Issues challenges in all supported schemes. and increased replay attack protection. Basic and Digest HTTP Authentication. • Authentication with integrity checking. There are several configuration options available. • Authentication-Info HTTP header. There are a few notable features of RFC-2617 that are not implemented yet: • Nonce tracking. 16.3 Configuration Options The Zend\Authentication\Adapter\Http class requires a configuration array passed to its constructor. The “resolved” credentials are then compared to the values submitted by the client to determine whether authentication is successful.1 Introduction Zend\Authentication\Adapter\Http provides a mostly-compliant implementation of RFC-2617. • Includes support for authenticating against text files and provides an interface for authenticating against other sources. the HTTP authentication class itself.

Its resolve() method walks through the text file. if it’s set to 3600 (for example). The text file format similar to Apache htpasswd files: 1 <username>:<realm>:<credentials>\n Each line consists of three fields . Sets the number of seconds for which the nonce is valid. A text file resolver class is included with this adapter. once nonce tracking and stale support are implemented.1 File Resolver The file resolver is a very simple class.1: Configuration Options Option Required Name acYes cept_schemes realm Yes diYes. Disabled by default. There are two equally easy ways to create a File resolver: 78 Chapter 16.username. It has a single property specifying a filename. Release 2. usernames should be unique within a given realm. which can also be passed to the constructor. See notes below. This will be resolved in a future release. Basic authentication expects to receive the Base64 encoded version of the user’s password.4. accept_schemes contains digest use_opaqueNo algoNo rithm proxy_authNo Description Determines which authentication schemes the adapter will accept from the client. it will cause the adapter to prompt the client for new credentials every hour.0. Sets the authentication realm. Specified the algorithm. this same file format serves both Basic and Digest authentication. searching for a line with a matching username and realm.4 Resolvers The resolver’s job is to take a username and realm. Therefore. Specifies whether to send the opaque value in the header. or effectively how long a client’s authentication information is accepted. True by default. when gest_domains accept_schemes contains digest nonce_timeout when Yes. the credentials field should be written in clear text. and credentials . The URIs need not all point to the same server. The credentials field is opaque to the file resolver. realm. Currently. This setting is supposed to determine the valid lifetime of a given nonce. Zend\Authentication\Adapter\Http relies on objects implementing Zend\Authentication\Adapter\Http\ResolverInterface. Must be a space=separated list containing ‘basic’ and/or ‘digest’. the realm. the only supported option (for now). but any other kind of resolver can be created simply by implementing the resolver interface. on the hour. HTTP Authentication Adapter .Zend Framework 2 Documentation. In Basic authentication. 16. Space-separated list of URIs for which the same authentication information is valid. and their password (each separated by colons). 16. and return some kind of credential value. it should be the MD5 hash described above. In Digest authentication. the only supported hash algorithm is MD5. it simply returns that value as-is to the caller. instead of normal origin server authentication. Note: The current implementation of the nonce_timeout has some interesting side effects. Enable to perform Proxy authentication.each separated by a colon. Currently. Digest authentication expects to receive a hash of the user’s username. Defaults to MD5.6 Table 16.

$digestResolver->setFile(’files/digestPasswd. $adapter->setRequest($request). if (!$result->isValid()) { // Bad userame/password. This array will cause the adapter to accept either Basic or Digest authentication. $basicResolver = new FileResolver(). Note that this could just as easily be two different classes: 1 2 3 4 5 6 7 8 9 10 use Zend\Authentication\Adapter\Http\FileResolver.5. Since we’re supporting both Basic and Digest authentication. and will require authenticated access to all the areas of the site under /members_only and /my_account. or 1 2 3 $path = ’files/passwd. we need two different resolver objects. $digestResolver = new FileResolver(). ’/members_only /my_account’.txt’).txt’. create the Zend\Authentication\Adapter\Http object: 1 $adapter = new Zend\Authentication\Adapter\Http($config). or canceled password prompt } 16. $adapter->setDigestResolver($digestResolver). $resolver = new FileResolver(). $adapter->setBasicResolver($basicResolver). we perform the authentication. The realm value is usually displayed by the browser in the password dialog box. of course. Finally. The adapter needs a reference to both the Request and Response objects in order to do its job: 1 2 3 4 5 6 7 8 9 10 assert($request instanceof Zend\Http\Request). $result = $adapter->authenticate().6 1 2 3 use Zend\Authentication\Adapter\Http\FileResolver. $adapter->setResponse($response).0. 3600.txt’). => => => => ’basic digest’. Release 2. $basicResolver->setFile(’files/basicPasswd. set up an array with the required configuration values: 1 2 3 4 5 6 $config = array( ’accept_schemes’ ’realm’ ’digest_domains’ ’nonce_timeout’ ).Zend Framework 2 Documentation. If the given path is empty or not readable.5 Basic Usage First. Basic Usage 79 . assert($response instanceof Zend\Http\Response). behaves as described above. The nonce_timeout. Next. $path = ’files/passwd. $resolver = new FileResolver($path). $resolver->setFile($path). an exception is thrown.txt’. ’My Web Site’. 16.

0. Release 2. HTTP Authentication Adapter .6 80 Chapter 16.Zend Framework 2 Documentation.

17. It has been tested to work with Microsoft Active Directory and OpenLDAP. Zend\Authentication\Adapter\Ldap as AuthAdapter. diagnostic information for troubleshooting authentication problems. an exploration of its API. $log_path = $config->production->ldap->log_path. unset($options[’log_path’]). Zend\Log\Logger. and failover capabilities. 81 . Zend\Log\Writer\Stream as LogWriter. even if you’re not using Zend\Mvc./ldap-config. $username = $this->getRequest()->getPost(’username’). $configData = $configReader->fromFile(’.CHAPTER SEVENTEEN LDAP AUTHENTICATION 17. $password = $this->getRequest()->getPost(’password’). true).1 Introduction Zend\Authentication\Adapter\Ldap supports web application authentication with LDAP services. multi-domain authentication. $config = new Config($configData. $configReader = new ConfigReader(). $auth = new AuthenticationService().ini’). This documentation includes a guide on using Zend\Authentication\Adapter\Ldap. Zend\Config\Reader\Ini as ConfigReader.2 Usage To incorporate Zend\Authentication\Adapter\Ldap authentication into your application quickly. Its features include username and domain name canonicalization. $adapter = new AuthAdapter($options. an outline of the various available options. $username. Zend\Log\Filter\Priority as LogFilter. Zend\Config\Config. but it should also work with other LDAP service providers. the meat of your code should look something like the following: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 use use use use use use use Zend\Authentication\AuthenticationService. $options = $config->production->ldap->toArray(). and example options for both Active Directory and OpenLDAP servers.

DC=net" ldap.host = dc1. $writer = new LogWriter($log_path).accountDomainName = w. A regular array would work equally well. $writer->addFilter($filter). Typical options for Active Directory ldap.password = pass1 ldap.. Release 2.server1.6 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 $password). but it is highly recommended that you use a logger.DC=net" The above configuration will instruct Zend\Authentication\Adapter\Ldap to attempt to authenticate users 82 Chapter 17. } } } Of course.accountCanonicalForm = 3 ldap.username = "CN=user1.accountDomainNameShort = W ldap.accountDomainNameShort = FOO ldap. Typical options for OpenLDAP ldap. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [production] ldap.net ldap. which is a nice feature in itself for something that has a history of being notoriously difficult to debug. The Zend\Config\Reader\Ini code is used above to load the adapter options.> 1) { // $messages[2] and up are log messages $message = str_replace("\n". "\n ".log .useStartTls = true ldap. $message).server2. $filter = new LogFilter(Logger::DEBUG).log_path = /tmp/ldap. For details regarding the options array.net ldap.server1. The names of the servers (e. see the Server Options section below. $logger->addWriter($writer).bindRequiresDn = true . It is also optional.DC=w.w.ini file that has options for two separate servers.baseDn = "CN=Users.server2.DC=foo.net ldap.g.host = s0.server2.foo.accountCanonicalForm = 3 ldap. foreach ($messages as $i => $message) { if ($i-. LDAP Authentication . in order. Note that Zend\Config\Reader\Ini requires that any values with “equals” characters (=) will need to be quoted (like the DNs shown below).baseDn = "OU=Sales.accountDomainName = foo.DC=net" ldap.server1. ‘server1’ and ‘server2’) are largely arbitrary.Zend Framework 2 Documentation. The following is an example ldap-config. Zend\Authentication\Adapter\Ldap will record just about every bit of information anyone could want in $messages (more below).server1.server1. if ($log_path) { $messages = $result->getMessages(). With multiple sets of server options the adapter will try each.server2. $logger = new Logger. until the credentials are successfully authenticated.net ldap.0.server1.DC=foo. the logging code is optional. $logger->debug("Ldap: $i: $message").server1. $result = $auth->authenticate($adapter).server2.server2.server1.

foo.net will be tried.foo.3. Release 2. The $options parameter is required and must be an array containing one or more sets of options. the AD server dc1. Each comma-separated component is an attribute and value representing a node.net (the same options as the above INI representation): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Array ( [server2] => Array ( [host] => dc1. Note that it is an array of arrays of Zend\Ldap\Ldap options.DC=foo.DC=net [password] => pass1 [baseDn] => OU=Sales. With servers in different domains. If the authentication fails for any reason. Below is print_r() output of an example options parameter containing two sets of server options for LDAP servers s0.w.DC=foo. the options must still be within another array. The components are evaluated in reverse. this configuration illustrates multi-domain authentication.net and dc1.DC=w.w.net [useStartTls] => 1 [accountDomainName] => w. the user account CN=Bob Carter. The API 83 .6 with the OpenLDAP server s0.3 The API The Zend\Authentication\Adapter\Ldap constructor accepts three parameters.DC=net ) [server1] => Array ( [host] => s0.0. You can also have multiple servers in the same domain to provide redundancy.net [accountDomainNameShort] => FOO [accountCanonicalForm] => 3 [username] => CN=user1. 17.foo.DC=net is located directly within the 17. For example.CN=Users. which means we can omit a number of options associated with retrieving the DN for a username being authenticated.w.net [accountDomainNameShort] => W [accountCanonicalForm] => 3 [baseDn] => CN=Users. we provide it here for name canonicalization purposes (described in the Username Canonicalization section below). Even if you will be using only one LDAP server. Note that in this case.net first.DC=net [bindRequiresDn] => 1 ) ) The information provided in each set of options above is different mainly because AD does not require a username be in DN form when binding (see the bindRequiresDn option in the Server Options section below).Zend Framework 2 Documentation. Note: What is a Distinguished Name? A DN or “distinguished name” is a string that represents the path to an object within the LDAP directory.DC=w.net [accountDomainName] => foo. even though OpenLDAP has no need for the short NetBIOS style domain name used by Windows.

a special exception is thrown and caught by Zend\Authentication\Adapter\Ldap that causes that server to be ignored and the next set of server options is selected.g. LDAP Authentication . the adapter can authenticate users in multiple domains and provide failover so that if one server is not available.Zend Framework 2 Documentation. another will be queried. Release 2. With multiple sets of server options. If a domain does match. if the bind is not successful.0.6 CN=Users. largely unmodified. and the adapter’s authenticate() method returns a successful result. the credentials supplied by the user through your HTML login form).g. If a domain is present. the adapter iterates over each set of server options. ‘server1’ and ‘server2’ shown above) are largely arbitrary. which are passed. etc). the ‘. This structure is best explored with an LDAP browser like the ADSI Edit MMC snap-in for Active Directory or phpLDAPadmin. to Zend\Ldap\Ldap::setOptions(): 84 Chapter 17. and authenticate() returns a failure result with error messages from the last iteration. the authentication fails.net or FOO\alice).net or FOO). Alternatively. sets them on the internal Zend\Ldap\Ldap instance. If all server options have been tried without success. If the bind is successful.DC=net container.‘INI property separator.g. and calls the Zend\Ldap\Ldap::bind() method with the username and password being authenticated. ‘&‘ for XML entity references.. Zend\Ldap\Ldap proceeds to try to bind with the supplied credentials. the identifiers should be present (as opposed to being numeric indexes) and should not contain any special characters used by the associated file formats (e.DC=w. but does not match either of the server’s domain names (foo. Zend\Ldap\Ldap throws a Zend\Ldap\Exception\LdapException which is caught by Zend\Authentication\Adapter\Ldap and the next set of server options is tried. the iteration stops. The names of servers (e.4 Server Options Each set of server options in the context of ZendAuthenticationAdapterLdap consists of the following options. 17. they may also be set with the setUsername() and setPassword() methods.e. Note: The Gory Details: What Happens in the Authenticate Method? When the authenticate() method is called. The Zend\Ldap\Ldap class checks to see if the username is qualified with a domain (e. or if the user did not supply a qualified username. The username and password parameters of the Zend\Authentication\Adapter\Ldap constructor represent the credentials being authenticated (i.. but for the sake of using Zend\Config\Reader\Ini. has a domain component like alice@foo.

Release 2.1: Server Options Description The hostname of LDAP server that these options represent. For example. username The DN of the account used to perform account DN lookups. A value of TRUE is strongly favored in production environments to prevent passwords from be transmitted in clear text. if it is not already in DN form. Meaning. if Zend\Authentication\AuthenticationService was used) will always be FOO\alice. it should be sufficient to derive it from the user’s DNS domain using DC= components. This option is not required.6 Table 17.com). FoO\aLicE. The default value is FALSE. that may be awkward for the application’s high-level logic).. whether it be alice. a baseDn of DC=foo. this option must be set to TRUE (e.DC=net) will be more efficient..g.DC=net should work.g. OU=Sales. alice@foo. useStartTls Whether or not the LDAP client should use TLS (aka SSLv2) encrypted transport.DC=net (basically all servers except AD). A more precise location (e. For example.g. usernames in principal name form (e. this instructs Zend\Ldap\Ldap to automatically retrieve the DN corresponding to the username being authenticated.net) are not supported..net and the user supplies 17. If this option is not supplied.. the LDAP client will attempt an “anonymous bind” when performing account DN lookups.g. if you are uncertain about the correct baseDn value. accountDoThe FQDN domain name for which the target LDAP server is an authority (e.. alice@foo. This option is required. This option is required. as there are many use-cases that require generating the principal name form.g. Values are as follows: 2 for traditional username style names (e. The useStartTls option should be favored over useSsl but not all servers support this newer mechanism. with a value of 3. this option is required. The useSsl and useStartTls options are mutually exclusive. an account with read-only access to objects under the baseDn is all that is necessary (and preferred based on the Principle of Least Privilege). This value also changes the default port value (see port description above). example.g.net. etc.g. but not required. the identity returned by Zend\Authentication\Result::getIdentity() (and Zend\Authentication\AuthenticationService::getIdentity(). This account does not need to be a privileged account. alice).g. accountCanon. 3 for backslash-style names (e.net.net\alice. for OpenLDAP).DC=foo. foo. The default value is FALSE. LDAP servers that require the username to be in DN form when performing the “bind” require this option. mainName This option is used to canonicalize names so that the username supplied by the user can be converted as necessary for binding. if accountDomainName is foo. and then re-bind with the proper DN. It is strongly recommended that you supply this option. useSsl Whether or not the LDAP client should use SSL encrypted transport. the default port value is 389.com with an OpenLDAP server. but useStartTls should be favored if the server and LDAP client library support it. See the Account Name Canonicalization section in the Zend\Ldap\Ldap documentation for details. and a failure will result).net).g. This option also controls the default acountFilterFormat used when searching for accounts. FOO\alice) or 4 for principal style usernames (e.0. Server Options 85 bob@bar. however. The port on which the LDAP server is listening. The default value is 4 (e.. the default port value is 636. alice@foo. Name host port . bindRequiresDn Some LDAP servers require that the username used to bind be in DN form like CN=Alice Baker.DC=foo. as servers frequently require that a certificate be installed separately after installation. If useSsl is TRUE. If useSsl is FALSE. FOO\alice.net). and therefore this option may be FALSE with AD (and it should be.net. The useSsl and useStartTls options are mutually exclusive.g. that the same accountCanonicalForm be used with all server options so that the resulting usernames are always canonicalized to the same form (e. Currently only Microsoft Active Directory Server (ADS) is known not to require usernames to be in DN form when binding.Zend Framework 2 Documentation. Note that when using multiple sets of server options it is recommended. regardless of what form Alice supplied. See the accountFilterFormat option. if bindRequiresDn is TRUE.. alice@foo. but if it is not supplied.A value of 2.4. 3 or 4 indicating the form to which account names should be canonicalized after icalForm successful authentication. password The password of the account used to perform account DN lookups.. the server will not be queried. if you canonicalize to EXAMPLE\username with an AD server but to username@example.OU=Sales. if the user’s principal name is alice@foo. Otherwise. If this option is TRUE. It is also used to determine if the server is an authority for the supplied username (e. baseDn The DN under which all accounts being authenticated are located. as retrieving the DN requires an extra round trip to the server)..

index 1 should be logged and. using the FlashMessenger helper). to resolve this issue you can set “TLS_REQCERT never” in the OpenLDAP client ldap.Zend Framework 2 Documentation. 17. this string is empty. indexes 2 and higher could be logged as well (although the final message always includes the string from index 1). If the authentication is successful. All log messages in order starting at index 2.6.0.g.5 Collecting Debugging Messages Zend\Authentication\Adapter\Ldap collects debugging information within its authenticate() method.conf (and restart the web server) to indicate to the OpenLDAP client library that you trust the server. user=friendly message that is suitable for displaying to users (e. Alternatively. you can export the LDAP server’s root certificate and put it on the web server so that the OpenLDAP client can validate the server’s identity. “Invalid credentials”). In practice.6 Common Options for Specific Servers 17. The array returned by Zend\Authentication\Result::getMessages() is described as follows Table 17. LDAP Authentication .. if debugging information is being collected.2: Debugging Messages Messages Array Index Index 0 Index 1 Indexes 2 and higher Description A generic.g.1 Options for Active Directory For ADS. If the authentication is successful. Assuming the PHP LDAP extension is ultimately linked to the OpenLDAP client libraries. this string is empty. This information is stored in the Zend\Authentication\Result object as messages.6 Note: If you enable useStartTls = TRUE or useSsl = TRUE you may find that the LDAP client generates an error claiming that it cannot validate the server’s certificate. Release 2. index 0 should be displayed to the user (e. the following options are noteworthy: 86 Chapter 17.. 17. A more detailed error message that is not suitable to be displayed to users but should be logged for the benefit of server operators. if you are concerned that the server could be spoofed.

DC=foo. FOO\alice). In general. accountCanonicalForm accountDomainName accountDomainNameShort Note: Technically there should be no danger of accidental cross-domain authentication with the current Zend\Authentication\Adapter\Ldap implementation.6 Table 17.6.6.. Common Options for Specific Servers 87 ..0. You almost certainly want this to be 3 for backslash style names (e. which are most familiar to Windows users. As with all servers.) This is required with AD unless accountCanonicalForm 2 is used. is discouraged. alice). This is required if the backslash style accountCanonicalForm is used. account name ambiguity is known to be the source of security issues. or if an alternative adapter is used (e. For the sake of security. so always try to use qualified account names.3: Options for Active Directory Name host useStartTls useSsl baseDn Additional Notes As with all servers. this option is required.. Possibly used as an alternative to useStartTls (see above). CN=Users.g. BAR\alice and FOO\alice will be treated as the same user).DC=net).g.. this should be TRUE if the server has the necessary certificate installed. but this may not be true of a future implementation that discovers the domain at runtime. as this may grant access to your application to users with the same username in other trusted domains (e.2 Options for OpenLDAP For OpenLDAP or a generic LDAP server using a typical posixAccount style schema. 17. Ask your AD administrator what the best DN for accounts for your application would be. Kerberos).Zend Framework 2 Documentation. You should not use the unqualified form 2 (e.g.. the following options are noteworthy: 17. since server domains are explicitly checked. (See also note below. By default AD places all user accounts under the Users container (e. Release 2. which. this option is required. The NetBIOS name of the domain that users are in and for which the AD server is an authority. again. but the default is not common in larger organizations.g.g.

4: Options for OpenLDAP Name host useStartTls useSsl username Additional Notes As with all servers.net. password The password corresponding to the username above.Optional.g. LDAP Authentication . baseDn As with all servers.6 Table 17. but the default value is 4 (principal style names like alice@foo. this should be TRUE if the server has the necessary certificate installed.net). this option is required. For backslash style names use value 3. this option is required and should be a short name that corresponds adequately to the NameShort accountDomainName (e. but this may be omitted if the LDAP server permits an anonymous binding to query user accounts.0. For the sake of security. this option is required and indicates the DN under which all accounts being authenticated are located. if your accountDomainName is foo.. mainName accountDoIf AD is not also being used. which is not recommended. this value is not required. accountCanon. as OpenLDAP requires that usernames be in DN form when performing a bind. bindRequiresDn Required and must be TRUE. Possibly used as an alternative to useStartTls (see above).. if accountCanonicalForm 3 mainis used. 88 Chapter 17. which may not icalForm be ideal if your users are used to backslash style names (e. Otherwise.Zend Framework 2 Documentation. as OpenLDAP requires that usernames be in DN form when performing a bind. FOO\alice). accountDoRequired unless you’re using accountCanonicalForm 2. a good accountDomainNameShort value might be FOO). Try to use an unprivileged account. Release 2.g. Required and must be a DN.

The Zend\Barcode component is divided into two subcomponents: barcode objects and renderers. Objects allow you to create barcodes independently of the renderer. Renderer allow you to draw barcodes based on the support required.CHAPTER EIGHTEEN INTRODUCTION Zend\Barcode\Barcode provides a generic way to generate barcodes. 89 .

Introduction .6 90 Chapter 18. Release 2.Zend Framework 2 Documentation.0.

Using Zend\Barcode\Barcode::factory() with Zend\Config\Config objects You may pass a Zend\Config\Config object to the factory in order to create the necessary objects. • The name of the barcode format (e. $rendererOptions ). $renderer = Barcode::factory( ’code39’. // Only the text to draw is required $barcodeOptions = array(’text’ => ’ZEND-FRAMEWORK’).. we will use the Code39 barcode type together with the Image renderer. “image”) (required) • Options to pass to the barcode object (an array or a Traversable object) (optional) • Options to pass to the renderer object (an array or a Traversable object) (optional) • Boolean to indicate whether or not to automatically render errors.CHAPTER NINETEEN BARCODE CREATION USING ZEND\BARCODE\BARCODE CLASS 19. 1 2 3 4 5 6 7 8 9 10 use Zend\Barcode\Barcode. In this first example. // No required options $rendererOptions = array(). “code39”) or a Traversable object (required) • The name of the renderer (e.g. The following example is functionally equivalent to the previous. If an exception occurs.1 Using Zend\Barcode\Barcode::factory Zend\Barcode\Barcode uses a factory method to create an instance of a renderer that extends Zend\Barcode\Renderer\AbstractRenderer. the provided barcode object will be replaced with an Error representation (optional default TRUE) Getting a Renderer with Zend\Barcode\Barcode::factory() Zend\Barcode\Barcode::factory() instantiates barcode classes and renderers and ties them together. The factory method accepts five arguments.g. 91 . ’image’.. $barcodeOptions.

$renderer = Barcode::factory($config). To draw a barcode. // Only the text to draw is required $barcodeOptions = array(’text’ => ’ZEND-FRAMEWORK’). // No required options $rendererOptions = array(). $rendererOptions )->draw(). 1 2 3 4 5 6 7 8 9 10 11 12 92 Chapter 19. $rendererOptions ). Release 2.6 1 2 3 4 5 6 7 8 9 10 11 12 use Zend\Config\Config. // No required options $rendererOptions = array().2 Drawing a barcode When you draw the barcode. ’image’. use Zend\Barcode\Barcode. // Draw the barcode in a new image. ’rendererParams’ => array(’imageType’ => ’gif’). you retrieve the resource in which the barcode is drawn. // Draw the barcode in a new image. or simply use the proxy method provided by Zend\Barcode\Barcode. $barcodeOptions. $imageResource = Barcode::factory( ’code39’. ’renderer’ => ’image’. 19. Barcode creation using Zend\Barcode\Barcode class . 1 2 3 4 5 6 7 8 9 10 11 12 Drawing a barcode with Zend\Barcode\Barcode::draw() use Zend\Barcode\Barcode. you can call the draw() of the renderer. Drawing a barcode with the renderer object use Zend\Barcode\Barcode. )). ’barcodeParams’ => array(’text’ => ’ZEND-FRAMEWORK’). $barcodeOptions. // Using only one Zend\Config\Config object $config = new Config(array( ’barcode’ => ’code39’. ’image’. $imageResource = Barcode::draw( ’code39’.Zend Framework 2 Documentation.0. // Only the text to draw is required $barcodeOptions = array(’text’ => ’ZEND-FRAMEWORK’).

// send the headers and the image Barcode::factory( ’code39’.Zend Framework 2 Documentation. ’image’.3 Renderering a barcode When you render a barcode. 19. $rendererOptions )->render(). $rendererOptions ).6 19. // No required options $rendererOptions = array(). to a browser).g.3. // Only the text to draw is required $barcodeOptions = array(’text’ => ’ZEND-FRAMEWORK’). // send the headers and the image Barcode::render( ’code39’. 1 2 3 4 5 6 7 8 9 10 11 12 13 This will generate this barcode: Renderering a barcode with Zend\Barcode\Barcode::render() use Zend\Barcode\Barcode. $barcodeOptions. you send the headers and you send the resource (e.0. Renderering a barcode with the renderer object use Zend\Barcode\Barcode. Renderering a barcode 93 . 1 2 3 4 5 6 7 8 9 10 11 12 13 This will generate the same barcode as the previous example. // Draw the barcode in a new image. ’image’. Release 2. you draw the barcode. $barcodeOptions. // Only the text to draw is required $barcodeOptions = array(’text’ => ’ZEND-FRAMEWORK’). // No required options $rendererOptions = array(). // Draw the barcode in a new image. you can call the render() method of the renderer or simply use the proxy method provided by Zend\Barcode\Barcode. To render a barcode.

0. Release 2.Zend Framework 2 Documentation. Barcode creation using Zend\Barcode\Barcode class .6 94 Chapter 19.

the values have no units. Objects have a large number of options.CHAPTER TWENTY ZEND\BARCODE\BARCODE OBJECTS Barcode objects allow you to generate barcodes independently of the rendering support.g. All options have a corresponding getter prefixed with “get” (e. • As an array passed to the setOptions() method.” For example.1 Common Options In the following list. // Case 1: constructor $barcode = new Object\Code39($options). the default value of the “thin bar” is “1 unit”. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 20. Most of them are common to all objects. $barcode->setOptions($options). Setters are each named by uppercasing the initial letter of the option and prefixing the name with “set” (e. you can retrieve the barcode as an array of drawing instructions that you can provide to a renderer. The real units depend on the rendering support (see the renderers documentation for more information). $options = array(’text’ => ’ZEND-FRAMEWORK’. $barcode->setText(’ZEND-FRAMEWORK’) ->setBarHeight(40). Available options are: 95 . we will use the term “unit. // Case 2: setOptions() $barcode = new Object\Code39(). ’barHeight’ => 40). Different ways to parameterize a barcode object use Zend\Barcode\Object. After generation. “barHeight” becomes “setBarHeight”). // Case 3: individual setters $barcode = new Object\Code39(). • Via individual setters for each configuration type.g. “getBarHeight”). These options can be set in three ways: • As an array or a Traversable object) object passed to the constructor.

barThickWidth and fontSize) Color of the bar and the text. array(’text’ => ’ZEND-FRAMEWORK’) ).0. if you need to extend the embedding objects 50 Height of the bars 3 Width of the thick bar 1 1 0x000000 (black) 0xFFFFFF (white) 0 NULL 10 FALSE TRUE TRUE FALSE FALSE FALSE NULL Width of the thin bar Factor by which to multiply bar widths and font sizes (barHeight.6 Table 20. Zend\Barcode\Barcode Objects . for example.ttf’ // or: Barcode::render( ’code39’. This value can be always be overridden for individual objects by using the setFont() method.1: Common Options Option barcodeNamespace barHeight barThickWidth barThinWidth factor foreColor backgroundColor orientation font fontSize withBorder withQuietZones drawText stretchText withChecksum withChecksumInText text Data Type String Integer Integer Integer Integer Integer Integer or String Float String or Integer Float Boolean Boolean Boolean Boolean Boolean Boolean String Default Description Value Zend\Barcode\Object Namespace of the barcode. “#333333”) Orientation of the barcode Font path to a TTF font or a number between 1 and 5 if using image generation with GD (internal fonts) Size of the font (not applicable with numeric fonts) Draw a border around the barcode and the quiet zones Leave a quiet zone before and after the barcode Set if the text is displayed below the barcode Specify if the text is stretched all along the barcode Indicate whether or not the checksum is automatically added to the barcode Indicate whether or not the checksum is displayed in the textual representation The text to represent as a barcode 20. “#333333”) Color of the background. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 use Zend\Barcode\Barcode. // In your bootstrap: Barcode::setBarcodeFont(’my_font. barThinWidth. Release 2.ttf’).g. ’pdf’.1 Particular case of static setBarcodeFont() You can set a commont font for all your objects by using the static method Zend\Barcode\Barcode::setBarcodeFont().Zend Framework 2 Documentation. // Later in your code: Barcode::render( ’code39’. 96 Chapter 20. ’image’. Could be provided as an integer or as a HTML value (e. // will use ’my_font.g. Could be provided as an integer or as a HTML value (e.1.

2 Common Additional Getters Table 20. ’font’ => 3 ) ).2: Common Getters Getter getType() getRawText() getTextToDisplay() getQuietZone() getInstructions() getHeight($recalculate = false) getWidth($recalculate = false) getOffsetTop($recalculate = false) getOffsetLeft($recalculate = false) Data Type String String String Integer Array Integer Description Return the name of the barcode class without the namespace (e.0. Return the height of the barcode calculated after possible rotation Integer Integer Return the width of the barcode calculated after possible rotation Return the position of the top of the barcode calculated after possible rotation Integer Return the position of the left of the barcode calculated after possible rotation 20.2. the checksum value Return the size of the space needed before and after the barcode without any drawing Return drawing instructions as an array. Zend\Barcode\Object\Code39 returns simply “code39”) Return the original text provided to the object Return the text to display. Common Additional Getters 97 .g. Release 2.6 17 18 19 20 21 array( ’text’ => ’ZEND-FRAMEWORK’. including.Zend Framework 2 Documentation. // will use the 3rd GD internal font 20. if activated.

6 98 Chapter 20.Zend Framework 2 Documentation. Release 2. Zend\Barcode\Barcode Objects .0.

21. It is internally used to automatically render an exception caught by the Zend\Barcode component.1 Zend\Barcode\Object\Error This barcode is a special case.2 Zend\Barcode\Object\Code128 • Name: Code 128 • Allowed characters: the complete ASCII-character set • Checksum: optional (modulo 103) • Length: variable There are no particular options for this barcode. 99 .CHAPTER TWENTYONE DESCRIPTION OF SHIPPED BARCODES You will find below detailed information about all barcode types shipped by default with Zend Framework. 21.3 Zend\Barcode\Object\Codabar • Name: Codabar (or Code 2 of 7) • Allowed characters:‘0123456789-$:/. 21.+’ with ‘ABCD’ as start and stop characters • Checksum: none • Length: variable There are no particular options for this barcode.

Note: If the number of characters is lower than 2.Zend Framework 2 Documentation.1: Zend\Barcode\Object\Code25interleaved Options Option withBearerBars Data Type Boolean Default Value FALSE Description Draw a thick bar at the top and the bottom of the barcode. Zend\Barcode\Object\Ean2 will automatically prepend the missing zero to the barcode text. Release 2. 100 Chapter 21. and has the same particulars and options. 21. Note: If the number of characters is not even. Description of shipped barcodes .0.6 Zend\Barcode\Object\Ean2 This barcode extends Zend\Barcode\Object\Ean5 (EAN 5).4 Zend\Barcode\Object\Code25 • Name: Code 25 (or Code 2 of 5 or Code 25 Industrial) • Allowed characters:‘0123456789’ • Checksum: optional (modulo 10) • Length: variable There are no particular options for this barcode.5 Zend\Barcode\Object\Code25interleaved This barcode extends Zend\Barcode\Object\Code25 (Code 2 of 5). 21. and has the same particulars and options. Zend\Barcode\Object\Code25interleaved will automatically prepend the missing zero to the barcode text.6 21. and adds the following: • Name: Code 2 of 5 Interleaved • Allowed characters:‘0123456789’ • Checksum: optional (modulo 10) • Length: variable (always even number of characters) Available options include: Table 21. and adds the following: • Name: EAN-2 • Allowed characters:‘0123456789’ • Checksum: only use internally but not displayed • Length: 2 characters There are no particular options for this barcode.

6 21. 21.7 Zend\Barcode\Object\Ean5 This barcode extends Zend\Barcode\Object\Ean13 (EAN 13).7.9 Zend\Barcode\Object\Ean13 • Name: EAN-13 • Allowed characters:‘0123456789’ • Checksum: mandatory (modulo 10) • Length: 13 characters (including checksum) 21. and has the same particulars and options. Release 2. Zend\Barcode\Object\Ean8 will automatically prepend the missing zero to the barcode text.8 Zend\Barcode\Object\Ean8 This barcode extends Zend\Barcode\Object\Ean13 (EAN 13). and adds the following: • Name: EAN-5 • Allowed characters:‘0123456789’ • Checksum: only use internally but not displayed • Length: 5 characters There are no particular options for this barcode. Note: If the number of characters is lower than 8. 21. Zend\Barcode\Object\Ean5 101 . and adds the following: • Name: EAN-8 • Allowed characters:‘0123456789’ • Checksum: mandatory (modulo 10) • Length: 8 characters (including checksum) There are no particular options for this barcode. Note: If the number of characters is lower than 5.0.Zend Framework 2 Documentation. and has the same particulars and options. Zend\Barcode\Object\Ean5 will automatically prepend the missing zero to the barcode text.

Zend\Barcode\Object\Identcode will automatically prepend missing zeros to the barcode text. Note: If the number of characters is lower than 13.11 Zend\Barcode\Object\Identcode This barcode extends Zend\Barcode\Object\Code25interleaved (Code 2 of 5 Interleaved).12 Zend\Barcode\Object\Itf14 This barcode extends Zend\Barcode\Object\Code25interleaved (Code 2 of 5 Interleaved). 21. 21.10 Zend\Barcode\Object\Code39 • Name: Code 39 • Allowed characters:‘0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -. and inherits some of its capabilities.$/+%’ • Checksum: optional (modulo 43) • Length: variable Note: Zend\Barcode\Object\Code39 will automatically add the start and stop characters (‘*’) for you.0. and inherits some of its capabilities. • Name: ITF-14 • Allowed characters:‘0123456789’ 102 Chapter 21. Release 2. 21.6 There are no particular options for this barcode. There are no particular options for this barcode. Zend\Barcode\Object\Ean13 will automatically prepend the missing zero to the barcode text. it also has a few particulars of its own. Note: If the number of characters is lower than 12. Description of shipped barcodes . it also has a few particulars of its own. The option withQuietZones has no effect with this barcode.Zend Framework 2 Documentation. • Name: Identcode (Deutsche Post Identcode) • Allowed characters:‘0123456789’ • Checksum: mandatory (modulo 10 different from Code25) • Length: 12 characters (including checksum) There are no particular options for this barcode.

it also has a few particulars of its own.0. Zend\Barcode\Object\Itf14 will automatically prepend missing zeros to the barcode text. Zend\Barcode\Object\Leitcode will automatically prepend missing zeros to the barcode text. 10 or 12 characters (including checksum) There are no particular options for this barcode. Zend\Barcode\Object\Leitcode 103 . Note: If the number of characters is lower than 14. 21. 21.6 • Checksum: mandatory (modulo 10) • Length: 14 characters (including checksum) There are no particular options for this barcode. 21. 21. • Name: Leitcode (Deutsche Post Leitcode) • Allowed characters:‘0123456789’ • Checksum: mandatory (modulo 10 different from Code25) • Length: 14 characters (including checksum) There are no particular options for this barcode.14 Zend\Barcode\Object\Planet • Name: Planet (PostaL Alpha Numeric Encoding Technique) • Allowed characters:‘0123456789’ • Checksum: mandatory (modulo 10) • Length: 12 or 14 characters (including checksum) There are no particular options for this barcode.15 Zend\Barcode\Object\Postnet • Name: Postnet (POSTal Numeric Encoding Technique) • Allowed characters:‘0123456789’ • Checksum: mandatory (modulo 10) • Length: 6.Zend Framework 2 Documentation. Release 2.13 Zend\Barcode\Object\Leitcode This barcode extends Zend\Barcode\Object\Identcode (Deutsche Post Identcode). 7. Note: If the number of characters is lower than 14.13. and inherits some of its capabilities.

Release 2. Zend\Barcode\Object\Upce will automatically prepend missing zeros to the barcode text. • Name: UPC-A (Universal Product Code) • Allowed characters:‘0123456789’ • Checksum: mandatory (modulo 10) • Length: 12 characters (including checksum) There are no particular options for this barcode. Description of shipped barcodes .Zend Framework 2 Documentation. The first character of the text to encode is the system (0 or 1). 21. and inherits some of its capabilities. 104 Chapter 21.17 Zend\Barcode\Object\Upca This barcode extends Zend\Barcode\Object\Ean13 (EAN-13).16 Zend\Barcode\Object\Royalmail • Name: Royal Mail or RM4SCC (Royal Mail 4-State Customer Code) • Allowed characters:‘0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ’ • Checksum: mandatory • Length: variable There are no particular options for this barcode.0. The option withQuietZones has no effect with this barcode. it also has a few particulars of its own.6 21. it also has a few particulars of its own. 21. • Name: UPC-E (Universal Product Code) • Allowed characters:‘0123456789’ • Checksum: mandatory (modulo 10) • Length: 8 characters (including checksum) There are no particular options for this barcode.18 Zend\Barcode\Object\Upce This barcode extends Zend\Barcode\Object\Upca (UPC-A). Note: If the number of characters is lower than 8. Zend\Barcode\Object\Upca will automatically prepend missing zeros to the barcode text. and inherits some of its capabilities. Note: If the number of characters is lower than 12.

18.Zend Framework 2 Documentation. 21. Zend\Barcode\Object\Upce will automatically replace it by 0.6 Note: If the first character of the text to encode is not 0 or 1. Zend\Barcode\Object\Upce 105 . Release 2. The option withQuietZones has no effect with this barcode.0.

Description of shipped barcodes .Zend Framework 2 Documentation.0. Release 2.6 106 Chapter 21.

$renderer->setOptions($options). // Case 2 $renderer = new Renderer\Pdf(). // Case 1 $renderer = new Renderer\Pdf($options). These options can be set in three ways: • As an array or a Traversable object passed to the constructor. we will use the term “unit. • As an array passed to the setOptions() method. // Case 3 $renderer = new Renderer\Pdf(). $renderer->setTopOffset(10). All options have a correspondant getter prefixed with “get” (e. “getBarHeight”). • As discrete values passed to individual setters. the values have no unit.1 Common Options In the following list.” For example.g. “barHeight” => “setBarHeight”).CHAPTER TWENTYTWO ZEND\BARCODE RENDERERS Renderers have some common options. Available options are: 107 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 22. $options = array(’topOffset’ => 10).” The real units depend on the rendering support. the default value of the “thin bar” is “1 unit.g. Different ways to parameterize a renderer object use Zend\Barcode\Renderer. The individual setters are obtained by uppercasing the initial letter of the option and prefixing the name with “set” (e.

Top position of the barcode inside the renderer. Size of a rendering module in the support.0. “jpg” or “gif”. The barcode object to render.3 Zend\Barcode\Renderer\Pdf The PDF renderer will draw the instruction list of the barcode object in a PDF document. “center” or “right”. this value will override the “verticalPosition” option. this value will override the “horizontalPosition” option.6 Table 22. Zend\Barcode\Renderer\Image returns “image”). 108 Chapter 22. 22. the width will be calculated by the barcode object. Release 2. The default width of a module is 1 pixel. Zend\Barcode Renderers . Whether or not to automatically render errors. Can be useful with PDF or if the setWidth() method is used with an image renderer. If used. for example. String String Integer Integer Boolean “top” 0 0 FALSE Float 1 Zend\Barcode\Object NULL An additional getter exists: getType(). the height will be calculated by the barcode object. 22. There are no particular options for this renderer.Zend Framework 2 Documentation.5 point.2: Zend\Barcode\Renderer\Image Options Option height width imageType Data Type Integer Integer String Default Value 0 0 “png” Description Allow you to specify the height of the result image. “jpeg”. Specify the image format. Can be “png”. if you need to extend the Namespace renderers “left” Can be “left”. It returns the name of the renderer class without the namespace (e. Allow you to specify the width of the result image. “middle” or “bottom”. Can be useful with PDF or if the setHeight() method is used with an image renderer. Can be “top”.1: Common Options Option rendererNamespace horizontalPosition verticalPosition leftOffset topOffset automaticRenderError moduleSize barcode Data Type String Default Description Value Zend\Barcode\Renderer of the renderer.g. Top position of the barcode inside the renderer. Note that some errors (or exceptions) can not be rendered. If “0”. If used.2 Zend\Barcode\Renderer\Image The Image renderer will draw the instruction list of the barcode object in an image resource. Available options are: Table 22. the provided barcode object will be replaced with an Error representation. If an exception occurs. The default width of a module is 0. If “0”. The component requires the GD extension.

which comes with basic logic. ). // Via factory: $cache = StorageFactory::factory(array( ’adapter’ => ’apc’.2 Quick Start Caching adapters can either be created from the provided Zend\Cache\StorageFactory factory. you need to catch them manually or you can use the plugin Zend\Cache\Storage\Plugin\ExceptionHandler to automatically catch them and redirect exceptions into a log file using the option “exception_callback”. or by simply instantiating one of the Zend\Cache\Storage\Adapter\*classes. They come with tons of methods to read. write and modify stored items and to get information about stored items and the storage.CHAPTER TWENTYTHREE ZEND\CACHE\STORAGE\ADAPTER 23. Configuration is handled by either Zend\Cache\Storage\Adapter\AdapterOptions. To make life easier. these are then passed to an options class instance).1 Overview Storage adapters are wrappers for real storage resources such as memory and the filesystem. Alternately. or an adapter-specific options class if it exists. or alternately pass an associative array of options in either place (internally. Note: Many methods throw exceptions Because many caching methods can throw exceptions. 23. using the well known adapter pattern. 1 2 3 4 5 6 7 8 9 use Zend\Cache\StorageFactory. You may pass the options instance to the class at instantiation or via the setOptions() method. the Zend\Cache\StorageFactory comes with a factory method to create an adapter and create/add all requested plugins at once. All adapters implement the interface Zend\Cache\Storage\StorageInterface and most extend Zend\Cache\Storage\Adapter\AbstractAdapter. 109 . you can pass either the options instance or associative array to the Zend\Cache\StorageFactory::factory method. ’plugins’ => array( ’exception_handler’ => array(’throw_exceptions’ => false). )).

If item exists set parameter $success to true. 23. Alternately. If item can’t load set parameter $success to false and returns null. $plugin = StorageFactory::pluginFactory(’exception_handler’. $cache->addPlugin($plugin). array( ’throw_exceptions’ => false. Return type boolean 110 Chapter 23.6 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // Alternately: $cache = StorageFactory::adapterFactory(’apc’). you can pass either the options instance or associative array to the Zend\Cache\StorageFactory::factory method. or alternately pass an associative array of options in either place (internally. getItem(string $key. boolean & $success = null. The following configuration options are defined by Zend\Cache\Storage\Adapter\AdapterOptions and are available for every supported adapter.0.4 The StorageInterface The Zend\Cache\Storage\StorageInterface is the basic interface implemented by all storage adapters. Option ttl namespace key_pattern readable writable Data Type integer string null string boolean boolean Default Value 0 “zfcache” null true true Description Time to live The “namespace” in which cache items will live Pattern against which to validate cache keys Enable/Disable reading data from cache Enable/Disable writing data to cache 23. )). mixed & $casToken = null) Load an item with the given $key. $plugin = new Zend\Cache\Storage\Plugin\ExceptionHandler(array( ’throw_exceptions’ => false.Zend Framework 2 Documentation. Zend\Cache\Storage\Adapter . Return type mixed getItems(array $keys) Load all items given by $keys returning key-value pairs. )).3 Basic Configuration Options Basic configuration is handled by either Zend\Cache\Storage\Adapter\AdapterOptions. these are then passed to an options class instance). Adapter-specific configuration options are descriped on adapter level below. set parameter $casToken and returns mixed value of item. $cache->addPlugin($plugin). // Or manually: $cache = new Zend\Cache\Storage\Adapter\Apc(). or an adapter-specific options class if it exists. Release 2. You may pass the options instance to the class at instantiation or via the setOptions() method. Return type array hasItem(string $key) Test if an item exists.

string $key. mixed $value) Store an item.Zend Framework 2 Documentation. Return type boolean touchItems(array $keys) Reset lifetime of multiple items. Return type boolean checkAndSetItem(mixed $token. mixed $value) Replace an item. Return type boolean addItems(array $keyValuePairs) Add multiple items. Return type boolean addItem(string $key.6 hasItems(array $keys) Test multiple items. Return type boolean 23.4. Return type array|boolean getMetadatas(array $keys) Get multiple metadata. Return type boolean replaceItem(string $key. The StorageInterface 111 . It uses the token received from getItem() to check if the item has changed before overwriting it. Release 2. mixed $value) Set item only if token matches. Return type string[] getMetadata(string $key) Get metadata of an item. Return type array setItem(string $key. Return type boolean setItems(array $keyValuePairs) Store multiple items. Return type boolean touchItem(string $key) Reset lifetime of an item.0. Return type boolean replaceItems(array $keyValuePairs) Replace multiple items. mixed $value) Add an item. Return type boolean removeItem(string $key) Remove an item.

Zend\Cache\Storage\Adapter . int $value) Increment an item. int $value) Decrement an item. Return type boolean decrementItem(string $key. Return type boolean getCapabilities() Capabilities of this storage. getAvailableSpace() Get available space in bytes. Return type integer|float 23.7 The ClearByNamespaceInterface The Zend\Cache\Storage\ClearByNamespaceInterface implements a method to clear all items of a given namespace. Release 2. 112 Chapter 23. Return type integer|float 23.6 The TotalSpaceCapableInterface The Zend\Cache\Storage\TotalSpaceCapableInterface implements a method to make it possible getting the total space of the storage.6 removeItems(array $keys) Remove multiple items.Zend Framework 2 Documentation. clearByNamespace(string $namespace) Remove items of given namespace. Return type Zend\Cache\Storage\Capabilities 23. Return type integer|boolean incrementItems(array $keyValuePairs) Increment multiple items. Return type boolean incrementItem(string $key.0.5 The AvailableSpaceCapableInterface The Zend\Cache\Storage\AvailableSpaceCapableInterface implements a method to make it possible getting the current available space of the storage. Return type interger|boolean decrementItems(array $keyValuePairs) Decrement multiple items. getTotalSpace() Get total space in bytes.

Return type Zend\Cache\Storage\IteratorInterface 23. flush() Flush the whole storage.8 The ClearByPrefixInterface The Zend\Cache\Storage\ClearByPrefixInterface implements a method to clear all items of a given prefix (within the current configured namespace). optimize() Optimize the storage. Return type boolean 23.0.Zend Framework 2 Documentation.11 The IterableInterface The Zend\Cache\Storage\IterableInterface implements a method to get an iterator to iterate over items of the storage. Return type boolean 23. clearByPrefix(string $prefix) Remove items matching given prefix. The ClearByPrefixInterface 113 . Return type boolean 23.12 The OptimizableInterface The Zend\Cache\Storage\OptimizableInterface implements a method to run optimization processes on the storage. Release 2. clearExpired() Remove expired items. getIterator() Get an Iterator. Return type boolean 23.10 The FlushableInterface The Zend\Cache\Storage\FlushableInterface implements a method to flush the complete storage.9 The ClearExpiredInterface The Zend\Cache\Storage\ClearExpiredInterface implements a method to clear all expired items (within the current configured namespace). It extends IteratorAggregate so it’s possible to directly iterate over the storage using foreach.8.6 Return type boolean 23.

string[] $tags) Set tags to an item by given key. object (serialized) internal_key. This adapter implements the following interfaces: • Zend\Cache\Storage\StorageInterface • Zend\Cache\Storage\AvailableSpaceCapableInterface • Zend\Cache\Storage\ClearByNamespaceInterface • Zend\Cache\Storage\ClearByPrefixInterface • Zend\Cache\Storage\FlushableInterface • Zend\Cache\Storage\IterableInterface • Zend\Cache\Storage\TotalSpaceCapableInterface Table 23.14 The Apc Adapter The Zend\Cache\Storage\Adapter\Apc adapter stores cache items in shared memory through the required PHP extension APC (Alternative PHP Cache). boolean $disjunction = false) Remove items matching given tags. array (serialized). Return type string[]|false clearByTags(string[] $tags. Zend\Cache\Storage\Adapter .13 The TaggableInterface The Zend\Cache\Storage\TaggableInterface implements methods to mark items with one or more tags and to clean items matching tags.0. hits. ttl 1 0 true 1 <ini value of apc. size.6 23. Release 2. atime. (An empty array will remove all tags) Return type boolean getTags(string $key) Get tags of an item by given key. integer. If $disjunction is true only one of the given tags must match else all given tags must match.use_request_time> false 5182 true <Option value of namespace_separator> 114 Chapter 23. string.Zend Framework 2 Documentation.1: Capabilities Capability supportedDatatypes supportedMetadata minTtl maxTtl staticTtl ttlPrecision useRequestTime expiredRead maxKeyLength namespaceIsPrefix namespaceSeparator Value null. ctime. Return type boolean 23. setTags(string $key. mtime. double. boolean. rtime.

4: Adapter specific options Name namespace_separator pathname mode handler Data Type string string string string Default Value ”:” “” “c” “flatfile” Describtion A separator for the namespace and prefix Pathname to the database file The mode to open the database Please read dba_open for more information The name of the handler which shall be used for accessing the database.2: Adapter specific options Name namespace_separator Data Type string Default Value ”:” Describtion A separator for the namespace and prefix 23. Release 2. double => string <none> 0 0 true <Option value of namespace_separator> Table 23. 23. null => string.15 The Dba Adapter The Zend\Cache\Storage\Adapter\Dba adapter stores cache items into dbm like databases using the required PHP extension dba.15.Zend Framework 2 Documentation. The Dba Adapter 115 .0.6 Table 23. Note: This adapter doesn’t support automatically expire items Because of this adapter doesn’t support automatically expire items it’s very important to clean outdated items by self.3: Capabilities Capability supportedDatatypes supportedMetadata minTtl maxKeyLength namespaceIsPrefix namespaceSeparator Value string. integer => string. boolean => string. This adapter implements the following interfaces: • Zend\Cache\Storage\StorageInterface • Zend\Cache\Storage\AvailableSpaceCapableInterface • Zend\Cache\Storage\ClearByNamespaceInterface • Zend\Cache\Storage\ClearByPrefixInterface • Zend\Cache\Storage\FlushableInterface • Zend\Cache\Storage\IterableInterface • Zend\Cache\Storage\OptimizableInterface • Zend\Cache\Storage\TotalSpaceCapableInterface Table 23.

5: Capabilities Capability supportedDatatypes supportedMetadata minTtl maxTtl staticTtl ttlPrecision useRequestTime expiredRead maxKeyLength namespaceIsPrefix namespaceSeparator Value string. ctime 1 0 false 1 false true 251 true <Option value of namespace_separator> 116 Chapter 23. This adapter implements the following interfaces: • Zend\Cache\Storage\StorageInterface • Zend\Cache\Storage\AvailableSpaceCapableInterface • Zend\Cache\Storage\ClearByNamespaceInterface • Zend\Cache\Storage\ClearByPrefixInterface • Zend\Cache\Storage\ClearExpiredInterface • Zend\Cache\Storage\FlushableInterface • Zend\Cache\Storage\IterableInterface • Zend\Cache\Storage\OptimizableInterface • Zend\Cache\Storage\TaggableInterface • Zend\Cache\Storage\TotalSpaceCapableInterface Table 23.0. filespec. integer => string. atime.6 23.16 The Filesystem Adapter The Zend\Cache\Storage\Adapter\Filesystem adapter stores cache items into the filesystem.Zend Framework 2 Documentation. null => string. Zend\Cache\Storage\Adapter . boolean => string. Release 2. double => string mtime.

integer.7: Capabilities Capability supportedDatatypes supportedMetadata minTtl maxTtl staticTtl ttlPrecision useRequestTime expiredRead maxKeyLength namespaceIsPrefix namespaceSeparator Value null.6: Adapter specific options Name namespace_separator cache_dir clear_stat_cache dir_level dir_permission file_locking file_permission key_pattern no_atime no_ctime umask Data Type string string boolean integer integer false boolean integer false string boolean boolean integer false Default Value ”:” “” true 1 0700 true 0600 Describtion A separator for the namespace and prefix Directory to store cache files Call clearstatcache() enabled? Defines how much sub-directaries should be created Set explicit permission on creating new directories Lock files on writing Set explicit permission on creating new files /^[a-z0-9_\+\-]*$/Di Validate key against pattern true Don’t get ‘fileatime’ as ‘atime’ on metadata true Don’t get ‘filectime’ as ‘ctime’ on metadata false Use umask to set file and directory permissions 23. double. Release 2.17.6 Table 23. This adapter implements the following interfaces: • Zend\Cache\Storage\StorageInterface • Zend\Cache\Storage\AvailableSpaceCapableInterface • Zend\Cache\Storage\FlushableInterface • Zend\Cache\Storage\TotalSpaceCapableInterface Table 23. The Memcached Adapter 117 . object (serialized) <none> 1 0 true 1 false false 255 true <none> 23.0. boolean. string. It’s using the required PHP extension memcached which is based on Libmemcached. array (serialized).Zend Framework 2 Documentation.17 The Memcached Adapter The Zend\Cache\Storage\Adapter\Memcached adapter stores cache items over the memcached protocol.

setoption.8: Adapter specific options Default Value servers array [] lib_options array [] Name Data Type Describtion List of servers in [] = array(string host. integer. Zend\Cache\Storage\Adapter . null.net/manual/memcached. This adapter implements the following interfaces: • Zend\Cache\Storage\StorageInterface • Zend\Cache\Storage\AvailableSpaceCapableInterface • Zend\Cache\Storage\ClearByPrefixInterface • Zend\Cache\Storage\ClearExpiredInterface • Zend\Cache\Storage\FlushableInterface • Zend\Cache\Storage\IterableInterface • Zend\Cache\Storage\TaggableInterface • Zend\Cache\Storage\TotalSpaceCapableInterface Table 23.6 Table 23. boolean. double. The array value is the option value Please read this<http://php.Zend Framework 2 Documentation. integer port) Assosiative array of Libmemcached options were the array key is the option name (without the prefix “OPT_”) or the constant value.9: Capabilities Capability supportedDatatypes supportedMetadata minTtl maxTtl staticTtl ttlPrecision useRequestTime expiredRead maxKeyLength namespaceIsPrefix Value string.18 The Memory Adapter The Zend\Cache\Storage\Adapter\Memory adapter stores cache items into the PHP process using an array.0.php> for more information 23. object. Release 2. array. resource mtime 1 <Value of PHP_INT_MAX> false 0.05 false true 0 false 118 Chapter 23.

19 The WinCache Adapter The Zend\Cache\Storage\Adapter\WinCache adapter stores cache items into shared memory through the required PHP extension WinCache.19.11: Capabilities Capability supportedDatatypes supportedMetadata minTtl maxTtl staticTtl ttlPrecision useRequestTime expiredRead namespaceIsPrefix namespaceSeparator Value null. size 1 0 true 1 <ini value of apc.10: Adapter specific options Name memory_limit Data Type string integer Default Value <50% of ini memory_limit> value Describtion Limit of how much memory can PHP allocate to allow store items into this adapter • If the used memory of PHP exceeds this limit an OutOfSpaceException will be thrown. double. boolean.6 Table 23.Zend Framework 2 Documentation. 23. integer. array (serialized). The WinCache Adapter 119 . object (serialized) internal_key. This adapter implements the following interfaces: • Zend\Cache\Storage\StorageInterface • Zend\Cache\Storage\AvailableSpaceCapableInterface • Zend\Cache\Storage\FlushableInterface • Zend\Cache\Storage\TotalSpaceCapableInterface Table 23. the value is measured in bytes (Shorthand notation may also be used) Note: All stored items will be lost after terminating the script. string. Release 2.use_request_time> false true <Option value of namespace_separator> 23.0. ttl. • A number less or equal 0 will disable the memory limit • When a number is used. hits.

This adapter implements the following interfaces: • Zend\Cache\Storage\StorageInterface • Zend\Cache\Storage\ClearByNamespaceInterface • Zend\Cache\Storage\FlushableInterface • Zend\Cache\Storage\TotalSpaceCapableInterface 120 Chapter 23.6 Table 23. Zend\Cache\Storage\Adapter . array (serialized).0. integer.Zend Framework 2 Documentation. This adapter implements the following interfaces: • Zend\Cache\Storage\StorageInterface • Zend\Cache\Storage\AvailableSpaceCapableInterface • Zend\Cache\Storage\ClearByNamespaceInterface • Zend\Cache\Storage\FlushableInterface • Zend\Cache\Storage\TotalSpaceCapableInterface Table 23. object (serialized) <none> 1 0 0 true 1 false false true :: 23.21 The ZendServerShm Adapter The Zend\Cache\Storage\Adapter\ZendServerShm adapter stores cache items in shared memory through the Zend Server Data Caching API. double.20 The ZendServerDisk Adapter This Zend\Cache\Storage\Adapter\ZendServerDisk adapter stores cache items on filesystem through the Zend Server Data Caching API. Release 2. boolean. string.12: Adapter specific options Name namespace_separator Data Type string Default Value ”:” Describtion A separator for the namespace and prefix 23.13: Capabilities Capability supportedDatatypes supportedMetadata minTtl maxTtl maxKeyLength staticTtl ttlPrecision useRequestTime expiredRead namespaceIsPrefix namespaceSeparator Value null.

14: Capabilities Capability supportedDatatypes supportedMetadata minTtl maxTtl maxKeyLength staticTtl ttlPrecision useRequestTime expiredRead namespaceIsPrefix namespaceSeparator Value null. ). if (!$success) { $result = doExpansiveStuff(). Examples 121 .22 Examples Basic usage $cache = \Zend\Cache\StorageFactory::factory(array( ’adapter’ => array( ’name’ => ’filesystem’ ). double. $result = $cache->getItem($key. array (serialized). ’plugins’ => array( // Don’t throw exceptions on cache errors ’exception_handler’ => array( 1 2 3 4 5 6 7 8 9 10 11 12 13 23.22.0. boolean. ) )). } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Get multiple rows from db // Instantiate the cache instance using a namespace for the same type of items $cache = \Zend\Cache\StorageFactory::factory(array( ’adapter’ => array( ’name’ => ’filesystem’ // With a namespace we can indicate the same type of items // -> So we can simple use the db id as cache key ’options’ => array( ’namespace’ => ’dbtable’ ). $success). $cache->setItem($key. string.Zend Framework 2 Documentation.6 Table 23. ’plugins’ => array( // Don’t throw exceptions on cache errors ’exception_handler’ => array( ’throw_exceptions’ => false ). Release 2. integer. $key = ’unique-cache-key’. object (serialized) <none> 1 0 0 true 1 false false true :: 23. $result).

Zend\Cache\Storage\Adapter . $query = ’SELECT * FROM dbtable WHERE id IN (’ . if (count($results) < count($ids)) { // Load rows from db if loading from cache failed $missingIds = array_diff($ids. // merge results from cache and db $results = array_merge($results. $missingResults = array(). } // Update cache items of the loaded rows from db $cache->setItems($missingResults). foreach ($pdo->query($query. array_keys($results)). $results = $cache->getItems($ids). ’)’. 2).0.’. implode(’.6 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ’throw_exceptions’ => false ). Release 2. PDO::FETCH_ASSOC) as $row) { $missingResults[ $row[’id’] ] = $row. $missingResults). // Load two rows from cache if possible $ids = array(1.Zend Framework 2 Documentation. $missingIds) . // We store database rows on filesystem so we need to serialize them ’Serializer’ ) )). } 122 Chapter 23.

24. you can use the method getCapabilities() of the storage adapter but only the storage adapter and its plugins have permissions to change them. see the examples for details. string $metadata) Set supported metadata.CHAPTER TWENTYFOUR ZEND\CACHE\STORAGE\CAPABILITIES 24.2 Available Methods __construct(Zend\Cache\Storage\StorageInterface $storage. you can also change capabilities because you have access to the marker object and can create your own marker to instantiate a new object of Zend\Cache\Storage\Capabilities. stdClass $marker. you can subscribe to the “change” event to get notifications. Return type array setSupportedMetadata(stdClass $marker. Return type Zend\Cache\Storage\Capabilities getMinTtl() Get minimum supported time-to-live. array $capabilities = array(). Return type array setSupportedDatatypes(stdClass $marker. If you are writing your own plugin or adapter. (Returning 0 means items never expire) Return type integer 123 . Zend\Cache\Storage\Capabilities|null $baseCapabilities = null) Constructor getSupportedDatatypes() Get supported datatypes. for example.1 Overview Storage capabilities describes how a storage adapter works and which features it supports. array $datatypes) Set supported datatypes. Because capabilities are mutable. To get capabilities of a storage adapter. by changing some options. Return type Zend\Cache\Storage\Capabilities getSupportedMetadata() Get supported metadata.

Return type Zend\Cache\Storage\Capabilities getExpiredRead() Get flag indicating if expired items are readable.6 setMinTtl(stdClass $marker. Return type Zend\Cache\Storage\Capabilities getMaxTtl() Get maximum supported time-to-live. 124 Chapter 24. Return type Zend\Cache\Storage\Capabilities getUseRequestTime() Get the “use request time” flag status. Zend\Cache\Storage\Capabilities .Zend Framework 2 Documentation. int $maxKeyLength) Set maximum key length. boolean $flag) Set if the time-to-live is handled statically (on write) or dynamically (on read). Return type Zend\Cache\Storage\Capabilities getNamespaceIsPrefix() Get if namespace support is implemented as a key prefix. Return type float setTtlPrecision(stdClass $marker. int $minTtl) Set minimum supported time-to-live. Release 2. or dynamic (on read). Return type Zend\Cache\Storage\Capabilities getTtlPrecision() Get time-to-live precision. float $ttlPrecision) Set time-to-live precision. boolean $flag) Set if expired items are readable. Return type Zend\Cache\Storage\Capabilities getMaxKeyLength() Get maximum key length. Return type boolean setExpiredRead(stdClass $marker. Return type boolean setUseRequestTime(stdClass $marker. Return type integer setMaxTtl(stdClass $marker. boolean $flag) Set the “use request time” flag. Return type boolean setStaticTtl(stdClass $marker. int $maxTtl) Set maximum supported time-to-live.0. Return type integer setMaxKeyLength(stdClass $marker. Return type Zend\Cache\Storage\Capabilities getStaticTtl() Is the time-to-live handled static (on write).

function($event) { echo count($event->getParams()) . $supportedDatatypes = $cache->getCapabilities()->getSupportedDatatypes().6 Return type boolean setNamespaceIsPrefix(stdClass $marker. ’ capabilities changed’. } else { $cache->set($key.3. Examples 125 . serialize($object)). Return type Zend\Cache\Storage\Capabilities 24. $cache = StorageFactory::adapterFactory(’filesystem’. // now you can run specific stuff in base of supported feature if ($supportedDatatypes[’object’]) { $cache->set($key. string $separator) Set the namespace separator if namespace is implemented as a key prefix. Return type Zend\Cache\Storage\Capabilities getNamespaceSeparator() Get namespace separator if namespace is implemented as a key prefix. )). array( ’no_atime’ => false. $cache = StorageFactory::adapterFactory(’filesystem’).Zend Framework 2 Documentation. }). // change option which changes capabilities $cache->getOptions()->setNoATime(true). Release 2. boolean $flag) Set if namespace support is implemented as a key prefix. // Catching capability changes $cache->getEventManager()->attach(’capability’.0. Return type string setNamespaceSeparator(stdClass $marker.3 Examples Get storage capabilities and do specific stuff in base of it use Zend\Cache\StorageFactory. } 1 2 3 4 5 6 7 8 9 10 11 Listen to change event use Zend\Cache\StorageFactory. $object). 1 2 3 4 5 6 7 8 9 10 11 12 13 24.

0. Zend\Cache\Storage\Capabilities .6 126 Chapter 24.Zend Framework 2 Documentation. Release 2.

// Via factory: $cache = StorageFactory::factory(array( ’adapter’ => ’filesystem’. // Alternately: $cache = StorageFactory::adapterFactory(’filesystem’). To make life easier. $cache->addPlugin($plugin). 127 . $cache->addPlugin($plugin).events).2 Quick Start Storage plugins can either be created from Zend\Cache\StorageFactory with the pluginFactory. )).post . // Or manually: $cache = new Zend\Cache\Storage\Adapter\Filesystem(). 25. changing the result (with setResult of Zend\Cache\Storage\PostEvent) and catching exceptions (with Zend\Cache\Storage\ExceptionEvent). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 use Zend\Cache\StorageFactory.1 Overview Cache storage plugins are objects to add missing functionality or to influence behavior of a storage adapter. the Zend\Cache\StorageFactory comes with the method factory to create an adapter and all given plugins at once. skipping and directly return a result (using stopPropagation). ’plugins’ => array(’serializer’).CHAPTER TWENTYFIVE ZEND\CACHE\STORAGE\PLUGIN 25. $plugin = new Zend\Cache\Storage\Plugin\Serializer(). The plugins listen to events the adapter triggers and can change called method arguments (*. $plugin = StorageFactory::pluginFactory(’serializer’). or by simply instantiating one of the Zend\Cache\Storage\Plugin\*classes.

4 The ExceptionHandler Plugin The Zend\Cache\Storage\Adapter\ExceptionHandler plugin catches all exceptions thown on reading or writing to cache and sends the exception to a defined callack function. addItem() and addItems(). 25.6 25. Table 25. setItems().6 The OptimizeByFactor Plugin The Zend\Cache\Storage\Adapter\OptimizeByFactor plugin calls the storage method optimize() randomly (by factor) after removing items from cache.Zend Framework 2 Documentation.0. Table 25. Table 25.5 The IgnoreUserAbort Plugin The Zend\Cache\Storage\Adapter\IgnoreUserAbort plugin ignores script terminations by users until write operations to cache finished.2: Plugin specific options Name Data Type Default Value null true Describtion Callback will be called on an exception and get the exception as argument Re-throw catched excaptions excepcallable tion_callback null throw_exceptions boolean 25.3: Plugin specific options Name exit_on_abort Data Type Default Value Describtion boolean |true |Terminate script execution if user abort the script 25.1: Plugin specific options Name clearing_factor Data Type integer Default Value 0 Describtion The automatic clearing factor Note: ** The ClearExpiredInterface is required ** The storage have to implement the Zend\Cache\Storage\ClearExpiredInterface to work with this plugin. Table 25. It’s configurable if the plugin should re-throw the catched exception. Release 2. Zend\Cache\Storage\Plugin .4: Plugin specific options Name optimizing_factor Data Type integer Default Value 0 Describtion The automatic optimization factor 128 Chapter 25.3 The ClearExpiredByFactor Plugin The Zend\Cache\Storage\Adapter\ClearExpiredByFactor plugin calls the storage method clearExpired() randomly (by factor) after every call of setItem().

Return type void detach(Zend\EventManager\EventManagerInterface $events) Defined by Zend\EventManager\ListenerAggregateInterface. Return type void 25. Return type Zend\Cache\Storage\Plugin\PluginOptions attach(Zend\EventManager\EventManagerInterface $events) Defined by Zend\EventManager\ListenerAggregateInterface. Table 25. attach one or more listeners.Zend Framework 2 Documentation.5: Plugin specific options Name serializer Data Type Default Value Describtion null string null The serializer to use Zend\Serializer\Adapter\AdapterInterface • If null use the default serializer • If string instantiate the serializer with serializer_options array [] Array of serializer options used to instantiate the serializer serializer_options 25.7 The Serializer Plugin The Zend\Cache\Storage\Adapter\Serializer plugin will serialize data on writing to cache and unserialize on reading.8 Available Methods setOptions(Zend\Cache\Storage\Plugin\PluginOptions $options) Set options.0. 25. Return type Zend\Cache\Storage\Plugin\PluginInterface getOptions() Get options. So it’s possible to store different datatypes into cache storages only support strings. Release 2. The Serializer Plugin 129 . detach all previously attached listeners.6 Note: ** The OptimizableInterface is required ** The storage have to implement the Zend\Cache\Storage\OptimizableInterface to work with this plugin.7.

pre’. // Method ’getItem’ with key ’cache-key’ started // Method ’getItem’ with key ’cache-key’ finished 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 130 Chapter 25. params[’key’]). } $this->handles = array(). return $this.6 25. Zend\Cache\Storage\Plugin . use Zend\Cache\Storage\Plugin\AbstractPlugin.post’. $this->handles[] = $events->attach(’getItem.Zend Framework 2 Documentation. } public function onGetItemPost(Event $event) { $params = $event->getParams(). array($this. use Zend\EventManager\EventManagerInterface. // This method have to attach all events required by this plugin public function attach(EventManagerInterface $events) { $this->handles[] = $events->attach(’getItem.9 Examples Basics of writing an own storage plugin use Zend\Cache\Storage\Event. array($this.0. } // This method have to attach all events required by this plugin public function detach(EventManagerInterface $events) { foreach ($this->handles as $handle) { $events->detach($handle). ’onGetItemPost’)). class MyPlugin extends AbstractPlugin { protected $handles = array(). $cache->addPlugin($plugin). } } // After defining this basic plugin we can instantiate and add it to an adapter instance $plugin = new MyPlugin(). echo sprintf("Method ’getItem’ with key ’%s’ finished\n". ’onGetItemPre’)). // Now on calling getItem our basic plugin should print the expacted output $cache->getItem(’cache-key’). Release 2. params[’key’]). echo sprintf("Method ’getItem’ with key ’%s’ started\n". return $this. } public function onGetItemPre(Event $event) { $params = $event->getParams().

26. Please read documentation of specific patterns to get more information. To configure a pattern object. the OutputCache pattern could assist. ObjectCache or ClassCache patterns to cache method and function calls. array( ’storage’ => ’apc’. All cache patterns implement the same interface.1 Overview Cache patterns are configurable objects to solve known performance bottlenecks. to cache output generation. or provide your options (either as an associative array or PatternOptions instance) as the second argument to the factory. It’s also possible to use a single instance of Zend\Cache\Pattern\PatternOptions and pass it to multiple pattern objects. Configuration is provided via the Zend\Cache\Pattern\PatternOptions class. or. you can set an instance of Zend\Cache\Pattern\PatternOptions with setOptions.2 Quick Start Pattern objects can either be created from the provided Zend\Cache\PatternFactory factory. // OR. For example you can use one of the CallbackCache. 131 . by simply instantiating one of the Zend\Cache\Pattern\*Cache classes. which can simply be instantiated with an associative array of options passed to the constructor. )). 1 2 3 4 5 26. Zend\Cache\Pattern\PatternInterface. $callbackCache->setOptions(new Zend\Cache\Pattern\PatternOptions(array( ’storage’ => ’apc’. 1 2 3 4 // Via the factory: $callbackCache = Zend\Cache\PatternFactory::factory(’callback’.CHAPTER TWENTYSIX ZEND\CACHE\PATTERN 26. ))). Each should be used only in the specific situations they are designed to address. and most extend the abstract class Zend\Cache\Pattern\AbstractPattern to implement basic logic.3 Available Methods The following methods are implemented by Zend\Cache\Pattern\AbstractPattern. the equivalent manual instantiation: $callbackCache = new Zend\Cache\Pattern\CallbackCache().

Zend\Cache\Pattern .Zend Framework 2 Documentation.0. Release 2. Return type Zend\Cache\Pattern\PatternInterface getOptions() Get all pattern options.6 setOptions(Zend\Cache\Pattern\PatternOptions $options) Set pattern options. Return type Zend\Cache\Pattern\PatternOptions 132 Chapter 26.

))). ’cache_output’ => true.CHAPTER TWENTYSEVEN ZEND\CACHE\PATTERN\CALLBACKCACHE 27.2 Quick Start For instantiation you can use the PatternFactory or do it manual: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Cache\PatternFactory. 27.3 Configuration Options Option storage Data Type Default Value <none> true Description The storage to write/read cached data Cache output of callback string array Zend\Cache\Storage\StorageInterface cache_outputboolean 133 . ’cache_output’ => true. )). // Via the factory: $callbackCache = PatternFactory::factory(’callback’. 27.1 Overview The callback cache pattern caches calls of non specific functions and methods given as a callback. // OR. array( ’storage’ => ’apc’. the equivalent manual instantiation: $callbackCache = new \Zend\Cache\Pattern\CallbackCache(). use Zend\Cache\Pattern\PatternOptions. $callbackCache->setOptions(new PatternOptions(array( ’storage’ => ’apc’.

Return type Zend\Cache\Pattern\PatternOptions 27.4 Available Methods call(callable $callback.6 27. Return type mixed generateKey(callable $callback. Release 2. Return type Zend\Cache\Pattern\CallbackCache getOptions() Get all pattern options. 1 2 3 4 5 134 Chapter 27. array( ’storage’ => ’apc’ )).Zend Framework 2 Documentation. Return type mixed __call(string $function. array $args = array()) Generate a unique key in base of a key representing the callback part and a key representing the arguments part. $callbackCache = PatternFactory::factory(’callback’.5 Examples Instantiating the callback cache pattern use Zend\Cache\PatternFactory. array $args = array()) Call the specified callback or get the result from cache. Return type string setOptions(Zend\Cache\Pattern\PatternOptions $options) Set pattern options. Zend\Cache\Pattern\CallbackCache .0. array $args) Function call handler.

array $args = array()) Call the specified method of the configured class. 28.3 Configuration Options Default Value storage string array <none> Zend\Cache\Storage\StorageInterface class string <none> cache_output boolean true cache_by_default boolean true class_cache_methods array [] class_non_cache_methods array [] Option Data Type Description The storage to write/read cached data The class name Cache output of callback Cache method calls by default List of methods to cache (If cache_by_default is disabled) List of methods to no-cache (If cache_by_default is enabled) 28.4 Available Methods call(string $method. It has the same methods but instead it generates the internally used callback in base of the configured class name and the given method name.2 Quick Start Instantiating the class cache pattern 1 2 3 4 5 6 use Zend\Cache\PatternFactory. 135 . array( ’class’ => ’MyClass’. ’storage’ => ’apc’ )).CHAPTER TWENTYEIGHT ZEND\CACHE\PATTERN\CLASSCACHE 28. $classCache = PatternFactory::factory(’class’. 28.1 Overview The ClassCache pattern is an extension to the CallbackCache pattern.

’storage’ => ’apc’. Return type mixed __set(string $name. Return type void __get(string $name) Get a static property of the configured class. Release 2.6 Return type mixed __call(string $method. // The feed reader doesn’t output anything // so the output don’t need to be catched and cached ’cache_output’ => false. array $args) Call the specified method of the configured class. array( ’class’ => ’Zend\Feed\Reader\Reader’. 1 2 3 4 5 6 7 8 9 136 Chapter 28. )). Return type string setOptions(Zend\Cache\Pattern\PatternOptions $options) Set pattern options. Return type Zend\Cache\Pattern\PatternOptions 28. Return type void generateKey(string $method. Zend\Cache\Pattern\ClassCache .Zend Framework 2 Documentation.5 Examples Caching of import feeds $cachedFeedReader = Zend\Cache\PatternFactory::factory(’class’. Return type Zend\Cache\Pattern\ClassCache getOptions() Get all pattern options.0. array $args = array()) Generate a unique key in base of a key representing the callback part and a key representing the arguments part. Return type mixed __isset(string $name) Checks if a static property of the configured class exists. Return type boolean __unset(string $name) Unset a static property of the configured class. mixed $value) Set a static property of the configured class.

Examples 137 .5. // OR $feed = $cachedFeedReader->import(’http://www. array(’http://www. Release 2.planet-php.planet-php.6 10 11 12 $feed = $cachedFeedReader->call("import".Zend Framework 2 Documentation. 28.0.net/rdf/’)).net/rdf/’).

Zend Framework 2 Documentation.0. Zend\Cache\Pattern\ClassCache .6 138 Chapter 28. Release 2.

$objectCache = PatternFactory::factory(’object’.3 Configuration Options Option storage object object_key Default Value string array <none> Zend\Cache\Storage\StorageInterface object <none> null string <Class name of object> boolean true boolean true array [] [] false Data Type Description The storage to write/read cached data The object to cache methods calls of A hopefully unique key of the object Cache output of callback Cache method calls by default List of methods to cache (If cache_by_default is disabled) List of methods to no-cache (If cache_by_default is enabled) Cache calls of magic object properties cache_output cache_by_default object_cache_methods obarray ject_non_cache_methods obboolean ject_cache_magic_properties 139 . $object = new stdClass().2 Quick Start Instantiating the object cache pattern 1 2 3 4 5 6 7 use Zend\Cache\PatternFactory.1 Overview The ObjectCache pattern is an extension to the CallbackCache pattern. 29.CHAPTER TWENTYNINE ZEND\CACHE\PATTERN\OBJECTCACHE 29. array( ’object’ => $object. It has the same methods but instead it generates the internally used callback in base of the configured object and the given method name. 29. ’storage’ => ’apc’ )).

0.4 Available Methods call(string $method. Return type mixed __set(string $name. Return type mixed __call(string $method.Zend Framework 2 Documentation. Zend\Cache\Pattern\ObjectCache .6 29. Return type Zend\Cache\Pattern\ObjectCache getOptions() Get all pattern options. Return type void __get(string $name) Get a property of the configured object. array $args = array()) Call the specified method of the configured object. Return type void generateKey(string $method.5 Examples Caching a filter 140 Chapter 29. Return type Zend\Cache\Pattern\PatternOptions 29. Release 2. Return type boolean __unset(string $name) Unset a property of the configured object. mixed $value) Set a property of the configured object. array $args = array()) Generate a unique key in base of a key representing the callback part and a key representing the arguments part. array $args) Call the specified method of the configured object. Return type mixed __isset(string $name) Checks if static property of the configured object exists. Return type string setOptions(Zend\Cache\Pattern\PatternOptions $options) Set pattern options.

.. ’object_key’ => ’RealpathFilter’. 29. ))./.5./. array( ’object’ => $filter.0.6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $filter = new Zend\Filter\RealPath()./mypath’)). Examples 141 ./mypath’). $path = $cachedFilter->call("filter". Release 2. $cachedFilter = Zend\Cache\PatternFactory::factory(’object’.. // OR $path = $cachedFilter->filter(’/www/var/path/. // The realpath filter doesn’t output anything // so the output don’t need to be catched and cached ’cache_output’ => false..Zend Framework 2 Documentation. ’storage’ => ’apc’. array(’/www/var/path/.

6 142 Chapter 29.Zend Framework 2 Documentation. Release 2.0. Zend\Cache\Pattern\ObjectCache .

3 Configuration Options Option storage Data Type string array Zend\Cache\Storage\StorageInterface Default Value <none> Description The storage to write/read cached data 30. Return type boolean end() Stops buffering output. array( ’storage’ => ’apc’ )).2 Quick Start Instantiating the output cache pattern 1 2 3 4 5 use Zend\Cache\PatternFactory. 30.CHAPTER THIRTY ZEND\CACHE\PATTERN\OUTPUTCACHE 30. write buffered data to cache using the given key on start() and displays the buffer. Return type boolean setOptions(Zend\Cache\Pattern\PatternOptions $options) Set pattern options.4 Available Methods start(string $key) If there is a cached item with the given key display it’s data and return true else start buffering output until end() is called or the script ends and return false. 30. $outputCache = PatternFactory::factory(’output’.1 Overview The OutputCache pattern caches output between calls to start() and end(). 143 .

include ’/path/to/view/script. )).5 Examples Caching simple view scripts $outputCache = Zend\Cache\PatternFactory::factory(’output’. $outputCache->end(). $outputCache->start(’mySimpleViewScript’).6 Return type Zend\Cache\Pattern\OutputCache getOptions() Get all pattern options. Return type Zend\Cache\Pattern\PatternOptions 30. Zend\Cache\Pattern\OutputCache .phtml’.0. Release 2. array( ’storage’ => ’apc’. 1 2 3 4 5 6 7 144 Chapter 30.Zend Framework 2 Documentation.

’public_dir’ => __DIR__. 31. 200). headers and write to public directory $capture->start(). // Don’t forget to change HTTP response code header(’Status: 200’. 1 2 3 4 5 6 7 8 9 10 11 12 $capture = Zend\Cache\PatternFactory::factory(’capture’. array( // Start capturing all output excl. The Webserver needs to be configured to run a PHP script generating the requested resource so further requests for the same resource can be shipped without calling PHP again.htdocs ErrorDocument 404 /index.3 Configuration Options Option public_dir index_filename file_locking file_permission dir_permission umask Data Type string string boolean integer boolean integer boolean integer boolean Default Value <none> “index.html” true 0600 (false on win) 0700 (false on win) false Description Location of public directory to write output to The name of the first file if only a directory was requested Locking output files on writing Set permissions of generated output files Set permissions of generated output directories Using umask on generationg output files / directories 145 .2 Quick Start Simplest usage as Apache-404 handler 1 2 # . true.CHAPTER THIRTYONE ZEND\CACHE\PATTERN\CAPTURECACHE 31.php use Zend\Cache\PatternFactory. )).1 Overview The CaptureCache pattern is useful to auto-generate static resources in base of a HTTP request. It comes with basic logic to manage generated resources. // do stuff to dynamically generate output 31.php // index.

0.Zend Framework 2 Documentation.htdocs ErrorDocument 404 /index.5 Examples Scaling images in base of request # . Return type void get(string|null $pageId = null) Get content of an already cached page. Return type boolean remove(string|null $pageId = null) Remove a page. // TODO 1 2 1 2 3 4 5 6 146 Chapter 31. )). Return type Zend\Cache\Pattern\OutputCache getOptions() Get all pattern options. Zend\Cache\Pattern\CaptureCache . Return type boolean clearByGlob(string $pattern = ‘**’) Clear pages matching glob pattern.4 Available Methods start(string|null $pageId = null) Start capturing output. string|null $pageId = null) Write content to page identity. Return type void set(string $content.6 31.php $captureCache = Zend\Cache\PatternFactory::factory(’capture’. Return type void setOptions(Zend\Cache\Pattern\PatternOptions $options) Set pattern options.php // index. Return type Zend\Cache\Pattern\PatternOptions 31. Release 2. Return type string|false has(string|null $pageId = null) Check if a page has been created. array( ’public_dir’ => __DIR__.

Typically. a captcha is used with form submissions where authenticated users are not necessary. 147 . it is used as a challenge-response to ensure that the individual submitting information is a human and not an automated process. Captchas can take a variety of forms. presenting skewed fonts. and presenting multiple images and asking how they relate. including asking logic questions. but you want to prevent spam submissions. The Zend\Captcha component aims to provide a variety of back ends that may be utilized either standalone or in conjunction with the Zend\Form component.CHAPTER THIRTYTWO INTRODUCTION CAPTCHA stands for “Completely Automated Public Turing test to tell Computers and Humans Apart”.

6 148 Chapter 32. Introduction . Release 2.Zend Framework 2 Documentation.0.

CHAPTER THIRTYTHREE CAPTCHA OPERATION All CAPTCHA adapter implement Zend\Captcha\AdapterInterface. The most interesting methods are generate() and render(). be it an image. generate() is used to create the CAPTCHA token. with corresponding form fields. or some other CAPTCHA. ’wordLen’ => 6. A simple use case might look like the following: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // Originating request: $captcha = new Zend\Captcha\Figlet(array( ’name’ => ’foo’. input => captcha value ($captcha->isValid($_POST[’foo’]. public function getName(). // // // if } On a subsequent request: Assume a captcha setup as before. // Get helper name used for rendering this captcha type public function getHelperName(). //this will output a Figlet string echo $captcha->getFiglet()->render($captcha->getWord()). interface AdapterInterface extends ValidatorInterface { public function generate(). This process typically will store the token in the session so that you may compare against it in subsequent requests. } The name setter and getter are used to specify and retrieve the CAPTCHA identifier. a logic problem. render() is used to render the information that represents the CAPTCHA. )). use Zend\Validator\ValidatorInterface. public function setName($name). ’timeout’ => 300. a figlet. $_POST)) { // Validated! 149 . which looks like the following: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 namespace Zend\Captcha. the value of $_POST[’foo’] would be key/value array: id => captcha ID. $id = $captcha->generate().

Captcha Operation . you probably prefer the use of Zend\Captcha functionality combined with the power of the Zend\Form component.Zend Framework 2 Documentation.6 Note: Under most circumstances. 150 Chapter 33. For an example on how to use Zend\Form\Element\Captcha. Release 2. have a look at the Zend\Form Quick Start.0.

$ttl should be specified in seconds. and to retrieve the current value. All word CAPTCHAs allow you to pass an array of options or Traversable object to the constructor. • getWord() allows you to retrieve the generated word to use with the CAPTCHA. In addition to the methods required by the Zend\Captcha\AdapterInterface Zend\Captcha\AbstractWord exposes the following methods: interface. 34. Note: Zend\Captcha\AbstractWord is an abstract class and may not be instantiated directly. • setTimeout($ttl) and getTimeout() allow you to specify the time-to-live of the session token. 151 . session TTL and the session container object to use. • setSessionClass($class) and getSessionClass() allow you to specify an alternate Zend\Session\Container implementation to use to persist the CAPTCHA token and to retrieve the current value. the wordLen.1 Zend\Captcha\AbstractWord Zend\Captcha\AbstractWord is an abstract adapter that serves as the base class for most other CAPTCHA adapters. It provides mutators for specifying word length. the session timeout is 5 minutes. and to retrieve the current value. alternately. It will generate the word for you if none has been generated yet. Zend\Captcha\AbstractWord also encapsulates validation logic. getSession() allows you to retrieve the current session object. timeout. Each concrete implementation may define additional keys or utilize the options in other ways. • setUseNumbers($numbers) and getUseNumbers() allow you to specify if numbers will be considered as possible characters for the random work or only letters would be used. • setWordLen($length) and getWordLen() allow you to specify the length of the generated “word” in characters. or. • setSession(Zend\Session\Container $session) allows you to specify a session object to use for persisting the CAPTCHA token. the word length is 8 characters. • getId() allows you to retrieve the current token identifier. By default. By default. and Zend\Session\Container is used for persistence (using the namespace “Zend\Form\Captcha\<captcha ID>”). pass them to setOptions().CHAPTER THIRTYFOUR CAPTCHA ADAPTERS The following adapters are shipped with Zend Framework by default. and sessionClass keys may all be used.

Currently.0. • setDotNoiseLevel($level) and getDotNoiseLevel(). Release 2. • setImgUrl($imgUrl) and getImgUrl() allow you to specify the relative path to a CAPTCHA image to use for HTML markup. performing various skewing permutations to make it difficult to automatically decipher. 34. Garbage collection will run every 1/$gcFreq calls. • setImgDir($imgDir) and getImgDir() allow you to specify the directory for storing CAPTCHA images.3 Zend\Captcha\Figlet The Zend\Captcha\Figlet adapter utilizes Zend\Text\Figlet to present a figlet to the user. • setGcFreq($gcFreq) and getGcFreg() allow you to specify how frequently garbage collection should run. The default is 200px. deleting all images that have expired. • setSuffix($suffix) and getSuffix() allow you to specify the filename suffix for the CAPTCHA image. the Zend\Captcha\Image adapter can only generate PNG images. along with setLineNoiseLevel($level) and getLineNoiseLevel(). The default is 50px. As such. This value is required. Options passed to the constructor will also be passed to the Zend\Text\Figlet object. Garbage collection is run periodically each time the CAPTCHA object is invoked.2 Zend\Captcha\Dumb The Zend\Captcha\Dumb adapter is mostly self-descriptive. It extends Zend\Captcha\AbstractWord. CAPTCHA Adapters . • setWidth($width) and getWidth() allow you to specify the width in pixels of the generated CAPTCHA image. See the Zend\Text\Figlet documentation for details on what configuration options are available.6 34. The default is “/images/captcha/”. The default is “. The default is “. Expiration values should be specified in seconds. The default is 24px. the CAPTCHA will throw an exception during generation if the font file has not been specified. Each unit of $level produces one 152 Chapter 34.4 Zend\Captcha\Image The Zend\Captcha\Image adapter takes the generated word and renders it as an image. 34.png”. it’s not a good CAPTCHA solution and should only be used for testing. • setFont($font) and getFont() allow you to specify the font you will use. • setHeight($height) and getHeight() allow you to specify the height in pixels of the generated CAPTCHA image. It requires the GD extension compiled with TrueType or Freetype support. This is typically a longer than the session lifetime. relative to the bootstrap script. Note: changing this value will not change the type of the generated image. and additionally exposes the following methods: • setExpiration($expiration) and getExpiration() allow you to specify a maximum lifetime the CAPTCHA image may reside on the filesystem. Zend\Captcha\Image extends Zend\Captcha\AbstractWord./images/captcha/”. • setFontSize($fsize) and getFontSize() allow you to specify the font size in pixels for generating the CAPTCHA. It provides a random string that must be typed in reverse to validate. $font should be a fully qualified path to the font file.Zend Framework 2 Documentation. The default is 100. allow you to control how much “noise” in the form of random dots and lines the image would contain.

This must be specified during construction. although it may be overridden at any point. • setPubKey($key) and getPubKey() allow you to specify the public key to use with the ReCaptcha service.0. although it may be overridden at any point. “height”. It exposes the following methods: • setPrivKey($key) and getPrivKey() allow you to specify the private key to use for the ReCaptcha service. This must be specified during construction. All of the above options may be passed to the constructor by simply removing the ‘set’ method prefix and casting the initial letter to lowercase: “suffix”.6 random dot or line. 34. etc. The noise is added twice . The default is 100 dots and 5 lines. Zend\Captcha\ReCaptcha 153 . • setService(ZendService\ReCaptcha\ReCaptcha $service) and getService() allow you to set and get the ReCaptcha service object. “imgUrl”.5. 34. Release 2.5 Zend\Captcha\ReCaptcha The Zend\Captcha\ReCaptcha adapter uses Zend\Service\ReCaptcha\ReCaptcha to generate and validate CAPTCHAs.before and after the image distortion transformation.Zend Framework 2 Documentation.

CAPTCHA Adapters .6 154 Chapter 34.0.Zend Framework 2 Documentation. Release 2.

CHAPTER THIRTYFIVE INTRODUCTION Zend\Config is designed to simplify access to configuration data within applications. // Print a configuration datum (results in ’www. ’username’ => ’dbuser’.example.com’. Zend\Config provides adapters that read and write configuration data stored in . It provides a nested object property-based user interface for accessing this configuration data within application code. ’params’ => array( ’host’ => ’db.example. JSON.example. ’localhost’). it is expected that users would use one of the reader classes to read a configuration file.com’) echo $config->webhost. ’dbname’ => ’mydatabase’ ) ) ). 155 . The configuration data may come from a variety of media supporting hierarchical data storage. ’database’ => array( ’adapter’ => ’pdo_mysql’. Along with the object oriented access to the data values. YAML and XML files. ’password’ => ’secret’. one may simply pass the data to Zend\Config\Config‘s constructor in order to utilize a simple object-oriented interface: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // An array of configuration data is given $configArray = array( ’webhost’ => ’www. Zend\Config\Config provides nested object property syntax to access configuration data passed to its constructor. Zend\Config\Config also has get() method that returns the supplied value if the data element doesn’t exist in the configuration array. // Create the object-oriented wrapper using the configuration data $config = new Zend\Config\Config($configArray). but if configuration data are available in a PHP array.com’. Currently.1 Using Zend\Config\Config with a Reader Class Normally. As illustrated in the example above. 35.ini. For example: 1 $host = $config->database->get(’host’.

’password’ => ’secret’. 1 2 3 4 5 156 Chapter 35. // Print a configuration datum (results in ’www.php’).2 Using Zend\Config\Config with a PHP Configuration File It is often desirable to use a purely PHP-based configuration file.6 35. ’dbname’ => ’mydatabase’ ) ) ). ’params’ => array( ’host’ => ’db.example.com’.com’) echo $config->webhost. ’username’ => ’dbuser’.0.php return array( ’webhost’ => ’www. Introduction . Release 2.com’.example. ’database’ => array( ’adapter’ => ’pdo_mysql’. The following code illustrates how easily this can be accomplished: 1 2 3 4 5 6 7 8 9 10 11 12 13 // config.example.Zend Framework 2 Documentation. // Consumes the configuration array $config = new Zend\Config\Config(include ’config.

which may be multi-dimensional. The isReadOnly() method can be used to determine if modifications to a given Zend\Config\Config object are allowed and the setReadOnly() method can be used to stop any further modifications to a Zend\Config\Config object that was created allowing modifications. then the resulting object property is created as a new Zend\Config\Config object. configuration data made available through Zend\Config\Config are read-only. Third-party open source solutions are readily available for the purpose of creating and modifying configuration data for various storage media. The items in $localConfig will override any items with the same name in $config. Zend\Config\Config implements the Countable and Iterator interfaces in order to facilitate simple access to configuration data.com’. given $config and $localConfig. The setReadOnly() method can then be used to prevent any further modifications after the merge is complete. and an assignment (e. such that a hierarchy of configuration data may be created with any number of levels. Zend\Config\Config objects support the count() function and PHP constructs such as foreach. user scripts may provide such arrays directly to Zend\Config\Config‘s constructor. allowing modification of data values. This occurs recursively. you can merge data from $localConfig to $config using $config->merge($localConfig). loaded with the array data. 157 . Zend\Config\Config supports unsetting of values (i. Thus. Also. Tools for creating and modifying configuration data for various storage media are out of scope with respect to Zend\Config\Config. so data can be organized from general to specific. without using a reader class. Note: The Zend\Config\Config object that is performing the merge must have been constructed to allow modifications. Concrete adapter classes adapt configuration data from storage to produce the associative array for Zend\Config\Config‘s constructor.g. you can merge them into a single object using the merge() function.e. By default.) results in a thrown exception. If needed. Each value in the configuration data array becomes a property of the Zend\Config\Config object. Note: Modifying Config does not save changes It is important not to confuse such in-memory modifications with saving configuration data out to specific storage media. when modifications are allowed. unset($config->database->host)). by passing TRUE as the second parameter of the constructor. If a value is itself an array. For example.CHAPTER THIRTYSIX THEORY OF OPERATION Configuration data are made accessible to Zend\Config\Config‘s constructor with an associative array.. $config->database->host = ’example. This default behavior may be overridden through the constructor. If you have two Zend\Config\Config objects. The key is used as the property name.

6 158 Chapter 36. Release 2. Theory of Operation .Zend Framework 2 Documentation.0.

the key separator character is the period character (“.CHAPTER THIRTYSEVEN ZEND\CONFIG\READER Zend\Config\Reader gives you the ability to read a config file. Please review this documentation to be aware of its specific behaviors. that define the two methods fromFile() and fromString(). It works with concrete implementations for different file format. Suppose we have the following INI configuration file: 159 . • Reading of specific sections. $reader->setNestSeparator(’-’). such as how the special values of “TRUE”.”). Zend\Config\Reader\Ini utilizes the parse_ini_file() PHP function. For example: 1 2 $reader = new Zend\Config\Reader\Ini(). 37. “FALSE”. This can be changed. In this example there are configuration data for both a production system and for a staging system. “no”. which propagate to Zend\Config\Reader\Ini. using the setNestSeparator() method. Note: Key Separator By default. however. “yes”. The following example illustrates a basic use of Zend\Config\Reader\Ini for loading configuration data from an INI file. and “NULL” are handled. The concrete implementations of this interface are: • Zend\Config\Reader\Ini • Zend\Config\Reader\Xml • Zend\Config\Reader\Json • Zend\Config\Reader\Yaml The fromFile() and fromString() return a PHP array contains the data of the configuration file. The Zend\Config\Reader is only an interface. Note: Differences from ZF1 The Zend\Config\Reader component no longer supports the following features: • Inheritance of sections.1 Zend\Config\Reader\Ini Zend\Config\Reader\Ini enables developers to store configuration data in a familiar INI format and read them in the application by using an array syntax.

example. echo $data[’webhost’] // prints "www.params. The root element of the XML file or string is irrelevant and may be named arbitrarily.ini’).com</webhost> 160 Chapter 37. Zend\Config\Reader .Zend Framework 2 Documentation.example.example.com’ ’dbuser’ ’secret’ ’dbproduction’ We can use the Zend\Config\Reader\Ini to read this INI file: 1 2 3 4 5 $reader = new Zend\Config\Reader\Ini().adapter database.ini’ 37.com’ database. for instance: 1 2 webhost = ’www.com" echo $data[’database’][’params’][’dbname’].params. Suppose we have the following XML configuration file: 1 2 3 <?xml version="1.example.password database.6 1 2 3 4 5 6 webhost database.username params. $data = $reader->fromFile(’/path/to/config. Release 2.ini’ can be used also in a subelement of a value.example.dbname = = = = = ’pdo_mysql’ ’db.example.example.com’ ’dbuser’ ’secret’ ’dbproduction’ And assign the @include as sublement of the database value: 1 2 webhost = ’www. For instance we can have an INI file like that: 1 2 3 4 5 adapter params.com’ @include = ’database.username database.adapter database.params. // prints "dbproduction" The Zend\Config\Reader\Ini supports a feature to include the content of a INI file in a specific section of another INI file.params.username database.params. For instance. The @include = ’file-to-include.host database.password params.ini’ If we read this file using the component Zend\Config\Reader\Ini we will obtain the same configuration data structure of the previous example.@include = ’database.com’ ’pdo_mysql’ ’db.params.2 Zend\Config\Reader\Xml Zend\Config\Reader\Xml enables developers to read configuration data in a familiar XML format and read them in the application by using an array syntax.host params.password database.dbname = = = = = ’pdo_mysql’ ’db.params.com’ ’dbuser’ ’secret’ ’dbproduction’ We can include this configuration in another INI file.0. The following example illustrates a basic use of Zend\Config\Reader\Xml for loading configuration data from an XML file.0" encoding="utf-8"?>?> <config> <webhost>www. suppose we have an INI file with the database configuration: 1 2 3 4 5 database.params.host database.dbname = = = = = = ’www.example.

0.example. // prints "dbproduction" Zend\Config\Reader\Xml utilizes the XMLReader PHP class. This is provided using the standard function XInclude of XML.com"/> <username value="dbuser"/> <password value="secret"/> <dbname value="dbproduction"/> </params> </database> </config> We can use the Zend\Config\Reader\Xml to read this XML file: 1 2 3 4 5 $reader = new Zend\Config\Reader\Xml().example.3 Zend\Config\Reader\Json Zend\Config\Reader\Json enables developers to read configuration data in a JSON format and read them in the application by using an array syntax.example.com</webhost> <xi:include href="database. for instance: 1 2 3 4 5 <?xml version="1.example.6 4 5 6 7 8 9 10 11 12 13 <database> <adapter value="pdo_mysql"/> <params> <host value="db. Zend\Config\Reader\Json 161 . Release 2. Suppose we have an XML files that contains only the database configuration: 1 2 3 4 5 6 7 8 9 10 11 12 <?xml version="1.org/2001/XInclude" to the XML file.w3. $data = $reader->fromFile(’/path/to/config. Please review this documentation to be aware of its specific behaviors.com</host> <username>dbuser</username> <password>secret</password> <dbname>dbproduction</dbname> </params> </database> </config> We can include this configuration in another XML file. Using Zend\Config\Reader\Xml we can include the content of XML files in a specific XML element.0" encoding="utf-8"?> <config> <database> <adapter>pdo_mysql</adapter> <params> <host>db.org/2001/XInclude"> <webhost>www.xml"/> 37.com" echo $data[’database’][’params’][’dbname’].0" encoding="utf-8"?> <config xmlns:xi="http://www. echo $data[’webhost’] // prints "www.xml’). To use this function you have to add the namespace xmlns:xi="http://www.3. which propagate to Zend\Config\Reader\Xml.xml"/> </config> The syntax to include an XML file in a specific element is <xi:include href="file-to-include. The following example illustrates a basic use of Zend\Config\Reader\Json for loading configuration data from a JSON file.w3.Zend Framework 2 Documentation. Suppose we have the following JSON configuration file: 37.

"params" : { "host" : "db. echo $data[’webhost’] // prints "www. "database" : { "adapter" : "pdo_mysql". Release 2. "@include" : "database. In order to use the YAML reader we need to pass a callback to an external PHP library or use the Yaml PECL extension.example. This is provided using the special syntax @include. Zend\Config\Reader .example. "password" : "secret".com". The following example illustrates a basic use of Zend\Config\Reader\Yaml that use the Yaml PECL extension. "username" : "dbuser".4 Zend\Config\Reader\Yaml Zend\Config\Reader\Yaml enables developers to read configuration data in a YAML format and read them in the application by using an array syntax. $data = $reader->fromFile(’/path/to/config.com database: 162 Chapter 37.com".Zend Framework 2 Documentation.json’). "params" : { "host" : "db. "dbname" : "dbproduction" } } } We can include this configuration in another JSON file. "dbname" : "dbproduction" } } } We can use the Zend\Config\Reader\Json to read this JSON file: 1 2 3 4 5 $reader = new Zend\Config\Reader\Json().com". // prints "dbproduction" Zend\Config\Reader\Json utilizes the Zend\Json\Json class.example.com". for instance: 1 2 3 4 { "webhost" : "www. "username" : "dbuser". Using Zend\Config\Reader\Json we can include the content of a JSON file in a specific JSON section or element. Suppose we have a JSON file that contains only the database configuration: 1 2 3 4 5 6 7 8 9 10 11 { "database" : { "adapter" : "pdo_mysql". "password" : "secret".example.com" echo $data[’database’][’params’][’dbname’].json" } 37.example.0.6 1 2 3 4 5 6 7 8 9 10 11 12 { "webhost" : "www. Suppose we have the following YAML configuration file: 1 2 webhost: www.example.

com" echo $data[’database’][’params’][’dbname’].example. This is provided using the special syntax @include.php’). for instance: webhost: www. Suppose we have a YAML file that contains only the database configuration: 1 2 3 4 5 6 7 database: adapter: pdo_mysql params: host: db. $reader = new Zend\Config\Reader\Yaml(array(’Spyc’.’YAMLLoadString’)). Using Zend\Config\ReaderYaml we can include the content of a YAML file in a specific YAML section or element. // prints "dbproduction" You can also instantiate the Zend\Config\Reader\Yaml without any parameter and specify the YAML reader in a second moment using the setYamlDecoder() method. Release 2.com username: dbuser password: secret dbname: dbproduction We can include this configuration in another YAML file. $data = $reader->fromFile(’/path/to/config. Zend\Config\Reader\Yaml 163 . // prints "dbproduction" If you want to use an external YAML reader you have to pass the callback function in the constructor of the class. if you want to use the Spyc library: 1 2 3 4 5 6 7 8 // include the Spyc library require_once (’path/to/spyc.com @include: database.Zend Framework 2 Documentation. For instance.4.yaml’).6 3 4 5 6 7 8 adapter: pdo_mysql params: host: db.example.com username: dbuser password: secret dbname: dbproduction We can use the Zend\Config\Reader\Yaml to read this YAML file: 1 2 3 4 5 $reader = new Zend\Config\Reader\Yaml().example.example.0.com" echo $data[’database’][’params’][’dbname’].example. echo $data[’webhost’] // prints "www.yaml’). echo $data[’webhost’] // prints "www. $data = $reader->fromFile(’/path/to/config.yaml 37.

6 164 Chapter 37.Zend Framework 2 Documentation.0. Zend\Config\Reader . Release 2.

$config->production->database->params->password = ’secret’. true). $config->production->database->params->host = ’localhost’. By default the top-level configuration is always written into section names. To create a section in the root or to create a branch. there are some things to know. The default is a single dot. which defines with which character the single nodes are separated. $config->production->webhost = ’www. 165 . Using Zend\Config\Writer\Ini This example illustrates the basic use of Zend\Config\Writer\Ini to create a new config file: 1 2 3 4 5 6 7 8 9 10 // Create the config object $config = new Zend\Config\Config(array(). you simply say set the parameter of the Config object via the parameter accessor (->). like it is accepted by Zend\Config\Reader\Ini by default. $config->production->database = array(). To create or modify a value.”). you just create a new array (“$config->branch = array(). When modifying or creating a Zend\Config\Config object. $config->production->database->params->username = ’production’. By calling $writer->setRenderWithoutSectionsFlags(true). As an addition Zend\Config\Writer\Ini has an additional option parameter nestSeparator. $config->production = array().com’. The Zend\Config\Writer is an interface that defines two methods: toFile() and toString().CHAPTER THIRTYEIGHT ZEND\CONFIG\WRITER Zend\Config\Writer gives you the ability to write config files out of array. Zend\Config\Config and any Traversable object. all options are written into the global namespace of the INI file and no sections are applied. $config->production->database->params = array(). We have five specific writers that implement this interface: • Zend\Config\Writer\Ini • Zend\Config\Writer\Xml • Zend\Config\Writer\PhpArray • Zend\Config\Writer\Json • Zend\Config\Writer\Yaml 38.example.1 Zend\Config\Writer\Ini The INI writer has two modes for rendering with regard to sections.

com</webhost> <database> <params> <host>localhost</host> <username>production</username> <password>secret</password> <dbname>dbproduction</dbname> </params> </database> </production> </zend-config> 166 Chapter 38. The result of this code is an XML string contains the following data: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?xml version="1.0" encoding="UTF-8"?> <zend-config> <production> <webhost>www.params. $writer = new Zend\Config\Writer\Xml(). The result of this code is an INI string contains the following values: 1 2 3 4 5 6 [production] webhost = "www.2 Zend\Config\Writer\Xml The Zend\Config\Writer\Xml can be used to generate an XML string or file starting from a Zend\Config\Config object.params. Release 2.example. true).host = "localhost" database.com" database. 38.example.password = "secret" database.dbname = "dbproduction" You can use the method toFile() to store the INI data in a file. $writer = new Zend\Config\Writer\Ini().username = "production" database. echo $writer->toString($config).example. Zend\Config\Writer . $config->production->database->params->dbname = ’dbproduction’. $config->production->webhost = ’www.params. $config->production->database->params->host = ’localhost’.0. $config->production->database = array(). echo $writer->toString($config). Using Zend\Config\Writer\Ini This example illustrates the basic use of Zend\Config\Writer\Xml to create a new config file: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // Create the config object $config = new Zend\Config\Config(array().Zend Framework 2 Documentation.com’. $config->production->database->params->password = ’secret’.params. $config->production->database->params = array().6 11 12 13 14 $config->production->database->params->dbname = ’dbproduction’. $config->production = array(). $config->production->database->params->username = ’production’.

0. The result of this code is a PHP script that returns an array as follow: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php return array ( ’production’ => array ( ’webhost’ => ’www. $config->production->database->params->host = ’localhost’. ). ’password’ => ’secret’.example. 38. ). $config->production->database->params->password = ’secret’. $config->production->webhost = ’www. $config->production = array(). ’dbname’ => ’dbproduction’.4 Zend\Config\Writer\Json The Zend\Config\Writer\Json can be used to generate a PHP code that returns the JSON representation of a Zend\Config\Config object. echo $writer->toString($config). $config->production->database = array().6 You can use the method toFile() to store the XML data in a file. true). ).3. 38. $config->production->database->params->username = ’production’. ’username’ => ’production’.com’. ’database’ => array ( ’params’ => array ( ’host’ => ’localhost’. Release 2. $writer = new Zend\Config\Writer\PhpArray(). 38.Zend Framework 2 Documentation. Using Zend\Config\Writer\PhpArray This example illustrates the basic use of Zend\Config\Writer\PhpArray to create a new config file: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // Create the config object $config = new Zend\Config\Config(array().3 Zend\Config\Writer\PhpArray The Zend\Config\Writer\PhpArray can be used to generate a PHP code that returns an array representation of an Zend\Config\Config object.com’. ). You can use the method toFile() to store the PHP script in a file. $config->production->database->params->dbname = ’dbproduction’.example. $config->production->database->params = array(). Zend\Config\Writer\PhpArray 167 .

"database" : { "params" : { "host" : "localhost". Zend\Config\Writer .example. true). "username" : "production". "password" : "secret". $config->production->webhost = ’www. 38. $config->production->database->params->dbname = ’dbproduction’. In order to use the YAML writer we need to pass a callback to an external PHP library or use the Yaml PECL extension. 168 Chapter 38.5 Zend\Config\Writer\Yaml The Zend\Config\Writer\Yaml can be used to generate a PHP code that returns the YAML representation of a Zend\Config\Config object.com’.example.6 Using Zend\Config\Writer\Json This example illustrates the basic use of Zend\Config\Writer\Json to create a new config file: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // Create the config object $config = new Zend\Config\Config(array(). $config->production->webhost = ’www.example. $config->production->database->params = array(). The result of this code is a JSON string contains the following values: 1 2 3 4 5 6 7 8 9 10 { "webhost" : "www. $config->production->database->params->host = ’localhost’. $config->production->database->params = array(). $config->production = array(). The Zend\Config\Writer\Json class uses the Zend\Json\Json component to convert the data in a JSON format. Release 2.0. true).Zend Framework 2 Documentation.com". $config->production->database->params->username = ’production’. $config->production->database = array(). $config->production = array(). Using Zend\Config\Writer\Yaml This example illustrates the basic use of Zend\Config\Writer\Yaml to create a new config file using the Yaml PECL extension: 1 2 3 4 5 6 7 // Create the config object $config = new Zend\Config\Config(array(). $writer = new Zend\Config\Writer\Json(). echo $writer->toString($config).com’. $config->production->database->params->password = ’secret’. $config->production->database = array(). "dbname" : "dbproduction" } } } You can use the method toFile() to store the JSON data in a file.

$config->production->database->params->dbname = ’dbproduction’. The result of this code is a YAML string contains the following values: 1 2 3 4 5 6 7 webhost: www. For instance. if you want to use the Spyc library: 1 2 3 4 5 // include the Spyc library require_once (’path/to/spyc.0.’YAMLDump’)). Release 2. 38.6 8 9 10 11 12 13 14 $config->production->database->params->host = ’localhost’. $config->production->database->params->username = ’production’. Zend\Config\Writer\Yaml 169 . $writer = new Zend\Config\Writer\Yaml().Zend Framework 2 Documentation.php’). echo $writer->toString($config). echo $writer->toString($config).example. $writer = new Zend\Config\Writer\Yaml(array(’Spyc’. $config->production->database->params->password = ’secret’.5. If you want to use an external YAML writer library you have to pass the callback function in the constructor of the class.com database: params: host: localhost username: production password: secret dbname: dbproduction You can use the method toFile() to store the YAML data in a file.

Zend Framework 2 Documentation. Zend\Config\Writer .0. Release 2.6 170 Chapter 38.

39. $processor = new Zend\Config\Processor\Constant().1 Zend\Config\Processor\Constant Using Zend\Config\Processor\Constant This example illustrates the basic use of Zend\Config\Processor\Constant: 1 2 3 4 5 6 7 8 define (’TEST_CONST’. echo $config->foo. • Zend\Config\Processor\Filter: filter the configuration data using Zend\Filter.CHAPTER THIRTYNINE ZEND\CONFIG\PROCESSOR Zend\Config\Processor gives you the ability to perform some operations on a Zend\Config\Config object. • Zend\Config\Processor\Queue: manage a queue of operations to apply to configuration data. echo $config->foo .2 Zend\Config\Processor\Filter Using Zend\Config\Processor\Filter This example illustrates the basic use of Zend\Config\Processor\Filter: 171 . // set true to Zend\Config\Config to allow modifications $config = new Zend\Config\Config(array(’foo’ => ’TEST_CONST’). 39.’. translate configuration values in other languages using Below we reported some examples for each type of processor. ’bar’). bar. This example returns the output: TEST_CONST. • Zend\Config\Processor\Translator: Zend\I18n\Translator. true). • Zend\Config\Processor\Token: find and replace specific tokens. The Zend\Config\Processor is an interface that defines two methods: process() and processValue(). These operations are provided by the following concrete implementations: • Zend\Config\Processor\Constant: manage PHP constant values. $processor->process($config). ’..

$queue->process($config). 39. true). $upperProcessor = new FilterProcessor($upper). Release 2. Zend\Filter\StringToUpper.0. 39. This example returns the output: bar. echo $config->foo. The filters in the queue are applied with a FIFO logic (First In.Zend Framework 2 Documentation. echo $config->foo. 172 Chapter 39. $upper = new StringToUpper(). $lower = new StringToLower(). $config = new Config(array (’foo’ => ’bar’). This example returns the output: bar. Zend\Config\Processor . Zend\Config\Processor\Filter as FilterProcessor. echo $config->foo . $upper = new StringToUpper(). true). $lowerProcessor = new FilterProcessor($lower). $queue->insert($lowerProcessor).6 1 2 3 4 5 6 7 8 9 10 11 12 use Zend\Filter\StringToUpper. Zend\Config\Config. $queue->insert($upperProcessor).3 Zend\Config\Processor\Queue Using Zend\Config\Processor\Queue This example illustrates the basic use of Zend\Config\Processor\Queue: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 use use use use use Zend\Filter\StringToLower. use Zend\Config\Processor\Filter as FilterProcessor.BAR. use Zend\Config\Config. $config = new Config(array (’foo’ => ’bar’).’. $processor = new TokenProcessor(). First Out). ’. $upperProcessor = new FilterProcessor($upper). Zend\Config\Processor\Queue. true). $queue = new Queue(). $upperProcessor->process($config).4 Zend\Config\Processor\Token Using Zend\Config\Processor\Token This example illustrates the basic use of Zend\Config\Processor\Token: 1 2 3 4 // set the Config to true to allow modifications $config = new Config(array(’foo’ => ’Value is TOKEN’).

Release 2. ’bar’). Italian: cane.0. 39.. echo "English: {$config->animal}. $processor = new TranslatorProcessor($translator).’.5 Zend\Config\Processor\Translator Using Zend\Config\Processor\Translator This example illustrates the basic use of Zend\Config\Processor\Translator: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 use Zend\Config\Config. Zend\Config\Processor\Translator 173 . use Zend\Config\Processor\Translator as TranslatorProcessor. // . echo $config->foo. /* * The following mapping would exist for the translation * loader you provide to the translator instance * $italian = array( ’dog’ => ’cane’ * * ). ’. ". echo "Italian: {$config->animal}". $processor->process($config). echo $config->foo . true). configure the translator .Value is bar.. use Zend\I18n\Translator\Translator. This example returns the output: Value is TOKEN. 39..5.6 5 6 7 8 $processor->addToken(’TOKEN’.Zend Framework 2 Documentation. */ $translator = new Translator().. $processor->process($config). $config = new Config(array(’animal’ => ’dog’). This example returns the output: English: dog.

Release 2.0.Zend Framework 2 Documentation. Zend\Config\Processor .6 174 Chapter 39.

40.’/config/my.’/config/my. Also this is really easy to do 175 . //Load a xml file as Config object $config = Zend\Config\Factory::fromFile(__DIR__.config.2 Storing configuration file Sometimes you want to store the configuration to a file. The factory has two purposes • Loading configuration file(s) • Storing a configuration file Note: Storing the configuration will be done to one file.xml’. The factory is not aware of merging two or more configurations and will not store it into multiple files.config. For merging multiple configuration files 40.php’).CHAPTER FORTY THE FACTORY The factory gives you the ability to load a configuration file to an array or to Zend\Config\Config object.1 Loading configuration file The next example illustrates how to load a single configuration file 1 2 3 4 5 //Load a php file as array $config = Zend\Config\Factory::fromFile(__DIR__. true). If you want to store particular configuration sections to a different file you should separate it manually.

Release 2.Zend Framework 2 Documentation. The Factory .0.6 176 Chapter 40.

literal “resetpassword” followed by a parameter we’re calling “userEmail”. it will recognize this fact and prepare Zend\Mvc components to handle the request. in case the command line has not been understood (no route matched). http route and can point to a MVC controller and an action.php First we need to create a route definition: user resetpassword <userEmail> This simple route definition expects exactly 3 arguments: a literal “user”. When a route matches. it can be shell script in application bin folder or simply an alias for php public/index. Note: We will use zf to depict the entry point for your application. we’d like to call action resetpassword of Application\Controller\IndexController.1 Writing console routes A console route defines required and optional command line parameters. • Console routing allows you to invoke controllers and action depending on command line parameters provided by the user. it behaves analogical to a standard. that will turn on verbose operation: 177 . When a Zend\Application is run from a console window (a shell window or Windows command prompt). • Module Manager integration allows ZF2 applications and modules to display help and usage information. • Console-aware action controllers will receive a console request containing all named parameters and flags.com When a user runs our application (zf) with these parameters. They are able to send output back to the console window. • Console prompts can be used to interact with the user by asking him questions and retrieving input. • Console adapters provide a level of abstraction for interacting with console on different operating systems. 41. but to function properly it requires at least one console route and one action controller to handle the request. Console support is enabled by default.CHAPTER FORTYONE INTRODUCTION Zend Framework 2 features built-in console support. Let’s assume we also accept one optional parameter. Let’s assume that we’d like our application to handle the following command line: > zf user resetpassword user@mail.

config. ’action’ => ’password’ ) ) ) ) ) ) ) See Also: To learn more about console routes and how to use them.6 user resetpassword [--verbose|-v] <userEmail> Now our console route expects the same 3 parameters but will also recognise an optional --verbose flag. after them or anywhere in between. Let’s use the definition above and configure our console route. Introduction . Flags can appear before positional parameters. Console routes are automatically loaded from the following location inside config file: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 array( ’router’ => array( ’routes’ => array( // HTTP routes are defined here ) ).0. Release 2.php array( ’console’ => array( ’router’ => array( ’routes’ => array( ’user-reset-password’ => array( ’options’ => array( ’route’ => ’user resetpassword [--verbose|-v] <userEmail>’. Note: The order of flags is ignored by Zend\Console. This applies both to route definitions and the order that flags are used on the command line. The order of multiple flags is also irrelevant. or its shorthand version: -v. please read this chapter: Console routes and routing 178 Chapter 41. ) Let’s create our console route and point it to Application\Controller\IndexController::resetpasswordAction() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // we could define routes for Application\Controller\IndexController in Application module config fil // which is usually located at modules/application/config/module. ’console’ => array( ’router’ => array( ’routes’ => array( // Console routes go here ) ) ).Zend Framework 2 Documentation. ’defaults’ => array( ’controller’ => ’Application\Controller\Index’.

// [.. It has also been emaile } } } We have created resetpasswordAction() than retrieves current request and checks if it’s really coming from the console (as a precaution). we might define a wildcard route or a 3rd party module might erroneously route some requests to our action . } // Get user email from console and check if the user used --verbose or -v flag $userEmail = $request->getParam(’userEmail’). Because we have not defined any http route pointing to it. use use use use Zend\Mvc\Controller\AbstractActionController. if (!$request instanceof ConsoleRequest){ throw new \RuntimeException(’You can only use this action from a console!’). // reset new password $newPassword = Rand::getString(16). Zend\View\Model\ViewModel. }else{ return "Done! New password for user $userEmail is ’$newPassword’. // Fetch the user and change his password. then email him . where true means a flag has been used and false otherwise.2 Handling console requests When a user runs our application from command line and arguments match our console route. // Make sure that we are running in a console and the user has not tricked our // application into running this action from a public web server. $verbose = $request->getParam(’verbose’). Zend\Math\Rand. // display standard index page } public function resetpasswordAction(){ $request = $this->getRequest(). it should never be possible.2..Zend Framework 2 Documentation. a controller class will be instantiated and an action method will be called. All console arguments supplied by the user are accessible via $request->getParam() method.0.\n". just like it is with http requests. In this example we do not want our action to be invocable from a web page. We will now add resetpassword action to Application\Controller\IndexController: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?php namespace Application\Controller.] if (!$verbose){ return "Done! $userEmail has received an email with his new password. When our action has finished working it returns a simple string that will be shown to the user in console window. Release 2. Flags will be represented by a booleans. class IndexController extends AbstractActionController { public function indexAction() { return new ViewModel().. Zend\Console\Request as ConsoleRequest. 41. Handling console requests 179 .that is why we want to make sure that the request is always coming from a Console environment. However in the future..6 41.

. all info from all modules will be concatenated. If you want your application to display important usage info first. Release 2. ConfigProviderInterface. } } Each module that implements ConsoleUsageProviderInterface will be queried for console usage info. This is also handled by Zend\Console together with MVC. Let’s modify our Application\Controller\IndexController to provide usage info: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php namespace Application.our module implement this feature and provides console usag public function getAutoloaderConfig() { // [. ConsoleUsageProviderInterface { public function getConfig() { // [. ’Email of the user for a password reset’ ). ’(optional) turn on verbose mode’ ). class Module implements AutoloaderProviderInterface. It has been covered in more detail in the following chapter: Console-aware action controllers 41.6 See Also: There are different ways you can interact with console from a controller.0.Zend Framework 2 Documentation. use Zend\ModuleManager\Feature\ConfigProviderInterface. // Describe expected parameters array( ’EMAIL’. array( ’--verbose|-v’.. See Also: 180 Chapter 41.] } // <.. use Zend\Console\Adapter\AdapterInterface as Console. ).3 Adding console usage info It is a common practice for console application to display usage information when run for the first time (without any arguments). Usage info in ZF2 console applications is provided by loaded modules. Note: The order of usage info displayed in the console is the order modules load. In case no console route matches console arguments. Zend\Console will query all loaded modules and ask for their console usage info. Introduction . use Zend\ModuleManager\Feature\ConsoleUsageProviderInterface.] } public function getConsoleUsage(Console $console){ return array( // Describe available commands ’user resetpassword [--verbose|-v] EMAIL’ => ’Reset password for a user’. On route mismatch.. formatted to console width and shown to the user. change the order your modules are loaded.

Release 2. please read this chapter: Console-aware modules 41.3. Adding console usage info 181 .0.6 Modules can also provide an application banner (title).Zend Framework 2 Documentation. To learn more about the format expected from getConsoleUsage() and about application banners.

0. Introduction .Zend Framework 2 Documentation.6 182 Chapter 41. Release 2.

router.1 Router configuration All Console Routes are automatically read from the following configuration location: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // This can sit inside of modules/Application/config/module. please read this chapter: Console-aware modules.php or any other module’s config. ’console’ => array( ’router’ => array( ’routes’ => array( // Console routes go here ) ) ). All of them are defined in Zend\Mvc\Router\Console\* classes. array( ’router’ => array( ’routes’ => array( // HTTP routes are here ) ).console.] ’my-first-route’ => array( 183 . ) Console Routes will only be processed when the application is run inside console (terminal) window. It is possible to define only HTTP routes (only web application) or only Console routes (which means we want a console-only application which will refuse to run in a browser). Actions can perform any numer of task prior to returning a result. They have no effect in web (http) request and will be ignored.routes: // [. which means that command line arguments are read and used to determine the appropriate action controller and action method that will handle the request. A single route can be described with the following array: 1 2 3 // inside config.CHAPTER FORTYTWO CONSOLE ROUTES AND ROUTING Zend Framework 2 has native MVC integration with console. When a zf2 application is run in console for the first time (without arguments) it can display usage information that is provided by modules. that will be displayed to the user in his console window. See Also: Routes are used to handle real commands. To learn more about providing usage information.config... but they are not used to create help messages (usage information). 42. There are several routes you can use with Console.

--name=NAME [--method=METHOD]) 42.e. It expects two parameters: foo and bar. ’action’ => ’password’ ) ) ) We have created a simple console route with a name my-first-route. It will not match if there are any more params. It recognizes the following types of parameters: • Literal parameters (i.2. Application\Controller\IndexController::passwordAction() action will be invoked. We can also provide optional literal parameters.e. we can skip that ’options’ => array( ’route’ => ’foo bar’. If user puts these in a console. ’defaults’ => array( 184 Chapter 42.6 4 5 6 7 8 9 10 11 12 ’type’ => ’simple’ // <. Console routes and routing .simple route is created by default.2 Basic route This is the default route type for console. ’defaults’ => array( ’controller’ => ’Application\Controller\Index’.1 Literal parameters These parameters are expected to appear on the command line exactly the way they are spelled in the route. The order of words is also enforced. ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. For example: 1 2 3 4 5 6 7 8 9 ’show-users’ => array( ’options’ => array( ’route’ => ’show users’. for example: 1 2 3 4 ’show-users’ => array( ’options’ => array( ’route’ => ’show [all] users’.e. ’action’ => ’show’ ) ) ) This route will only match for the following command line > zf show users It expects mandatory literal parameters show users.e.Zend Framework 2 Documentation. create <modelName> [<destination>]) • Value flags (i. Release 2. See Also: You can read more about how ZF2 routing works in this chapter.0. 42. or if one of the words is missing. --verbose --direct [-d] [-a]) • Positional value parameters (i. create object (external|internal)) • Literal flags (i.

The above route definition is equivalent to: show [ all | deleted | locked | admin ] users 42. which enables us to capture commands such: > zf show users > zf show locked users > zf show admin users etc.2. The can be defined in any order and the user can provide them in any other order. Basic route 185 . ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. ’action’ => ’show’ ) ) ) This route will match both without and with second parameter being one of the words. Release 2. Note: Whitespaces in route definition are ignored. If you separate your parameters with more spaces. The order of flags is ignored. or separate alternatives and pipe characters with spaces.0. ’action’ => ’show’ ) ) ) Now this route will match for both of these commands: > zf show users > zf show all users We can also provide parameter alternative: 1 2 3 4 5 6 7 8 9 ’show-users’ => array( ’options’ => array( ’route’ => ’show [all|deleted|locked|admin] users’. Let’s create a route with optional long flags 1 2 3 4 5 6 7 8 9 ’check-users’ => array( ’options’ => array( ’route’ => ’check users [--verbose] [--fast] [--thorough]’.Zend Framework 2 Documentation. ’defaults’ => array( ’controller’ => ’Application\Controller\Users’.2.6 5 6 7 8 9 ’controller’ => ’Application\Controller\Users’.2 Literal flags Flags are a common concept for console tools. it won’t matter for the parser. You can define any number of optional and mandatory flags. ’action’ => ’check’ ) ) ) This route will match for commands like: > zf check users > zf check users --fast 42.

0. Release 2. Console routes and routing . for example: 1 2 3 4 5 6 7 8 9 ’check-users’ => array( ’options’ => array( ’route’ => ’check users [--verbose|-v] [--fast|-f] [--thorough|-t]’.positional and flags.: > zf check users --expired > zf check users --expired --fast > zf check users --verbose --thorough --suspicious We can also use short flags in our routes and group them with long flags for convenience. ’action’ => ’check’ ) ) ) This route will only match if we provide either --suspicious or --expired flag. Let’s take a look at the following route definition: 1 2 3 4 5 6 7 8 9 ’delete-user’ => array( ’options’ => array( ’route’ => ’delete user <userEmail>’.Zend Framework 2 Documentation. Positional value parameters are expected to appear in an exact position on the command line.e. ’action’ => ’check’ ) ) ) Now we can use short versions of our flags: > zf check users -f > zf check users -v --thorough > zf check users -t -f -v 42. i.3 Positional value parameters Value parameters capture any text-based input and come in two forms . ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. ’defaults’ => array( ’controller’ => ’Application\Controller\Users’.2. ’action’ => ’delete’ ) ) ) This route will match for commands like: 186 Chapter 42.6 > zf check users --verbose --thorough > zf check users --thorough --fast We can also define one or more mandatory long flags and group them as an alternative: 1 2 3 4 5 6 7 8 9 ’check-users’ => array( ’options’ => array( ’route’ => ’check users (--suspicious|--expired) [--verbose] [--fast] [--thorough]’.

2.2. for example: 1 2 3 4 5 6 7 8 9 ’create-user’ => array( ’options’ => array( ’route’ => ’create user <firstName> <lastName> <email> <position>’.4 Value flag parameters Positional value parameters are only matched if they appear in the exact order as described in the route. Basic route 187 .org We can access the email value by calling $this->getRequest()->getParam(’userEmail’) inside of our controller action (you can read more about accessing values here) We can also define optional positional value parameters by adding square brackets: 1 2 3 4 5 6 7 8 9 ’delete-user’ => array( ’options’ => array( ’route’ => ’delete user [<userEmail>]’. ’defaults’ => array( ’controller’ => ’Application\Controller\Users’.Zend Framework 2 Documentation. If we do not want to enforce the order of parameters. ’action’ => ’create’ ) ) ) This allows us to capture commands such as: > zf create user Johnny Bravo john@acme. If it is not provided. we could write something like this: > zf create user "Johnan Tom" Bravo john@acme. Value flags can be defined and matched in any order. They can digest text-based values. for example: 1 2 3 4 5 6 7 ’find-user’ => array( ’options’ => array( ’route’ => ’find user [--id=] [--firstName=] [--lastName=] [--email=] [--position=] ’. ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. Release 2. We can define any number of positional value parameters.0. userEmail parameter will not be required for the route to match. For example.org Entertainer Note: Command line arguments on all systems must be properly escaped.6 > zf delete user john@acme. userEmail parameter will not be set. ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. ’action’ => ’delete’ ) ) ) In this case. ’action’ => ’find’ ) 42.org "Head of the Entertainment Department" 42.org > zf delete user betty@acme. to create a user with two names and a complex position description. otherwise they will not be passed to our application correctly. we can define value flags.

’action’ => ’rename’ ) ) ) The --id parameter is required for this route to match. It is also possible to define mandatory value flags: 1 2 3 4 5 6 7 8 9 ’rename-user’ => array( ’options’ => array( ’route’ => ’rename user --id= [--firstName=] [--lastName=]’. ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. ’defaults’ => array( ’controller’ => ’Application\Controller\Index’. 188 Chapter 42. Note: The parser understands values that are provided after equal symbol (=) and separated by a space. It is the recommended way and will guarantee proper inter-operation with other modules in your application. ’action’ => ’consoledefault’ ) ) ) Note: This route type is rarely used. Values with one more whitespaces however. Release 2.Zend Framework 2 Documentation. Console routes and routing . The following commands will work with this route: > zf rename user --id 123 > zf rename user --id 123 --firstName Jonathan > zf rename user --id=123 --lastName=Bravo 42. 1 2 3 4 5 6 7 8 9 ’default-route’ => array( ’options’ => array( ’type’ => ’catchall’. Values without whitespaces can be provided after = symbol or after a space.6 8 9 ) ) This route will match for any of the following routes: > > > > > > > zf zf zf zf zf zf zf find find find find find find find user user user user user user user --id 29110 --id=29110 --firstName=Johny --lastName=Bravo --lastName Bravo --firstName Johny --position=Executive --firstName=Bob --position "Head of the Entertainment Department" Note: The order of flags is irrelevant for the parser. You could use it as a last console route. read about the preferred way of displaying console usage information. regardless of the parameters provided.3 Catchall route This special route will catch all console requests. to display usage information. In previous example. Before you do so. must be properly quoted and written after a space. all value flags are optional.0.

4 Console routes cheat-sheet Param type Literal params Literal Literal alternative Literal. optional alternative Flags Flag long Flag long. optional “-b” or “-z”. “–bar” flag before or after “foo” as first parameter.4. optional Literal. optional. optional Value Flag Value Flag. “-b” flag before or after “foo” as first parameter. “–bar” with a value. optionally followed by any text (stored as “bar” param) “foo” as first parameter. optionally “–bar” with a value. before or after “foo” as first parameter. “bar” or “baz” flag before or after (stored as (--bar|--baz):myParam “myParam” param) foo “foo”. optional Flag short. before or after “foo” as first parameter. before or after foo <bar> foo [<bar>] foo --bar= foo [--bar=] foo “foo” followed by “bar” or “baz” (stored as “myParam” (bar|baz):myParam param) foo “foo” followed by optional “bar” or “baz” (stored as [bar|baz]:myParam “myParam” param) foo “foo”. optional “bar” or “baz” foo --bar foo [--bar] foo [--bar|--baz] foo -b foo [-b] foo [-b|-z] foo [--bar|-b] “foo” as first parameter. before or after “foo” as first parameter. alternative Flag short Flag short. optional “–bar” or “-b” before or after “foo” followed by any text (stored as “bar” param) “foo”. optional “-b” or “-z” flag before or after (stored [-b|-z]:myParam as “myParam” param) 42.0. optional “-b” flag before or after “foo” as first parameter. optional. optional “bar” “foo”. Console routes cheat-sheet 189 . Release 2. optional “bar” or “baz” flag before or after (as [--bar|--baz]:myParam “myParam” param) foo “foo”. optional Flag long. optional “–bar” or “–baz”. optional Parameter groups Literal params group Literal optional params group Long flags group Long optional flags group Short flags group Short optional flags group Example route definition foo foo foo foo bar (bar|baz) [bar] [bar|baz] Explanation “foo” followed by “bar” “foo” followed by “bar” or “baz” “foo”.Zend Framework 2 Documentation.6 42. optional “–bar” flag before or after “foo” as first parameter. alternative Flag long/short alternative Value parameters Value positional param Value positional param. “-b” or “-z” flag before or after (stored as (-b|-z):myParam “myParam” param) foo “foo”.

Zend Framework 2 Documentation. Console routes and routing .6 190 Chapter 42. Release 2.0.

"Version 0. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // modules/Application/Module. 43. In order to do so. Let’s do this now. class Module implements ConsoleBannerProviderInterface { /** * This method is defined in ConsoleBannerProviderInterface */ public function getConsoleBanner(Console $console){ return "==------------------------------------------------------==\n" . we’ll see our newly created banner. The strategy currently supports two types of information: application banners and usage information.0. 191 . " Welcome to my ZF2 Console-enabled app \n" .1 Application banner The first time you run your ZF2 application in a Console. use Zend\ModuleManager\Feature\ConsoleBannerProviderInterface.CHAPTER FORTYTHREE CONSOLE-AWARE MODULES Zend Framework 2 has native MVC integration with console. our Module class has to implement Zend\ModuleManager\Feature\ConsoleBannerProviderInterface. The integration also works with modules loaded with Module Manager.php <?php namespace Application. ZF2 ships with RouteNotFoundStrategy which is responsible of displaying usage information inside Console. in case the user has not provided any arguments. use Zend\Console\Adapter\AdapterInterface as Console. "==------------------------------------------------------==\n" . or arguments could not be understood. } } After running our application. You will see something like this: Our Application module (and any other module) can provide application banner. it will not be able to display any usage information or present itself.1\n" .

User module will add-on a short info about itself: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // modules/User/Module. Release 2.2 Usage information In order to display usage information. 1 2 3 4 5 6 7 <?php // config/application. Let’s modify our example and add new method: 1 2 3 4 5 6 7 8 9 10 11 12 // modules/Application/Module.config.php return array( ’modules’ => array( ’Application’. They will be joined together in the order modules are loaded. Console-aware modules . } } Because User module is loaded after Application module. ConsoleUsageProviderInterface { public function getConsoleBanner(Console $console){ // . } 192 Chapter 43. class Module implements ConsoleBannerProviderInterface. ’User’.no trimming or other adjustments will be performed on the text..php <?php namespace Application. // < load user module in modules/User ). use Zend\ModuleManager\Feature\ConsoleBannerProviderInterface.0.6 Console banners can be provided by 1 or more modules. If you’d like to fit your banner inside console window.Zend Framework 2 Documentation.. use Zend\Console\Adapter\AdapterInterface as Console. Let’s create and load second module that provides a banner. the result will look like this: Note: Application banner is displayed as-is . use Zend\Console\Adapter\AdapterInterface as Console. you could check its width with $console->getWidth(). 43. class Module implements ConsoleBannerProviderInterface { /** * This method is defined in ConsoleBannerProviderInterface */ public function getConsoleBanner(Console $console){ return "User Module BETA1".php <?php namespace User. use Zend\ModuleManager\Feature\ConsoleBannerProviderInterface. use Zend\ModuleManager\Feature\ConsoleUsageProviderInterface. our Module class has to implement Zend\ModuleManager\Feature\ConsoleUsageProviderInterface.

it will be automatically aligned in 2 columns. ’(enable|disable) debug’ => ’Enable or disable debug mode for the application.6 13 14 15 16 17 18 19 20 21 22 23 /** * This method is defined in ConsoleUsageProviderInterface */ public function getConsoleUsage(Console $console){ return array( ’show stats’ => ’Show application statistics’.’ ). If you’d like to fit your usage information inside console window. It will display information for thi } Note: The text provided is displayed as-is . ).user name. which will be joined together and displayed to the user. 1 2 3 4 5 6 7 8 public function getConsoleUsage(Console $console){ return array( ’delete user <userEmail>’ => ’Delete user with email <userEmail>’. you could check its width with $console->getWidth(). ’find user [--email=] [--name=]’ => ’Attempt to find a user by email or name’.2. for example: 1 2 3 public function getConsoleUsage(Console $console){ return ’User module expects exactly one argument . The order in which usage information is displayed is the order in which modules are loaded.0.Zend Framework 2 Documentation. ’disable user <userEmail>’ => ’Disable user with email <userEmail>’. getConsoleUsage() can return a string. Release 2. Note: Usage info provided in modules does not connect with console routing. The first column will be prepended with script name (the entry point for the application). This is useful to display different ways of running the application. } } This will display the following information: Similar to application banner multiple modules can provide usage information.no trimming or other adjustments will be performed. Usage information 193 . You can describe console usage in any form you prefer and it does not affect how MVC handles console commands. ’list [all|disabled] users’ => ’Show a list of users’.2 List of commands If getConsoleUsage() returns and associative array.2. ’run cron’ => ’Run automated jobs’. 43.2.1 Free-form text In order to output free-form text as usage information. } 43. In order to handle real console requests you need to define 1 or more console routes. 43. or an array of strings.

’email of the user’ ). ’user email’ array( ’--verbose’ .e. the array() contains different number of elements) a new table will be started. for example: 1 2 3 4 5 6 public function getConsoleUsage(Console $console){ return array( ’Finding and listing users’. Below is an example: 1 2 3 4 5 6 7 8 9 public function getConsoleUsage(Console $console){ return array( array( ’<userEmail>’ . ’"quick" operation’ array( ’-v’ . Console-aware modules . ’wide output’ ). ’find user [--email=] [--name=]’ => ’Attempt to find a user by email or name’.Zend Framework 2 Documentation. you can always return free-form text that will not be transformed in any way. . for example: 1 2 3 4 5 6 7 8 9 public function getConsoleUsage(Console $console){ return array( array( ’<userEmail>’ . If you don’t like this behavior. possible values and other information.0.3 List of params and flags Returning an array of arrays from getConsoleUsage() will produce a listing of parameters. ’Same as --verbose’ array( ’-w’ . . ’Perform a "quick" operation’ ). } Using this method. array( ’-w’ . ’Wide output’) ).’ ). ’Display additional information during processin ’Do not check integrity. ’verbose mode’ array( ’--quick’ . switches. with new alignment and different column widths. The output will be aligned in multiple columns for readability. 43. } . ’Turn on verbose mode’ ). 194 Chapter 43. array( ’-v’ . If the window is resized. Release 2. you can always return free-form text that will not be transformed in any way.6 Note: Commands and their descriptions will be aligned in two columns. ’list [all|disabled] users [-w]’ => ’Show a list of users’. some texts might be wrapped but all content will be aligned accordingly. that fit inside Console window.2.2. array( ’--verbose’ . . In case the number of columns changes (i. . ’Same as --verbose’ ). some texts might be wrapped but all content will be aligned accordingly. array( ’--quick’ . we can display more than 2 columns of information. just make changes and f ’Display additional information during processin ’When listing users.4 Mixing styles You can use mix together all of the above styles to provide comprehensive usage information. This is useful for explaining flags. use the whole available scr Note: All info will be aligned in one or more columns that fit inside Console window. If you don’t like this behavior. 43. ’Full email address of the user to find. If the window is resized.

just make changes and f ’Display additional information during processin 43. array(’--name=NAME’. ’Display all users or only disabled accounts’). ’Display additional information during processin ’Do not check integrity. => ’Delete user with email <userEmail>’. array(’--email=EMAIL’. array(’-w’. Usage information 195 . } ’<userEmail>’ ’--verbose’ ’--quick’ ’-v’ .’). . . ’Wide output . => ’Disable user with email <userEmail>’.0. ’Full email address of the user to change. . Release 2. ’user email’ ’verbose mode’ ’"quick" operation’ ’Same as --verbose’ . ’Full name of the user to find.Zend Framework 2 Documentation. .When listing users use the whole available screen w ’Manipulation of user database:’.’ ). ’delete user <userEmail> [--verbose|-v] [--quick]’ ’disable user <userEmail> [--verbose|-v]’ array( array( array( array( ). . . ’Email of the user to find’).6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 array(’[all|disabled]’.2.

0. Release 2.Zend Framework 2 Documentation.6 196 Chapter 43. Console-aware modules .

the MVC will invoke a controller and an action.1 Handling console requests Console requests are very similar to HTTP requests. they implement a common interface and are created at the same time in the MVC workflow. ’defaults’ => array( 197 . the request will be routed. please read the chapter Console routes and routing 44. When the user runs an application in a console window. which holds the controller and action keys. To learn about creating console routes. This is analogous to the way HTTP requests are handled in ZF2. See Also: To learn about defining and creating controllers.php array( ’router’ => array( ’routes’ => array( // HTTP routes are here ) ). ’console’ => array( ’router’ => array( ’routes’ => array( ’list-users’ => array( ’options’ => array( ’route’ => ’show [all|disabled|deleted]:mode users [--verbose|-v]’.CHAPTER FORTYFOUR CONSOLE-AWARE ACTION CONTROLLERS Zend Framework 2 has built-in MVC integration with the console. please read the chapter Routing and controllers In this example we’ll use the following simple route: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // FILE: modules/Application/config/module. at least one route must point to it. See Also: In order for a controller to be invoked. These correspond with controller aliases in the ServiceManager.config. In fact. Console routes match against command line arguments and provide a defaults array. In this chapter we will learn how ZF2 Controllers can interact with and return output to console window. By matching command line arguments against console routes we have defined in our application. and method names in the controller class.

Zend Framework 2 Documentation. class IndexController extends AbstractActionController { public function indexAction() { return new ViewModel(). switch ($mode) { case ’disabled’: $users = $this->getServiceLocator()->get(’users’)->fetchDisabledUsers(). case ’deleted’: $users = $this->getServiceLocator()->get(’users’)->fetchDeletedUsers().php show disabled users This route points to the method Application\Controller\IndexController::showUsersAction(). Let’s add it to our controller. // defaults to ’all’ $users = array(). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?php namespace Application\Controller. ’action’ => ’show-users’ ) ) ) ) ) ). and load users from our (theoretical) users service. case ’all’: default: $users = $this->getServiceLocator()->get(’users’)->fetchAllUsers(). In order to make 198 Chapter 44. // display standard index page } public function showUsersAction() { $request = $this->getRequest(). } } } We fetch the console request. Console-aware action controllers . break. break.6 16 17 18 19 20 21 22 23 24 ’controller’ => ’Application\Controller\Index’. ’all’).php show users > php public/index. use Zend\Mvc\Controller\AbstractActionController. ) This route will match commands such as: > php public/index. Release 2.0. // Check verbose flag $verbose = $request->getParam(’verbose’) || $request->getParam(’v’).php show all users > php public/index. break. read parameters. use Zend\View\Model\ViewModel. // Check mode $mode = $request->getParam(’mode’.

we will loop through them with and prepare a listing.2. } $result = ’’. we’ll have to display the result in the console window.2 Sending output to console The simplest way for our controller to display data in the console window is to return a string. // defaults to ’all’ $users = array().0. Let’s modify our example to output a list of users: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public function showUsersAction() { $request = $this->getRequest(). case ’deleted’: $users = $this->getServiceLocator()->get(’users’)->fetchDeletedUsers(). If there are 1 or more users. 44. "\n".6 this method functional. break. case ’all’: default: $users = $this->getServiceLocator()->get(’users’)->fetchAllUsers(). break. // Check verbose flag $verbose = $request->getParam(’verbose’) || $request->getParam(’v’).Zend Framework 2 Documentation. // show it in the console } On line 27. } if (count($users) == 0) { // Show an error message in the console return "There are no users in the database\n".= $user->name . foreach ($users as $user) { $result . Sending output to console 199 . It is then returned from the action and displayed in the console window. This is useful to block certain methods from running in the console or to change their behavior based on that context.otherwise we are returning an error message that will be immediately displayed and the application will end. // Check mode $mode = $request->getParam(’mode’. } return $result. ’all’).3 Are we in a console? Sometimes we might need to check if our method is being called from a console or from a web request. switch ($mode) { case ’disabled’: $users = $this->getServiceLocator()->get(’users’)->fetchDisabledUsers(). $user->email . 44. 44. Release 2. ’ ’ . break. we are checking if the users service found any users .

return $result.... Zend\View\Model\ViewModel. Zend\Console\Request as ConsoleRequest.. } } Note: You do not need to secure all your controllers and methods from console requests. 200 Chapter 44. } else { throw new RuntimeException(’Cannot handle request of type ’ . class IndexController extends AbstractActionController { public function showUsersAction() { $request = $this->getRequest()... fetch users from database . // . Zend\View\Model\ViewModel. use use use use use Zend\Mvc\Controller\AbstractActionController. The example below shows how a single controller method can handle both Console and HTTP requests: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 namespace Application\Controller. Zend\Console\Request as ConsoleRequest. } // . RuntimeException. } elseif ($request instanceof ConsoleRequest) { // .. Release 2. use use use use Zend\Mvc\Controller\AbstractActionController. there is no way for an HTTP action to be invoked unless there is at least one HTTP route that points to it. class IndexController extends AbstractActionController { public function showUsersAction() { $request = $this->getRequest().6 Here is an example of how to check if we are dealing with a console request: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 namespace Application\Controller.0. Controller actions will only be invoked when at least one console route matches it.. Similarly. HTTP and Console routes are separated and defined in different places in module (and application) configuration. RuntimeException.. There is no way to invoke a console action unless there is at least one route pointing to it. // Make sure that we are running in a console and the user has not tricked our // application into running this action from a public web server. $users = array(). get_class($request)). Console-aware action controllers . if ($request instanceof HttpRequest) { // display a web page with users list return new ViewModel($result).Zend Framework 2 Documentation. prepare console output and return it .. if (!$request instanceof ConsoleRequest) { throw new RuntimeException(’You can only use this action from a console!’). Zend\Http\Request as HttpRequest.

Reading values from console parameters 201 . Here. our action can now query parameters in the following way: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // an action inside Application\Controller\UsersController: public function showUsersAction() { $request = $this->getRequest().. 44.4. Release 2.all of them are described in the console routing chapter. it is a good idea to assign a name to the group. ’action’ => ’showusers’ ) ) ) If this route matches. 44. We can do this with the following syntax: 1 2 3 4 5 6 // inside of config. we’ll focus on how to retrieve values from distinct parameters and flags.console. we can access both literal parameters and value parameters from within the $request container.0.4 Reading values from console parameters There are several types of parameters recognized by the Console component . // We can access named value parameters directly by their name: $showUsersFromGroup = $request->getParam(’groupName’).routes: ’show-users’ => array( ’options’ => array( ’route’ => ’show (all|deleted|locked|admin) [<groupName>]’ ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. Assuming we have the following route: 1 2 3 4 5 6 7 8 9 10 // inside of config. which simplifies the branching in our action controllers.1 Positional parameters After a route matches.router. // Literal parameters can be checked with isset() against their exact spelling if (isset($request->getParam(’all’))) { // show all users } elseif (isset($request->getParam(’deleted’))) { // show deleted users } // .Zend Framework 2 Documentation.6 26 27 28 } } } 44.console.4.routes: ’show-users’ => array( ’options’ => array( ’route’ => ’show (all|deleted|locked|admin):userTypeFilter [<groupName>]’ ’defaults’ => array( ’controller’ => ’Application\Controller\Users’..router. } In case of parameter alternatives.

’action’ => ’find’.. $request->getParam(’email’.Zend Framework 2 Documentation. Given the following route: 1 2 3 4 5 6 7 8 9 ’find-user’ => array( ’options’ => array( ’route’ => ’find user [--fast] [--verbose] [--id=] [--firstName=] [--lastName=] [--email=] ’defaults’ => array( ’controller’ => ’Application\Controller\Users’. ) ) ) We can easily retrieve values in the following fashion: 1 2 3 4 5 6 7 8 9 10 11 public function findAction() { $request = $this->getRequest()..2 Flags Flags are directly accessible by name. // default null $request->getParam(’firstName’. Nonvalue flags will be equal to true. Console-aware action controllers . Value-capturing flags will contain string values.6 7 8 9 10 ’action’ ) ) ) => ’showusers’ Now we can use a the group name userTypeFilter to check which option has been selected by the user: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public function showUsersAction() { $request = $this->getRequest(). switch ($userTypeFilter) { case ’all’: // all users case ’deleted’: // deleted users case ’locked’ // . // . $request->getParam(’lastName’. null).0. } } 44.. null). // We can access named value parameters directly by their name: $showUsersFromGroup = $request->getParam(’groupName’). null). Release 2.4.. null). as provided by the user. // We can retrieve $searchId = $searchFirstName = $searchLastName = $searchEmail = values from value flags using their name $request->getParam(’id’. // Standard flags that have been matched will be equal to TRUE 202 Chapter 44. // The selected option from second parameter is now stored under ’userTypeFilter’ $userTypeFilter = $request->getParam(’userTypeFilter’).

// Check both alternatives $isFast = $request->getParam(’fast’. ’..6 12 13 14 15 16 17 18 19 20 $isFast $isVerbose = (bool) $request->getParam(’fast’..false). $isVerbose = $request->getParam(’verbose’. Release 2.false) || $request->getParam(’v’. if ($isFast) { // perform a fast query . Reading values from console parameters 203 . false).false) || $request->getParam(’f’. // default false = (bool) $request->getParam(’verbose’.Zend Framework 2 Documentation..false). // public function findAction() { $request = $this->getRequest().0. } 44... // ..false)..4. we have to check each alternative separately: 1 2 3 4 5 6 7 8 9 10 11 12 13 // Assuming our route now reads: // ’route’ => ’find user [--fast|-f] [--verbose|-v] . } else { // perform standard query .. } } In case of flag alternatives.

Console-aware action controllers .6 204 Chapter 44.0.Zend Framework 2 Documentation. Release 2.

charset and provides basic line drawing capabilities.1 Retreving console adapter If you are using MVC controllers you can obtain Console adapter instance using Service Manager. } catch (ConsoleException $e){ // Could not get console adapter . 1 2 3 4 5 6 7 8 9 10 11 12 13 namespace Application. See Also: Console Adapters can be used for a low-level access to the console. because it provides a convenient way for running modular console applications without directly writing to or reading from console window. Are we running in a console?’) } } } If you are using Zend\Console without MVC.CHAPTER FORTYFIVE CONSOLE ADAPTERS Zend Framework 2 provides console abstraction layer. which works around various bugs and limitations in operating systems. use Zend\Console\Exception\RuntimeException as ConsoleException. if (!$console instanceof Console) { throw new RuntimeException(’Cannot obtain console adapter. use Zend\Console\Adapter\AdapterInterface as Console. If you plan on building functional console applications you do not normally need to use adapters. we can get adapter using the following code: 1 2 3 4 5 6 7 8 use Zend\Console\Console. } 205 . It handles displaying of colored text. class Module { public function testAction() { $console = $this->getServiceManager()->get(’console’).most likely we are not running inside a console window. Make sure to read about console MVC integration first. try { $console = Console::getInstance(). retrieving console window size. 45.

This method will output a newline character at the end of text moving console cursor to next line. $console->getHeight() (int) Get real console window height in characters.2 Using console adapter 45.4 Reading from console $console->readChar( string $mask = null ) (string) Read a single character from console.2. $color = null. use getWidth() and getHeight() methods. 45. 45. For example. we can use the following syntax: $digit = $console->readChar(’0123456789’).2. 45.1 Window size and title $console->getWidth() (int) Get real console window width in characters. getWidth() will return 80. but it’s real.2. $x = 1. Console::getInstance() will always throw an exception if you attempt to get console instance in a non-console environment (i. optionally using foreground $color and background $bgColor. Optional (string) $mask can be provided to force entering only a selected set of characters. visible width is 80 chars. $console->writeAt( string $text.Zend Framework 2 Documentation.0. To retrieve far-right and bottom coordinates. You can override this behavior by manually instantiating one of Zend\Console\Adapter\* classes.2 Character set $console->isUtf8() (boolean) Is the console UTF-8 compatible (can display unicode strings) ? $console->getCharset() (Zend\Console\Charset\CharsetInterface) This method will return one of Console\Charset\* classes that represent the readable charset that can be used for line-drawing. It is automatically detected by the adapter. $bgColor = null ) Write a single line of $text to the console. $bgColor = null ) Write a $text to the console.e.6 Note: For practical and security reasons. $console->writeLine( string $text. MS Windows Command Prompt) width and height represent visible (real) size. int $x.if the window scrolling width is 120 chars. Top left corner of the screen has coordinates of $x = 1. $bgColor = null ) Write $text at the specified $x and $y coordinates of console window. Console adapters . 206 Chapter 45. For example . $color = null.e. $color = null.2. when running on a HTTP server). $console->getSize() (array) Get an array( $width. Note: On consoles with virtual buffers (i.3 Writing to console $console->write( string $text. $console->getTitle() (string) Get console window title. 45. Note: For UTF-8 enabled consoles (terminals) dimensions represent the number of multibyte characters (real characters). $height) with current console window dimensions. to read a single digit. Color value is one of the constants in Zend\Console\ColorInteface. without scrolling the window. int $y. Release 2.

$console->clear() Clear the screen.5 Miscellaneous $console->hideCursor() Hide blinking cursor from console. Using console adapter 207 . The line will be returned without ending newline character.2. $console->clearLine() Clear the line that the cursor currently sits at.2. 45.0.Zend Framework 2 Documentation. Optional (int) $maxLength can be used to limit the length of data that will be read. 45. Release 2. $console->showCursor() Show blinking cursor in console.6 $console->readLine( int $maxLength = 2048 ) (string) Read a single line of input from console.

Zend Framework 2 Documentation. Console adapters . Release 2.6 208 Chapter 45.0.

because it provides a convenient way for running modular console applications without directly writing to or reading from console window. if ($result) { // the user chose to continue } There is also a shorter method of displaying prompts. 209 . $noChar (string) The char that corresponds with NO choice. 1 2 3 4 5 6 7 use Zend\Console\Prompt. string $yesChar = ’y’. string $noChar = ’n’ ) $text (string) The text to show with the prompt $yesChar (string) The char that corresponds with YES choice. $confirm = new Prompt\Confirm(’Are you sure you want to continue?’). using static prompt() method: 1 2 3 4 5 6 use Zend\Console\Prompt. $result = $confirm->show(). 46. Confirm( string $text.CHAPTER FORTYSIX CONSOLE PROMPTS In addition to console abstraction layer Zend Framework 2 provides numerous convenience classes for interacting with the user in console environment. if ($result) { // the user chose to continue } Both of above examples will display something like this: See Also: Make sure to read about console MVC integration first. Defaults to y. This chapter describes available Zend\Console\Prompt classes and their example usage. $result = Prompt\Confirm::prompt(’Are you sure you want to continue?’). All prompts can be instantiated as objects and provide show() method.1 Confirm This prompt is best used for a yes / no type of choices. Defaults to n.

false.Zend Framework 2 Documentation. $allowedChars = ’abc’. Release 2.0. } else { $console->write("You chose NO"). Anythin above this limit will be truncated. } 46. ’y’. 100 ). $name = Line::prompt( ’What is your name?’. Example usage: use Zend\Console\Prompt\Line. Line( string $text = ’Please enter value’. $echo = true $text (string) The text to show with the prompt $allowedChars (string) A list of allowed keys that can be pressed. $ignoreCase = true. 210 Chapter 46. if ( Confirm::prompt(’Is this the correct answer? [y/n]’. bool $maxLength = 2048 ) $text (string) The text to show with the prompt $allowEmpty (boolean) Can this prompt be skipped. $console->write("Good day to you $name!"). 46.6 Example usage: use Zend\Console\Prompt\Confirm.3 Char This prompt reads a single keystroke and optionally validates it against a list o allowed characters. bool $allowEmpty = false. Char( string string bool bool bool ) $text = ’Please hit a key’. $allowEmpty = false.2 Line This prompt asks for a line of text input. ’n’) ) { $console->write("You chose YES"). Console prompts . by pressing [ENTER] ? (default fo false) $maxLength (integer) Maximum length of the input.

Zend Framework 2 Documentation. false.4 Select This prompt displays a number of choices and asks the user to pick one. if ($answer == ’b’) { $console->write(’Correct. } else { $console->write(’Wrong ! Try again..’). Select( string array bool bool ) $text = ’Please select one option’. true. } 46. ’Bananas’. $allowEmpty = false. false 46.0..e]’. by pressing [ENTER] ? (default fo false) $echo (boolean) Should the selection be displayed on the screen ? Example usage: $options = ’a’ => ’o’ => ’p’ => ’b’ => ’n’ => ). $options.b. $answer = Char::prompt( ’What is the correct answer? [a. $echo = false $text (string) The text to show with the prompt $options (array) An associative array with keys strokes (chars) and their displayed values. ’Pears’. ’abcde’.6 $ignoreCase (boolean) Ignore the case of chars pressed (default to true) $allowEmpty (boolean) Can this prompt be skipped.c. true ). Release 2.d. $allowEmpty (boolean) Can this prompt be skipped. array( ’Apples’. $options = array(). Select 211 . ’Oranges’. This it the right answer’).4. ’none of the above. by pressing [ENTER] ? (default fo false) $echo (boolean) Should the selection be displayed on the screen ? Example usage: use Zend\Console\Prompt\Char. false.’ $answer = Select::prompt( ’Which fruit do you like the best?’.

0. See Also: To learn more about accessing console. 212 Chapter 46. $options[$answer]). writing to and reading from it. $console->write("You told me that you like " . make sure to read the following chapter: Console adapters. Release 2. Console prompts .6 ).Zend Framework 2 Documentation.

“Cryptography Engineering”. RSA algorithm). • generate digital sign using public key algorithm (e.Kohno. and T. John Wiley & Sons (2010) • B. 213 . Coursera .free online course • N.g. • key exchange using the Diffie-Hellman method.Schneier “Applied Cryptography”. The available features are: • encrypt-then-authenticate using symmetric ciphers (the authentication step is provided using HMAC). Because the use of cryptography is not so easy we recommend to use the Zend\Crypt component only if you have a minimum background on this topic. • Secure password hash (e. • generate HMAC values.Schneier.CHAPTER FORTYSEVEN INTRODUCTION Zend\Crypt provides support of some cryptographic tools. The main scope of this component is to offer an easy and secure way to protect and authenticate sensitive data in PHP. PHP-CryptLib is an all-inclusive pure PHP cryptographic library for all cryptographic needs.g. yet extensible and powerful enough for even the most experienced developer. using PBKDF2 algorithm).Ferguson. B. • Key derivation function (e. It is meant to be easy to install and use.g. For an introduction to cryptography we suggest the following references: • Dan Boneh “Cryptography course” Stanford University.g. • encrypt/decrypt using symmetric and public key algorithm (e. RSA algorithm). • generate Hash values. John Wiley & Sons (1996) Note: PHP-CryptLib Most of the ideas behind the Zend\Crypt component have been inspired by the PHP-CryptLib project of Anthony Ferrara. using Bcrypt algorithm).

6 214 Chapter 47. Release 2.0.Zend Framework 2 Documentation. Introduction .

$blockCipher = BlockCipher::factory(’mcrypt’. used as key derivation function from the user’s key specified using the setKey() method. The encryption and authentication keys used by the BlockCipher are generated with the PBKDF2 algorithm. The Mcrypt adapter encrypts using the PKCS#7 padding mechanism by default. In order to encrypt a string we need to specify an encryption key and we used the setKey() method for that scope. echo "Encrypted text: $result \n". that contains the HMAC value. For instance. The BlockCipher is initialized using a factory method with the name of the cipher adapter to use (mcrypt) and the parameters to pass to the adapter (the AES algorithm). encoded in Base64 (default). $result = $blockCipher->encrypt(’this is a secret message’). 1 2 3 4 5 6 use Zend\Crypt\BlockCipher. array(’algo’ => ’aes’)). The adapter that implements the Mcrypt is Zend\Crypt\Symmetric\Mcrypt. and the encrypted text.CHAPTER FORTYEIGHT ENCRYPT/DECRYPT USING BLOCK CIPHERS Zend\Crypt\BlockCipher implements the encrypt-then-authenticate mode using HMAC to provide authentication. We support the standard algorithms of the Mcrypt extension. The encryption is provided by the encrypt() method. the IV vector. You can specify a different padding method using a special adapter for that (Zend\Crypt\Symmetric\Padding). In the following code we reported an example on how to use the BlockCipher class to encrypt-then-authenticate a string using the AES block cipher (with a key of 256 bit) and the HMAC algorithm (using the SHA-256 hash function). The output of the encryption is a string. with the CFB mode and the SHA512 hash function for HMAC you have to initialize the class as follow: 1 2 3 use Zend\Crypt\BlockCipher. $blockCipher = BlockCipher::factory(’mcrypt’. For instance. array( 215 . Note: Key size BlockCipher try to use always the longest size of the key for the specified cipher. if you want to use the Blowfish algorithm. The encryption mode used is the CBC (with a random IV by default) and SHA256 as default hash algorithm of the HMAC. $blockCipher->setKey(’encryption key’). You can change all the default settings passing the values to the factory parameters. for the AES algorithm it uses 256 bits and for the Blowfish algorithm it uses 448 bits. The symmetric cipher can be choose with a specific adapter that implements the Zend\Crypt\Symmetric\SymmetricInterface.

We can also initialize the BlockCipher manually without use the factory method. ’mode’ => ’cfb’. echo "Encrypted text: $result \n".0.Zend Framework 2 Documentation. 216 Chapter 48. We can inject the symmetric cipher adapter directly to the constructor of the BlockCipher class. $blockCipher = new BlockCipher(new Mcrypt(array(’algo’ => ’aes’)). To decrypt a string we can use the decrypt() method. CBC mode. $blockCipher->setKey(’encryption key’). Encrypt/decrypt using block ciphers . In order to successfully decrypt a string we have to configure the BlockCipher with the same parameters of the encryption. PKCS#7 padding. use Zend\Crypt\Symmetric\Mcrypt. $result = $blockCipher->encrypt(’this is a secret message’). Release 2. HMAC with SHA256. ’hash’ => ’sha512’ )). Note: Recommendation If you are not familiar with symmetric encryption techniques we strongly suggest to use the default values of the BlockCipher class. For instance. The default values are: AES algorithm. we can rewrite the previous example as follow: 1 2 3 4 5 6 7 use Zend\Crypt\BlockCipher.6 4 5 6 7 ’algo’ => ’blowfish’.

There is not a fixed value for that because the number of iterations depends on the CPU power. The syntax is calc($hash.1 Pbkdf2 adapter Pbkdf2 is a KDF that applies a pseudorandom function. The added computational work makes password cracking much more difficult. which can then be used as a cryptographic key in subsequent operations. 49. For instance. a value of 1‘000‘000 iterations. true). The number of iterations is a very important parameter for the security of the algorithm. We used the Rand::getBytes function of the Zend\Math\Rand class to generate a random bytes using a strong generators (the true value means the usage of strong generators). a KDF function can be used to generate encryption or authentication keys from a user password. $pass is the password. $iterations. $salt = Rand::getBytes(strlen($pass). $key = Pbkdf2::calc(’sha256’. echo "Key derivation : $key \n". $salt. $length) where $hash is the name of the hash function to use. You should always choose a number of iteration that prevent brute force attacks. to the input password or passphrase along with a salt value and repeats the process many times to produce a derived key. The Pbkdf2 adapter takes the password ($pass) and generate a binary key with a size double of the password. It is highly recommended to use always a KDF function of transformation a user’s password to a cryptography key. such as a cryptographic hash. that is equal to 1 sec of elaboration for the PBKDF2 algorithm. In the example below we show a typical usage of the Pbkdf2 adapter. $salt. since users normally choose keys they can write on keyboard.3 Ghz. a key derivation function (or KDF) derives one or more secret keys from a secret value such as a master key or other known information such as a password or passphrase using a pseudo-random function. use Zend\Math\Rand. $iterations is the number of iterations of the algorithm and $length is the size of the key to be generated. and is known as key stretching. $pass. echo "Original password: $pass \n". is enough secure using an Intel Core i5-2500 CPU at 3. Big values means more security. $salt is a pseudo random value. 10000.CHAPTER FORTYNINE KEY DERIVATION FUNCTION In cryptography. For instance. User passwords are not really suitable to be used as keys in cryptographic algorithms. $pass = ’password’. 217 . $pass. strlen($pass)*2). 1 2 3 4 5 6 7 8 9 use Zend\Crypt\Key\Derivation\Pbkdf2. The Zend\Crypt\Key\Derivation implements a key derivation function using specific adapters. These passwords use only 6 to 7 bits per character (or less).

$pass = ’password’. Below is reported a usage example of the SaltedS2k adapter. use Zend\Math\Rand.2 SaltedS2k adapter The SaltedS2k algorithm uses an hash function and a salt to generate a key based on a user’s password.Zend Framework 2 Documentation. Key derivation function . Release 2.0. echo "Original password: $pass \n". true). strlen($pass)*2). echo "Key derivation : $key \n". $pass. This algorithm doesn’t use a parameter that specify the number of iterations and for that reason it’s considered less secure compared with Pbkdf2.6 49. $salt = Rand::getBytes(strlen($pass). 1 2 3 4 5 6 7 8 9 use Zend\Crypt\Key\Derivation\SaltedS2k. $key = SaltedS2k::calc(’sha256’. 218 Chapter 49. We suggest to use the SaltedS2k algorithm only if you really need it. $salt.

$securePass = ’the stored bcrypt value’. } else { echo "The password is NOT correct.7 and the prefix used in the output was changed to ‘$2y$’ in order to put evidence on the correctness of the hash value. Example time: 1 2 3 4 5 6 7 8 9 10 11 use Zend\Crypt\Password\Bcrypt. If you are using PHP < 5. 219 . Note: Bcrypt with non-ASCII passwords (8-bit characters) The bcrypt implementation used by PHP < 5. This security flaw has been fixed starting from PHP 5. The cost parameter is an integer between 4 to 31. The output of the create() method is the encrypted password. the Zend\Crypt\Password\Bcrypt throws an exception suggesting to upgrade to PHP 5. thus more secure against brute force or dictionary attacks.\n". $bcrypt = new Bcrypt(). the Zend\Crypt\Password\Bcrypt class uses a value of 14 for bcrypts cost parameter. $bcrypt = new Bcrypt(). To verify if a given password is valid against a bcrypt value you can use the verify() method. A greater value means longer execution time for bcrypt. The example below shows how to use the bcrypt algorithm to store a user’s password: 1 2 3 4 use Zend\Crypt\Password\Bcrypt.7 can contains a security flaw if the password uses 8-bit characters (here’s the security report).CHAPTER FIFTY SECURE PASSWORD STORING Zend\Crypt\Password stores a user’s password in a secure way using dedicated adapters like the bcrypt algorithm.3.7 with 8-bit passwords.3.7+ or use only 7-bit passwords. } By default. If you want to change the cost parameter of the bcrypt algorithm you can use the setCost() method.3. Classic hashing mechanisms like MD5 or SHA are not considered secure anymore (read this post to know why). if ($bcrypt->verify($password. $password = ’the password to check’. The impact of this bug was that most (but not all) passwords containing non-ASCII characters with the 8th bit set were hashed incorrectly. $securePass)) { echo "The password is correct! \n".3. resulting in password hashes incompatible with those of OpenBSD’s original implementation of bcrypt. $securePass = $bcrypt->create(’user password’). This value can then be stored in a repository like a database.

Release 2. Secure Password Storing .6 220 Chapter 50.0.Zend Framework 2 Documentation.

Neither key can perform both functions. while the other is kept private. Here is reported an example of usage using the Zend\Crypt\PublicKey\DiffieHellman class: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 use Zend\Crypt\PublicKey\DiffieHellman. In Zend Framework we implemented two public key algorithms: Diffie-Hellman key exchange and RSA. It is one of the earliest practical examples of key exchange implemented within the field of cryptography. ’private’ => ’9920931406657259523640856959196798855714124956149426748625180803553539633227862014 ’81312712891672623072630995180324388841681491857745515696789091127409515009250358965 ’46342049838178521379132153348139908016819196219448310107072632515749339055798122538 ’04828702523796951800575031871051678091’ ). The diagram of operation of the Diffie-Hellman algorithm can be defined by the following picture (taken by the DiffieHellman Wikipedia page): The schema’s colors represent the parameters of the algorithm. One key locks or encrypts the plaintext. 51. This key can then be used to encrypt subsequent communications using a symmetric key cipher.CHAPTER FIFTYONE PUBLIC KEY CRYPTOGRAPHY Public-key cryptography refers to a cryptographic system requiring two separate keys. Although different.1 Diffie-Hellman The Diffie-Hellman algorithm is a specific method of exchanging cryptographic keys. The Diffie–Hellman key exchange method allows two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure communications channel. ’generator’=> ’2’. One of these keys is published or public. ’private’ => ’3341173579263955862573363571789256361254818065040216115107747831484146370794889978 ’1232563473041055194677275288017786897281696355182174038670007603421340815392469256 221 . one of which is secret and one of which is public. ’generator’=> ’2’. the two parts of the key pair are mathematically linked. and the other unlocks or decrypts the cyphertext. $aliceOptions = array( ’prime’ => ’1551728981814736974712322577637155399157248019669154044797077953140576293785419175 ’4236981889937278161526466314385615958256881888899512721588426754199503412587065565 ’1048705376814767265132557470407658574792912915723345106432450947150072296210941943 ’984760375594985848253359305585439638443’. $bobOptions = array( ’prime’ => $aliceOptions[’prime’].

DiffieHellman::FORMAT_BINARY). if the public key is large enough. Release 2. a generator (g) that is a primitive root mod p and a private integer number. as their public key. • encrypt/decrypt a string. $aliceSecretKey = $alice->computeSecretKey($bob->getPublicKey(DiffieHellman::FORMAT_BINARY). Anyone can use the public key to encrypt a message. } else { printf("The secret key is: %s\n". applying the encryption first and the digital signature after.2 RSA RSA is an algorithm for public-key cryptography that is based on the presumed difficulty of factoring large integers. $alice->generateKeys(). The prime factors must be kept secret. Whether breaking RSA encryption is as hard as factoring is an open question known as the RSA problem. Bob can check the correctness of the digital signature using the public key of Alice. authenticity and integrity of a message to Bob using the previous schemas in sequence. he is the only one that can decrypt the message. The security of the Diffie-Hellman exchange algorithm is related to the choice of these parameters. base64_encode($aliceSecretKey)). only someone with knowledge of the prime factors can feasibly decode the message. To know how to choose secure numbers you can read the RFC 3526 document. Because Bob he is the only one that can access to his private key. A user of RSA creates and then publishes the product of two large prime numbers. If you want don’t want to use the OpenSSL library you have to set the useOpensslExtension static method to false. if ($aliceSecretKey !== $bobSecretKey) { echo "ERROR!\n". Alice can provide encryption. Below we reported some examples of usage of the Zend\Crypt\PublicKey\Rsa class in order to: • generate a public key and a private key. $alice = new DiffieHellman($aliceOptions[’prime’]. 51.0. Bob can decrypt the message using his private key. the factoring problem. 222 Chapter 51. If Alice wants to provide authenticity and integrity of a message to Bob she can use her private key to sign the message. Note: The Zend\Crypt\PublicKey\DiffieHellman class use by default the OpenSSL extension of PHP to generate the parameters. $bob->generateKeys(). $aliceOptions[’generator’]. $bobOptions[’private’]). Suppose that Alice wants to send an encrypted message to Bob. The RSA algorithm can be used to encrypt/decrypt message and also to provide authenticity and integrity generating a digital signature of a message. along with an auxiliary value. DiffieHellman::FORMAT_BINARY). DiffieHellman::FORMAT_BINARY. $bobSecretKey = $bob->computeSecretKey($alice->getPublicKey(DiffieHellman::FORMAT_BINARY). $bobOptions[’generator’]. $aliceOptions[’private $bob = new DiffieHellman($bobOptions[’prime’]. Public key cryptography .Zend Framework 2 Documentation. Alice must use the public key of Bob to encrypt the message.6 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 ’6346473315660054548451083307242700347420706465071483108330449773716038209708335687 ’31616972608703322302585471319261275664’ ). } The parameters of the Diffie-Hellman class are: a prime number (p). but with currently published methods. DiffieHellman::FORMAT_BINARY.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 use Zend\Crypt\PublicKey\Rsa.88 bits.pub’. ’private_key’ => ’private_key. $rsaOptions->getPrivateKey()).1 Generate a public key and a private key In order to generate a public and private key you can use the following code: 1 2 3 4 5 6 7 8 9 10 11 12 use Zend\Crypt\PublicKey\RsaOptions.pem for the private key and the public_key. $rsaOptions->getPublicKey()).2. The maximum size of encryption is given by the length of the public/private key .0. This example generates a public and privat key of 2048 bit storing the keys in two separate files. printf("Encrypted message:\n%s\n".pub’.pem’. You can encrypt only small strings.pem’.pub for the public key. For instance. )).2 Encrypt and decrypt a string Below is reported an example on how to encrypt and decrypt a string using the RSA algorithm. $decrypt = $rsa->decrypt($encrypt). This limitation is related to the OpenSSL implementation for a security reason related to the nature of the RSA algorithm. file_put_contents(’private_key.2. An AES encryption key is 128 to 256 bits. $rsaOptions->generateKeys(array( ’private_key_bits’ => 2048.Zend Framework 2 Documentation. if ($text !== $decrypt) { echo "ERROR\n". $rsaOptions = new RsaOptions(array( ’pass_phrase’ => ’test’ )). ’binary_output’ => false )). $rsa = Rsa::factory(array( ’public_key’ => ’public_key. A hash is typically 128-256 bits (the PHP sha1() function returns a 160 bit hash). the private_key. The normal application of a public key encryption algorithm is to store a key or a hash of the data you want to respectively encrypt or sign. $text = ’This is the message to encrypt’. You can also generate the public and private key using OpenSSL from the command line (Unix style syntax): ssh-keygen -t rsa 51. file_put_contents(’public_key. } else { 51. ’pass_phrase’ => ’test’. 51.2. $encrypt). RSA 223 . So either of those will comfortably fit inside a single RSA encryption. if we use a size of 2048 bit you can encrypt string with a maximum size of 1960 bit (245 characters).6 • generate a digital signature of a file. $encrypt = $rsa->encrypt($text). Release 2.

} else { echo "The signature is not valid!\n". ’pass_phrase’ => ’passphrase of the private key’. if ($verify) { echo "The signature is OK\n". ’binary_output’ => false )). ’. $rsa->getOptions()->getPrivateKey()). Note: The implementation of Zend\Crypt\PublicKey\Rsa algorithm uses the OpenSSL extension of PHP. $rsa = Rsa::factory(array( ’private_key’ => ’path/to/private_key’. Public key cryptography .Zend Framework 2 Documentation. file_put_contents($filename . 224 Chapter 51.0. $rsa->getOptions()->getPublicKey()). } In this example we used the Base64 format to encode the digital signature of the file (binary_output is false). $signature. $signature). $file = file_get_contents(’path/file/to/sign’).sig’. Release 2. } 51.3 Generate a digital signature of a file Below is reported an example of how to generate a digital signature of a file.6 20 21 echo "Encryption and decryption performed successfully!\n". 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 use Zend\Crypt\PublicKey\Rsa.sig\n". $signature = $rsa->sign($file. $verify = $rsa->verify($file. echo "Signature save in $filename.2.

The most common use case. ’database’ => ’zend_db_example’. It is responsible for adapting any code written in or for Zend\Db to the targeted php extensions and vendor databases. UID will work in place of username. Another example is that in the case of Sqlsrv. ’password’ => ’developer-password’ )).Quickstart Creating an adapter can simply be done by instantiating the Zend\Db\Adapter\Adapter class. Effectively. of a Sqlite connection via PDO: 225 .CHAPTER FIFTYTWO ZEND\DB\ADAPTER The Adapter object is the most important sub-component of Zend\Db. Pdo_Sqlite. For example. it creates an abstraction layer for the PHP extensions. while not the most explicit. is to pass an array of configuration to the Adapter. It also creates a lightweight abstraction layer. Pdo_Mysql. called the “Platform” portion of the adapter. if the PHP manual uses a particular naming. but the above table represents the official abstraction names. Pdo=OtherPdoDriver the name of the database (schema) the connection username the connection password the IP address or hostname to connect to the port to connect to (if applicable) the character set to use Note: Other names will work as well. So. Here is a table for the key-value pairs that should be in configuration array. dbname in most cases will also work for ‘database’. Another example. for the various idiosyncrasies that each vendor-specific platform might have in its SQL/RDBMS implementation. which is called the “Driver” portion of the Zend\Db adapter. for example.1 Creating an Adapter . 52. this naming will be supported by our Driver. Sqlsrv. In doing this. Which format you chose is up to you. 1 $adapter = new Zend\Db\Adapter\Adapter($configArray). This driver array is an abstraction for the extension level required parameters. Key driver database username password hostname port charset Is Required? required generally required generally required generally required not generally required not generally required not generally required Value Mysqli. ’username’ => ’developer’. a MySQL connection using ext/mysqli: 1 2 3 4 5 6 $adapter = new Zend\Db\Adapter\Adapter(array( ’driver’ => ’Mysqli’.

(optional) an instance of Zend\Db\Platform\PlatformInterface. Release 2. ’database’ => ’path/to/sqlite. class Zend\Db\Adapter\Adapter { public function __construct($driver. array(5)).Zend Framework 2 Documentation. A Driver object will be created from the configuration array provided in the constructor.db’ )). see the section below on querying through the adapter 52. PlatformInterface $platform = null. and then the parameters for those placeholders are supplied separately. a default ResultSet object is created and utilized.6 1 2 3 4 $adapter = new Zend\Db\Adapter\Adapter(array( ’driver’ => ’Pdo_Sqlite’. This generally means that you will supply a SQL statement with the values substituted by placeholders. An example of this workflow with Zend\Db\Adapter\Adapter is: 1 $adapter->query(’SELECT * FROM ‘artist‘ WHERE ‘id‘ = ?’. query() prefers that you use “preparation” as a means for processing SQL statements. and all required dependencies are injected through the constructor. to understand this object’s role. And lastly.(optional) an instance of Zend\Db\ResultSet\ResultSet. ResultSet $queryResultSe } What can be injected: • $driver an array of connection parameters Zend\Db\Adapter\Driver\DriverInterface (see above) or an instance of • $platform . It is important to know that by using this style of adapter creation. Zend\Db\Adapter . the Adapter will attempt to create any dependencies that were not explicitly provided. A Platform object will be created based off the type of Driver class that was instantiated. see the next section.0. The above example will go through the following steps: 226 Chapter 52. Any of these objects can be injected. Zend\Db\Adapter\Adapter uses constructor injection. to do this. the default will be created based off the driver implementation • $queryResultSetPrototype . which has the following signature (in pseudo-code): 1 2 3 4 5 6 use Zend\Db\Adapter\Platform\PlatformInterface.3 Query Preparation Through Zend\Db\Adapter\Adapter::query() By default.2 Creating an Adapter Using Dependency Injection The more expressive and explicit way of creating an adapter is by injecting all your dependencies up front. The list of officially supported drivers: • Mysqli: The ext/mysqli driver • Pgsql: The ext/pgsql driver • Sqlsrv: The ext/sqlsrv driver (from Microsoft) • Pdo_Mysql: MySQL through the PDO extension • Pdo_Sqlite: SQLite though the PDO extension • Pdo_Pgsql: PostgreSQL through the PDO extension 52. use Zend\Db\ResultSet\ResultSet.

so that you have greater control over the prepare-then-execute workflow. might be because you are attempting to execute a DDL statement (which in most extensions and vendor platforms). To do this. Adapter gives you a routine called createStatement() that allows you to create a Driver specific Statement to use so you can manage your own prepare-then-execute workflow.6 Using the Driver Object The Driver object is the primary place where Zend\Db\Adapter\Adapter implements the connection level abstraction making it possible to use all of ZendDb’s interfaces via the various ext/mysqli.5 Creating Statements While query() is highly useful for one-off and quick querying of a database through Adapter. To make this possible. each driver is composed of 3 objects: • A connection: Zend\Db\Adapter\Driver\ConnectionInterface • A statement: Zend\Db\Adapter\Driver\StatementInterface • A result: Zend\Db\Adapter\Driver\ResultInterface Each of the built-in drivers practices “prytotyping” as a means of creating objects when new instances are requested. it generally makes more sense to create a statement and interact with it directly. clone the ResultSet prototype. Query Execution Through Zend\Db\Adapter\Adapter::query() 227 . and other PHP level drivers. 1 2 3 // with optional parameters to bind up-front $statement = $adapter->createStatement($sql. The primary difference to notice is that you must provide the Adapter::QUERY_MODE_EXECUTE (execute) as the second parameter. ext/sqlsrv. return the Result 52. Adapter::QUERY_MODE_EXECUTE). The workflow looks like this: • An adapter is created with a set of connection parameters • The adapter chooses the proper driver to instantiate. $result = $statement->execute(). or a result set producing statement • if it is a result set producing query. return it • else. 52.Zend Framework 2 Documentation. PDO. producing a Result object • check the Result object to check if the supplied sql was a “query”. Release 2. for example Zend\Db\Adapter\Driver\Mysqli • That driver class is instantiated 52. inject Result as datasource.0. are un-preparable. The primary purpose for needing to execute sql instead of prepare and execute a sql statement.4. $optionalParameters). An example of executing: 1 $adapter->query(’ALTER TABLE ADD INDEX(‘foo_index‘) ON (‘foo_column‘)’.6 • create a new Statement object • prepare an array into a ParameterContainer if necessary • inject the ParameterContainer into the Statement object • execute the Statement object. you have to execute statements directly. 52.4 Query Execution Through Zend\Db\Adapter\Adapter::query() In some cases.

interface StatementInterface extends StatementContainerInterface { public function getResource(). const PARAMETERIZATION_NAMED = ’named’. public function createStatement($sqlOrResource = null). statement or result objects are injected. defaults are instantiated This driver is now ready to be called on when particular workflows are requested. you can • Determine the name of the platform this driver supports (useful for choosing the proper platform object) • Check that the environment can support this driver • Return the Connnection object • Create a Statement object which is optionally seeded by an SQL statement (this will generally be a clone of a prototypical statement object) • Create a Result object which is optionally seeded by a statement resource (this will generally be a clone of a prototypical result object) • Format parameter names. public function createResult($resource). public function formatParameterName($name. const NAME_FORMAT_CAMELCASE = ’camelCase’. public function checkEnvironment(). public function isPrepared(). Release 2. /** Inherited from StatementContainerInterface */ public function setSql($sql). $type = null). public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE). const NAME_FORMAT_NATURAL = ’natural’. } From this DriverInterface. public function setParameterContainer(ParameterContainer $parameterContainer). public function prepare($sql = null). Zend\Db\Adapter . public function getParameterContainer().0.6 • If no connection. public function execute($parameters = null). public function getSql(). public function getLastGeneratedValue(). Here is what the Driver API looks like: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 namespace Zend\Db\Adapter\Driver. public function getPrepareType(). } Result objects generally look like this: 228 Chapter 52.Zend Framework 2 Documentation. public function getConnection(). interface DriverInterface { const PARAMETERIZATION_POSITIONAL = ’positional’. important to distinguish the difference between the various ways parameters are named between extensions • Retrieve the overall last generated value (such as an auto-increment value) Statement objects generally look like this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 namespace Zend\Db\Adapter\Driver.

// " echo $platform->getQuoteIdentifierSymbol(). generally speaking. public function getFieldCount(). public function getGeneratedValue(). public function quoteValueList($valueList). public function isQueryResult().0. // "schema".Zend Framework 2 Documentation. // "first_name" echo $platform->quoteIdentifier(’first_name’). // or $platform = $adapter->platform.’mytable’))). interface ResultInterface extends \Countable. the interface for a platform object looks like this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 namespace Zend\Db\Adapter\Platform. public function quoteIdentifier($identifier).6 1 2 3 4 5 6 7 8 9 10 11 namespace Zend\Db\Adapter\Driver.7 Using The Platform Object The Platform object provides an API to assist in crafting queries in a way that is specific to the SQL implementation of a particular vendor. public function getAffectedRows()."mytable" echo $platform->quoteIdentifierChain(array(’schema’. public function getQuoteIdentifierSymbol(). To get an idea of the capabilities. } While one can instantiate your own Plaform object. array $additionalSafeWords = array()). it is easier to get the proper Platform instance from the configured adapter (by default the Platform type will match the underlying driver implementation): 1 2 3 $platform = $adapter->getPlatform(). public function getIdentifierSeparator(). interface PlatformInterface { public function getName(). Nuances such as how identifiers or values are quoted. Release 2. } 52. \Iterator { public function buffer(). public function quoteIdentifierInFragment($identifier. // magic property access The following is a couple of example of Platform usage: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 /** @var $adapter Zend\Db\Adapter\Adapter */ /** @var $platform Zend\Db\Adapter\Platform\Sql92 */ $platform = $adapter->getPlatform(). Using The Platform Object 229 .7. or what the identifier separator character is are handled by this object. public function quoteIdentifierChain($identiferChain) public function getQuoteValueSymbol(). public function getResource(). public function quoteValue($value). // ’ 52.

// ’myvalue’ echo $platform->quoteValue(’myvalue’)."baz") echo $platform->quoteIdentifierInFragment(’(foo. ’)’.6 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 echo $platform->getQuoteValueSymbol(). Below is the ParameterContainer API: namespace Zend\Db\Adapter. class ParameterContainer implements \Iterator. // "foo" as "bar" echo $platform->quoteIdentifierInFragment(’foo as bar’)."Foo O’Bar"))).baz)’.Zend Framework 2 Documentation. Zend\Db\Adapter . This object implements the ArrayAccess interface. // additionally. ’=’)). $from) public function offsetSet($name.bar = boo. 52. echo $platform->getIdentifierSeparator(). $errata = null) public function offsetUnset($name) /** set values from array (will reset first) */ public function setFromArray(Array $data) /** methods to interact with value errata */ public function offsetSetErrata($name.8 Using The Parameter Container The ParameterContainer object is a container for the various parameters that need to be passed into a Statement object to fulfill all the various parameterized parts of the SQL statement. ordered by position */ public function getPositionalArray() /** iterator: */ public function count() 230 Chapter 52. ’Foo O\\’Bar’ echo $platform->quoteValueList(array(’value’. Release 2. // .0. $value. array(’(’. \ArrayAccess. with some safe words: // ("foo". // ’value’."bar" = "boo". \Countable { public function __construct(array $data = array()) /** methods to interact with values */ public function offsetExists($name) public function offsetGet($name) public function offsetSetReference($name. $errata) public function offsetGetErrata($name) public function offsetHasErrata($name) public function offsetUnsetErrata($name) /** errata only iterator */ public function getErrataIterator() /** get array with named keys */ public function getNamedArray() /** get array with int keys.

$qi(’artist’) . $fp(’id’)).9 Examples Creating a Driver and Vendor portable Query. $statement->execute($parameters). that this translated information will also be passed along to the actual php database driver. Release 2. 52. $qi(’id’) . 5. Preparing and Iterating Result 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 $adapter = new Zend\Db\Adapter\Adapter($driverConfig). $fp(’id’). NOW CHECK /* @var $statement Zend\Db\Adapter\DriverStatementInterface */ $statement = $adapter->query(’SELECT * FROM ’ . $qi = function($name) use ($adapter) { return $adapter->platform->quoteIdentifier($name). $qi(’artist’) . Examples 231 . This will ensure that if the underlying driver supports typing of bound parameters. 52. ’id’ => 1 ).6 public public public public public function function function function function current() next() key() valid() rewind() /** merge existing array of parameters with existing parameters */ public function merge($parameters) } In addition to handling parameter names and values. 5). }. be bound as an integer. $sql = ’UPDATE ’ . ’ WHERE id = ’ . For example. it might be important that: $container->offsetSet(’limit’. $parameters = array( ’name’ => ’Updated Artist’. ’ WHERE ’ .0. /* @var $results Zend\Db\ResultSet\ResultSet */ $results = $statement->execute(array(’id’ => 1)). pass in the ParameterContainer::TYPE_INTEGER constant as the 3rd parameter: $container->offsetSet(’limit’.Zend Framework 2 Documentation. ’ SET ’ . $container::TYPE_INTEGER). ’ = ’ . To achieve this. /** @var $statement Zend\Db\Adapter\Driver\StatementInterface */ $statement = $adapter->query($sql). }. $fp = function($name) use ($adapter) { return $adapter->driver->formatParameterName($name). $qi(’name’) . ’ = ’ . $fp(’name’) .9. the container will assist in tracking parameter types for PHP type to SQL type handling. // DATA INSERTED.

$name = $row[’name’].6 30 31 $row = $results->current().0.Zend Framework 2 Documentation. 232 Chapter 52. Release 2. Zend\Db\Adapter .

Zend\Db\ResultSet‘s must implement the Zend\Db\ResultSet\ResultSetInterface and all subcomponents of Zend\Db that return a ResultSet as part of their API will assume an instance of a ResultSetInterface should be returned. While data sources for this can be anything that is iterable. The following is an example workflow Zend\Db\Adapter\Adapter::query(): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 similar to what one might find inside use Zend\Db\Adapter\Driver\ResultInterface. generally a Zend\Db\Adapter\Driver\ResultInterface based object is the primary source for retrieving data. } } 233 . $result = $stmt->execute(). if ($result instanceof ResultInterface && $result->isQueryResult()) { $resultSet = new ResultSet. the Prototype pattern will be used by consuming object to clone a prototype of a ResultSet and return a specialized ResultSet with a specific data source injected. The interface of ResultSetInterface looks like this: 1 2 3 4 5 interface ResultSetInterface extends \Traversable. \Countable { public function initialize($dataSource). foreach ($resultSet as $row) { echo $row->my_column .1 Quickstart Zend\Db\ResultSet\ResultSet is the most basic form of a ResultSet object that will expose each row as either an ArrayObject-like object or an array of row data. In most casts. $stmt->prepare($parameters). By default. PHP_EOL. use Zend\Db\ResultSet\ResultSet. public function getFieldCount(). } 53. Zend\Db\Adapter\Adapter will use a prototypical Zend\Db\ResultSet\ResultSet object for iterating when using the Zend\Db\Adapter\Adapter::query() method. $resultSet->initialize($result).CHAPTER FIFTYTHREE ZEND\DB\RESULTSET Zend\Db\ResultSet is a sub-component of Zend\Db for abstracting the iteration of rowset producing queries. $stmt = $driver->createStatement(’SELECT * FROM users’).

$stmt->prepare($parameters). class UserEntity { protected $first_name. ResultSetInterface { public function initialize($dataSource) public function getDataSource() public function getFieldCount() /** Iterator */ public function public function public function public function public function next() key() current() valid() rewind() /** countable */ public function count() /** get rows as array */ public function toArray() } 53. HydratingRowSet will use the Reflection based hydrator to inject the row data directly into the protected members of the cloned UserEntity object: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 use Zend\Db\Adapter\Driver\ResultInterface.0. The HydratingResultSet will then hydrate that clone with the row data. and during iteration. Zend\Db\ResultSet . use Zend\Db\ResultSet\HydratingResultSet.3 Zend\Db\ResultSet\HydratingResultSet Zend\Db\ResultSet\HydratingResultSet is a more flexible ResultSet object that allows the developer to choose an appropriate “hydration strategy” for getting row data into a target object. } } $stmt = $driver->createStatement($sql). public function getFirstName() { return $this->first_name. either a instance of Zend\Db\ResultSet\ResultSet or a derivative of Zend\Db\ResultSet\AbstractResultSet will be being used. rows from the database will be iterated. if ($result instanceof ResultInterface && $result->isQueryResult()) { $resultSet = new HydratingResultSet(new ReflectionHydrator. Release 2. use Zend\Stdlib\Hydrator\Reflection as ReflectionHydrator. } public function getLastName() { return $this->last_name.6 53.2 Zend\Db\ResultSet\ResultSet and Zend\Db\ResultSet\AbstractResultSet For most purposes. While iterating over results. new UserEntity). $resultSet->initialize($result). In the example below. The implementation of the AbstractResultSet offers the following core functionality: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 abstract class AbstractResultSet implements Iterator. HydratingResultSet will take a prototype of a target object and clone it once for each row. $result = $stmt->execute(). protected $last_name. foreach ($resultSet as $user) { 234 Chapter 53.Zend Framework 2 Documentation.

Zend Framework 2 Documentation. $user->getLastName() . Zend\Db\ResultSet\HydratingResultSet 235 . PHP_EOL. see the Zend\Stdlib\Hydrator documentation to get a better sense of the different strategies that can be employed in order to populate a target object. } } For more information.6 21 22 23 echo $user->getFirstName() . 53. Release 2. ’ ’ .3.0.

Zend Framework 2 Documentation.0. Release 2. Zend\Db\ResultSet .6 236 Chapter 53.

Once they have been populated with values. or Data Manipulation Language): selecting. updating and deleting. as described in the sections below. to specialize each query.1 Zend\Db\Sql\Sql (Quickstart) As there are four primary tasks associated with interacting with a database (from the DML. $select->from(’foo’). 1 2 3 4 5 6 use Zend\Db\Sql\Sql. $sql = new Sql($adapter). Zend\Db\Sql objects require a Zend\Db\Adapter\Adapter object in order to produce the desired results. $sql = new Sql($adapter). $select->where(array(’id’ => 2)). $insert = $sql->insert(). $statement = $sql->prepareStatementForSqlObject($select). To prepare (using a Select object): 1 2 3 4 5 6 7 8 use Zend\Db\Sql\Sql. you can now interact with these objects. Insert. 54. $select->from(’foo’). To execute (using a Select object) 1 2 3 4 5 use Zend\Db\Sql\Sql. Zend\Db\Sql\Select. $select = $sql->select(). there are four primary objects that developers can interact or building queries. and generally used together within the same application. they are ready to either be prepared or executed. $sql = new Sql($adapter). inserting. As such. Since these four tasks are so closely related. The end result of an Zend\Db\Sql object will be to either produce a Statement and Parameter container that represents the target query. Update and Delete. // // // // @return @return @return @return Zend\Db\Sql\Select Zend\Db\Sql\Insert Zend\Db\Sql\Update Zend\Db\Sql\Delete As a developer. To achieve this. $select->where(array(’id’ => 2)). $select = $sql->select(). $results = $statement->execute().CHAPTER FIFTYFOUR ZEND\DB\SQL Zend\Db\Sql is a SQL abstraction layer for building platform specific SQL queries via a object-oriented API. $delete = $sql->delete(). Zend\Db\Sql\Sql objects help you create them and produce the result you are attempting to achieve. 237 . $select = $sql->select(). or a full string that can be directly executed against the database platform. $update = $sql->update().

StatementInterface $statement). $on. Insert. they are all primarily seeded with the same table when produced. $type = self::JOIN_INNER). const JOIN_LEFT = ’left’. // $select already has the from(’foo’) applied 54. ’foo’). insert. columns(array $columns. Update and Delete Each of these objects implement the following (2) interfaces: 1 2 3 4 5 6 interface PreparableSqlInterface { public function prepareStatement(Adapter $adapter.6 6 7 8 $selectString = $sql->getSqlStringForSqlObject($select). $select = new Select(). Zend\Db\Sql . join($name. const JOIN_RIGHT = ’right’. If a table is provided to the Select object.3 Zend\Db\Sql\Select Zend\Db\Sql\Select is an object who’s primary function is to present a unified API for building platform specific SQL SELECT queries. the following API can be used to further specify various select statement parts: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Select extends AbstractSql implements SqlInterface. then from() cannot be called later to change the name of the table. } These are the functions you can call to either produce (a) a prepared statement. Release 2. // @param Where $where public public public public function function function function __construct($table = null). Zend\Db\Sql\Sql objects can also be bound to a particular table so that in getting a select. const JOIN_OUTER = ’outer’.0. $adapter::QUERY_MODE_EXECUTE). or (b) a string to be executed.Zend Framework 2 Documentation. $columns = self::SQL_STAR. $results = $adapter->query($selectString.2 Zend\Db\Sql’s Select. $select = $sql->select(). PreparableSqlInterface { const JOIN_INNER = ’inner’. } interface SqlInterface { public function getSqlString(PlatformInterface $adapterPlatform = null). const SQL_STAR = ’*’. $prefixColumnsWithTable = true). public $where. to produce a $select bound to a specific table $select = new Select(’foo’). The class can be instantiated and consumed without Zend\Db\Sql\Sql: 1 2 3 4 use Zend\Db\Sql\Select. 238 Chapter 54. update. from($table). or delete object. Once you have a valid Select object. 1 2 3 4 use Zend\Db\Sql\Sql. $select->where(array(’id’ => 2)). $sql = new Sql($adapter. const ORDER_DESENDING = ’DESC’. const ORDER_ASCENDING = ’ASC’. // or. 54.

limit($limit).foo_id’). // expression to join on (will be quoted by platform object before insertion). $combination = Predicate\PredicateSet::OP_AND). // as an array to specify an alias: // produces SELECT "t".3.1 from(): 1 2 3 4 5 6 7 8 9 10 11 12 // as a string: $select->from(’foo’). 54. order($order). array(’bar’. ’bax’ AS ’baz’ $select->columns(array(’foo’ => ’bar’.3. 54. offset($offset). ’bar’)). // using a Sql\TableIdentifier: // same output as above $select->from(new TableIdentifier(array(’t’ => ’table’))).3. Zend\Db\Sql\Select 239 . having(): The Zend\Db\Sql\Select object provides bit of flexibility as it regards to what kind of parameters are acceptable when calling where() or having().3 join(): 1 2 3 4 5 6 7 8 9 10 $select->join( ’foo’ // table name. ’f.6 17 18 19 20 21 22 23 public public public public public public } function function function function function function where($predicate. right also represtned by constants ).Zend Framework 2 Documentation. ’baz’ => ’bax’)). group($group). // as an associative array with aliases as the keys: // produces ’bar’ AS ’foo’. // (optional) list of columns.2 columns(): 1 2 3 4 5 6 7 // as array of names $select->columns(array(’foo’.4 where(). The method signature is listed as: 54.0.* FROM "table" AS "t" $select->from(array(’t’ => ’table’)). $select->from(array(’f’ => ’foo’)) ->join(array(’b’ => ’bar’). $combination = Predicate\PredicateSet::OP_AND).id’. outer. same requiremetns as columns() above $select::JOIN_OUTER // (optional). ’id = bar. ’baz’). left.3. one of inner. // base table // join table with alias // join expression 54.3. having($predicate. Release 2. 54.foo_id = b.

and the value will target value.* FROM "foo" WHERE x = 5 AND y = z $select->from(’foo’)->where(array(’x = 5’. When the where/having() is processed.* FROM "foo" WHERE "c1" IS NULL AND "c2" IN (?. This means that there will be no quoting in the fragment provided. If you provide a Zend\Db\Sql\Where object to where() or a Zend\Db\Sql\Having object to having(). the internal objects for Select will be replaced completely. ’c2’ => array(1. If you provide an array who’s values are keyed with a string. So the following is possible: 1 2 3 4 5 $spec = function (Where $where) { $where->like(’username’. Consider the following code: 1 2 // SELECT "foo". ’y = z’)). Zend\Db\Sql . 2. Consider the following code: 1 2 3 4 5 6 // SELECT "foo". $select->where($spec).* FROM "foo" WHERE x = 5 $select->from(’foo’)->where(’x = 5’). ’ralph%’). Consider the following code: 1 2 // SELECT "foo". If you provide a string. the value can either be a string that will be then used to build a Predicate\Expression or any object that implements Predicate\PredicateInterface. this string will be used to instantiate a Zend\Db\Sql\Predicate\Expression object so that it’s contents will be applied as is. ?) AND "c3" IS NOT NULL $select->from(’foo’)->where(array( ’c1’ => null. 3). there are a number of different ways to pass criteria to both having() and where(). these values will be handled in the following: • PHP value nulls will be made into a Predicate\IsNull object • PHP value array()s will be made into a Predicate\In object • PHP value strings will be made into a Predicate\Operator object such that the string key will be identifier. this function will be called with the Select’s Where object as the only parameter. If you provide an array who’s values are keyed by an integer. }. If you provide a Closure to where() or having(). new \Zend\Db\Sql\Predicate\IsNotNull(’c3’) )). $combination = Predicate\PredicateSet::OP_AND).0.Zend Framework 2 Documentation.6 1 2 3 4 5 6 7 8 /** * Create where clause * * @param Where|\Closure|string|array $predicate * @param string $combination One of the OP_* constants from Predicate\PredicateSet * @return Select */ public function where($predicate. Release 2. ?. As you can see. These objects are pushed onto the Where stack with the $combination provided. this object will be iterated to produce the WHERE or HAVING section of the SELECT statement. 240 Chapter 54.

5 order(): 1 2 3 4 5 6 7 8 9 $select = new Select. the table can be set at construction time or via into().4. // always takes an integer/numeric $select->offset(10). 1 2 54. // merging values with previous calls $insert->values(array(’col_2’ => ’value2’). ’age’ DESC $select = new Select. // produces ’id’ DESC $select = new Select. Release 2.0.6 54. Similarly to Select objects. Zend\Db\Sql\Insert 241 .3. ’age DESC’)). ’bar’)). values(array $values. age DESC’). // similarly takes an integer/numeric 54. ’name’ ASC. columns(array $columns).4. // produces ’name’ ASC.4. 54.3. // produces ’id’ DESC. $select->order(’id DESC’). PreparableSqlInterface { const VALUES_MERGE = ’merge’.Zend Framework 2 Documentation. into($table). // set the valid columns 54. const VALUES_SET = ’set’. $insert::VALUES_MERGE). $select->limit(5).4 Zend\Db\Sql\Insert The Insert API: 1 2 3 4 5 6 7 8 9 10 class Insert implements SqlInterface.1 columns(): 1 $insert->columns(array(’foo’.2 values(): 1 2 3 4 5 6 // default behavior of values is to set the values // succesive calls will not preserve values from previous calls $insert->values(array( ’col_1’ => ’value1’.6 limit() and offset(): 1 2 3 $select = new Select. ’col_2’ => ’value2’ )). $select->order(array(’name ASC’. ’age’ DESC 54. $flag = self::VALUES_SET). $select->order(’id DESC’) ->order(’name ASC. public public public public } function function function function __construct($table = null).

the parameters will be replaced with their proper placeholder (a named or positional parameter).7 Zend\Db\Sql\Where & Zend\Db\Sql\Having In the following. All of the parts that make up a where or having that are and’ed or or’d together are called predicates.6 Zend\Db\Sql\Delete 1 2 3 4 5 6 7 class Delete { public $where.Zend Framework 2 Documentation. we will talk about Where. $combination = Predicate\PredicateSet::OP_AND). Zend\Db\Sql . a Predicate (and PredicateSet). } 54.1 where(): See where section below.5. Having is implies as being the same API. 54. 54. the values will be interpolated into the fragments they belong to and properly quoted.5 Zend\Db\Sql\Update 1 2 3 4 5 6 7 8 9 10 11 class Update { const VALUES_MERGE = ’merge’.2 where(): See where section below.6 54. function table($table). Effectively. In parameterization. Where and Having extend from the same base object. 54. const VALUES_SET = ’set’. and the values stored inside a Adapter\ParameterContainer. The full set of predicates is called a PredicateSet.1 set(): 1 $update->set(array(’foo’ => ’bar’. or executed. public function where($predicate.0. function set(array $values. public function from($table).6. $flag = self::VALUES_SET).5. function where($predicate. public public public public public } $where. // @param Where $where function __construct($table = null). 242 Chapter 54. When executed. // @param Where $where public function __construct($table = null). $combination = Predicate\PredicateSet::OP_AND). 54. Release 2. This object set generally contains the values (and identifiers) separate from the fragment they belong to until the last possible moment when the statement is either used to be prepared (parameteritized). ’baz’ => ’bax’)).

$rightType = self: lessThanOrEqualTo($left. lessThanOrEqualTo(). isNull($identifier). $parameter). a distinction is made between what elements are considered identifiers (TYPE_IDENTIFIER) and which of those is a value (TYPE_VALUE). $leftType = self::TYPE_IDENTIFIER. $leftType = self::TYPE_IDENTIFIER. getExpressionData(). greaterThan(). // Inherited From PredicateSet public public public public public public } function function function function function function addPredicate(PredicateInterface $predicate. $leftType = self::TYPE_IDENTIFIER. Release 2. $like).0. described below. between($identifier. $combination = null). Each method in the Where API will produce a corresponding Predicate object of a similarly named type. literal($literal. class Operator implements PredicateInterface { 54. greaterThanOrEqualTo(): 1 2 3 4 5 6 7 8 9 $where->equalTo(’id’. $right. $right. public $UNNSET. Zend\Db\Sql\Where & Zend\Db\Sql\Having 243 . $right. unnest(). $right. $right. // same as the following workflow $where->addPredicate( new Predicate\Operator($left. orPredicate(PredicateInterface $predicate). $rightType) ). $leftType. isNotNull($identifier).1 equalTo(). array $valueSet = array()). with the full API of the object: 54. public $or. andPredicate(PredicateInterface $predicate). $rightTyp like($identifier.7. public $NEST. setUnnest(Predicate $predicate). $right.Zend Framework 2 Documentation. count(). public public public public public public public public public public public public public public function function function function function function function function function function function function function function nest(). getPredicates(). $minValue. $leftType = self::TYPE_IDENTIFIER. $rightType = self::TYP lessThan($left. There is also a special use case type for literal values (TYPE_LITERAL).7. public $AND.6 It is important to know that in this API. in($identifier. equalTo($left. $rightType = self::TY greaterThan($left. Operator::OPERATOR_EQUAL_TO. lessThan(). The Zend\Db\Sql\Where (Predicate/PredicateSet) API: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 // Where & Having: class Predicate extends PredicateSet { public $and. public $OR. 5). These are all exposed via the Zend\Db\Sql\ExpressionInterface interface. $rightType = greaterThanOrEqualTo($left. $maxValue). $leftType = self::TYPE_IDENTIFIER.

$operator = self::OPERATOR_EQUAL_TO. getLeft(). 1 2 3 4 5 6 $where->literal($literal. 244 Chapter 54. getOperator(). public public public public public public public public public public public public } __construct($left = null. // same as $where->addPredicate( new Predicate\Expression($literal. Zend\Db\Sql . $le setLeft($left). setLeftType($type).7. $right = null. setLike($like).3 literal($literal. ’<=’. 54. ’=’.0. setOperator($operator). getLeftType(). ’<’. getRight(). ’>=’. setIdentifier($identifier). $like = null). getExpressionData(). getIdentifier(). $parameter). Release 2. ’<’. $like): // same as $where->addPredicate( new Predicate\Like($identifier. ’!=’. ’>=’. // full API class Like { public public public public public } implements PredicateInterface function function function function function __construct($identifier = null. getRightType().Zend Framework 2 Documentation. getLike(). ’<=’. $like): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $where->like($identifier.7. ’>’. 54. setRightType($type).2 like($identifier. ’!=’. $like) ).6 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 const const const const const const const const const const const const OPERATOR_EQUAL_TO OP_EQ OPERATOR_NOT_EQUAL_TO OP_NE OPERATOR_LESS_THAN OP_LT OPERATOR_LESS_THAN_OR_EQUAL_TO OP_LTE OPERATOR_GREATER_THAN OP_GT OPERATOR_GREATER_THAN_OR_EQUAL_TO OP_GTE function function function function function function function function function function function function = = = = = = = = = = = = ’=’. $parameter). $parameter) ). ’>’. setRight($value).

} 54. public function getIdentifier(). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $where->isNotNull($identifier). PredicateInterface { const PLACEHOLDER = ’?’. // same as $where->addPredicate( new Predicate\IsNull($identifier) ).. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $where->isNull($identifier).6 in($identifier. public function setExpression($expression).4 isNull($identifier). public function getIdentifier().7. array $valueSet = array()).Zend Framework 2 Documentation.5 isNotNull($identifier). public function setParameters($parameters). // same as $where->addPredicate( new Predicate\IsNotNull($identifier) ). .7. Release 2. } 54. public function setIdentifier($identifier).7.6 7 8 9 10 11 12 13 14 15 16 17 18 19 // full API class Expression implements ExpressionInterface. $valueParameter = null /*[. public function __construct($expression = null. // full API class IsNotNull implements PredicateInterface { public function __construct($identifier = null).0. public function getParameters(). public function getTypes().7. // same as 54. array $valueSet = array()). Zend\Db\Sql\Where & Zend\Db\Sql\Having 245 . $valueParameter. } 54.. public function setIdentifier($identifier). public function getExpression(). // full API class IsNull implements PredicateInterface { public function __construct($identifier = null). public function setTypes(array $types). 1 2 3 $where->in($identifier.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $where->between($identifier. $maxValue).Zend Framework 2 Documentation. Release 2. $minValue.6 4 5 6 7 8 9 10 11 12 13 14 15 16 $where->addPredicate( new Predicate\In($identifier.7 between($identifier. public function setMinValue($minValue). $maxValue). array $valueSet = array()). $minValue. $valueSet) ). public function setMaxValue($maxValue). setValueSet(array $valueSet). $maxValue) ). 54. // same as $where->addPredicate( new Predicate\Between($identifier. setIdentifier($identifier).7. // full API class In implements { public function public function public function public function public function } PredicateInterface __construct($identifier = null. getIdentifier(). $minValue. public function getIdentifier(). Zend\Db\Sql . public function setSpecification($specification). // full API class Between implements PredicateInterface { public function __construct($identifier = null. public function setIdentifier($identifier). $maxValue = null). getValueSet().0. public function getMinValue(). $minValue = null. public function getMaxValue(). } 246 Chapter 54.

The TableGateway concrete implementation simply adds a sensible constructor to the AbstractTableGateway class so that out-of-the-box. that allows for expanding the behaviors of the base TableGateway implementation without having to extend the class with this new functionality. These methods are selectWith(). public function update($set. updateWith() and deleteWith(). public function insert($set). 247 . AbstractTableGateway also implements a “Feature” API. update(). public $adapter. Adapter $adapter. The API of the concrete TableGateway is: 1 2 3 4 5 6 7 8 9 10 11 12 13 class TableGateway extends AbstractTableGateway { public $lastInsertValue. 55. public function __construct($table. In addition. } There are two primary implementations of the TableGatewayInterface that are of the most useful: AbstractTableGateway and TableGateway. public $table. In code. public function getTable(). $where = null). TableGateway does not need to be extended in order to be consumed and utilized to its fullest. public function select($where = null).1 Basic Usage The quickest way to get up and running with Zend\Db\TableGateway is to configure and utilize the concrete implementation of the TableGateway. ResultSet $resultSetProt /** Inherited from AbstractTableGateway */ public function isInitialized(). insert(). delete(). The AbstractTableGateway is an abstract basic implementation that provides functionality for select(). public function delete($where). insertWith(). the interface for such an object looks like this: 1 2 3 4 5 6 7 8 interface Zend\Db\TableGateway\TableGatewayInterface { public function getTable(). as well as an additional API for doing these same kinds of tasks with explicit SQL objects.CHAPTER FIFTYFIVE ZEND\DB\TABLEGATEWAY The Table Gateway object is intended to provide an object that represents a table in a database. $features = null. and the methods of this object mirror the most common operations on a database table. public function initialize().

The following usage is possible: 1 2 3 4 5 6 7 8 9 use Zend\Db\TableGateway\TableGateway. this implementation makes no assumptions about table structure or metadata. delete($where). The concrete TableGateway object practices constructor injection for getting dependencies and options into the instance. $projectTable = new TableGateway(’project’. use Zend\Db\Sql\Select. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Db\TableGateway\TableGateway. Out of the box. } // or. ascending $rowset = $artistTable->select(function (Select $select) { $select->where->like(’name’. which in turn. The table name and an instance of an Adapter are all that is needed to setup a working TableGateway object.Zend Framework 2 Documentation. // search for at most 2 artists who’s name starts with Brit. $where = null). PHP_EOL. updateWith(Update $update). update($set.0. getColumns(). Release 2. $adapter). selectWith(Select $select). $adapter). getFeatureSet(). when expecting a single row: $artistTable = new TableGateway(’artist’. $adapter). The select() method takes the same arguments as Zend\Db\Sql\Select::where() with the addition of also being able to accept a closure. $rowset = $artistTable->select(array(’id’ => 2)). echo ’Projects of type PHP: ’. select($where = null). Zend\Db\TableGateway . var_dump($artistRow). will be passed the current Select object that is being used to build the SELECT query. $artistRow = $rowset->current(). insertWith(Insert $insert). deleteWith(Delete $delete). $rowset = $projectTable->select(array(’type’ => ’PHP’)). getResultSetPrototype(). $artistTable = new TableGateway(’artist’. getLastInsertValue(). getSql(). $select->order(’name ASC’)->limit(2). }). insert($set). and when select() is executed. 248 Chapter 55.6 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public public public public public public public public public public public public public public } function function function function function function function function function function function function function function getAdapter(). ’Brit%’). a simple ResultSet object with the populated Adapter’s Result (the datasource) will be returned and ready for iteration. foreach ($rowset as $projectRow) { echo $projectRow[’name’] .

Release 2. 1 $table = new TableGateway(’artist’. This is more useful when you are extending the AbstractTableGateway implementation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 use Zend\Db\TableGateway\AbstractTableGateway. $this->initialize(). 55. $adapter. new Feature\MeatadataFeature()). This allows for a wider array of possible mixing and matching of features to achieve a particular behiavior that needs to be attained to make the base implementation of TableGateway useful for a particular problem. in a bootstrap Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter). new Feature\RowGatewayFeature(’id’)). $results = $table->select(array(’id’ => 2)). $artistRow->save().2. $this->featureSet->addFeature(new Feature\GlobalAdapterFeature()). class MyTableGateway extends AbstractTableGateway { public function __construct() { $this->table = ’my_table’.6 55. $this->featureSet = new Feature\FeatureSet(). There are a number of features built-in and shipped with Zend\Db: • GlobalAdapterFeature: the ability to use a global/static adapter without needing to inject it into a TableGateway instance. use Zend\Db\TableGateway\Feature. } } // elsewhere in code. $adapter. • MetadataFeature: the ability populate TableGateway with column information from a Metadata object. or model somewhere $table = new MyTableGateway(). 1 $table = new TableGateway(’artist’.Zend Framework 2 Documentation. update(). // in a controller. $adapter. or as an array of Feature objects. • EventFeature: the ability utilize a TableGateway object with Zend\EventManager and to be able to subscribe to various events in a TableGateway lifecycle. $artistRow = $results->current(). as a FeatureSet object. The constructor can take Features in 3 different forms: as a single feature object. TableGateway Features 249 .0. • RowGatewayFeature: the ability for select() to return a ResultSet object that upon iteration will 1 2 3 4 5 6 $table = new TableGateway(’artist’. 1 $table = new TableGateway(’artist’. new Feature\MasterSlaveFeature($slaveAdapter)). features should be injected though the constructor. It will also store the primary key information in case RowGatewayFeature needs to consume this information. and delete() while using a slave adapter for all select() operations. // adapter is statially loaded • MasterSlaveFeature: the ability to use a master adapter for insert(). $adapter. With the TableGateway object. $artistRow->name = ’New Name’.2 TableGateway Features The Features API allows for extending the functionality of the base TableGateway object without having to polymorphically extend the base class. new Feature\EventFeature($eventManagerInstance)).

Zend\Db\TableGateway .6 250 Chapter 55. Release 2.0.Zend Framework 2 Documentation.

and have methods such as save() and delete() that will help persist this row-as-an-object in the database itself. // get array of data $rowData = $resultSet->current()->getArrayCopy(). Likewise. // row gateway $rowGateway = new RowGateway(’id’. The workflow described above is greatly simplified when RowGateway is used in conjunction with the TableGateway feature.CHAPTER FIFTYSIX ZEND\DB\ROWGATEWAY Zend\Db\RowGateway is a sub-component of Zend\Db that implements the Row Gateway pattern from PoEAA. $adapter). $rowGateway->first_name = ’New Name’. } 56.1 Quickstart While most of the time. it is possible to use it standalone. array(2)). after a row from the database is retrieved. What this achieves is a Table Gateway object that when select()’ing from a table. // query the database $resultSet = $adapter->query(’SELECT * FROM ‘user‘ WHERE ‘id‘ = ?’. public function delete(). // or delete this row: $rowGateway->delete(). The interface for a Row Gateway object simply adds save() and delete() and this is the interface that should be assumed when a component has a dependency that is expected to be an instance of a RowGateway object: 1 2 3 4 5 interface RowGatewayInterface { public function save(). $rowGateway->save(). will produce a ResultSet 251 . To use it standalone. This effectively means that Row Gateway objects primarily model a row in a database. or it can be delete()’d from the table. it can then be manipulated and save()’d back to the database in the same position (row). The following use case demonstrates Zend\Db\RowGateway\RowGateway usage in its simplest form: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 use Zend\Db\RowGateway\RowGateway. you simply need an Adapter and a set of data to work with. $rowGateway->populate($rowData). RowGateway will be used in conjucntion with other Zend\Db\ResultSet producing objects. ’my_table’.

$artistRow->name = ’New Name’. $table = new TableGateway(’artist’. $adapter. Its usage looks like this: 1 2 3 4 5 6 7 8 9 use Zend\Db\TableGateway\Feature\RowGatewayFeature. $artistRow = $results->current().0.Zend Framework 2 Documentation. use Zend\Db\TableGateway\TableGateway. Release 2. 252 Chapter 56.6 that is then capable of producing valid Row Gateway objects. new RowGatewayFeature(’id’)). $artistRow->save(). Zend\Db\RowGateway . $results = $table->select(array(’id’ => 2)).

This is best demonstrated by the script below. information will come from querying the INFORMATION_SCHEMA tables generally accessible to all database connections about the currently accessible schema. public function getColumnNames($table. $schema = null). The primary interface for the Metadata objects is: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 interface MetadataInterface { public function getSchemas(). Metadata::get*Names() methods will return an array of strings. public function getColumns($table. $schema = null). public function getTable($tableName.CHAPTER FIFTYSEVEN ZEND\DB\METADATA Zend\Db\Metadata is as sub-component of Zend\Db that makes it possible to get metadata information about tables. $includeViews = false). given an adapter. public function getTableNames($schema = null. $schema = null). constraints. public function getTriggers($schema = null). public function getTriggerNames($schema = null). public function getConstraint($constraintName. public function getConstraintKeys($constraint. $schema = null). public function getView($viewName. $table. $table. In most cases. $includeViews = false). public function getViewNames($schema = null). public function getTrigger($triggerName.1 Basic Usage Usage of Zend\Db\Metadata is very straight forward. triggers. $schema = null). $schema = null). $table. public function getViews($schema = null). while the other methods will return specific value objects with the containing information. public function getColumn($columnName. public function getConstraints($table. choose the best strategy (based on the database platform being used) for retrieving metadata. $schema = null). $schema = null). 253 . columns. $schema = null). public function getTables($schema = null. and other information from a database in a standardized way. 1 2 $metadata = new Zend\Db\Metadata\Metadata($adapter). The top level class Zend\Db\Metadata\Metadata will. } 57.

0. implode(’.’ . echo ’ With constraints: ’ . ’ -> ’ . PHP_EOL. $column->getName() . implode(’. PHP_EOL. $constraint->getType() . } The ColumnObject: 254 Chapter 57. foreach ($table->getColumns() as $column) { echo ’ ’ . PHP_EOL. echo ’ With columns: ’ . public function setColumns(array $columns). public function getName(). } echo PHP_EOL. PHP_EOL. public function getConstraints(). ’ -> ’ . } Metadata returns value objects that provide an interface to help developers better explore the metadata. if ($constraint->isForeignKey()) { $fkCols = array(). public function setName($name). } echo ’----’ . foreach ($tableNames as $tableName) { echo ’In Table ’ . Release 2. $constraint->getColumns()). foreach ($metadata->getConstraints($tableName) as $constraint) { /** @var $constraint Zend\Db\Metadata\Object\ConstraintObject */ echo ’ ’ . } echo ’ => ’ . } echo ’ column: ’ . ’. Below is the API for the various value objects: The TableObject: 1 2 3 4 5 6 7 8 9 10 class Zend\Db\Metadata\Object\TableObject { public function __construct($name).6 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 // get the table names $tableNames = $metadata->getTableNames(). public function getColumns().Zend Framework 2 Documentation. PHP_EOL. PHP_EOL. $table = $metadata->getTable($tableName). ’. $tableName . } echo PHP_EOL. ’. $fkCols). public function setConstraints($constraints). foreach ($constraint->getReferencedColumns() as $refColumn) { $fkCols[] = $constraint->getReferencedTableName() . $column->getDataType() . Zend\Db\Metadata . $constraint->getName() . $refColumn. if (!$constraint->hasColumns()) { continue.

public function getErrata($errataName). public function isNullable(). public function setNumericPrecision($numericPrecision). public function getName(). public function getDataType(). public function setType($type). public function getOrdinalPosition(). public function setReferencedColumns(array $referencedColumns). public function setReferencedTableSchema($referencedTableSchema). public function setDataType($dataType). public function hasColumns(). public function getNumericUnsigned(). $tableName. public function getName(). public function getReferencedTableSchema(). $errataValue). public function setSchemaName($schemaName). 57.0. public function getSchemaName(). public function isNumericUnsigned(). public function getReferencedColumns(). Release 2. public function setCharacterMaximumLength($characterMaximumLength). public function setNumericScale($numericScale). public function getTableName(). public function setColumnDefault($columnDefault). $schemaName = null). public function setCharacterOctetLength($characterOctetLength). public function getIsNullable(). public function setReferencedTableName($referencedTableName). public function setTableName($tableName). public function setIsNullable($isNullable). public function getTableName(). public function setSchemaName($schemaName). $tableName. public function getErratas().Zend Framework 2 Documentation. public function setTableName($tableName). public function getNumericPrecision(). public function getColumns(). public function setErratas(array $erratas). $schemaName = null).1. public function getSchemaName(). public function getReferencedTableName(). public function setName($name). } The ConstraintObject: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Zend\Db\Metadata\Object\ConstraintObject { public function __construct($name. public function setName($name). public function getCharacterMaximumLength(). public function setMatchOption($matchOption). public function setColumns(array $columns). public function setNumericUnsigned($numericUnsigned). public function getColumnDefault(). public function getMatchOption(). public function getNumericScale(). public function setErrata($errataName. public function setOrdinalPosition($ordinalPosition). public function getCharacterOctetLength().6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Zend\Db\Metadata\Object\ColumnObject { public function __construct($name. Basic Usage 255 . public function getType().

isForeignKey(). getCheckClause(). public function getEventObjectSchema(). public function setEventObjectTable($eventObjectTable). public function getEventObjectTable(). public function setActionOrder($actionOrder).6 23 24 25 26 27 28 29 30 31 32 33 34 public public public public public public public public public public } function function function function function function function function function function getUpdateRule(). Release 2. public function setActionReferenceNewTable($actionReferenceNewTable). public function getActionTiming(). public function getActionReferenceOldRow(). getDeleteRule(). public function setActionReferenceOldRow($actionReferenceOldRow). public function getEventObjectCatalog(). setCheckClause($checkClause). public function getActionOrder(). public function setEventManipulation($eventManipulation). public function getActionReferenceOldTable(). public function setCreated($created). public function setEventObjectCatalog($eventObjectCatalog). Zend\Db\Metadata . public function setActionReferenceNewRow($actionReferenceNewRow). isPrimaryKey(). setDeleteRule($deleteRule). public function setEventObjectSchema($eventObjectSchema). public function getActionReferenceNewTable(). setUpdateRule($updateRule). public function getActionOrientation(). isCheck(). } 256 Chapter 57. public function getActionStatement(). isUnique(). public function getEventManipulation(). public function setName($name).Zend Framework 2 Documentation. public function setActionCondition($actionCondition). public function getCreated(). public function setActionOrientation($actionOrientation). public function setActionTiming($actionTiming). The TriggerObject: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Zend\Db\Metadata\Object\TriggerObject { public function getName().0. public function getActionReferenceNewRow(). public function setActionStatement($actionStatement). public function getActionCondition(). public function setActionReferenceOldTable($actionReferenceOldTable).

MovieFinder is a dependency of MovieLister. If you are not familiar with the concept of DI. or Fabien Potencier’s Series on DI. we’ll explain the act of injecting dependencies simply with this below code: 1 $b = new MovieLister(new MovieFinder()). is an object that is capable of creating objects on request and managing the “wiring”. you might find that the simple act of wiring an object has gotten more complex. and you find that this wiring is creating more boilerplate code. DiC’s are generally either in the form of smallish objects that suit a very specific pattern. for more complex code. In it’s simplest form. Since the patterns that developers employ in writing DI capable code vary. here are a couple of great reads: Matthew Weier O’Phinney’s Analogy. this makes for an excellent opportunity to utilize a Dependency Injection Container.CHAPTER FIFTYEIGHT INTRODUCTION TO ZEND\DI 58. for those requested objects. When this becomes the case. or the injection of required dependencies. Simply put. Above. or larger DiC frameworks. Zend\Di is a DiC framework. a Dependency Injection Container (here-in called a DiC for brevity).1 Dependency Injection Dependency Injection (here-in called DI) is a concept that has been talked about in numerous places over the web.2 Dependency Injection Containers When your code is written in such a way that all your dependencies are injected into consuming objects. While for the simplest code there is no configuration needed. Zend\Di is capable of being configured to wire these complex use cases 257 . and the use cases are quite simple. Ralph Schindler’s Learning DI. 58. and MovieFinder was injected into MovieLister.

0. Introduction to Zend\Di . Release 2.6 258 Chapter 58.Zend Framework 2 Documentation.

CHAPTER FIFTYNINE ZEND\DI QUICKSTART This QuickStart is intended to get developers familiar with the concepts of the Zend\Di DiC. Generally speaking. } } } namespace MyMovieApp { class MovieFinder { protected $dbAdapter = null. $password) { $this->username = $username. you find yourself writing the following to wire and utilize this code: 259 . $this->password = $password. Assume for a moment. you are already injecting all your dependencies: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 namespace MyLibrary { class DbAdapter { protected $username = null. code is never as simple as it is inside this example. so working knowledge of the other sections of the manual is suggested. } } class MovieLister { protected $movieFinder = null. } } } With the above code. protected $password = null. public function __construct($username. public function __construct(MovieFinder $movieFinder) { $this->movieFinder = $movieFinder. you have the following code as part of your application that you feel is a good candidate for being managed by a DiC. after all. public function __construct(\MyLibrary\DbAdapter $dbAdapter) { $this->dbAdapter = $dbAdapter.

Release 2. it will be consulting the RuntimeDefinition. it is a great candidate for using Zend\Di. $config->password).6 1 2 3 4 5 6 7 8 // $config object is assumed $dbAdapter = new MyLibrary\DbAdapter($config->username. this is achieved by passing them as the second argument of get(): 1 2 3 4 5 6 7 // inside each controller $di = new Zend\Di\Di(). of the constructor consuming these named parameters. if ($config) { $this->configure($config).0. The usage is as simple as: 1 2 3 4 5 6 7 8 9 10 11 12 // inside a bootstrap somewhere $di = new Zend\Di\Di(). not only can this become repetitive and boring to write. which uses reflection to understand the structure of the code. // inside each controller $movieLister = $di->get(’MyMovieApp\MovieLister’). but also unmaintainable if for example you want to swap out one of these dependencies on a wholesale scale. with constructor injection. If you were to want to pass in the username and password at call time. foreach ($movieLister as $movie) { // iterate and display $movie } In the above example. $di->instanceManager()->setParameters(’MyLibrary\DbAdapter’. } } This means that when $di->get() is called. Once it knows the structure of the code. Zend\Di Quickstart . array( ’username’ => $config->username. array( ’username’ => $config->username.Zend Framework 2 Documentation. Here is the Zend\Di\Di constructor: 1 2 3 4 5 6 7 8 9 public function __construct(DefinitionList $definitions = null. Zend\Di\Definition\RuntimeDefinition will utilize the names of the parameters in the methods as the class parameter names. it can then know how the dependencies fit together and how to go about wiring your objects for you. ’password’ => $config->password )). $movieLister = $di->get(’MyMovieApp\MovieLister’. This is how both username and password key are mapped to the first and second parameter. InstanceManager $instanceManager { $this->definitions = ($definitions) ?: new DefinitionList(new Definition\RuntimeDefinition()) $this->instanceManager = ($instanceManager) ?: new InstanceManager(). respectively. By ‘default’. $movieLister = new MyMovieApp\MovieLister($movieFinder). ’password’ => $config->password )). we mean that Zend\Di\Di is constructed with a DefinitionList seeded with a RuntimeDefinition (uses Reflection) and an empty instance manager and no configuration. foreach ($movieLister as $movie) { // iterate and display $movie } If you are doing this above wiring in each controller or view that wants to list movies. we are obtaining a default instance of Zend\Di\Di. foreach ($movieLister as $movie) { 260 Chapter 59. Since this example of code already practices good dependency injection. $movieFinder = new MyMovieApp\MovieFinder($dbAdapter).

261 .Zend Framework 2 Documentation. Release 2. these parameter names will be applied to any class that accepts a parameter of such name.0.6 8 9 // iterate and display $movie } It is important to note that when using call time parameters. you can utilize $di->newInstance(). This means subsequent calls to get() will return the same instance as previous calls. this instance of MovieLister will be automatically shared. If you wish to have completely new instances of MovieLister. By calling $di->get().

Release 2.0. Zend\Di Quickstart .Zend Framework 2 Documentation.6 262 Chapter 59.

Order is important. 60. The RuntimeDefinition will respond to query’s about classes by using Reflection. the easier of a time Zend\Di\Definition\RuntimeDefinition will have determining the structure of your code. } } The IntrospectionStrategy object is an object that determines the rules. the pattern /^set[A-Z]{1}\w*/ is registered by default. when no other DefinitionList is provided. it is important that your autoloaders are already setup and ready to use. the type-hints of the parameters. This is what the constructor of a RuntimeDefinition looks like: 1 2 3 4 5 6 7 public function __construct(IntrospectionStrategy $introspectionStrategy = null. and the default values to determine if something is optional or required when making a call to that method. The more explicit you can be in your method naming and method signatures. 263 . by default. Definitions in the front of the list will be consulted on a class before definitions at the end of the list. Zend\Di has a very good chance of understanding how to wire things up without much added complexity. clear and concise code. array $explicitClass { $this->introspectionStrategy = ($introspectionStrategy) ?: new IntrospectionStrategy(). this is a list of patterns.2 RuntimeDefinition The default DefinitionList instantiated by Zend\Di\Di. 60. Here are the things it knows how to do: • Whether or not to use Annotations (Annotations are expensive and off by default. for how the RuntimeDefinition will introspect information about your classes. This means that if you’ve written non-ambiguous. Note: Regardless of what kind of Definition strategy you decide to use. or guidelines.CHAPTER SIXTY ZEND\DI DEFINITION Definitions are the place where Zend\Di attempts to understand the structure of the code it is attempting to wire.1 DefinitionList Definitions are introduced to the Zend\Di\Di object through a definition list implemented as Zend\Di\DefinitionList (SplDoublyLinkedList). has as Definition\RuntimeDefinition baked-in. if ($explicitClasses) { $this->setExplicitClasses($explicitClasses). This Runtime definitions uses any available information inside methods: their signature. the names of parameters. read more about these in the Annotations section) • Which method names to include in the introspection.

str_replace(’_’. $di = new Di($definitionList.3 CompilerDefinition The CompilerDefinition is very much similar in nature to the RuntimeDefinition with the exception that it can be seeded with more information for the purposes of “compiling” a definition. )). or explicitly look up for particular pre-defined classes. ’. this is the place to do it. By using the compiler. Zend\Di Definition .php’. but if you wish to create a special AnnotationManager with your own annotations. file_put_contents( __DIR__ . This is useful when you do not want to be making all those (sometimes expensive) calls to reflection and the annotation scanning system during the request of your application. This is useful when your strategy for inspecting one set of classes might differ from those of another strategy for another set of classes.6 • Which interface names represent the interface injection pattern. ’/’.php new Definition\ArrayDefinition(include __DIR__ . ’/path/to/data/di/My_MovieApp-definition. which is default). the following code will suffice: 1 2 3 4 5 6 7 8 protected function setupDi(Application $app) { $definitionList = new DefinitionList(array( new Definition\ArrayDefinition(include __DIR__ .Zend Framework 2 Documentation. a definition can be created and written to disk to be used during a request. The constructor for the IntrospectionStrategy looks like this: 1 2 3 4 public function __construct(AnnotationManager $annotationManager = null) { $this->annotationManager = ($annotationManager) ?: $this->createDefaultAnnotationManager(). this is a list of patterns. } This will create a couple of files that will return an array of the definition for that class. $diCompiler->compile(). The RuntimeDefinition also can be used to look up either all classes (implicitly. To utilize this in an application. $diCompiler->addDirectory(’/path/to/classes/’ . ’-definition. ’/path/to/data/di/My_OtherClasses-definition $runtime = new Definition\RuntimeDefinition().0. let’s assume we want to create a script that will create definitions for some of our library code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // in "package name" format $components = array( ’My_MovieApp’. )./data/di/’ . ’My_OtherClasses’. 264 Chapter 60. as opposed to the task of scanning the actual code. ’/. new Configuration($this->config->di)).. the pattern /\w*Aware\w*/ is registered.’ ). true) . By default. var_export($diCompiler->toArrayDefinition()->toArray(). $component . null. $component)). ’<?php return ’ . } This goes to say that an AnnotationManager is not required. foreach ($components as $component) { $diCompiler = new Zend\Di\Definition\CompilerDefinition. Release 2. and also wish to extend the RuntimeDefinition to look for these special Annotations. For example. This can be achieved by using the setExplictClasses() method or by passing a list of classes as a second argument to the constructor of the RuntimeDefinition. 60.

$di). you might want to simply define your complete class’s definition with an xml.example 60.4.6 9 10 11 $di->instanceManager()->addTypePreference(’Zend\Di\LocatorInterface’. you may want to override some information inside of a RuntimeDefinition. or php file describing the structure.0. Release 2.4 ClassDefinition The idea behind using a ClassDefinition is two-fold. ini. 60. } The above code would more than likely go inside your application’s or module’s bootstrap file. This represents the simplest and most performant way of configuring your DiC for usage. Secondly. First.Zend Framework 2 Documentation. Todo . ClassDefinition 265 . This class definition can be fed in via Configuration or by directly instantiating and registering the Definition with the DefinitionList. $app->setLocator($di).

0. Release 2.Zend Framework 2 Documentation.6 266 Chapter 60. Zend\Di Definition .

public function __construct($username. you should attempt to not use the same parameter name twice in the same class when you expect that that parameters is used for either instance configuration or an object dependency.CHAPTER SIXTYONE ZEND\DI INSTANCEMANAGER The InstanceManage is responsible for any runtime information associated with the Zend\Di\Di DiC. each uniquely named.1 Parameters Parameters are simply entry points for either dependencies or instance configuration values. This leads to an ambiguous parameter. 267 . } } class MovieLister { protected $movieFinder = null. $password) { $this->username = $username. This means that the information that goes into the instance manager is specific to both how the particular consuming Application’s needs and even more specifically to the environment in which the application is running. A class consist of a set of parameters. public function __construct(\MyLibrary\DbAdapter $dbAdapter) { $this->dbAdapter = $dbAdapter. $this->password = $password. When writing your classes. Our movie finder example can be further used to explain these concepts: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 namespace MyLibrary { class DbAdapter { protected $username = null. 61. protected $password = null. } } } namespace MyMovieApp { class MovieFinder { protected $dbAdapter = null. and is a situation best avoided.

it must be provided to the instance manager in the form of parameters. When looking at the above code. more than likely. and MovieLister has one parameter: movieFinder. the class DbAdapter has 2 parameters: username and password.Zend Framework 2 Documentation.2 Preferences In some cases. you might be using interfaces as type hints as opposed to concrete types. The following ways of using parameters are available: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // setting instance configuration into the instance manager $di->instanceManager()->setParameters(’MyLibrary\DbAdapter’. Since the DiC cannot reasonably know this information. array( ’dbAdapter’ => new MyLibrary\DbAdaper(’myusername’. username and password do not have type-hints and are. // forcing a particular dependency to be used by the instance manager $di->instanceManager()->setParameters(’MyMovieApp\MovieFinder’. array( ’username’ => $config->username. Zend\Di InstanceManager . // passing instance parameters at call time $movieLister = $di->get(’MyMovieApp\MovieLister’. 268 Chapter 61. // passing a specific instance at call time $movieLister = $di->get(’MyMovieApp\MovieLister’. Lets assume the movie example was modified in the following way: 1 2 3 4 5 6 7 8 9 10 namespace MyMovieApp { interface MovieFinderInterface { // methods required for this type } class GenericMovieFinder implements MovieFinderInterface { protected $dbAdapter = null. ’mypassword’) )). Release 2. 61. ’password’ => $config->password )). } } } In the above example. array( ’username’ => ’myusername’.0.6 29 30 31 32 33 34 public function __construct(MovieFinder $movieFinder) { $this->movieFinder = $movieFinder. Not doing so will force $di->get(‘MyMovieApp\MovieLister’) to throw an exception. Any of these can be utilized for injection of either dependencies or scalar values during instance configuration or during call time. scalar in nature. array( ’dbAdapter’ => new MyLibrary\DbAdaper(’myusername’. ’mypassword’) )). since the dbAdapter parameter and the movieFinder parameter are both type-hinted with concrete types. MovieFinder has one parameter: dbAdapter. ’password’ => ’mypassword’ )). the DiC can assume that it can fulfill these object tendencies by itself. On the other hand.

’MyLibrary\DbAdapter’. $im->addAlias(’dbadapter-readwrite’. so this type of ‘preference’ needs to be made known to the instance manager.0. As you can imagine. } } class MovieLister { protected $movieFinder = null. the other will be for read-write operations: Note: Aliases can also have parameters registered at alias time 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // assume the MovieLister example of code from the QuickStart $im = $di->instanceManager(). To give this information to the instance manager. Aliases 269 . 61. array( ’username’ => $config->db->readAdapter->username. ’MyMovieApp\MovieLister’). ’MyMovieApp\GenericMovie // assuming all instance config for username.3 Aliases In some situations. Zend\Di. as opposed to using the full class name. array( ’username’ => $config->db->readWriteAdapter>username. it creates a simpler. )). as opposed to attaching that configuration to the class name. To demonstrate both of these points. Release 2. see the following code example: 1 2 3 $di->instanceManager()->addTypePreference(’MyMovieApp\MovieFinderInterface’. // add aliases for specific instances $im->addAlias(’dbadapter-readonly’. we’ll look at a use case where we’ll have two separate DbAdapters. ’password’ => $config->db->readWriteAdapter>password. ’password’ => $config->db->readAdapter->password. Second. you’ll find that you need to alias an instance. There are two main reasons to do this. if that is what the consumer decides they want to do.6 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public function __construct(\MyLibrary\DbAdapter $dbAdapter) { $this->dbAdapter = $dbAdapter. one will be for read-only operations. This allows multiple implementations of this base interface to be used as a dependency.3. you can then attach a specific instance configuration to that alias. public function __construct(MovieFinderInterface $movieFinder) { $this->movieFinder = $movieFinder. 61. by itself would not be able to determine what kind of concrete object to use fulfill this dependency.Zend Framework 2 Documentation. ’MyLibrary\DbAdapter’. you might find that you need to have the same object type in two separate contexts. This means that when you alias a particular class. // add alias for short naming $im->addAlias(’movielister’. alternative name to use when using the DiC. password is setup $di->get(’MyMovieApp\MovieLister’). First. } } } What you’ll notice above is that now the MovieLister type minimally expects that the dependency injected implements the MovieFinderInterface.

$movieListerRead = $di->get(’MyMovieApp\MovieLister’). // set a default type to use. pointing to an alias $im->addTypePreference(’MyLibrary\DbAdapter’.Zend Framework 2 Documentation. ’dbadapter-readonly’). $movieListerReadWrite = $di->get(’MyMovieApp\MovieLister’. array(’dbAdapter’ => ’dbadapter-readwrite’ 270 Chapter 61.6 16 17 18 19 20 21 22 )). Zend\Di InstanceManager . Release 2.0.

// an array of supertypes the class implements ’methods’ => array( ’setSomeParameter’ => array( // a method name ’parameterName’ => array( ’name’. each specifying values for respectively. definition setup and instance manager setup. // the name of the instantiator. ’runtime’ => array(/* @todo runtime information */). 271 . // type or null ’is-required’ // bool ) ) ) ) ) ). by default this is __construct ’supertypes’ => array(). This file will produce an array (typically) and have a particular iterable structure. The definition section expects the following information expressed as a PHP array: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $config = array( ’definition’ => array( ’compiler’ => array(/* @todo compiler information */). ’class’ => array( ’instantiator’ => ’’. The top two keys are ‘definition’ and ‘instance’.CHAPTER SIXTYTWO ZEND\DI CONFIGURATION Most of the configuration for both the setup of Definitions as well as the setup of the Instance Manager can be attained by a configuration file. // string parameter name ’type’.

0.6 272 Chapter 62. Release 2.Zend Framework 2 Documentation. Zend\Di Configuration .

public function setBam(Bam $bam){ $this->bam = $bam.1 Debugging a DiC It is possible to dump the information contained within both the Definition and InstanceManager for a Di instance. $baz = $di->get(’Foo\Bar\Baz’).2.2 Complex Use Cases 63. } } namespace { include ’zf2bootstrap. $di = new Zend\Di\Di.php’. If you are using a RuntimeDefinition where upon you expect a particular definition to be resolve at the first-call. The easiest way is to do the following: 1 Zend\Di\Display\Console::export($di).1 Interface Injection 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 namespace Foo\Bar { class Baz implements BamAwareInterface { public $bam. array(’A\ClassIWantTo\GetTheDefinitionFor’)).CHAPTER SIXTYTHREE ZEND\DI DEBUGGING & COMPLEX USE CASES 63. you can see that information to the console display to force it to read that class: 1 Zend\Di\Display\Console::export($di. } } class Bam { } interface BamAwareInterface { public function setBam(Bam $bam). } 273 . 63.

php’.2. } } interface Block { } } namespace MyModule { class BlockOne implements \Application\Block {} class BlockTwo implements \Application\Block {} } namespace { include ’zf2bootstrap. $di->configure(new Zend\Di\Config(array( ’definition’ => array( ’class’ => array( ’Foo\Bar\Baz’ => array( ’setBam’ => array(’required’ => true) ) ) ) ))). $baz = $di->get(’Foo\Bar\Baz’). $di = new Zend\Di\Di. } } class Bam { } } namespace { $di = new Zend\Di\Di.6 63.0.2 Setter Injection with Class Definition 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 namespace Foo\Bar { class Baz { public $bam.3 Multiple Injections To A Single Injection Point 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 namespace Application { class Page { public $blocks.Zend Framework 2 Documentation. ’required’ => true) ) ) ) 274 Chapter 63. $di->configure(new Zend\Di\Config(array( ’definition’ => array( ’class’ => array( ’Application\Page’ => array( ’addBlock’ => array( ’block’ => array(’type’ => ’Application\Block’. Release 2. public function addBlock(Block $block){ $this->blocks[] = $block.2. } 63. public function setBam(Bam $bam){ $this->bam = $bam. Zend\Di Debugging & Complex Use Cases .

6 29 30 31 32 33 34 35 36 37 38 39 40 ). Complex Use Cases 275 .0. ’MyModule\BlockTwo’ ) ) ) ))).Zend Framework 2 Documentation.2. ’instance’ => array( ’Application\Page’ => array( ’injections’ => array( ’MyModule\BlockOne’. $page = $di->get(’Application\Page’). Release 2. } 63.

Zend\Di Debugging & Complex Use Cases .Zend Framework 2 Documentation. Release 2.0.6 276 Chapter 63.

Currently.CHAPTER SIXTYFOUR INTRODUCTION The Zend\Dom component provides tools for working with DOM documents and structures. we offer Zend\Dom\Query. 277 . which provides a unified interface for querying DOM documents utilizing both XPath and CSS selectors.

6 278 Chapter 64. Introduction .0. Release 2.Zend Framework 2 Documentation.

error‘.required‘. optionally passing a document to query (a string). that is an 279 . You can utilize any of the following. It was developed to aid with functional testing of MVC applications.1 Theory of Operation To use Zend\Dom\Query. – word match: the attribute contains a word matching the string: ‘div[bar~=”baz”]’ would match a div element with a “bar” attribute that contains the word “baz”. Three different types of matching are provided: – exact match: the attribute exactly matches the string: ‘div[bar=”baz”]’ would match a div element with a “bar” attribute that exactly matches the value “baz”. ‘<div bar=”foo baz”>’ would match. in any combination: • element types: provide an element type to match: ‘div’. each method will return a Zend\Dom\NodeList object with any matching nodes. but could also be used for rapid development of screen scrapers. etc. ‘div > span’ would select only ‘span’ elements that are direct descendents of a ‘div’. CSS selector notation is provided as a simpler and more familiar notation for web developers to utilize when querying documents with XML structures. etc. 65. ‘div. etc. • arbitrary attributes: arbitrary element attributes to match. • direct descendents: utilize ‘>’ between selectors to denote direct descendents. ‘span’.query were both inspirations for the component).error‘. ‘div .foo span #one‘ would select an element of id ‘one’ that is a descendent of arbitrary depth beneath a ‘span’ element. • descendents: string together multiple selectors to indicate a hierarchy along which to search. ‘a’.CHAPTER SIXTYFIVE ZEND\DOM\QUERY Zend\Dom\Query provides mechanisms for querying XML and (X) HTML documents utilizing either XPath or CSS selectors. ‘div#nav’. ‘label. you can use either the query() or queryXpath() methods. but ‘<div bar=”foo bazbat”>’ would not. ‘h2’. • id attributes: element ID attributes to match: ‘#content’. which is in turn a descendent of arbitrary depth beneath an element with a class of ‘foo’. • style attributes: CSS style attributes to match: ‘. The primary difference between Zend\Dom\Query and using DOMDocument + DOMXPath is the ability to select against CSS selectors. Can also be used with any of the selectors above. this will match as long as the named style is present anywhere in the style declaration. – substring match: the attribute contains the string: ‘div[bar*=”baz”]’ would match a div element with a “bar” attribute that contains the string “baz” anywhere within it. you instantiate a Zend\Dom\Query object. If an element defines more than one style. The notation should be familiar to anybody who has developed Cascading Style Sheets or who utilizes Javascript toolkits that provide functionality for selecting nodes utilizing CSS selectors (Prototype’s $$() and Dojo’s dojo. Once you have a document.

6 descendent of arbitrary depth beneath a ‘div’ element. $encoding = null): specify an XHTML string to query against. you can pass any valid XPath query to this method. a string to query against.1 Zend\Dom\Query The following methods are available to Zend\Dom\Query: • setDocumentXml($document.0. as well as to pull them and/or their content directly for examination and manipulation.foo . • setEncoding($encoding): specify an encoding string to use. For example. and it will return a Zend\Dom\NodeList object. 65. $encoding = null): specify an HTML string to query against. Zend\Dom\NodeList implements Countable and Iterator. $dom = new Query($html). Zend\Dom\Query . you can then work with the result object to determine information about the nodes. consider the following call. As an example.Zend Framework 2 Documentation. • setDocumentXhtml($document. 280 Chapter 65. • setDocument($document. Release 2. This encoding will be passed to DOMDocument’s constructor if specified. $count = count($results). $results = $dom->execute(’. $encoding = null): specify an XML string to query against.2. // get number of matches: 4 foreach ($results as $result) { // $result is a DOMElement } Zend\Dom\Query also allows straight XPath queries utilizing the queryXpath() method.2 Methods Available The Zend\Dom\Query family of classes have the following methods available. that selects against the HTML above: 1 2 3 4 5 6 7 8 9 use Zend\Dom\Query. it would match the link to the word ‘One’ in the listing below: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div> <table> <tr> <td class="foo"> <div> Lorem ipsum <span class="bar"> <a href="/foo/bar" id="one">One</a> <a href="/foo/baz" id="two">Two</a> <a href="/foo/bat" id="three">Three</a> <a href="/foo/bla" id="four">Four</a> </span> </div> </td> </tr> </table> </div> Once you’ve performed your query. • setDocumentHtml($document. 65. $encoding = null): specify Zend\Dom\Query will then attempt to autodetect the document type. and stores the results internally as a DOMDocument and DOMNodeList.bar a’).

Methods Available 281 . will be one of the DOC_XML. • queryXpath($xPathQuery): query the document using XPath notation.Zend Framework 2 Documentation.2.0. DOC_XHTML. Additionally. or DOC_HTML class constants. • execute($query): query the document using CSS selector notation. • getEncoding(): retrieves the specified encoding. 65. • getDocumentType(): retrieve the document type of the document provided to the object.2 Zend\Dom\NodeList As mentioned previously. 65. and as such can be used in a foreach() loop as well as with the count() function. • getDocument(): retrieve the DOMDocument the selection was made against. so this value will always be populated. Release 2. Zend\Dom\Query converts CSS selector queries to XPath. • getXpathQuery(): return the XPath query used to produce the result.6 • getDocument(): retrieve the original document string provided to the object. it exposes the following methods: • getCssQuery(): return the CSS selector query used to produce the result (if any). Internally. Zend\Dom\NodeList implements both Iterator and Countable.2.

Release 2. Zend\Dom\Query .Zend Framework 2 Documentation.6 282 Chapter 65.0.

The basic architecture allows you to attach and detach listeners to named events. class Foo implements EventManagerAwareInterface { protected $events. 283 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 use Zend\EventManager\EventManagerInterface. and interrupt execution of listeners. you will compose an EventManager instance in a class. )). use Zend\EventManager\EventManagerAwareInterface. 66. } return $this->events. public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers(array( __CLASS__. trigger events. get_called_class(). both on a per-instance basis as well as via shared collections. • Implementing Aspect-Oriented designs.2 Quick Start Typically. $this->events = $events. • Implementing event-driven architectures. } public function getEventManager() { if (null === $this->events) { $this->setEventManager(new EventManager()).1 Overview The EventManager is a component designed for the following use cases: • Implementing simple subject/observer patterns. return $this. use Zend\EventManager\EventManager.CHAPTER SIXTYSIX THE EVENTMANAGER 66.

However. $params = json_encode($e->getParams()). Listeners attach to a SharedEventCollection in roughly the same way the do normal event managers. }). you can inject individual EventManager instances with a well-known SharedEventCollection. ’bat’). and trigger the event. and the EventManager instance will query it for additional listeners. which has accessors for retrieving the event name.6 25 26 } } The above allows users to access the EventManager instance. function ($e) use ($log) { $event = $e->getName(). the “context”. assuming 284 Chapter 66. $this->getEventManager()->trigger(__FUNCTION__. it will be lazily instantiated on-demand. using params {"baz" : "baz". $this. Remember the example of composing an EventManager. which is usually the current function/method name. any PHP callback is valid. specifying a named event and the callback to notify. which is usually the current object instance. an anonymous function is shown in the example in order to keep the example self-contained. context. Basic triggering takes three arguments: the event name. Again. Release 2. Sometimes you may want to specify listeners without yet having an object instance of the class composing an EventManager. the call to attach is identical to the EventManager. $event. ’bat’). Listeners attach to the EventManager. Let’s add a listener. Zend Framework enables this through the concept of a SharedEventCollection. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 use Zend\Log\Factory as LogFactory. $target = get_class($e->getTarget()). $log = LogFactory($someConfig). 1 2 3 4 5 6 7 8 9 10 class Foo { // ... but expects an additional parameter at the beginning: a named instance. assume events definition from above public function bar($baz. $log->info(sprintf( ’%s called on %s. and the arguments. $bat = null) { $params = compact(’baz’. triggering events is only interesting if something is listening for the event. The callback receives an Event object. "bat" : "bat"}" Note that the second argument to attach() is any valid callback. Simply put. or any strings you provide in an array to the constructor. // Results in log message: $foo->bar(’baz’. $target. } } In turn. An EventManager is really only interesting if it triggers some events. or reset it with a new instance.0. // reading: bar called on Foo. $foo->getEventManager()->attach(’bar’. which are usually the arguments provided to the current function/method. The EventManager . how we passed it __CLASS__? That value. $params). $foo = new Foo(). As an example. you could also utilize a valid function name. $params )). if one does not exist. a string referencing a static method.Zend Framework 2 Documentation. a functor. or an array callback with a named static method or instance method. and parameters. may be used to identify an instance when using a SharedEventCollection. using params %s’.

Be aware. The EventManager also provides the ability to detach listeners. ’names’). Attaching to many events at once $events = new EventManager(). $events->attach(array(’these’. 66. As such. test and loop through the results returned by listeners. $callback). and many events.0beta4. "bat" : "bat"}" Note: StaticEventManager As of 2. you can use the StaticEventManager singleton as a SharedEventCollection. The EventManager component allows for this. $target = get_class($e->getTarget()). many contexts. you will instead configure a SharedEventManager instance that will be injected by the framework into individual EventManager instances.0.Zend Framework 2 Documentation. Many of these features are detailed in the examples. // Assume $events is a Zend\EventManager\SharedEventManager instance $log = LogFactory($someConfig).2. we could change the above example to attach via the shared collection: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 use Zend\Log\Factory as LogFactory. $params )). via dependency injection). $foo->getEventManager()->setSharedEventCollection($events). }). Quick Start 285 . however.6 we have a SharedEventManager instance that we know has been injected in our EventManager instances (for instance.1 Wildcard Listeners Sometimes you’ll want to attach the same listener to many events or to all events of a given instance – or potentially.0. // And we can still trigger the above event: $foo->bar(’baz’. with a shared event collection. $params = json_encode($e->getParams()). $target. and more. that its usage is deprecated within the framework.0beta3. using params {"baz" : "baz". ’are’. using params %s’. it’s globally available by simply calling StaticEventManager::getInstance(). short-circuit execution of an event either from within a listener or by testing return values of listeners. $event. 66. ’bat’).0. Release 2. you do not need to worry about where and how to get access to the SharedEventCollection. // Later. // results in log message: // bar called on Foo.2. $events->attach(’Foo’. 1 2 Note that if you specify a priority. and starting with 2. instantiate Foo: $foo = new Foo(). prioritize listeners. $log->info(sprintf( ’%s called on %s. function ($e) use ($log) { $event = $e->getName(). ’bar’. ’event’. that priority will be used for all events specified.

’names’). // Attach to many events on the contexts "foo" and "bar" $events->attach(array(’foo’. ’are’. $events->attach(’*’. 286 Chapter 66. $callback). Attaching to many events at once via a SharedEventManager $events = new SharedEventManager(). the specified listener should be notified for any event they trigger. ’event’. // Attach to all events on the contexts "foo" and "bar" $events->attach(array(’foo’. shared_collections An instance of a SharedEventCollection instance to use when triggering events. $callback). 1 2 3 4 5 6 Note that if you specify a priority. that priority will be used for all events specified. that priority will be used for this listener for any event triggered. if provided. Release 2. array(’these’. 66. ’names’). $callback).0.Zend Framework 2 Documentation. 1 2 3 4 5 6 Note that if you specify a priority. 1 2 Note that if you specify a priority. What the above specifies is that any event triggered will result in notification of this particular listener. 66. The above is specifying that for the contexts “foo” and “bar”. $callback). that priority will be used for all events specified. ’bar’). The EventManager .6 Attaching using the wildcard $events = new EventManager(). // Attach to many events on the context "foo" $events->attach(’foo’. ’*’. ’are’. Attaching to many events at once via a SharedEventManager $events = new SharedEventManager(). event_class The name of an alternate Event class to use for representing events passed to listeners. using the given identifier. array(’these’.3 Configuration Options EventManager Options identifier A string or array of strings to which the given EventManager instance can answer when accessed via a SharedEventManager. // Attach to all events on the context "foo" $events->attach(’foo’. ’*’. $callback). ’event’. ’bar’).4 Available Methods __construct __construct(null|string|int $identifier) Constructs a new EventManager instance. for purposes of shared collections.

we recommend using the parameters passed to the function/method (compact() is often useful here). test for short-circuiting. The method returns an instance of ResponseCollection. If a $priority is provided. triggerUntil triggerUntil(string $event. or a SharedEventCollection instance otherwise. and more. $context should be the current object instance. setSharedCollections setSharedCollections(SharedEventCollection $collections = null) An instance of a SharedEventCollection instance to use when triggering events. listening for the event $event. as needed. for all matches. $params should typically be an associative array or ArrayAccess instance. if $callback returns a boolean true value. This method can also take a callback and behave in the same way as triggerUntil(). higher values execute earliest.0. attach attach(string $event. Returns either a null if no collection is attached. The $aggregate is then passed the EventManager instance to its attach() method so that it may register listeners. with the addition that it passes the return value from each listener to $callback. Release 2. Returns a boolean true if any listeners have been identified and unsubscribed. mixed $argv. instantiates that class. callback $callback.Zend Framework 2 Documentation. ”. or the name of the function if not triggering within an object. the listeners will be removed.post”. trigger trigger(string $event. the listener will be inserted into the internal listener stack using that priority. The recommendation is to use the current function/method name for $event. just like trigger(). attachAggregate attachAggregate(string|ListenerAggregate $aggregate) If a string is passed for $aggregate. getSharedCollections getSharedCollections() Returns the currently attached SharedEventCollection instance. The ListenerAggregate instance is returned.pre”. and negative priorities are allowed. which may be used to introspect return values of the various listeners. callback $callback) Triggers all listeners to a named event. Available Methods 287 . mixed $target. and a boolean false otherwise. and detaches any that match $listener so that they will no longer be triggered. execution of the listeners is interrupted.6 setEventClass setEventClass(string $class) Provide the name of an alternate Event class to use when creating events to pass to triggered listeners.) The method returns an instance of Zend\Stdlib\CallbackHandler. detachAggregate detachAggregate(ListenerAggregate $aggregate) Loops through all listeners of all events to identify listeners that are represented by the aggregate.4. int $priority) Attaches $callback to the EventManager instance. this value can later be passed to detach() if desired. mixed $context. You can test for this using $result->stopped(). mixed $argv. callback $callback) Triggers all listeners to a named event. and a boolean false otherwise. getEvents getEvents() Returns an array of all event names that have listeners attached. 66. etc. (Default priority is “1”. appending it with values such as ”. detach detach(CallbackHandler $listener) Scans all listeners. Returns a boolean true if any listeners have been identified and unsubscribed.

288 Chapter 66. } $values[’date’] = new Datetime($values[’date’]).0. To do this. You will then pull that value back into your method. return. prepareArgs prepareArgs(array $args) Creates an ArrayObject from the provided $args. 66.5 Examples Modifying Arguments Occasionally it can be useful to allow listeners to modify the arguments they receive so that later listeners or the calling method will receive those changed values. you can pass your arguments to prepareArgs(). $date = isset($argv[’values’][’date’]) ? $argv[’values’][’date’] : new DateTime(’now’). if (!$values) { return. This can be useful if you want yours listeners to be able to modify arguments such that later listeners or the triggering method can see the changes. } if (!isset($values[’date’])) { $values[’date’] = new DateTime(’now’). you might want to pre-filter a date that you know will arrive as a string and convert it to a DateTime argument. $v->inject(array( ’date’ => ’2011-08-10 15:30:29’. } } $v = new ValueObject(). $this. $v->getEventManager()->attach(’inject’. The EventManager . Release 2..6 getListeners getListeners(string $event) Returns a Zend\Stdlib\PriorityQueue instance of all listeners attached to $event. $argv).Zend Framework 2 Documentation. )). // . $this->getEventManager()->trigger(__FUNCTION__. }). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class ValueObject { // assume a composed event manager function inject(array $values) { $argv = compact(’values’). clearListeners clearListeners(string $event) Removes all listeners attached to $event. $argv = $this->getEventManager()->prepareArgs($argv). and pass this new object when triggering an event. As an example.. function($e) { $values = $e->getParam(’values’).

if an event creates a Response object. ’response’). 66. you may want to return a value that stopped execution.5.6 Short Circuiting One common use case for events is to trigger listeners until either one indicates no further processing should be done. we could do the check from the method triggering the event. $argv. 1 2 3 4 5 6 7 8 9 10 11 12 class Foo implements DispatchableInterface { // assume composed event manager public function dispatch(Request $request. function($v) { return ($v instanceof Response). you often want to check the cache early. Response $response = null) { $argv = compact(’request’.Zend Framework 2 Documentation. and last() method to retrieve the return value from the last executed listener: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Foo implements DispatchableInterface { // assume composed event manager public function dispatch(Request $request.. and return last result: if ($results->stopped()) { return $results->last(). return $response. or until a return value meets specific criteria. } } Assigning Priority to Listeners One use case for the EventManager is for implementing caching systems. $argv. $results = $this->getEventManager()->triggerUntil(__FUNCTION__. or use it some way.. ’response’). }). Both trigger() and triggerUntil() return a ResponseCollection instance. $this. and save to it late. Release 2. $results = $this->getEventManager()->triggerUntil(__FUNCTION__. Alternately. As examples. } // continue. } } Typically. // Test if execution was halted. Response $response = null) { $argv = compact(’request’. $this. Examples 289 . As such. 1 2 3 4 5 6 7 $listener = function($e) { // do some work // Stop propagation and return a response $e->stopPropagation(true). }). it may want execution to stop. }. function($v) { return ($v instanceof Response). call its stopped() method to test if execution was stopped.0.

let’s create a ListenerAggregateInterface that can handle caching for us: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 use use use use Zend\Cache\Cache. public function __construct(Cache $cache) { $this->cache = $cache.. protected $listeners = array(). // If an event stopped propagation. 100). we want an event that will trigger early. So. } } Now. $this. ’save’). an event should trigger late. array($this. $this->getEventManager()->trigger(’get.post’. } public function attach(EventCollection $events) { $this->listeners[] = $events->attach(’get. the lower it is.Zend Framework 2 Documentation. $params). return the value if ($results->stopped()) { return $results->last(). Zend\EventManager\EventCollection. Release 2. The EventManager . Here is the class in which we want caching: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class SomeValueObject { // assume it composes an event manager public function get($id) { $params = compact(’id’). } // do some work. and values will trigger in the order registered within a given priority. our method will need to trigger an event at method start as well as at method end. array($this.. -100). $results = $this->getEventManager()->trigger(’get. to implement a caching system. At method start. Zend\EventManager\EventInterface. class CacheListener implements ListenerAggregateInterface { protected $cache. at method end.pre’. $this. the earlier that listener will execute. } public function detach(EventManagerInterface $events) { foreach ($this->listeners as $index => $listener) { if ($events->detach($listener)) { unset($this->listeners[$index]). Zend\EventManager\ListenerAggregateInterface. } 290 Chapter 66.6 The third argument to attach() is a priority value. ’load’).post’. $params). the later it executes.pre’. $this->listeners[] = $events->attach(’get. The higher this number.0. The value defaults to 1. $params[’__RESULT__’] = $someComputedContent.

$id = get_class($e->getTarget()) . $content = $params[’__RESULT__’]. if not. if we have a cached entry. $value->getEventManager()->attachAggregate($cacheListener). 1 2 3 $value = new SomeValueObject().6 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 } } public function load(EventInterface $e) { $id = get_class($e->getTarget()) . a computed entry will be cached when we complete the method.0. if (false !== ($content = $this->cache->load($id))) { $e->stopPropagation(true). return $content. Now. json_encode($e->getParams()). ’-’ . } } public function save(EventInterface $e) { $params = $e->getParams(). Release 2.5. it will be returned immediately. json_encode($params). ’-’ . 66. $cacheListener = new CacheListener($cache).Zend Framework 2 Documentation. } } We can then attach the aggregate to an instance. unset($params[’__RESULT__’]). $this->cache->save($content. $id). Examples 291 . as we call get().

Zend Framework 2 Documentation.0. The EventManager . Release 2.6 292 Chapter 66.

The RSS specification provides for many optional properties. array() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // Loop over each channel item/entry and store relevant data for each foreach ($slashdotRss as $item) { 293 . and turning the result back into XML. } // Initialize the $channel = array( ’title’ ’link’ ’description’ ’items’ ). and Zend\Feed\PubSubHubbub for working with Hub servers. Note: Be aware Many RSS feeds have different channel and item properties available. Zend\Feed supports all optional properties of the core RSS and Atom specifications. and entry attributes. not covered in the core API but used in conjunction with RSS and Atom feeds. etc. $slashdotRss->getDescription(). we demonstrate a simple use case of retrieving an RSS feed and saving relevant portions of the feed data to a simple PHP array.org/Slashdot/slashdot’). Zend\Feed\Writer for writing RSS and Atom feeds. which could then be used for printing the data. Reading RSS Feed Data with Zend\Feed\Reader // Fetch the latest Slashdot headlines try { $slashdotRss = Zend\Feed\Reader\Reader::import(’http://rss.CHAPTER SIXTYSEVEN INTRODUCTION Zend\Feed provides functionality for consuming RSS and Atom feeds. this modification support could provide support for the Atom Publishing Protocol. Zend\Feed consists of Zend\Feed\Reader for reading RSS and Atom feeds. In the example below. so be aware of this when writing code to work with RSS data. channel/feed data array => => => => $slashdotRss->getTitle(). feed attributes. It provides a natural syntax for accessing elements of feeds. In the future. Furthermore.slashdot. Zend\Feed also has extensive support for modifying feed and entry structure with the same natural syntax. exit. both Zend\Feed\Reader and Zend\Feed\Writer support extensions which allows for working with additional data in feeds. } catch (Zend\Feed\Exception\Reader\RuntimeException $e) { // feed import failed echo "Exception caught importing feed: {$e->getMessage()}\n". $slashdotRss->getLink(). storing to a database.

e. 294 Chapter 67.Zend Framework 2 Documentation.0. ’link’ => $item->getLink(). i. ’description’ => $item->getDescription() ). Release 2. The process is identical for Atom feeds since Zend\Feed features a common denominator API. } Your $channel array now contains the basic meta-information for the RSS channel and all items that it contained. Introduction . all getters and setters are the same regardless of feed format.6 21 22 23 24 25 26 $channel[’items’][] = array( ’title’ => $item->getTitle().

you may use the saveXml() method. simply use the Zend\Feed\Reader\Reader::import() method: 1 $feed = Zend\Feed\Reader\Reader::import(’http://feeds. // importing a feed from a PHP string variable $feedFromPHP = Zend\Feed\Reader\Reader::importString($feedString). 68. In each of the examples above. On the other hand.com/feedName’). an object of a class that extends Zend\Feed\Reader\Feed\AbstractFeed is returned upon success. by using Zend\Feader\Reader.example. If an RSS feed were retrieved via one of the import methods above. // dump the feed to standard output print $feed->saveXml(). such as an unreadable or malformed feed.1 Dumping the contents of a feed To dump the contents of a Zend\Feed\Reader\Feed\AbstractFeed instance. 1 2 3 4 assert($feed instanceof Zend\Feed\Reader\Feed\AbstractFeed). then a Zend\Feed\Reader\Feed\Atom object is returned. depending on the type of the feed.CHAPTER SIXTYEIGHT IMPORTING FEEDS Zend\Feed enables developers to retrieve feeds very easily. then a Zend\Feed\Reader\Feed\Rss object would be returned. 295 . if an Atom feed were imported.xml’). You can also use Zend\Feed\Reader\Reader to fetch the contents of a feed from a file or the contents of a PHP string variable: 1 2 3 4 5 // importing a feed from a text file $feedFromFile = Zend\Feed\Reader\Reader::importFile(’feed. If you know the URI of a feed. The import methods will also throw a Zend\Feed\Exception\Reader\RuntimeException object upon failure.

Importing Feeds .0.Zend Framework 2 Documentation.6 296 Chapter 68. Release 2.

CHAPTER

SIXTYNINE

RETRIEVING FEEDS FROM WEB PAGES
Web pages often contain <link> tags that refer to feeds with content relevant to the particular page. Zend\Feed\Reader\Reader enables you to retrieve all feeds referenced by a web page with one simple method call:
1

$feedLinks = Zend\Feed\Reader\Reader::findFeedLinks(’http://www.example.com/news.html’);

Here the findFeedLinks() method returns a Zend\Feed\Reader\FeedSet object, that is in turn, a collection of other Zend\Feed\Reader\FeedSet objects, that are referenced by <link> tags on the news.html web page. Zend\Feed\Reader\Reader will throw a Zend\Feed\Reader\Exception\RuntimeException upon failure, such as an HTTP 404 response code or a malformed feed. You can examine all feed links located by iterating across the collection:
1 2 3 4 5 6 7

$rssFeed = null; $feedLinks = Zend\Feed\Reader\Reader::findFeedLinks(’http://www.example.com/news.html’); foreach ($feedLinks as $link) { if (stripos($link[’type’], ’application/rss+xml’) !== false) { $rssFeed = $link[’href’]; break; }

Each Zend\Feed\Reader\FeedSet object will expose the rel, href, type and title properties of detected links for all RSS, Atom or RDF feeds. You can always select the first encountered link of each type by using a shortcut:
1 2 3

$rssFeed = null; $feedLinks = Zend\Feed\Reader\Reader::findFeedLinks(’http://www.example.com/news.html’); $firstAtomFeed = $feedLinks->atom;

297

Zend Framework 2 Documentation, Release 2.0.6

298

Chapter 69. Retrieving Feeds from Web Pages

CHAPTER

SEVENTY

CONSUMING AN RSS FEED
Reading an RSS feed is as simple as passing the URL of the feed to Zend\Feed\Reader\Reader‘s import method.
1

$channel = new Zend\Feed\Reader\Reader::import(’http://rss.example.com/channelName’);

If any errors occur fetching the feed, a Zend\Feed\Reader\Exception\RuntimeException will be thrown. Once you have a feed object, you can access any of the standard RSS “channel” properties directly on the object:
1

echo $channel->getTitle();

Properties of the channel can be accessed via getter methods, such as getTitle, getAuthor ... If channel properties have attributes, the getter method will return a key/value pair, where the key is the attribute name, and the value is the attribute value.
1 2

$author = $channel->getAuthor(); echo $author[’name’];

Most commonly you’ll want to loop through the feed and do something with its entries. Zend\Feed\Reader\Feed\Rss internally converts all entries to a Zend\Feed\Reader\Entry\Rss. Entry properties, similary to channel properties, can be accessed via getter methods, such as getTitle, getDescription ... An example of printing all titles of articles in a channel is:
1 2 3

foreach ($channel as $item) { echo $item->getTitle() . "\n"; }

If you are not familiar with RSS, here are the standard elements you can expect to be available in an RSS channel and in individual RSS items (entries). Required channel elements: • title- The name of the channel • link- The URL of the web site corresponding to the channel • description- A sentence or several describing the channel Common optional channel elements: • pubDate- The publication date of this set of content, in RFC 822 date format • language- The language the channel is written in

299

Zend Framework 2 Documentation, Release 2.0.6

• category- One or more (specified by multiple tags) categories the channel belongs to RSS <item> elements do not have any strictly required elements. However, either title or description must be present. Common item elements: • title- The title of the item • link- The URL of the item • description- A synopsis of the item • author- The author’s email address • category- One more categories that the item belongs to • comments-URL of comments relating to this item • pubDate- The date the item was published, in RFC 822 date format In your code you can always test to see if an element is non-empty with:
1 2 3

if ($item->getPropname()) { // ... proceed. }

Where relevant, Zend\Feed supports a number of common RSS extensions including Dublin Core, Atom (inside RSS) and the Content, Slash, Syndication, Syndication/Thread and several other extensions or modules. For further information, the official RSS 2.0 specification is available at: http://blogs.law.harvard.edu/tech/rss

300

Chapter 70. Consuming an RSS Feed

CHAPTER

SEVENTYONE

CONSUMING AN ATOM FEED
Zend\Feed\Reader\Feed\Atom is used in much the same way as Zend\Feed\Reader\Feed\Rss. It provides the same access to feed-level properties and iteration over entries in the feed. The main difference is in the structure of the Atom protocol itself. Atom is a successor to RSS; it is a more generalized protocol and it is designed to deal more easily with feeds that provide their full content inside the feed, splitting RSS‘ description tag into two elements, summary and content, for that purpose.
Basic Use of an Atom Feed

Read an Atom feed and print the title and summary of each entry:
1 2 3 4 5 6 7

$feed = Zend\Feed\Reader\Reader::import(’http://atom.example.com/feed/’); echo ’The feed contains ’ . $feed->count() . ’ entries.’ . "\n\n"; foreach ($feed as $entry) { echo ’Title: ’ . $entry->getTitle() . "\n"; echo ’Description: ’ . $entry->getDescription() . "\n"; echo ’URL: ’ . $entry->getLink() . "\n\n"; }

In an Atom feed you can expect to find the following feed properties: • title- The feed’s title, same as RSS‘s channel title • id- Every feed and entry in Atom has a unique identifier • link- Feeds can have multiple links, which are distinguished by a type attribute The equivalent to RSS‘s channel link would be type="text/html". if the link is to an alternate version of the same content that’s in the feed, it would have a rel="alternate" attribute. • subtitle- The feed’s description, equivalent to RSS‘ channel description • author- The feed’s author, with name and email sub-tags Atom entries commonly have the following properties: • id- The entry’s unique identifier • title- The entry’s title, same as RSS item titles • link- A link to another format or an alternate view of this entry The link property of an atom entry typically has an href attribute. • summary- A summary of this entry’s content • content- The full content of the entry; can be skipped if the feed just contains summaries

301

Zend Framework 2 Documentation, Release 2.0.6

• author- with name and email sub-tags like feeds have • published- the date the entry was published, in RFC 3339 format • updated- the date the entry was last updated, in RFC 3339 format Where relevant, Zend\Feed supports a number of common RSS extensions including Dublin Core and the Content, Slash, Syndication, Syndication/Thread and several other extensions in common use on blogs. For more information on Atom and plenty of resources, see http://www.atomenabled.org/.

302

Chapter 71. Consuming an Atom Feed

CHAPTER

SEVENTYTWO

CONSUMING A SINGLE ATOM ENTRY
Single Atom <entry> elements are also valid by themselves. Usually the URL for an entry is the feed’s URL followed by /<entryId>, such as http://atom.example.com/feed/1, using the example URL we used above. This pattern may exist for some web services which use Atom as a container syntax. If you read a single entry, you will have a Zend\Feed\Reader\Entry\Atom object.
Reading a Single-Entry Atom Feed $entry = Zend\Feed\Reader\Reader::import(’http://atom.example.com/feed/1’); echo ’Entry title: ’ . $entry->getTitle();

1 2

303

Zend Framework 2 Documentation, Release 2.0.6

304

Chapter 72. Consuming a Single Atom Entry

CHAPTER

SEVENTYTHREE

ZEND\FEED AND SECURITY
73.1 Introduction
As with any data coming from a source that is beyond the developer’s control, special attention needs to be given to securing, validating and filtering that data. Similar to data input to our application by users, data coming from RSS and Atom feeds should also be considered unsafe and potentially dangerous, as it allows the delivery of HTML and xHTML 1 . Because data validation and filtration is out of Zend\Feed‘s scope, this task is left for implementation by the developer, by using libraries such as Zend\Escaper for escaping and HTMLPurifier for validating and filtering feed data. Escaping and filtering of potentially insecure data is highly recommended before outputting it anywhere in our application or before storing that data in some storage engine (be it a simple file, a database...).

73.2 Filtering data using HTMLPurifier
Currently the best available library for filtering and validating (x)HTML data in PHP is HTMLPurifier and, as such, is the recommended tool for this task. HTMLPurifier works by filtering out all (x)HTML from the data, except for the tags and attributes specifically allowed in a whitelist, and by checking and fixing nesting of tags, ensuring a standardscompliant output. The following examples will show a basic usage of HTMLPurifier, but developers are urged to go through and read HTMLPurifier’s documentation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

// Setting HTMLPurifier’s options $options = array( // Allow only paragraph tags // and anchor tags wit the href attribute array( ’HTML.Allowed’, ’p,a[href]’ ), // Format end output with Tidy array( ’Output.TidyFormat’, true ), // Assume XHTML 1.0 Strict Doctype array( ’HTML.Doctype’,
1

http://tools.ietf.org/html/rfc4287#section-8.1

305

Zend Framework 2 Documentation, Release 2.0.6

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

’XHTML 1.0 Strict’ ), // Disable cache, but see note after the example array( ’Cache.DefinitionImpl’, null ) ); // Configuring HTMLPurifier $config = HTMLPurifier_Config::createDefault(); foreach ($options as $option) { $config->set($option[0], $option[1]); } // Creating a HTMLPurifier with it’s config $purifier = new HTMLPurifier($config); // Fetch the RSS try { $rss = Zend\Feed\Reader\Reader::import(’http://www.planet-php.net/rss/’); } catch (Zend\Feed\Exception\Reader\RuntimeException $e) { // feed import failed echo "Exception caught importing feed: {$e->getMessage()}\n"; exit; } // Initialize the channel data array // See that we’re cleaning the description with HTMLPurifier $channel = array( ’title’ => $rss->getTitle(), ’link’ => $rss->getLink(), ’description’ => $purifier->purify($rss->getDescription()), ’items’ => array() ); // Loop over each channel item and store relevant data // See that we’re cleaning the descriptions with HTMLPurifier foreach ($rss as $item) { $channel[’items’][] = array( ’title’ => $item->getTitle(), ’link’ => $item->getLink(), ’description’ => $purifier->purify($item->getDescription()) ); }

Note: HTMLPurifier is using the PHP Tidy extension to clean and repair the final output. If this extension is not available, it will silently fail but its availability has no impact on the library’s security.

Note: For the sake of this example, the HTMLPurifier’s cache is disabled, but it is recommended to configure caching and use its standalone include file as it can improve the performance of HTMLPurifier substantially.

306

Chapter 73. Zend\Feed and Security

Zend Framework 2 Documentation, Release 2.0.6

73.3 Escaping data using Zend\Escaper
To help prevent XSS attacks, Zend Framework has a new component Zend\Escaper, which complies to the current OWASP recommendations, and as such, is the recommended tool for escaping HTML tags and attributes, Javascript, CSS and URLs before outputing any potentially insecure data to the users.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

try { $rss = Zend\Feed\Reader\Reader::import(’http://www.planet-php.net/rss/’); } catch (Zend\Feed\Exception\Reader\RuntimeException $e) { // feed import failed echo "Exception caught importing feed: {$e->getMessage()}\n"; exit; } // Validate all URIs $linkValidator = new Zend\Validator\Uri; $link = null; if ($linkValidator->isValid($rss->getLink())) { $link = $rss->getLink(); } // Escaper used for escaping data $escaper = new Zend\Escaper\Escaper(’utf-8’); // Initialize the $channel = array( ’title’ ’link’ ’description’ ’items’ ); channel data array => => => => $escaper->escapeHtml($rss->getTitle()), $escaper->escapeHtml($link), $escaper->escapeHtml($rss->getDescription()), array()

// Loop over each channel item and store relevant data foreach ($rss as $item) { $link = null; if ($linkValidator->isValid($rss->getLink())) { $link = $item->getLink(); } $channel[’items’][] = array( ’title’ => $escaper->escapeHtml($item->getTitle()), ’link’ => $escaper->escapeHtml($link), ’description’ => $escaper->escapeHtml($item->getDescription()) ); }

The feed data is now safe for output to HTML templates. You can, of course, skip escaping when simply storing the data persistently but remember to escape it on output later! Of course, these are just basic examples, and cannot cover all possible scenarios that you, as a developer, can, and most likely will, encounter. Your responsibility is to learn what libraries and tools are at your disposal, and when and how to use them to secure your web applications.

73.3. Escaping data using Zend\Escaper

307

Zend Framework 2 Documentation, Release 2.0.6

308

Chapter 73. Zend\Feed and Security

CHAPTER

SEVENTYFOUR

ZEND\FEED\READER\READER
74.1 Introduction
Zend\Feed\Reader\Reader is a component used to consume RSS and Atom feeds of any version, including RDF/RSS 1.0, RSS 2.0, Atom 0.3 and Atom 1.0. The API for retrieving feed data is deliberately simple since Zend\Feed\Reader is capable of searching any feed of any type for the information requested through the API. If the typical elements containing this information are not present, it will adapt and fall back on a variety of alternative elements instead. This ability to choose from alternatives removes the need for users to create their own abstraction layer on top of the component to make it useful or have any in-depth knowledge of the underlying standards, current alternatives, and namespaced extensions. Internally, Zend\Feed\Reader\Reader works almost entirely on the basis of making XPath queries against the feed XML‘s Document Object Model. This singular approach to parsing is consistent and the component offers a plugin system to add to the Feed and Entry level API by writing Extensions on a similar basis. Performance is assisted in three ways. First of all, Zend\Feed\Reader\Reader supports caching using Zend\Cache to maintain a copy of the original feed XML. This allows you to skip network requests for a feed URI if the cache is valid. Second, the Feed and Entry level API is backed by an internal cache (non-persistent) so repeat API calls for the same feed will avoid additional DOM or XPath use. Thirdly, importing feeds from a URI can take advantage of HTTP Conditional GET requests which allow servers to issue an empty 304 response when the requested feed has not changed since the last time you requested it. In the final case, an instance of Zend\Cache will hold the last received feed along with the ETag and Last-Modified header values sent in the HTTP response. Zend\Feed\Reader\Reader is not capable of constructing feeds and delegates this responsibility to Zend\Feed\Writer\Writer.

74.2 Importing Feeds
Feeds can be imported from a string, file or an URI. Importing from a URI can additionally utilise a HTTP Conditional GET request. If importing fails, an exception will be raised. The end result will be an object of type Zend\Feed\Reader\Feed\AbstractFeed, the core implementations of which are Zend\Feed\Reader\Feed\Rss and Zend\Feed\Reader\Feed\Atom. Both objects support multiple (all existing) versions of these broad feed types. In the following example, we import an RDF/RSS 1.0 feed and extract some basic information that can be saved to a database or elsewhere.
1 2 3 4

$feed = Zend\Feed\Reader\Reader::import(’http://www.planet-php.net/rdf/’); $data = array( ’title’ => $feed->getTitle(), ’link’ => $feed->getLink(),

309

Zend Framework 2 Documentation, Release 2.0.6

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

’dateModified’ ’description’ ’language’ ’entries’ );

=> => => =>

$feed->getDateModified(), $feed->getDescription(), $feed->getLanguage(), array(),

foreach ($feed as $entry) { $edata = array( ’title’ => $entry->getTitle(), ’description’ => $entry->getDescription(), ’dateModified’ => $entry->getDateModified(), ’authors’ => $entry->getAuthors(), ’link’ => $entry->getLink(), ’content’ => $entry->getContent() ); $data[’entries’][] = $edata; }

The example above demonstrates Zend\Feed\Reader\Reader‘s API, and it also demonstrates some of its internal operation. In reality, the RDF feed selected does not have any native date or author elements, however it does utilise the Dublin Core 1.1 module which offers namespaced creator and date elements. Zend\Feed\Reader\Reader falls back on these and similar options if no relevant native elements exist. If it absolutely cannot find an alternative it will return NULL, indicating the information could not be found in the feed. You should note that classes implementing Zend\Feed\Reader\Feed\AbstractFeed also implement the SPL Iterator and Countable interfaces. Feeds can also be imported from strings or files.
1 2 3 4 5 6 7 8

// from a URI $feed = Zend\Feed\Reader\Reader::import(’http://www.planet-php.net/rdf/’); // from a String $feed = Zend\Feed\Reader\Reader::importString($feedXmlString); // from a file $feed = Zend\Feed\Reader\Reader::importFile(’./feed.xml’);

74.3 Retrieving Underlying Feed and Entry Sources
Zend\Feed\Reader\Reader does its best not to stick you in a narrow confine. If you need to work on a feed outside of Zend\Feed\Reader\Reader, you can extract the base DOMDocument or DOMElement objects from any class, or even an XML string containing these. Also provided are methods to extract the current DOMXPath object (with all core and Extension namespaces registered) and the correct prefix used in all XPath queries for the current Feed or Entry. The basic methods to use (on any object) are saveXml(), getDomDocument(), getElement(), getXpath() and getXpathPrefix(). These will let you break free of Zend\Feed\Reader and do whatever else you want. • saveXml() returns an XML string containing only the element representing the current object. • getDomDocument() returns the DOMDocument object representing the entire feed (even if called from an Entry object). • getElement() returns the DOMElement of the current object (i.e. the Feed or current Entry). • getXpath() returns the DOMXPath object for the current feed (even if called from an Entry object) with the namespaces of the current feed type and all loaded Extensions pre-registered.

310

Chapter 74. Zend\Feed\Reader\Reader

Zend Framework 2 Documentation, Release 2.0.6

• getXpathPrefix() returns the query prefix for the current object (i.e. the Feed or current Entry) which includes the correct XPath query path for that specific Feed or Entry. Here’s an example where a feed might include an RSS Extension not supported by Zend\Feed\Reader\Reader out of the box. Notably, you could write and register an Extension (covered later) to do this, but that’s not always warranted for a quick check. You must register any new namespaces on the DOMXPath object before use unless they are registered by Zend\Feed\Reader or an Extension beforehand.
1 2 3 4 5 6 7

$feed = Zend\Feed\Reader\Reader::import(’http://www.planet-php.net/rdf/’); $xpathPrefix = $feed->getXpathPrefix(); $xpath = $feed->getXpath(); $xpath->registerNamespace(’admin’, ’http://webns.net/mvcb/’); $reportErrorsTo = $xpath->evaluate(’string(’ . $xpathPrefix . ’/admin:errorReportsTo)’);

Warning: If you register an already registered namespace with a different prefix name to that used internally by Zend\Feed\Reader\Reader, it will break the internal operation of this component.

74.4 Cache Support and Intelligent Requests
74.4.1 Adding Cache Support to ZendFeedReaderReader
Zend\Feed\Reader\Reader supports using an instance of Zend\Cache to cache feeds (as XML) to avoid unnecessary network requests. Adding a cache is as simple here as it is for other Zend Framework components, create and configure your cache and then tell Zend\Feed\Reader\Reader to use it! The cache key used is “Zend\Feed\Reader\” followed by the MD5 hash of the feed’s URI.
1 2 3

$cache = Zend\Cache\StorageFactory::adapterFactory(’Memory’); Zend\Feed\Reader\Reader::setCache($cache);

74.4.2 HTTP Conditional GET Support
The big question often asked when importing a feed frequently, is if it has even changed. With a cache enabled, you can add HTTP Conditional GET support to your arsenal to answer that question. Using this method, you can request feeds from URIs and include their last known ETag and Last-Modified response header values with the request (using the If-None-Match and If-Modified-Since headers). If the feed on the server remains unchanged, you should receive a 304 response which tells Zend\Feed\Reader\Reader to use the cached version. If a full feed is sent in a response with a status code of 200, this means the feed has changed and Zend\Feed\Reader\Reader will parse the new version and save it to the cache. It will also cache the new ETag and Last-Modified header values for future use. These “conditional” requests are not guaranteed to be supported by the server you request a URI of, but can be attempted regardless. Most common feed sources like blogs should however have this supported. To enable conditional requests, you will need to provide a cache to Zend\Feed\Reader\Reader.
1 2 3 4 5 6

$cache = Zend\Cache\StorageFactory::adapterFactory(’Memory’); Zend\Feed\Reader\Reader::setCache($cache); Zend\Feed\Reader\Reader::useHttpConditionalGet(); $feed = Zend\Feed\Reader\Reader::import(’http://www.planet-php.net/rdf/’);

74.4. Cache Support and Intelligent Requests

311

Zend Framework 2 Documentation, Release 2.0.6

In the example above, with HTTP Conditional GET requests enabled, the response header values for ETag and LastModified will be cached along with the feed. For the the cache’s lifetime, feeds will only be updated on the cache if a non-304 response is received containing a valid RSS or Atom XML document. If you intend on managing request headers from outside Zend\Feed\Reader\Reader, you can set the relevant If-None-Matches and If-Modified-Since request headers via the URI import method.
1 2 3 4 5

$lastEtagReceived = ’5e6cefe7df5a7e95c8b1ba1a2ccaff3d’; $lastModifiedDateReceived = ’Wed, 08 Jul 2009 13:37:22 GMT’; $feed = Zend\Feed\Reader\Reader::import( $uri, $lastEtagReceived, $lastModifiedDateReceived );

74.5 Locating Feed URIs from Websites
These days, many websites are aware that the location of their XML feeds is not always obvious. A small RDF, RSS or Atom graphic helps when the user is reading the page, but what about when a machine visits trying to identify where your feeds are located? To assist in this, websites may point to their feeds using <link> tags in the <head> section of their HTML. To take advantage of this, you can use Zend\Feed\Reader\Reader to locate these feeds using the static findFeedLinks() method. This method calls any URI and searches for the location of RSS, RDF and Atom feeds assuming the website’s HTML contains the relevant links. It then returns a value object where you can check for the existence of a RSS, RDF or Atom feed URI. The returned object is an ArrayObject subclass called Zend\Feed\Reader\FeedSet so you can cast it to an array, or iterate over it, to access all the detected links. However, as a simple shortcut, you can just grab the first RSS, RDF or Atom link using its public properties as in the example below. Otherwise, each element of the ArrayObject is a simple array with the keys “type” and “uri” where the type is one of “rdf”, “rss” or “atom”.
1 2 3 4 5 6 7 8 9 10 11

$links = Zend\Feed\Reader\Reader::findFeedLinks(’http://www.planet-php.net’); if (isset($links->rdf)) { echo $links->rdf, "\n"; // http://www.planet-php.org/rdf/ } if (isset($links->rss)) { echo $links->rss, "\n"; // http://www.planet-php.org/rss/ } if (isset($links->atom)) { echo $links->atom, "\n"; // http://www.planet-php.org/atom/ }

Based on these links, you can then import from whichever source you wish in the usual manner. This quick method only gives you one link for each feed type, but websites may indicate many links of any type. Perhaps it’s a news site with a RSS feed for each news category. You can iterate over all links using the ArrayObject’s iterator.
1 2 3 4 5

$links = Zend\Feed\Reader::findFeedLinks(’http://www.planet-php.net’); foreach ($links as $link) { echo $link[’href’], "\n"; }

312

Chapter 74. Zend\Feed\Reader\Reader

Zend Framework 2 Documentation, Release 2.0.6

74.6 Attribute Collections
In an attempt to simplify return types, return types from the various feed and entry level methods may include an object of type Zend\Feed\Reader\Collection\AbstractCollection. Despite the special class name which I’ll explain below, this is just a simple subclass of SPL‘s ArrayObject. The main purpose here is to allow the presentation of as much data as possible from the requested elements, while still allowing access to the most relevant data as a simple array. This also enforces a standard approach to returning such data which previously may have wandered between arrays and objects. The new class type acts identically to ArrayObject with the sole addition being a new method getValues() which returns a simple flat array containing the most relevant information. A simple example of this is Zend\Feed\Reader\Reader\FeedInterface::getCategories(). When used with any RSS or Atom feed, this method will return category data as a container object called Zend\Feed\Reader\Collection\Category. The container object will contain, per category, three fields of data: term, scheme and label. The “term” is the basic category name, often machine readable (i.e. plays nice with URIs). The scheme represents a categorisation scheme (usually a URI identifier) also known as a “domain” in RSS 2.0. The “label” is a human readable category name which supports HTML entities. In RSS 2.0, there is no label attribute so it is always set to the same value as the term for convenience. To access category labels by themselves in a simple value array, you might commit to something like:
1 2 3 4 5 6

$feed = Zend\Feed\Reader\Reader::import(’http://www.example.com/atom.xml’); $categories = $feed->getCategories(); $labels = array(); foreach ($categories as $cat) { $labels[] = $cat[’label’] }

It’s a contrived example, but the point is that the labels are tied up with other information. However, the container class allows you to access the “most relevant” data as a simple array using the getValues() method. The concept of “most relevant” is obviously a judgement call. For categories it means the category labels (not the terms or schemes) while for authors it would be the authors’ names (not their email addresses or URIs). The simple array is flat (just values) and passed through array_unique() to remove duplication.
1 2 3

$feed = Zend\Feed\Reader\Reader::import(’http://www.example.com/atom.xml’); $categories = $feed->getCategories(); $labels = $categories->getValues();

The above example shows how to extract only labels and nothing else thus giving simple access to the category labels without any additional work to extract that data by itself.

74.7 Retrieving Feed Information
Retrieving information from a feed (we’ll cover entries and items in the next section though they follow identical principals) uses a clearly defined API which is exactly the same regardless of whether the feed in question is RSS, RDF or Atom. The same goes for sub-versions of these standards and we’ve tested every single RSS and Atom version. While the underlying feed XML can differ substantially in terms of the tags and elements they present, they nonetheless are all trying to convey similar information and to reflect this all the differences and wrangling over alternative tags are handled internally by Zend\Feed\Reader\Reader presenting you with an identical interface for each. Ideally, you should not have to care whether a feed is RSS or Atom so long as you can extract the information you want. Note: While determining common ground between feed types is itself complex, it should be noted that RSS in particular is a constantly disputed “specification”. This has its roots in the original RSS 2.0 document which contains 74.6. Attribute Collections 313

Zend Framework 2 Documentation, Release 2.0.6

ambiguities and does not detail the correct treatment of all elements. As a result, this component rigorously applies the RSS 2.0.11 Specification published by the RSS Advisory Board and its accompanying RSS Best Practices Profile. No other interpretation of RSS 2.0 will be supported though exceptions may be allowed where it does not directly prevent the application of the two documents mentioned above. Of course, we don’t live in an ideal world so there may be times the API just does not cover what you’re looking for. To assist you, Zend\Feed\Reader\Reader offers a plugin system which allows you to write Extensions to expand the core API and cover any additional data you are trying to extract from feeds. If writing another Extension is too much trouble, you can simply grab the underlying DOM or XPath objects and do it by hand in your application. Of course, we really do encourage writing an Extension simply to make it more portable and reusable, and useful Extensions may be proposed to the Framework for formal addition. Here’s a summary of the Core API for Feeds. You should note it comprises not only the basic RSS and Atom standards, but also accounts for a number of included Extensions bundled with Zend\Feed\Reader\Reader. The naming of these Extension sourced methods remain fairly generic - all Extension methods operate at the same level as the Core API though we do allow you to retrieve any specific Extension object separately if required.

314

Chapter 74. Zend\Feed\Reader\Reader

Zend Framework 2 Documentation, Release 2.0.6

Table 74.1: Feed Level API Methods getId() getTitle() getDescription() getLink() Returns a unique ID associated with this feed Returns the title of the feed Returns the text description of the feed. Returns a URI to the HTML website containing the same or similar information as this feed (i.e. if the feed is from a blog, it should provide the blog’s URI where the HTML version of the entries can be read). Returns the URI of this feed, which may be the same as the URI used to import the feed. There are important cases where the feed link may differ because the source URI is being updated and is intended to be removed in the future. Returns an object of type ZendFeedReaderCollectionAuthor which is an ArrayObject whose elements are each simple arrays containing any combination of the keys “name”, “email” and “uri”. Where irrelevant to the source data, some of these keys may be omitted. Returns either the first author known, or with the optional $index parameter any specific index on the array of Authors as described above (returning NULL if an invalid index). Returns the date on which this feed was created. Generally only applicable to Atom where it represents the date the resource described by an Atom 1.0 document was created. The returned date will be a DateTime object. Returns the date on which this feed was last modified. The returned date will be a DateTime object. Returns the date on which this feed was last built. The returned date will be a DateTime object. This is only supported by RSS - Atom feeds will always return NULL. Returns the language of the feed (if defined) or simply the language noted in the XML document. Returns the generator of the feed, e.g. the software which generated it. This may differ between RSS and Atom since Atom defines a different notation. Returns any copyright notice associated with the feed. Returns an array of all Hub Server URI endpoints which are advertised by the feed for use with the Pubsubhubbub Protocol, allowing subscriptions to the feed for real-time updates. Returns a ZendFeedReaderCollectionCategory object containing the details of any categories associated with the overall feed. The supported fields include “term” (the machine readable category name), “scheme” (the categorisation scheme and domain for this category), and “label” (a HTML decoded human readable category name). Where any of the three fields are absent from the field, they are either set to the closest available alternative or, in the case of “scheme”, set to NULL. Returns an array containing data relating to any feed image or logo, or NULL if no image found. The resulting array may contain the following keys: uri, link, title, description, height, and width. Atom logos only contain a URI so the remaining metadata is drawn from RSS feeds only.

getFeedLink()

getAuthors()

getAuthor(integer $index = 0) getDateCreated() getDateModified() getLastBuildDate() getLanguage() getGenerator() getCopyright() getHubs() getCategories()

getImage()

Given the variety of feeds in the wild, some of these methods will undoubtedly return NULL indicating the relevant information couldn’t be located. Where possible, Zend\Feed\Reader\Reader will fall back on alternative elements during its search. For example, searching an RSS feed for a modification date is more complicated than it looks. RSS 2.0 feeds should include a <lastBuildDate> tag and (or) a <pubDate> element. But what if it doesn’t, maybe this is an RSS 1.0 feed? Perhaps it instead has an <atom:updated> element with identical information (Atom may be used to supplement RSS‘s syntax)? Failing that, we could simply look at the entries, pick the most recent, and use its <pubDate> element. Assuming it exists... Many feeds also use Dublin Core 1.0 or 1.1 <dc:date> elements for feeds and entries. Or we could find Atom lurking again. The point is, Zend\Feed\Reader\Reader was designed to know this. When you ask for the modification date (or anything else), it will run off and search for all these alternatives until it either gives up and returns NULL, or finds an alternative that should have the right answer.

74.7. Retrieving Feed Information

315

Zend Framework 2 Documentation, Release 2.0.6

In addition to the above methods, all Feed objects implement methods for retrieving the DOM and XPath objects for the current feeds as described earlier. Feed objects also implement the SPL Iterator and Countable interfaces. The extended API is summarised below.

74.8 Retrieving Entry/Item Information
Retrieving information for specific entries or items (depending on whether you speak Atom or RSS) is identical to feed level data. Accessing entries is simply a matter of iterating over a Feed object or using the SPL Iterator interface Feed objects implement and calling the appropriate method on each. Table 74.2: Entry Level API Methods getId() getTitle() getDescription() getLink() getPermaLink() getAuthors() Returns a unique ID for the current entry. Returns the title of the current entry. Returns a description of the current entry. Returns a URI to the HTML version of the current entry. Returns the permanent link to the current entry. In most cases, this is the same as using getLink(). Returns an object of type ZendFeedReaderCollectionAuthor which is an ArrayObject whose elements are each simple arrays containing any combination of the keys “name”, “email” and “uri”. Where irrelevant to the source data, some of these keys may be omitted. Returns either the first author known, or with the optional $index parameter any specific index on the array of Authors as described above (returning NULL if an invalid index). Returns the date on which the current entry was created. Generally only applicable to Atom where it represents the date the resource described by an Atom 1.0 document was created. Returns the date on which the current entry was last modified Returns the content of the current entry (this has any entities reversed if possible assuming the content type is HTML). The description is returned if a separate content element does not exist. Returns an array containing the value of all attributes from a multi-media <enclosure> element including as array keys: url, length, type. In accordance with the RSS Best Practices Profile of the RSS Advisory Board, no support is offers for multiple enclosures since such support forms no part of the RSS specification. Returns the number of comments made on this entry at the time the feed was last generated Returns a URI pointing to the HTML page where comments can be made on this entry Returns a URI pointing to a feed of the provided type containing all comments for this entry (type defaults to Atom/RSS depending on current feed type). Returns a ZendFeedReaderCollectionCategory object containing the details of any categories associated with the entry. The supported fields include “term” (the machine readable category name), “scheme” (the categorisation scheme and domain for this category), and “label” (a HTML decoded human readable category name). Where any of the three fields are absent from the field, they are either set to the closest available alternative or, in the case of “scheme”, set to NULL.

getAuthor(integer $index = 0) getDateCreated()

getDateModified() getContent()

getEnclosure()

getCommentCount() getCommentLink() getCommentFeedLink([string $type = ‘atom’|’rss’]) getCategories()

The extended API for entries is identical to that for feeds with the exception of the Iterator methods which are not needed here.

316

Chapter 74. Zend\Feed\Reader\Reader

Zend Framework 2 Documentation, Release 2.0.6

Caution: There is often confusion over the concepts of modified and created dates. In Atom, these are two clearly defined concepts (so knock yourself out) but in RSS they are vague. RSS 2.0 defines a single <pubDate> element which typically refers to the date this entry was published, i.e. a creation date of sorts. This is not always the case, and it may change with updates or not. As a result, if you really want to check whether an entry has changed, don’t rely on the results of getDateModified(). Instead, consider tracking the MD5 hash of three other elements concatenated, e.g. using getTitle(), getDescription() and getContent(). If the entry was truly updated, this hash computation will give a different result than previously saved hashes for the same entry. This is obviously content oriented, and will not assist in detecting changes to other relevant elements. Atom feeds should not require such steps. Further muddying the waters, dates in feeds may follow different standards. Atom and Dublin Core dates should follow ISO 8601, and RSS dates should follow RFC 822 or RFC 2822 which is also common. Date methods will throw an exception if DateTime cannot load the date string using one of the above standards, or the PHP recognised possibilities for RSS dates. Warning: The values returned from these methods are not validated. This means users must perform validation on all retrieved data including the filtering of any HTML such as from getContent() before it is output from your application. Remember that most feeds come from external sources, and therefore the default assumption should be that they cannot be trusted.

74.9 Extending Feed and Entry APIs
Extending Zend\Feed\Reader\Reader allows you to add methods at both the feed and entry level which cover the retrieval of information not already supported by Zend\Feed\Reader\Reader. Given the number of RSS and Atom extensions that exist, this is a good thing since Zend\Feed\Reader\Reader couldn’t possibly add everything. There are two types of Extensions possible, those which retrieve information from elements which are immediate children of the root element (e.g. <channel> for RSS or <feed> for Atom) and those who retrieve information from child elements of an entry (e.g. <item> for RSS or <entry> for Atom). On the filesystem these are grouped as classes within a namespace based on the extension standard’s name. For example, internally we have Zend\Feed\Reader\Extension\DublinCore\Feed and Zend\Feed\Reader\Extension\DublinCore\Entry classes which are two Extensions implementing Dublin Core 1.0 and 1.1 support. Extensions are loaded into Zend\Feed\Reader\Reader using a Zend\ServiceManager\AbstractPluginManager implementation, Zend\Feed\Reader\ExtensionManager, so its operation will be familiar from other Zend Framework components. Zend\Feed\Reader\Reader already bundles a number of these Extensions, however those which are not used internally and registered by default (so called Core Extensions) must be registered to Zend\Feed\Reader\Reader before they are used. The bundled Extensions include: Table 74.3: Core Extensions (pre-registered) DublinCore (Feed and Entry) Content (Entry only) Atom (Feed and Entry) Slash WellFormedWeb Thread Podcast Implements support for Dublin Core Metadata Element Set 1.0 and 1.1 Implements support for Content 1.0 Implements support for Atom 0.3 and Atom 1.0 Implements support for the Slash RSS 1.0 module Implements support for the Well Formed Web CommentAPI 1.0 Implements support for Atom Threading Extensions as described in RFC 4685 Implements support for the Podcast 1.0 DTD from Apple

The Core Extensions are somewhat special since they are extremely common and multi-faceted. For example, we have a Core Extension for Atom. Atom is implemented as an Extension (not just a base class) because it doubles as a valid

74.9. Extending Feed and Entry APIs

317

Zend Framework 2 Documentation, Release 2.0.6

RSS module - you can insert Atom elements into RSS feeds. I’ve even seen RDF feeds which use a lot of Atom in place of more common Extensions like Dublin Core. Table 74.4: Non-Core Extensions (must register manually) Syndication CreativeCommons Implements Syndication 1.0 support for RSS feeds A RSS module that adds an element at the <channel> or <item> level that specifies which Creative Commons license applies.

The additional non-Core Extensions are offered but not registered to Zend\Feed\Reader\Reader by default. If you want to use them, you’ll need to tell Zend\Feed\Reader\Reader to load them in advance of importing a feed. Additional non-Core Extensions will be included in future iterations of the component. Registering an Extension with Zend\Feed\Reader\Reader, so it is loaded and its API is available to Feed and Entry objects, is a simple affair using the Zend\Feed\Reader\ExtensionManager. Here we register the optional Syndication Extension, and discover that it can be directly called from the Entry level API without any effort. Note that Extension names are case sensitive and use camel casing for multiple terms.
1 2 3

Zend\Feed\Reader\Reader::registerExtension(’Syndication’); $feed = Zend\Feed\Reader\Reader::import(’http://rss.slashdot.org/Slashdot/slashdot’); $updatePeriod = $feed->getUpdatePeriod();

In the simple example above, we checked how frequently a feed is being updated using the getUpdatePeriod() method. Since it’s not part of Zend\Feed\Reader\Reader‘s core API, it could only be a method supported by the newly registered Syndication Extension. As you can also notice, the new methods from Extensions are accessible from the main API using PHP‘s magic methods. As an alternative, you can also directly access any Extension object for a similar result as seen below.
1 2 3 4

Zend\Feed\Reader\Reader::registerExtension(’Syndication’); $feed = Zend\Feed\Reader\Reader::import(’http://rss.slashdot.org/Slashdot/slashdot’); $syndication = $feed->getExtension(’Syndication’); $updatePeriod = $syndication->getUpdatePeriod();

74.9.1 Writing ZendFeedReaderReader Extensions
Inevitably, there will be times when the Zend\Feed\Reader\Reader API is just not capable of getting something you need from a feed or entry. You can use the underlying source objects, like DOMDocument, to get these by hand however there is a more reusable method available by writing Extensions supporting these new queries. As an example, let’s take the case of a purely fictitious corporation named Jungle Books. Jungle Books have been publishing a lot of reviews on books they sell (from external sources and customers), which are distributed as an RSS 2.0 feed. Their marketing department realises that web applications using this feed cannot currently figure out exactly what book is being reviewed. To make life easier for everyone, they determine that the geek department needs to extend RSS 2.0 to include a new element per entry supplying the ISBN-10 or ISBN-13 number of the publication the entry concerns. They define the new <isbn> element quite simply with a standard name and namespace URI:
1 2

JungleBooks 1.0: http://example.com/junglebooks/rss/module/1.0/

A snippet of RSS containing this extension in practice could be something similar to:
1 2 3 4 5 6

<?xml version="1.0" encoding="utf-8" ?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:jungle="http://example.com/junglebooks/rss/module/1.0/"> <channel> <title>Jungle Books Customer Reviews</title>

318

Chapter 74. Zend\Feed\Reader\Reader

Zend Framework 2 Documentation, Release 2.0.6

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

<link>http://example.com/junglebooks</link> <description>Many book reviews!</description> <pubDate>Fri, 26 Jun 2009 19:15:10 GMT</pubDate> <jungle:dayPopular> http://example.com/junglebooks/book/938 </jungle:dayPopular> <item> <title>Review Of Flatland: A Romance of Many Dimensions</title> <link>http://example.com/junglebooks/review/987</link> <author>Confused Physics Student</author> <content:encoded> A romantic square?! </content:encoded> <pubDate>Thu, 25 Jun 2009 20:03:28 -0700</pubDate> <jungle:isbn>048627263X</jungle:isbn> </item> </channel> </rss>

Implementing this new ISBN element as a simple entry level extension would require the following class (using your own class namespace outside of Zend).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

class My\FeedReader\Extension\JungleBooks\Entry extends Zend\Feed\Reader\Extension\AbstractEntry { public function getIsbn() { if (isset($this->data[’isbn’])) { return $this->data[’isbn’]; } $isbn = $this->xpath->evaluate( ’string(’ . $this->getXpathPrefix() . ’/jungle:isbn)’ ); if (!$isbn) { $isbn = null; } $this->data[’isbn’] = $isbn; return $this->data[’isbn’]; } protected function registerNamespaces() { $this->xpath->registerNamespace( ’jungle’, ’http://example.com/junglebooks/rss/module/1.0/’ ); } }

This extension is easy enough to follow. It creates a new method getIsbn() which runs an XPath query on the current entry to extract the ISBN number enclosed by the <jungle:isbn> element. It can optionally store this to the internal non-persistent cache (no need to keep querying the DOM if it’s called again on the same entry). The value is returned to the caller. At the end we have a protected method (it’s abstract so it must exist) which registers the Jungle Books namespace for their custom RSS module. While we call this an RSS module, there’s nothing to prevent the same element being used in Atom feeds - and all Extensions which use the prefix provided by getXpathPrefix() are actually neutral and work on RSS or Atom feeds with no extra code. Since this Extension is stored outside of Zend Framework, you’ll need to register the path prefix for your Extensions so Zend\Loader\PluginLoader can find them. After that, it’s merely a matter of registering the Extension, if

74.9. Extending Feed and Entry APIs

319

Zend Framework 2 Documentation, Release 2.0.6

it’s not already loaded, and using it in practice.
1 2 3 4 5 6 7 8 9

if (!Zend\Feed\Reader\Reader::isRegistered(’JungleBooks’)) { $extensions = Zend\Feed\Reader\Reader::getExtensionManager(); $extensions->setInvokableClass(’JungleBooksEntry’, ’My\FeedReader\Extension\JungleBooks\Entry’); Zend\Feed\Reader\Reader::registerExtension(’JungleBooks’); } $feed = Zend\Feed\Reader\Reader::import(’http://example.com/junglebooks/rss’); // ISBN for whatever book the first entry in the feed was concerned with $firstIsbn = $feed->current()->getIsbn();

Writing a feed level Extension is not much different. The example feed from earlier included an unmentioned <jungle:dayPopular> element which Jungle Books have added to their standard to include a link to the day’s most popular book (in terms of visitor traffic). Here’s an Extension which adds a getDaysPopularBookLink() method to the feel level API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

class My\FeedReader\Extension\JungleBooks\Feed extends Zend\Feed\Reader\Extension\AbstractFeed { public function getDaysPopularBookLink() { if (isset($this->data[’dayPopular’])) { return $this->data[’dayPopular’]; } $dayPopular = $this->xpath->evaluate( ’string(’ . $this->getXpathPrefix() . ’/jungle:dayPopular)’ ); if (!$dayPopular) { $dayPopular = null; } $this->data[’dayPopular’] = $dayPopular; return $this->data[’dayPopular’]; } protected function registerNamespaces() { $this->xpath->registerNamespace( ’jungle’, ’http://example.com/junglebooks/rss/module/1.0/’ ); } }

Let’s repeat the last example using a custom Extension to show the method being used.
1 2 3 4 5 6 7 8 9

if (!Zend\Feed\Reader\Reader::isRegistered(’JungleBooks’)) { $extensions = Zend\Feed\Reader\Reader::getExtensionManager(); $extensions->setInvokableClass(’JungleBooksFeed’, ’My\FeedReader\Extension\JungleBooks\Feed’); Zend\Feed\Reader\Reader::registerExtension(’JungleBooks’); } $feed = Zend\Feed\Reader\Reader::import(’http://example.com/junglebooks/rss’); // URI to the information page of the day’s most popular book with visitors $daysPopularBookLink = $feed->getDaysPopularBookLink();

Going through these examples, you’ll note that we don’t register feed and entry Extensions separately. Extensions within the same standard may or may not include both a feed and entry class, so Zend\Feed\Reader\Reader only requires you to register the overall parent name, e.g. JungleBooks, DublinCore, Slash. Internally, it can check at what level Extensions exist and load them up if found. In our case, we have a full set of Extensions now:

320

Chapter 74. Zend\Feed\Reader\Reader

Zend Framework 2 Documentation. Extending Feed and Entry APIs 321 . 74.9.0. Release 2.6 JungleBooks\Feed and JungleBooks\Entry.

6 322 Chapter 74. Zend\Feed\Reader\Reader . Release 2.Zend Framework 2 Documentation.0.

0 source elements which carry source feed metadata for a specific entry within an aggregate feed (i.1 Introduction Zend\Feed\Writer\Writer is the sibling component to Zend\Feed\Reader\Reader responsible for generating feeds for output. there are four renderers . These checks are not tied to any of the feed standards definitions. The container objects also contain methods to allow for fast rendering and export of the final feed. data set on any Zend\Feed\Writer\Writer Data Container object is translated at render time onto a DOMDocument object using the necessary feed elements. Zend\Feed\Writer\Writer is the inverse of Zend\Feed\Reader\Reader.e. It has two core sets of classes: data containers and renderers. As a result of this design. It supports the Atom 1. offer a simple Extension system which allows for any extension and module for either of these two specifications to be implemented if they are not provided out of the box. and these can be reused at will. For each supported feed type there is both an Atom 1. For example. etc. Where Zend\Feed\Reader\Reader focuses on providing an easy to use architecture fronted by getter methods. however. 323 .0 specific classes. The former implements Atom 2.0 specification (RFC 4287) and RSS 2. the current feed is not the entry’s original source). and based on its content attempts to generate valid feed markup. Each renderer accepts a container.0 renderer. 75. In addition to the main data container classes.0 as specified by the RSS Advisory Board (RSS 2.CHAPTER SEVENTYFIVE ZEND\FEED\WRITER\WRITER 75. Zend\Feed\Writer\Source and Zend\Feed\Writer\Deleted. These methods perform some data validity testing. dates. Using a DOMDocument class rather than a templating solution has numerous advantages.2 Architecture The architecture of Zend\Feed\Writer\Writer is very simple. the rest may even be obvious.0.two matching container renderers per supported feed type. Zend\Feed\Writer\Writer is fronted by similarly named setters or mutators. The latter implements the Atom Tombstones RFC allowing feeds to carry references to entries which have been deleted. While there are two main data container types. the most obvious being the ability to export the DOMDocument for additional processing and relying on PHP DOM for correct and valid rendering. In many ways. The sole purpose of these containers is to collect data about the feed to generate using a simple interface of setter methods. It does. there are two additional Atom 2.11). The Entry classes can be attached to any Feed class.0 and RSS 2. The containers include the Zend\Feed\Writer\Feed and Zend\Feed\Writer\Entry classes. This ensures the API won’t pose a learning curve to anyone familiar with Zend\Feed\Reader\Reader. It does not deviate from these standards. it will validate any passed URIs. Behind the scenes.

)).0.com’). $entry->setDescription(’Exposing the difficultly of porting games to English. $entry->setDateModified(time()). ’email’ => ’paddy@example.com’. Zend\Feed\Writer\Writer . The example is long enough as is .0 feed. it can make Extensions somewhat interesting. $entry->addAuthor(array( ’name’ => ’Paddy’. this removes the default safeguard of ensuring you have sufficient data set to render a wholly valid feed. $feed->setDateModified(time()). $feed->addEntry($entry). ’uri’ => ’http://www.example. offer feed and entry level data containers.example.example. )). Here is an example to generate a minimal Atom 1. */ $entry = $feed->createEntry(). To explain this more clearly. Release 2. ’atom’). $feed->setTitle(’Paddy\’s Blog’). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 /** * Create the parent feed */ $feed = new Zend\Feed\Writer\Feed.com’.com/’).Zend Framework 2 Documentation. Note that entries must * be manually added once created. $feed->addAuthor(array( ’name’ => ’Paddy’. $entry->setDateCreated(time()). As this demonstrates. $entry->setContent( ’I am not writing the article. ’uri’ => ’http://www.0 and ignored for RSS. $feed->setFeedLink(’http://www. This forms a data hierarchy resembling a normal feed. $entry->setLink(’http://www. There is.’).example. i. In the case of Source or Deleted (Tomestone) containers. A typical Extension offering namespaced feed and entry level elements.com/atom’. each feed or entry uses a separate data container. 75.’ ). no complex integration work required since all Extension classes are simply registered and automatically used by the core classes. /** * Add one or more entries. ’email’ => ’paddy@example. While it is possible to ignore Exceptions.e. into which has been added some Entry containers and a Deleted container. $entry->setTitle(’All Your Base Are Belong To Us’). it will report this by throwing an Exception. $feed->setLink(’http://www. these are rendered only for Atom 2. Due to the system being divided between data containers and renderers. $feed->addHub(’http://pubsubhubbub. We’ll meet Extensions in more detail at the end of this section. this hierarchy has its pieces passed to relevant renderers and the partial feeds (all DOMDocuments) are then pieced together to create a complete feed.). you may construct a set of data containers for a feed where there is a Feed container.com’.example. fortunately. 324 Chapter 75.com’. When rendering is performed. and matching renderers.com/all-your-base-are-belong-to-us’). must itself reflect the exact same architecture.3 Getting Started Using Zend\Feed\Writer\Writer is as simple as setting data and triggering the renderer.6 If the renderer is unable to generate valid feed markup.appspot. perhaps due to the container missing an obligatory data point.

This will differ for RSS 2.0. Release 2. Getting Started 325 .com</email> <uri>http://www.]]> </summary> <published>2009-12-14T20:28:18+00:00</published> <updated>2009-12-14T20:28:18+00:00</updated> <link rel="alternate" type="text/html" href="http://www. The output rendered should be as follows: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?xml version="1.com</uri> </author> <content type="html"> <![CDATA[I am not writing the article.com" version="1.0" encoding="utf-8"?> <feed xmlns="http://www.0 since a title may be omitted so long as a description is present.com</id> <author> <name>Paddy</name> <email>paddy@example. The example is long enough as is .org/2005/Atom"> <title type="text">Paddy’s Blog</title> <subtitle type="text">Writing about PC Games since 176 BC. It should be noted that omitting an obligatory point of data.0alpha"> Zend\Feed\Writer </generator> <link rel="alternate" type="text/html" href="http://www.example.com/atom"/> <id>http://www.com"/> <link rel="self" type="application/atom+xml" href="http://www.</subtitle> <updated>2009-12-14T20:28:18+00:00</updated> <generator uri="http://framework.example.example.com/all-your-base-are-belong-to-us</id> <author> <name>Paddy</name> <email>paddy@example. This gives rise to Exceptions that differ between the two standards depending on the renderer in use.]]> </content> </entry> </feed> This is a perfectly valid Atom 1.0 example.6 36 37 38 39 40 /** * Render the resulting feed to Atom 1. such as a title.com/all-your-base-are-belong-to-us"/> <id>http://www.0 feed.Zend Framework 2 Documentation.w3.0 and assign to $out.com</email> <uri>http://www. By design.0.3.example.appspot.zend. This built in safeguard was added to ensure users without in-depth knowledge of the relevant specifications have a bit less to worry about. 75.10.com/"/> <entry> <title type="html"><![CDATA[All Your Base Are Belong To Us]]></title> <summary type="html"> <![CDATA[Exposing the difficultly of porting games to English. */ $out = $feed->export(’atom’). * You can substitute "atom" with "rss" to generate an RSS 2.example.). will trigger an Exception when rendering as Atom 1.example. Zend\Feed\Writer\Writer will not render an invalid feed for either standard unless the end-user deliberately elects to ignore all Exceptions.example.com</uri> </author> <link rel="hub" href="http://pubsubhubbub.

meaning that an Extension may define its own container classes which are registered to the base container classes as extensions. This will be addressed in a future release. you must first setup the data necessary for the feed being rendered.all Extension methods operate at the same level as the Core API though we do allow you to retrieve any specific Extension object separately if required. and are checked when any method call triggers the base container’s __call() method. In addition to the API detailed below. the class also implements the Countable and Iterator interfaces. Both classes are also amenable to Extensions.6 75.4 Setting Feed Data Points Before you can render a feed. Zend\Feed\Writer\Writer offers this API via its data container classes Zend\Feed\Writer\Feed and Zend\Feed\Writer\Entry (not to mention the Atom 2. Here’s a summary of the Core API for Feeds. Release 2. By design. The naming of these Extension sourced methods remain fairly generic . 326 Chapter 75. but also accounts for a number of included Extensions bundled with Zend\Feed\Writer\Writer.0 specific and Extension classes). meaning you may reuse any data container with any renderer without requiring additional work.0. the API closely matches that for Zend\Feed\Reader\Reader to avoid undue confusion and uncertainty. Zend\Feed\Writer\Writer . This utilises a simple setter style API which doubles as an initial method for validating the data being set. These classes merely store all feed data in a type-agnostic manner. Note: Users have commented that the lack of a simple array based notation for input data gives rise to lengthy tracts of code. The Feed Level API for data is contained in Zend\Feed\Writer\Feed. You should note it comprises not only the basic RSS and Atom standards.Zend Framework 2 Documentation.

the current Zend Framework version and the Framework’s URI. The type should be one of “atom”.0 HTML link should point to the feed source’s HTML page. The method addCategory() allows adding a single category at a time. This is the Entry level data container. setDateSets the date on which this feed was created.an author element containing the email reference with the name in brackets. addAuSets the data for authors. createReturns a new instance of ZendFeedWriterDeleted. the link is set as the ID. and a Dublin Core creator element only containing the name. whereas for RSS 2. Set a URI to the HTML website containing the same or similar information as this feed (i. This is the Atom 2. it should provide the blog’s URI where the HTML version of the entries can be read). Release 2.0. tor() “version” and “uri”. setCopySets a copyright notice associated with the feed. Feed Data Points 327 addEntry() Adds an instance of ZendFeedWriterEntry to the current feed container for rendering. A Publisher may be implemented using ZendFeedPubsubhubbubPublisher. so you must explicitly call addEntry() to add the 75. The “scheme” (called the domain in RSS) is optional but must be a valid URI. “email” and “uri”. These are optional so long as a link is added.0 document was created. The “term” is a typically a category name suitable for inclusion in a URI.0 requires a URI. Setting entry for rendering. New entries are not automatically assigned to the current feed.Allows the setting of a generator. The parameter is an array of arrays where each sub-array may contain the thors() keys “name”.0 feeds and is automatically rendered as Date() the current date by default when not explicity set. addAuSets the data for a single author following the same array format as described above for a single thor() sub-array. For Atom 1.0 optionally may send a width. Language() setGenera. The expected parameter may be a UNIX Modified() timestamp or a DateTime object. it is recommended to include a link to the feed being generated so it has an identifiable final URI allowing a client to track its location changes without necessitating constant redirects.0 Tombstone level data Tombcontainer. height and image description.e. where each element is itself an array whose possible gories() keys include “term”. The expected parameter may be a UNIX timestamp or a DateTime object. RSS 2. “label” and “scheme”. At a minimum. addCateAccepts an array of categories for rendering. or “rdf”. description.e. Atom 1. i. whether the feed being generated or an alternate URI pointing to the FeedLinks() same feed but in a different format. The “label” may be a human readable category name supporting special characters (it is HTML encoded during rendering) and is a required key. This will be omitted unless set.1: Feed Level API Methods setId() Set a unique ID associated with this feed.0 it is added as a guid element. setDateSets the date on which this feed was last modified. setImage() Accepts an array of image metadata for an RSS image or Atom logo. createEnReturns a new instance of ZendFeedWriterEntry. RSS 2. rendering will create two elements . New entries try() are not automatically assigned to the current feed. setLastSets the date on which this feed was last build.0 this is an atom:id element. The RSS 2. “rss”. The method addHub() allows adding a single hub at a time. setSets the language of the feed. height and width. setAdd a link to an XML feed. if the feed is from a blog.Zend Framework 2 Documentation. The “uri” value is only applicable for Atom feeds since RSS contains no facility to show it. The array parameter may contain these using the keys: uri. title.0 only requires a URI. If omitted a default generator will be added referencing ZendFeedWriter. For RSS 2. right() addHubs() Accepts an array of Pubsubhubbub Hub Endpoints to be rendered in the feed as Atom links so that PuSH Subscribers may subscribe to your feed. where each sub-array contains the keys “type” and “uri”. Set the title of the feed. The expected parameter may be a UNIX timestamp Buildor a DateTime object. The parameter should be an array containing the keys “name”. Generally only applicable to Atom where it represents Created() the date the resource described by an Atom 1.6 Table 75.0. link. HTML link. so you must explicitly call setTitle() setDescription() setLink() . Note that you must implement a Pubsubhubbub Publisher in order for real-time updates to be enabled. Set the text description of the feed. and an image title. This will only be rendered for RSS 2.4. The parameter is an array of arrays.

Zend Framework 2 Documentation. The Entry Level API for data is contained in Zend\Feed\Writer\Entry. 328 Chapter 75. there are also matching getters to retrieve data from the Entry data container. The naming of these Extension sourced methods remain fairly generic . Zend\Feed\Writer\Writer . 75. For example.6 Note: In addition to these setters. but also accounts for a number of included Extensions bundled with Zend\Feed\Writer\Writer.all Extension methods operate at the same level as the Core API though we do allow you to retrieve any specific Extension object separately if required. setImage() is matched with a getImage() method. Release 2. You should note it comprises not only the basic RSS and Atom standards.5 Setting Entry Data Points Here’s a summary of the Core API for Entries and Items.0.

These are optional so long as a link is added. Set the title of the entry. Generally only applicable to Atom where it represents the date the resource described by an Atom 1. setTitle() setDescription() setContent() setLink() setFeedLinks() addAuthors() addAuthor() setDateCreated() setDateModified() setCopyright() setCategories() setCommentCount() setCommentLink() setCommentFeedLink() setCommentFeedLinks() setEncoding() Note: In addition to these setters. Accepts an array of categories for rendering. Sets the number of comments associated with this entry. For RSS 2. and a Dublin Core creator element only containing the name. the date used will be the current date and time. The parameter is an array of arrays. rendering will create two elements . The “scheme” (called the domain in RSS) is optional but must be a valid URI.0 this is an atom:id element.0 depending on the element or attribute needed. Sets the date on which this feed was created. This will default to UTF-8 which is the preferred encoding. Set the content of the entry. “rss” or “atom”. Set a URI to the HTML website containing the same or similar information as this entry (i.5.e. The expected parameter may be a UNIX timestamp or a DateTime object. Rendering differs between RSS and Atom 2. Set the text description of the entry. if the feed is from a blog. the link is set as the ID. The type should be one of “atom”.an author element containing the email reference with the name in brackets. Sets a copyright notice associated with the feed. If omitted. Sets a link to a XML feed containing comments associated with this entry. Same as setCommentFeedLink() except it accepts an array of arrays. the date used will be the current date and time. there are also matching getters to retrieve data from the Entry data container. “label” and “scheme”. i. Seta a link to a HTML page containing comments associated with this entry. or “rdf”.e.0 document was created. If omitted. it is recommended to include a link to the feed being generated so it has an identifiable final URI allowing a client to track its location changes without necessitating constant redirects.2: Entry Level API Methods setId() Set a unique ID associated with this entry. The “label” may be a human readable category name supporting special characters (it is encoded during rendering) and is a required key. “email” and “uri”. 75. Release 2. Sets the encoding of entry text. The parameter is an array containing the keys “uri” and “type”. it defaults to the type used when rendering the feed. Sets the date on which this feed was last modified. The “uri” value is only applicable for Atom feeds since RSS contains no facility to show it.0 it is added as a guid element. whether the feed being generated or an alternate URI pointing to the same feed but in a different format. Setting Entry Data Points 329 . where each sub-array contains the keys “type” and “uri”. it should provide the blog article’s URI where the HTML version of the entry can be read). where each subarray contains the expected parameters of setCommentFeedLink(). The parameter is an array of arrays where each sub-array may contain the keys “name”.Zend Framework 2 Documentation. where each element is itself an array whose possible keys include “term”. “rss”. The “term” is a typically a category name suitable for inclusion in a URI.0. The expected parameter may be a UNIX timestamp or a DateTime object. Add a link to an XML feed. If a type is omitted. where the type is one of “rdf”.0. Sets the data for authors.6 Table 75. whereas for RSS 2. Sets the data for a single author following the same format as described above for a single sub-array. At a minimum. For Atom 1.

Zend\Feed\Writer\Writer . Release 2.6 330 Chapter 75.Zend Framework 2 Documentation.0.

Pubsubhubbub has garnered attention because it is a pubsub protocol which is easy to implement and which operates over HTTP. Any feed may advertise that it supports one or more Hubs using an Atom namespaced link element with a rel attribute of “hub”. Its philosophy is to replace the traditional model where blog feeds have been polled at regular intervals to detect and retrieve updates. and forward all updates to all Subscribers subscribed to that feed. Pubsubhubbub forms part of what has been dubbed the real-time web. this can take a lot of time to propagate updates to interested parties from planet aggregators to desktop readers. It does not currently implement a Hub Server though this is in progress for a future Zend Framework release. which was recently revived as a response to the appearance of Pubsubhubbub. A common use case to enable blogs (Publishers) to “push” updates from their RSS or Atom feeds (Topics) to end Subscribers.CHAPTER SEVENTYSIX ZEND\FEED\PUBSUBHUBBUB Zend\Feed\PubSubHubbub is an implementation of the PubSubHubbub Core 0. and there are plugins available for Wordpress blogs. Once a ping is received. With a pubsub system in place. a central server which is notified of any updates by the Publisher and which then distributes these updates to all Subscribers. Feedburner. A Publisher is responsible for notifying all supported Hubs (many can be supported to add redundancy to the system) of any updates to its feeds. These Subscribers will have subscribed to the blog’s RSS or Atom feed via a Hub. rssCloud.1 What is PubSubHubbub? Pubsubhubbub is an open. Depending on the frequency of polling. It offers implementations of a Pubsubhubbub Publisher and Subscriber suited to Zend Framework and other PHP applications.2 Specification (Working Draft). 76. eliminating any delay. has also seen its usage increase significantly though it lacks a formal specification and currently does not support Atom 1.2 Specification: a Publisher and a Subscriber. process it for updated items. or the less well known rssCloud (described in 2001). simple web-scale pubsub protocol. Pubsubhubbub is already in use including in Google Reader.2 Architecture Zend\Feed\PubSubHubbub implements two sides of the Pubsubhubbub 0. the Hub will request the updated feed. poor timing or lack of suitability for web applications. This is achieved by pinging the supported Hub Servers with the URL of the updated feed. In Pubsubhubbub terminology. whether they be Atom or RSS based. any updatable resource capable of being subscribed to is referred to as a Topic. 331 . XEP-0060. updates are not simply polled by Subscribers. For this reason. The protocol does not exist in isolation.0 feeds. such as the familiar Jabber Publish-Subscribe protocol. Perhaps surprisingly given its relative early age. they are pushed to Subscribers. Pubsub systems have been around for a while. 76. However these have not achieved widespread adoption typically due to either their complexity.

Release 2.example. prompting all Subscribers to immediately retrieve the feed from the Publisher giving rise to a traffic spike.0. the Publisher implementation is extremely simple to use and requires very little work to setup and use when feeds are updated. Its setup for use is also simple. In Pubsubhubbub. $failedHubs = array(). the Subscriber implementation may handle any feed updates forwarded from a Hub by using Zend\Feed\PubSubHubbub\Subscriber\Callback. In order for these updates to be pushed to Subscribers.e the updated RSS or Atom feed). their use cases. and the URIs of all Topics to be included in the notifications. By design. The Subscriber never directly communicates with the Publisher since the Hub acts as an intermediary. Zend\Feed\PubSubHubbub implements Pubsubhubbub Publishers and Subscribers with the classes Zend\Feed\PubSubHubbub\Publisher and Zend\Feed\PubSubHubbub\Subscriber. the Publisher is the party who publishes a live feed and frequently updates it with new content. 332 Chapter 76. The following example shows a Publisher notifying a collection of Hubs about updates to a pair of local RSS and Atom feeds.com/’. fetch the updated feed. accepting subscriptions and sending updates to subscribed Subscribers. $publisher->notifyAll(). an aggregator. ’http://hubbub.appspot. This may be a blog. the Hub distributes the actual update in a “Fat Ping” so the Publisher is not subjected to any traffic spike. The Subscriber therefore communicates only with the Hub. Zend\Feed\PubSubHubbub .example. the Publisher must notify all of its supported Hubs that an update has occured using a simple HTTP POST request containing the URI or the updated Topic (i. if (!$publisher->isSuccess()) { // check for errors $errors = $publisher->getErrors(). so the notification can be re-attempted later and/or logged if any notifications happen to fail.Zend Framework 2 Documentation. Zend\Feed\PubSubHubbub\Publisher implements a full Pubsubhubbub Publisher. and APIs are covered in subsequent sections. This occurs in a pubsub system where the Hub merely informs Subscribers that an update is available. or even a web service with a public feed based API. requiring mainly that it is configured with the URI endpoint for all Hubs to be notified of updates. These classes. )). $publisher->addHubUrls(array( ’http://pubsubhubbub.3 Zend\Feed\PubSubHubbub\Publisher In Pubsubhubbub. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $publisher = new Zend\Feed\PubSubHubbub\Publisher. or when it receives updates from the Hub. The Hub will confirm receipt of the notification. $publisher->addUpdatedTopicUrls(array( ’http://www. either to subscribe or unsubscribe to Topics.net/rss’.example.net/atom’. As a result. ’http://www. In addition. )). it is strongly recommended to attempt the operation for failed Hub Endpoints at least once more at a future time.com’. 76. foreach ($errors as $error) { $failedHubs[] = $error[’hubUrl’]. In the event of any errors. This communication design (“Fat Pings”) effectively removes the possibility of a “Thundering Herd” issue. Each resulting error array also includes a “response” key containing the related HTTP response object. this means the Publisher has very little to do except send these Hub pings whenever its feeds change. This may require the use of either a scheduled task for this purpose or a job queue though such extra steps are optional.6 A Subscriber is any party or application which subscribes to one or more Hubs to receive updates from a Topic hosted by a Publisher. and forward any updates to any Subscribers who have subscribed to that Hub for updates from the relevant feed. The class retains a collection of errors which include the Hub URLs.

0. the URI the Subscriber has assigned to handle updates. This is handled by using an instance of Zend\Feed\PubSubHubbub\Subscriber\Callback when the Callback URL is accessed. They achieve this by subscribing to one or more of the Hubs advertised by that Topic.2 Specification. any Topic via any Hub advertised by that Topic.e. 76.0 links with a rel attribute of “hub”. the Subscriber is the party who wishes to receive updates to any Topic (RSS or Atom feed). Release 2. the Subscriber need never actually visit the original feed (though it’s still recommended at some level to ensure updates are retrieved if ever a Hub goes offline). To create and manage subscriptions. Important: Zend\Feed\PubSubHubbub\Subscriber implements the Pubsubhubbub 0. usually as a set of one or more Atom 1. i. In many cases as a final alternative. In this way. The Callback URL also handles events where the Hub contacts the Subscriber to confirm all subscriptions and unsubscriptions. and notify each in turn using the notifyHub() method which accepts the URI of a Hub endpoint as its only argument.4. The new specification allows the Callback URL to include a query string which is used by this class.4.e. The second role is to accept updates sent by a Hub to the Subscriber’s Callback URL. or unsubscribing from. the methods addHubUrls() and addUpdatedTopicUrls() pass each array value to the singular addHubUrl() and addUpdatedTopicUrl() public methods. You can also skip setting Hub URIs. but not supported by all Hubs. As this is a new specification version not all Hubs currently implement it. recognised as a parameter in the route associated with the Callback URI and used by the application’s Router. The Publisher implementation is very simple since most of the feed processing and distribution is handled by the selected Hubs. All subscription requests must contain the URI of the Topic being subscribed and a Callback URL which the Hub will use to confirm the subscription and to forward updates. i. unsubscribing (if necessary). It is however important to detect errors and reschedule notifications as soon as possible (with a reasonable maximum number of retries) to ensure notifications reach all Subscribers. including subscribing for new Topics with a Hub. Zend\Feed\PubSubHubbub\Subscriber 333 . It operates in conjunction with Zend\Feed\PubSubHubbub\Subscriber\Callback which accepts requests from a Hub to confirm all subscription or unsubscription attempts (to prevent third-party misuse). There are no other tasks to cover. There are also matching removeUpdatedTopicUrl() and removeHubUrl() methods. The Hub from that point forward will send an Atom or RSS feed containing all updates to that Subscriber’s Callback URL when it receives an update notification from the Publisher. This is handled by Zend\Feed\PubSubHubbub\Subscriber. The Subsciber therefore has two roles.Zend Framework 2 Documentation.1 Subscribing and Unsubscribing Zend\Feed\PubSubHubbub\Subscriber implements a full Pubsubhubbub Subscriber capable of subscribing to.4 Zend\Feed\PubSubHubbub\Subscriber In Pubsubhubbub. 76. Hubs may frequently poll your feeds to offer some additional tolerance for failures both in terms of their own temporary downtime or Publisher errors or downtime. In the interests of maximising compatibility it is therefore recommended that the query string component of the Subscriber Callback URI be presented as a path element.6 18 19 20 21 } } // reschedule notifications for the failed Hubs in $failedHubs If you prefer having more concrete control over the Publisher. and periodically renewing subscriptions since they may have a limited validity as set by the Hub. 76.

the component requires a database (a schema is provided later in this section). You may also pass a specific custom Zend\Db\Table\Abstract instance into the associated model Zend\Feed\PubSubHubbub\Model\Subscription. the URI of the Topic (Atom or RSS feed) to be subscribed to for updates.xml’). ‘subscription_state‘ varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL.com’). the Subscriber above will send a request to the Hub endpoint containing the following parameters (based on the previous example): 334 Chapter 76. and the URI of the endpoint for the Hub which will handle the subscription and forwarding of the updates. you may create your own Model using any other backend or database layer (e.e. i. ‘verify_token‘ varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL. In order to store subscriptions and offer access to this data for general use. While this Model is offered as a default ready-to-roll solution. While it should not be necessary per se.example. it is assumed the table name is “subscription” and it utilises Zend\Db\Table\Abstract in the background meaning it will use the default adapter you have set for your application. ‘created_time‘ datetime DEFAULT NULL. $subscriber = new Zend\Feed\PubSubHubbub\Subscriber. a subscription can be attempted as demonstrated below: 1 2 3 4 5 6 7 8 $storage = new Zend\Feed\PubSubHubbub\Model\Subscription. This custom adapter may be as simple in intent as changing the table name to use or as complex as you deem necessary. By default.com/hubbub/callback’).Zend Framework 2 Documentation. ‘expiration_time‘ datetime DEFAULT NULL. ‘lease_seconds‘ bigint(20) DEFAULT NULL. $subscriber->setTopicUrl(’http://www. Zend\Feed\PubSubHubbub . $subscriber->addHubUrl(’http://hubbub. This is supported by Zend\Feed\PubSubHubbub\Subscriber\Callback and requires no other work on your part.g. ‘hub_url‘ varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL.net/rss. Behind the scenes. The lifetime of a subscription may be determined by the Hub but most Hubs should support automatic subscription refreshes by checking with the Subscriber.mydomain. $subscriber->setStorage($storage). ‘topic_url‘ varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL.example. It is still strongly recommended that you use the Hub sourced subscription time to live (ttl) to schedule the creation of new subscriptions (the process is identical to that for any new subscription) to refresh it with the Hub. Doctrine) so long as the resulting class implements the interface Zend\Feed\PubSubHubbub\Model\SubscriptionInterface. With the relevant information to hand.0. $subscriber->setCallbackUrl(’http://www. An example schema (MySQL) for a subscription table accessible by the provided model may look similar to: 1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE IF NOT EXISTS ‘subscription‘ ( ‘id‘ varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT ’’. it covers cases where a Hub may not support automatic subscription refreshing and rules out Hub errors for additional redundancy.6 Any subscription (or unsubscription) requires the relevant information before proceeding. Release 2. PRIMARY KEY (‘id‘) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci. $subscriber->subscribeAll(). ‘secret‘ varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL.

4. Hubs should additionally attempt to automatically refresh subscriptions before they expire by contacting Subscribers (handled automatically by the Callback class). You ence.xml The URI of the topic (i. The appended query string contains a custom parameter (hence the xhub designation).topic http://www. Hubs may enforce their own maximum subscription period. This is a non=standard parameter used by this component in preference to encoding a subscription key in the URI path which is more difficult to implement in a Zend Framework application.callback http://www. It is a query string parameter preserved by the Hub and resent with all Subscriber requests. Technically this component does not distinguish between the two modes and treats both equally.879827871253878386 when it is confirming a subscription or unsubscription. a TTL). Zend\Feed\PubSubHubbub\Subscriber 335 .example. It is repeated twice in order of preference. A detailed example is offered later. hub.verify_token 3065919804abA verification token returned to the Subscriber by the Hub caa7212ae89. hub.verifysync Indicates to the Hub the preferred mode of verifying subscriptions or unsubscriptions.0. Unsubscription requests would use the “unsubscribe” value.subscription=5536df06b5dcb966edab3a4c4d56213c16a8184 The URI used by a Hub to contact the Subscriber and either request confirmation of a (un)subscription request or send updates from subscribed feeds. hub.mydomain.net/rss.6 Table 76.com/hubbub/callback/5536df06b5dcb966edab3a4c4d5621 To accomplish this. hub.1: Subscription request parameters PaValue Explanation rameter hub.modesubscribe Simple value indicating this is a subscription request. hub.verifyasync Indicates to the Hub the preferred mode of verifying subscriptions or unsubscriptions. Atom or RSS feed) which the Subscriber wishes to subscribe to for updates. All subscriptions should be renewed by simply re-subscribing before the subscription period ends to ensure continuity of updates.e. since not all Hubs support query string parameters.lease_seconds 2592000 The number of seconds for which the Subscriber would like a new subscription to remain valid for (i.Zend Framework 2 Documentation. Nevertheless. can modify several For example. The value would be passed into the method ZendPubSubHubbubSubscriberCallback::setSubscriptionKey(). Technically this component does not distinguish between the two modes and treats both equally. we still strongly recommend adding the subscription key as a path component in the form http://www. hub. Offers a measure of reliance that the confirmation request originates from the correct Hub to prevent misuse. It is repeated twice in order of preference.mydomain. of you these can parameters to set a different indicate lease a different seconds value preferusing 76. Its purpose is to allow the Subscriber to identify and look up the subscription associated with any Hub request in a backend storage medium.com/hubbub/callback?xhub.e. it requires defining a route capable of parsing out the final value of the key and then retrieving the value and passing it to the Subscriber Callback object. Release 2.

It is recommended to set a custom storage solution where these defaults are not apt either by passing in a new Model supporting the required interface or by passing a new instance of Zend\Db\Table\Abstract to the default Model’s constructor to change the used table name. In “sync” (synchronous) mode. In “async” (asynchronous) mode. the Hub must verify the request by forwarding a new verification request to the Callback URL set in the subscription or unsubscription parameters. The parameters included are identical to a subscription request with the exception that “hub. /** * Process the feed update asynchronously to avoid a Hub timeout. Conventions are great when they work! Note: While Hubs may require the use of a specific verification mode (both are supported by Zend\Feed\PubSubHubbub). Since Zend\Feed\PubSubHubbub implements the Subscriber verification role as a separate callback class and requires the use of a backend storage medium. the Hub will return a response to the subscription request immediately. To handle these Hub requests. the Callback URL should trigger the execution of an instance of Zend\Feed\PubSubHubbub\Subscriber\Callback to handle the request. By default.Zend Framework 2 Documentation. you may indicate a specific preference using the setPreferredVerificationMode() method. Release 2. /** * Check if the callback resulting in the receipt of a feed update. it actually supports both transparently though in terms of end-user performance. a new instance of Zend\PubSubHubbub\Subscriber will attempt to use a database backed storage medium which defaults to using the default Zend\Db adapter with a table name of “subscription”. $callback->sendResponse().mode” is set to “unsubscribe”. */ } 336 Chapter 76. * Otherwise it was either a (un)sub verification request or invalid request. which will include all future communications containing Topic (feed) updates. with the exception that we should call unsubscribeAll() instead. Using it is quite simple since most of its work is performed internally. Zend\Feed\PubSubHubbub . The Callback class should be configured to use the same storage medium as the Subscriber class. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $storage = new Zend\Feed\PubSubHubbub\Model\Subscription. and its verification request may occur at a later time. $callback->handle().4.6 Zend\Feed\PubSubHubbub\Subscriber::setLeaseSeconds() or show a preference for the async verify mode by using setPreferredVerificationMode(Zend\Feed\PubSubHubbub\PubSubHubbub::VERIFICATION_ However the Hubs retain the capability to enforce their own preferences and for this reason the component is deliberately designed to work across almost any set of options with minimum end-user configuration required. and before responding to the subscription request. */ if ($callback->hasFeedUpdate()) { $feedString = $callback->getFeedUpdate(). * Typically we need do nothing other than add feed update handling . $callback->setStorage($storage). Unsubscribing from a Topic follows the exact same pattern as the previous example.2 Handling Subscriber Callbacks Whenever a subscription or unsubscription request is made.the rest * is handled internally by the class. asynchronous verification is very much preferred to eliminate the impact of a poorly performing Hub tying up end-user server resources and connections for too long.0. 76. the Hub attempts to confirm a subscription as soon as it is received. $callback = new Zend\Feed\PubSubHubbub\Subscriber\Callback.

$callback->setStorage($storage). One symptom of a failure to promptly complete Hub requests is that a Hub may continue to attempt delivery of the update or verification request leading to duplicated update attempts being processed by the Subscriber. The example below demonstrates this using a Zend Framework controller. class CallbackController extends AbstractActionController { public function indexAction() { $storage = new Zend\Feed\PubSubHubbub\Model\Subscription.Zend Framework 2 Documentation.example. This appears problematic .com/callback?xhub. for historical reasons. and if no response is received within that time it may disconnect (assuming a delivery failure) and retry later. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 use Zend\Mvc\Controller\AbstractActionController.but in reality a Hub may apply a timeout of just a few seconds. 76.4. this requires some additional work to implement. /** * Inject subscription key parsing from URL path using * a parameter from Router. Note that Hubs are expected to distribute vast volumes of updates so their resources are stretched .4.1 (it was recently added in 0. 76.6 Note: It should be noted that Zend\Feed\PubSubHubbub\Subscriber\Callback may independently parse any incoming query string and other parameters. Important: It is essential that developers recognise that Hubs are only concerned with sending requests and receiving a response which verifies its receipt. Pubsubhubbub features both of these in the query strings it generates. any processing should be offloaded to another process or deferred until after a response has been returned to the Hub. Rather. primarily that this was not supported in Pubsubhubbub 0. The first step to make the Zend\Feed\PubSubHubbub\Subscriber\Callback class aware of the path contained subscription key. This is achieved simply by called the method Zend\Feed\PubSubHubbub\Subscriber\Callback::setSubscriptionKey() with the parameter being the key value available from the Router. Release 2. This is necessary since PHP alters the structure and keys of a query string when it is parsed into the $_GET or $_POST superglobals. However.2 specification. it is strongly recommended to use the most compatible means of adding this key to the Callback URL by appending it to the URL‘s path. $callback->setSubscriptionKey($subscriptionKey). would become Since the query string method is the default in anticipation of a greater level of future support for the full 0.subscription=key http://www. For example. It’s manually injected therefore since it also requires manually defining a route for this purpose. */ $subscriptionKey = $this->params()->fromRoute(’subkey’). The technically preferred method is to add this key to the Callback URL employed by the Hub in all future requests using a query string parameter with the key “xhub.please do process feeds asynchronously (e.example. Zend\Feed\PubSubHubbub\Subscriber 337 .g. Thus the URL http://www. If a feed update is received. it should never be processed on the spot since this leaves the Hub waiting for a response. all duplicate keys are ignored and periods are converted to underscores.com/callback/key. the Zend\Feed\PubSubHubbub\Subscriber\Callback class receives the combined key associated with any subscription from the Hub via one of two methods.0.subscription”.2 only). $callback = new Zend\Feed\PubSubHubbub\Subscriber\Callback. in a separate process or a job queue or even a cron scheduled task) as much as possible.3 Setting Up And Using A Callback URL Route As noted earlier.

’constraints’ => array( ’subkey’ => ’[a-z0-9]+’ ).6 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 $callback->handle(). 338 Chapter 76. Zend\Feed\PubSubHubbub . /** * Process the feed update asynchronously to avoid a Hub timeout.Zend Framework 2 Documentation.the rest is handled internally by the class. /** * Check if the callback resulting in the receipt of a feed update. * Otherwise it was either a (un)sub verification request or invalid * request. Release 2. */ } } } Actually adding the route which would map the path-appended key to a parameter for retrieval from a controller can be accomplished using a Route like in the example below.0. 1 2 3 4 5 6 7 8 9 10 11 // Callback Route to enable appending a PuSH Subscription’s lookup key $route = Zend\Mvc\Router\Http\Segment::factory(array( ’route’ => ’/callback/:subkey’. ’action’ => ’index’ ) )). Typically we need do nothing other than add feed update * handling . $callback->sendResponse(). */ if ($callback->hasFeedUpdate()) { $feedString = $callback->getFeedUpdate(). ’defaults’ => array( ’controller’ => ’application-index’.

77. 339 . coffee). which approach is more appropriate depends on the situation. if a form field is automatically populated with untrusted input (e. Following is a basic example of using a filter upon two input data.1 What is a filter? In the physical world. this value should either be free of HTML entities or contain only escaped HTML entities. and “to filter. A filter that escapes the HTML entities. This type of filtering is useful for web applications . a filter is an operator that produces a subset of the input. the ampersand (&) and double quote (“) characters: 1 2 3 4 $htmlEntities = new Zend\Filter\HtmlEntities(). // & echo $htmlEntities->filter(’"’). trimming unnecessary white space. To meet this requirement.2 Basic usage of filters Having this filter definition established provides the foundation for Zend\Filter\FilterInterface.removing illegal input. a filter is typically used for removing unwanted portions of input. and the desired portion of the input passes through as filter output (e. It also provides a simple filter chaining mechanism by which multiple filters may be applied to a single datum in a user-defined order. For example.g. etc. HTML entities that appear in the input must either be removed or escaped. 77.”).CHAPTER SEVENTYSEVEN INTRODUCTION The Zend\Filter component provides a set of commonly needed data filters. This basic definition of a filter may be extended to include generalized transformations upon input.. echo $htmlEntities->filter(’&’).. transforms the input (e.an operator that produces a subset of the input.g. however. which requires a single method named filter() to be implemented by a filter class. “&” is transformed to “&amp. A common transformation applied in web applications is the escaping of HTML entities. Supporting such use cases for web developers is important.” in the context of using Zend\Filter. if a Filter inherits from Zend\Filter\AbstractFilter (just like all out-of-the-box Filters) you can also use them as such: 1 2 $strtolower = new Zend\Filter\StringToLower.. from a web browser).g. in order to prevent undesired behavior and security vulnerabilities. // " Also. A filter that removes the HTML entities operates within the scope of the first definition of filter . means to perform some transformations upon input data. In such scenarios. Of course.

340 Chapter 77. Release 2.0.Zend Framework 2 Documentation.6 3 4 echo $strtolower(’I LOVE ZF2!’). Introduction . // i love zf2! $zf2love = $strtolower(’I LOVE ZF2!’).

that you would pass to the filter() method. but if you have the need to run a filter for multiple inputs. relative to the Zend\Filter namespace. ’MyCustom\Filter\MyNewFilter’ ). and applies the filter() method to the data input. The second argument is a string. Also. 341 .CHAPTER SEVENTYEIGHT USING THE STATICFILTER If it is inconvenient to load a given filter class and create an instance of the filter. The execute() method automatically loads the class. You can set and receive the FilterPluginManager for the StaticFilter to amend the standard filter classes. 1 2 3 echo StaticFilter::execute(’"’. the FilterChain class allows you to instantiate and run multiple filter and validator classes on demand to process sets of input data. if they are needed for the filter class. The static usage can be convenient for invoking a filter ad hoc. $filtered = $filter->filter($original). ’HtmlEntities’. creating an instance of the filter object and calling its filter() method.1 Double filtering When using two filters after each other you have to keep in mind that it is often not possible to get the original output by using the opposite filter. it’s more efficient to follow the first example above. This is useful when adding custom filters to be used by the StaticFilter. 1 2 3 4 5 $pluginManager = StaticFilter::getPluginManager()->setInvokableClass( ’myNewFilter’. The first argument of this method is a data input value. // Attach a filter $filter = new Zend\Filter\Word\UnderscoreToCamelCase(). ’HtmlEntities’). You can also pass an array of constructor arguments. you can use StaticFilter with it’s method execute() as an alternative invocation style. creates an instance. array(’quotestyle’ => ENT_QUOTES)). which corresponds to the basename of the filter class. Take the following example: 1 2 3 4 5 6 $original = "my_original_content". 1 echo StaticFilter::execute(’&’. 78. StaticFilter::setPluginManager(new MyFilterPluginManager()). See FilterChain.

0. It depends on the filter and also on the given input. 342 Chapter 78. But thinking logically this is not the case.Zend Framework 2 Documentation. $filtered = $filter2->filter($filtered) The above code example could lead to the impression that you will get the original output after the second filter has been applied. Release 2. Using the StaticFilter .6 7 8 9 // Use it’s opposite $filter2 = new Zend\Filter\Word\CamelCaseToUnderscore(). As you can see it is not always possible to get the original output by using a filter which seems to be the opposite. But after applying the second filter the result is My_Original_Content. After applying the first filter my_original_content will be changed to MyOriginalContent.

Otherwise they are suppressed. // Returns "Thisismycontent123" // First param in constructor is $allowWhiteSpace $filter = new \Zend\I18n\Filter\Alnum(true).1 Alnum The Alnum filter can be used to return only alphabetic characters and digits in the unicode “letter” and “number” categories. Methods for getting/setting the allowWhiteSpace option are also available: getAllowWhiteSpace() and setAllowWhiteSpace() • $locale: The locale string used in identifying the characters to filter (locale name. 79. All other characters are suppressed. en_US). The language itself is detected using the Locale. 343 . string $locale ]]) • $allowWhiteSpace: If set to true then whitespace characters are allowed. Within these languages the english alphabet is used instead of the characters from these languages. Japanese and Korean. which are ready for you to use. Methods for getting/setting the locale are also available: getLocale() and setLocale() Alnum Filter Usage // Default settings.g. // Returns "This is my content 123" 1 2 3 4 5 6 7 8 9 Note: Note: Alnum works on almost all languages. Supported Options for Alnum Filter The following options are supported for Alnum: Alnum([ boolean $allowWhiteSpace [. Default is “false” (whitespace is not allowed). echo $filter->filter("This is (my) content: 123"). echo $filter->filter("This is (my) content: 123"). e. If unset. respectively. it will use the default locale (Locale::getDefault()).CHAPTER SEVENTYNINE STANDARD FILTER CLASSES Zend Framework comes with a standard set of filters. deny whitespace $filter = new \Zend\I18n\Filter\Alnum(). except: Chinese.

string $locale ]]) • $allowWhiteSpace: If set to true then whitespace characters are allowed.g. echo $filter->filter("This is (my) content: 123"). deny whitespace $filter = new \Zend\I18n\Filter\Alpha(). 79. The language itself is detected using the Locale. Release 2. // Returns "This is my content " 1 2 3 4 5 6 7 8 9 Note: Note: Alpha works on almost all languages.3 BaseName Zend\Filter\BaseName allows you to filter a string which contains the path to a file and it will return the base name of this file. Methods for getting/setting the locale are also available: getLocale() and setLocale() Alpha Filter Usage // Default settings. All other characters are suppressed. Default is “false” (whitespace is not allowed). e. echo $filter->filter("This is (my) content: 123"). Japanese and Korean. Supported Options for Alpha Filter The following options are supported for Alpha: Alpha([ boolean $allowWhiteSpace [. If unset. // Returns "Thisismycontent" // Allow whitespace $filter = new \Zend\I18n\Filter\Alpha(true). Methods for getting/setting the allowWhiteSpace option are also available: getAllowWhiteSpace() and setAllowWhiteSpace() • $locale: The locale string used in identifying the characters to filter (locale name. Supported Options There are no additional options for Zend\Filter\BaseName.0. Otherwise they are suppressed. Within these languages the english alphabet is used instead of the characters from these languages. except: Chinese.2 Alpha The Alpha filter can be used to return only alphabetic characters in the unicode “letter” category. en_US).6 79. Standard Filter Classes . 344 Chapter 79. it will use the default locale (Locale::getDefault()).Zend Framework 2 Documentation.

4 Boolean This filter changes a given input to be a BOOLEAN value. This is often useful when working with databases or when processing form values.txt’). 1 2 3 $filter = new Zend\Filter\BaseName(). 1 2 3 4 $filter = new Zend\Filter\Boolean(). This will return ‘filename’. $value = ’’. print $filter->filter(’/vol/tmp/filename’). This will return ‘filename.4. this filter works by casting the input to a BOOLEAN value. // returns false This means that without providing any configuration. This option defaults to TRUE. 79.txt‘. $result = $filter->filter($value). Release 2.Zend Framework 2 Documentation. Changing the Default Behavior Sometimes casting with (boolean) will not suffice. Boolean 345 . • integer: Converts an integer 0 value to FALSE. Read the following for details. • type: The type option sets the boolean type which should be used. The following types can be handled: • boolean: Returns a boolean value as is. print $filter->filter(’/vol/tmp/filename. Supported Options The following options are supported for Zend\Filter\Boolean: • casting: When this option is set to TRUE then any given input will be casted to boolean. as well as which to omit.6 Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\BaseName(). in other words.0. 79. Zend\Filter\Boolean accepts all input types and returns a BOOLEAN just as you would get by type casting to BOOLEAN. • locale: This option sets the locale which will be used to detect localized input. it operates in a similar fashion to calling (boolean) $value. Zend\Filter\Boolean allows you to configure specific types to convert. Default Behavior By default.

This means that you can ask your customer in a form for “yes” or “no” within his native language and Zend\Filter\Boolean will convert the response to the appropriate boolean value.6 • float: Converts a float 0. 346 Chapter 79. All other given values will return TRUE by default. See the following examples: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // converts 0 to false $filter = new Zend\Filter\Boolean(Zend\Filter\Boolean::INTEGER). • empty_array: Converts an empty array to FALSE. // converts 0 and ’0’ to false $filter = new Zend\Filter\Boolean( Zend\Filter\Boolean::INTEGER + Zend\Filter\Boolean::ZERO ). // converts 0 and ’0’ to false $filter = new Zend\Filter\Boolean(array( ’type’ => array( ’integer’. you can either use the locale option. You can give one or multiple types and add them. ’zero’. // converts 0 and ’0’ to false $filter = new Zend\Filter\Boolean(array( ’type’ => array( Zend\Filter\Boolean::INTEGER. ).Zend Framework 2 Documentation. You can also give an instance of Zend\Config\Config to set the desired types. • null: Converts a NULL value to FALSE. ’locale’ => ’de’. Release 2. • yes: Converts a localized string which contains the word “no” to FALSE. you can give an array. 1 2 3 $filter = new Zend\Filter\Boolean(array( ’type’ => Zend\Filter\Boolean::ALL. • all: Converts all above types to BOOLEAN. )). Zend\Filter\Boolean can also recognise localized “yes” and “no” strings. you can use constants. Standard Filter Classes . Zend\Filter\Boolean::ZERO.0 value to FALSE. There are several ways to select which of the above types are filtered. To set the desired locale. or you can give a textual string. • string: Converts an empty string ‘’ to FALSE. Localized Booleans As mentioned previously. ). • zero: Converts a string containing the single character zero (‘0’) to FALSE. )). • php: Converts values according to PHP when casting them to BOOLEAN. • false_string: Converts a string containing the word “false” to a boolean FALSE. To set types after instantiation. use the setType() method.0. or the method setLocale().

which shows which values return TRUE or FALSE. )). 79. All other given values are returned without change when casting is set to FALSE Table 79. 79. $filter->setLocale(’en’).5 Callback This filter allows you to use own methods in conjunction with Zend\Filter.1: Usage without casting Type ZendFilterBoolean::BOOLEAN ZendFilterBoolean::INTEGER ZendFilterBoolean::FLOAT ZendFilterBoolean::STRING ZendFilterBoolean::ZERO ZendFilterBoolean::EMPTY_ARRAY ZendFilterBoolean::NULL ZendFilterBoolean::FALSE_STRING ZendFilterBoolean::YES True TRUE 0 0. You don’t have to create a new filter when you already have a method which does the job.0 “” “0” array() NULL “false” (case independently) localized “yes” (case independently) False FALSE 1 1. // returns true $filter->filter(’yes’). ’casting’ => false.6 4 5 6 7 8 9 10 11 12 )). // returns false echo $filter->filter(0). Callback 347 .0. // returns false echo $filter->filter(’nein’). // returns the value echo $filter->filter(2). In this case Zend\Filter\Boolean will work as described in the following table.0 “1” “true” (case independently) localized “no” (case independently) The following example shows the behaviour when changing the casting option: 1 2 3 4 5 6 7 8 9 10 11 12 13 $filter = new Zend\Filter\Boolean(array( ’type’ => Zend\Filter\Boolean::ALL.5. Disable Casting Sometimes it is necessary to recognise only TRUE or FALSE and return all other values without changes.Zend Framework 2 Documentation. Release 2. // returns true echo $filter->filter(1). Zend\Filter\Boolean allows you to do this by setting the casting option to FALSE.

1 2 3 4 $filter = new Zend\Filter\Callback(’strrev’). To get the actual set callback use getCallback() and to set another callback use setCallback(). which is defined within a class. Default Parameters Within a Callback It is also possible to define default parameters. $filter->filter(array(’value’ => ’Hello’)). 1 2 3 4 5 6 7 8 9 // Our classdefinition class MyClass { public function Reverse($param).Zend Framework 2 Documentation. print $filter->filter(’Hello!’). which are given to the called method as array when the filter is executed. Let’s expect we want to create a filter which reverses a string. It is also possible to use a method. 348 Chapter 79. This array will be concatenated with the value which will be filtered. • options: This property sets the options which are used when the callback is processed. print $filter->filter(’Hello!’). Standard Filter Classes . When you would call the above method definition manually it would look like this: 1 $value = MyMethod(’Hello’. ’param2’). ’key2’ => ’param2’) ) ). Note: Possible exceptions You should note that defining a callback method which can not be called will raise an exception. // returns "!olleH" As you can see it’s really simple to use a callback to define a own filter. } // The filter definition $filter = new Zend\Filter\Callback(array(’MyClass’. by giving an array as callback. Basic Usage The usage of this filter is quite simple.0. ’options’ => array(’key’ => ’param1’. ’Reverse’)). Release 2.6 Supported Options The following options are supported for Zend\Filter\Callback: • callback: This sets the callback which should be used. 1 2 3 4 5 6 7 $filter = new Zend\Filter\Callback( array( ’callback’ => ’MyMethod’. ’param1’.

and then either the key “options” or “adapterOptions” (which should be an array of options to provide to the adapter on instantiation). Supported Options The following options are supported for Zend\Filter\Compress and Zend\Filter\Decompress: • adapter: The compression adapter which should be used. if we want to compress a string. ). • options: Additional options which are given to the adapter at initiation.6. All compression filters may be used in approximately the same ways. )). 1 $filter = new Zend\Filter\Compress(’Bz2’). provide minimally the key “adapter”. To use a different adapter. ’options’ => array( ’blocksize’ => 8. Zend\Filter\Compress should be used when you wish to compress items. Release 2.Zend Framework 2 Documentation. Supported Compression Adapters The following compression formats are supported by their own adapter: • Bz2 • Gz • Lzf • Rar • Tar • Zip Each compression format has different capabilities as described below.0. file vs. Each adapter supports it’s own options. and differ primarily in the options available and the type of compression they offer (both algorithmically as well as string vs. The two filters are basically identical. directory) Generic Handling To create a compression filter you need to select the compression format you want to use. files. Details for all other adapters are described after this section. If you do. Compress and Decompress 349 . and directories. For instance. 79. You may also provide an array of options or a Traversable object. It defaults to Gz. and Zend\Filter\Decompress should be used when you wish to decompress items. in that they utilize the same backends. 1 2 3 4 5 6 $filter = new Zend\Filter\Compress(array( ’adapter’ => ’Bz2’.6 79. The following description takes the Bz2 adapter. we have to initiate Zend\Filter\Compress and indicate the desired adapter. you simply specify it to the constructor.6 Compress and Decompress These two filters are capable of compressing and decompressing strings.

$compressed = $filter->filter(’Uncompressed string’). and is then written into the given archive file. $compressed = $filter->filter(’Uncompressed string’). Compression formats like Rar can only handle files and directories. ’options’ => array( ’archive’ => ’filename. )). // Returns true on success and creates the archive file In the above example the uncompressed string is compressed. then the Gz adapter will be used. 1 2 3 $filter = new Zend\Filter\Decompress(’Bz2’). Note: Existing archives will be overwritten The content of any existing file will be overwritten when the given filename of the archive already exists. 1 2 3 4 5 6 7 8 $filter = new Zend\Filter\Compress(array( ’adapter’ => ’Bz2’. 1 2 3 $filter = new Zend\Filter\Compress(’Bz2’).6 Note: Default compression Adapter When no compression adapter is given.bz2’. The filtered value is the compressed version of the original string. then you must give the name of the file with its path. ’options’ => array( ’archive’ => ’filename. To get the compressed string. 1 $filter = new Zend\Filter\Decompress(’Bz2’). we have to give the original string. However. // Returns the compressed string Decompression works the same way.0. in this case we need an additional parameter which holds the name of the archive we want to create. // Returns the uncompressed string Note: Note on string compression Not all adapters support string compression. ). Almost the same usage is we want to decompress a string. consult the section for the adapter you wish to use. We just have to use the decompression filter in this case. )). When you want to compress a file. For details. $compressed = $filter->filter(’Compressed string’).Zend Framework 2 Documentation. Release 2. Creating an Archive Creating an archive file works almost the same as compressing a string. 350 Chapter 79. Standard Filter Classes .bz2’ ). 1 2 3 4 5 6 $filter = new Zend\Filter\Compress(array( ’adapter’ => ’Bz2’.

’options’ => array( ’archive’ => ’filename. $compressed = $filter->filter(’filename. // Returns true on success and creates the archive file You may also specify a directory instead of a filename. Decompressing an Archive Decompressing an archive file works almost like compressing it. ’options’ => array( ’target’ => ’C:\temp’. 1 2 3 4 5 6 7 8 $filter = new Zend\Filter\Compress(array( ’adapter’ => ’Bz2’. Bz2 Adapter The Bz2 Adapter can compress and decompress: • Strings • Files 79. In this case you can set the target parameter. or give the filename of the archive when you decompress the file. In this case the whole directory with all its files and subdirectories will be compressed into the archive. You must specify either the archive parameter.0.zip’).bz2’). then that directory must exist.Zend Framework 2 Documentation. // Returns true on success and decompresses the archive file Some adapters support decompressing the archive into another subdirectory. )). // Returns true on success and decompresses the archive file // into the given target directory Note: Directories to extract to must exist When you want to decompress an archive into a directory.bz2’ ). $compressed = $filter->filter(’C:\temp\somedir’). Compress and Decompress 351 . $compressed = $filter->filter(’filename.6 7 8 $compressed = $filter->filter(’C:\temp\compressme. // Returns true on success and creates the archive file Note: Do not compress large or base directories You should never compress large or base directories like a complete partition. 1 2 3 4 5 6 7 8 9 $filter = new Zend\Filter\Decompress(array( ’adapter’ => ’Zip’.6.txt’). Compressing a complete partition is a very time consuming task which can lead to massive problems on your server when there is not enough space or your script takes too much time. 1 2 3 $filter = new Zend\Filter\Decompress(’Bz2’). Release 2. ) )).

• Level: This compression level to use. the related methods for ‘Blocksize’ are getBlocksize() and setBlocksize(). For example. Standard Filter Classes . ‘compress’ and ‘deflate’. You can also use the setOptions() method which accepts all options as array. All options can be set at instantiation or by using a related method. • Mode: There are two supported modes.0. The default value is ‘compress’. The default value is ‘4’. Release 2. There are no options available to customize this adapter. Rar Adapter The Rar Adapter can compress and decompress: • Files • Directories 352 Chapter 79. The default value is ‘9’. This adapter makes use of PHP‘s Lzf extension. It can be from ‘0’ to ‘9’. Lzf Adapter The Lzf Adapter can compress and decompress: • Strings Note: Lzf supports only strings The Lzf adapter can not handle files and directories. To customize the compression this adapter supports the following options: • Archive: This parameter sets the archive file which should be used or created. For example. All options can be set at initiation or by using a related method. Gz Adapter The Gz Adapter can compress and decompress: • Strings • Files • Directories This adapter makes use of PHP‘s Zlib extension. • Blocksize: This parameter sets the blocksize to use. You can also use the setOptions() method which accepts all options as array. the related methods for ‘Level’ are getLevel() and setLevel().Zend Framework 2 Documentation. this adapter supports the following options: • Archive: This parameter sets the archive file which should be used or created. It can be from ‘0’ to ‘9’.6 • Directories This adapter makes use of PHP‘s Bz2 extension. To customize compression.

Note: Rar compression not supported Due to restrictions with the Rar compression format. All options can be set at instantiation or by using a related method. This means that created Tar files will not only have the subdirectory but the complete path for the compressed file. All options can be set at instantiation or by using a related method.6. ‘Gz’ which makes use of PHP‘s Zlib extension and ‘Bz2’ which makes use of PHP‘s Bz2 extension. • Callback: A callback which provides compression support to this adapter. 79. You can also use the setOptions() method which accepts all options as array. The default value is ‘NULL‘. This adapter makes use of PHP‘s Rar extension.6 Note: Rar does not support strings The Rar Adapter can not handle strings. • Mode: A mode to use for compression. Release 2. the related methods for ‘Target’ are getTarget() and setTarget(). you must provide a callback to the adapter that can invoke a Rar compression program. For example. You can also use the setOptions() method which accepts all options as array. To customize the compression this adapter supports the following options: • Archive: This parameter sets the archive file which should be used or created. Supported are either ‘NULL‘ which means no compression at all.Zend Framework 2 Documentation. • Target: The target where the decompressed files will be written to. For example. Compress and Decompress 353 . Note: Directory usage When compressing directories with Tar then the complete file path is used. the related methods for ‘Target’ are getTarget() and setTarget(). • Target: The target where the decompressed files will be written to. Tar Adapter The Tar Adapter can compress and decompress: • Files • Directories Note: Tar does not support strings The Tar Adapter can not handle strings. there is no compression available for free. To customize the compression this adapter supports the following options: • Archive: This parameter sets the archive file which should be used or created. When you want to compress files into a new Rar archive. This adapter makes use of PEAR‘s Archive_Tar component. • Password: The password which has to be used for decompression.0.

You can also use the setOptions() method which accepts all options as array.0. This returns “2012”. To customize the compression this adapter supports the following options: • Archive: This parameter sets the archive file which should be used or created.6 Zip Adapter The Zip Adapter can compress and decompress: • Strings • Files • Directories Note: Zip does not support string decompression The Zip Adapter can not handle decompression to a string. 79. Standard Filter Classes . 354 Chapter 79. removing all but digits.7 Digits Returns the string $value. decompression will always be written to a file. Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Digits(). the related methods for ‘Target’ are getTarget() and setTarget(). Supported Options There are no additional options for Zend\Filter\Digits.Zend Framework 2 Documentation. For example. print $filter->filter(’HTML 5 for Dummies’). • Target: The target where the decompressed files will be written to. This returns “5”. print $filter->filter(’October 2012’). All options can be set at instantiation or by using a related method. This adapter makes use of PHP‘s Zip extension. Release 2. 1 2 3 $filter = new Zend\Filter\Digits().

It should be one of the algorithm ciphers supported by Zend\Crypt\Symmetric\Mcrypt (see the getSupportedAlgorithms() method).9 Encrypt and Decrypt These filters allow to encrypt and decrypt any given string. The encrypted envelope key from the user who encrypted the content. Supported Options There are no additional options for Zend\Filter\Dir. The encryption key with which the input will be encrypted. Therefor they make use of Adapters. The encryption mode which has to be used. the Advanced Encryption Standard (see Zend\Crypt\BlockCipher for more details).8 Dir Given a string containing a path to a file. • compression: If the encrypted value should be compressed.6 79. The algorithm which has to be used by the adapter Zend\Crypt\Symmetric\Mcrypt. then you can omit this parameter. this function will return the name of the directory. Dir 355 . If not set it defaults to aes. print $filter->filter(’C:/Temp/x’). • mode: Only BlockCipher. You can either provide the path and filename of the key file. 79. print $filter->filter(’/etc/passwd’). Supported Options The following options are supported for Zend\Filter\Encrypt and Zend\Filter\Decrypt: • adapter: This sets the encryption adapter which should be used • algorithm: Only BlockCipher.8. It should be one of the modes which can be found under ‘PHP’s mcrypt modes‘_. When the package option has been set. Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Dir(). This returns “C:/Temp”. You need the same key for decryption. • key: Only BlockCipher. • envelope: Only OpenSSL. Actually there are adapters for the Zend\Crypt\BlockCipher class and the OpenSSL extension of PHP. If not set it defaults to ‘cbc’. 79. This returns “/etc”.0. or just the content of the key file itself.Zend Framework 2 Documentation. Release 2. Default is no compression. 1 2 3 $filter = new Zend\Filter\Dir().

If not set it defaults to the path set within the Mcrypt extension. $encrypted = $filter->filter(’text to be encrypted’). • private: Only OpenSSL. // Use the OpenSSL adapter $filter2 = new Zend\Filter\Encrypt(array(’adapter’ => ’openssl’)). 356 Chapter 79. or just the content of the key file itself. Note: When you do not supply the adapter option or do not use setAdapter(). also the usage of the adapters differ. Encryption with BlockCipher To encrypt a string using the BlockCipher you have to specify the encryption key using the setKey() method or passing it during the constructor. • vector: Only BlockCipher. Your private key which will be used for encrypting the content. Release 2. 1 2 3 4 5 // Use the BlockCipher adapter $filter1 = new Zend\Filter\Encrypt(array(’adapter’ => ’BlockCipher’)). Adapter Usage As these two encryption methodologies work completely different. The directory where the mode can be found. $filter->setAdapter(’openssl’). You can give multiple public keys by using an array. You can eigther provide the path and filename of the key file. printf ("Encrypted text: %s\n". If not set it will be a random vector. Standard Filter Classes . Also the private key can be either a filename with path of the key file. 1 2 3 // Use the OpenSSL adapter $filter = new Zend\Filter\Encrypt(). 1 2 3 4 5 6 7 8 9 10 11 12 // Use the default AES encryption algorithm $filter = new Zend\Filter\Encrypt(array(’adapter’ => ’BlockCipher’)). $encrypted). The public key of the user whom you want to provide the encrpted content.Zend Framework 2 Documentation. You have to select the adapter you want to use when initiating the filter. • package: Only OpenSSL. If the envelope key should be packed with the encrypted value. Default is FALSE. then the BlockCipher adapter will be used per default. // or // $filter = new Zend\Filter\Encrypt(array( // ’adapter’ => ’BlockCipher’. $filter->setKey(’encryption key’).6 • mode_directory: Only BlockCipher. You can get and set the encryption values also afterwards with the getEncryption() and setEncryption() methods. // ’key’ => ’encryption key’ // )). and the getAdapter() method to receive the actual set adapter. The initialization vector which shall be used. • public: Only OpenSSL. or just the content of the key file itself. To set another adapter you can also use setAdapter().0.

If you try to execute the following code the output will be always different (note that even if the output is always different you can decrypt it using the same key). $text = ’message to encrypt’. If you don’t specify an initialization Vector (salt or iv). printf("%s\n". Decryption with BlockCipher For decrypting content which was previously encrypted with BlockCipher you need to have the options with which the encryption has been called. $filter->setKey(’encryption key’). the BlockCipher will generate a random value during each encryption. // use the default adapter that is BlockCipher $filter = new \Zend\Filter\Encrypt(). $filter->setKey(’encryption key’).Zend Framework 2 Documentation. We suggest to use the setVector() method only if you really need it.9. 1 2 3 4 5 6 7 8 9 $key = ’encryption key’.0. // output: // 04636a6cb8276fad0787a2e187803b6557f77825d5ca6ed4392be702b9754bb3MTIzNDU2Nzg5MDEyMzQ1NgZ+zPwTGpV6gQ Note: For a security reason it’s always better to use a different Vector on each encryption. That means you will need to install the Mcrypt module in your PHP environment. Encrypt and Decrypt 357 . using the setVector() method. for ($i=0. $filter->setKey(’encryption key’). $filter->setVector(’12345678901234567890’). var_dump($filter->getEncryption()). $filter->filter(’message’)). $i++) { printf("%d) %s\n". } If you want to obtain the same output you need to specify a fixed Vector. Release 2. // Will print: //array(4) { // ["key_iteration"]=> // int(5000) // ["algorithm"]=> // string(3) "aes" // ["hash"]=> // string(6) "sha256" // ["key"]=> // string(14) "encryption key" //} Note: The BlockCipher adapter uses the Mcrypt PHP extension by default. $filter->filter($text)). 79. $i.6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // Use the default AES encryption algorithm $filter = new Zend\Filter\Encrypt(array(’adapter’ => ’BlockCipher’)). This script will produce always the same encryption output. 1 2 3 4 5 6 7 8 // use the default adapter that is BlockCipher $filter = new \Zend\Filter\Encrypt(). $i < 10.

’/public/key/path/second. ’/public/key/path/second. 1 2 3 4 5 6 7 8 9 10 11 // Use openssl and provide a private key $filter = new Zend\Filter\Encrypt(array( ’adapter’ => ’openssl’.pem’. // output: // Decrypt: message Note that even if we did not specify the same Vector.pem’ )). Standard Filter Classes . As soon as you have provided all options decryption is as simple as encryption. but also the passphrase to decode the encrypted key.pem’. 1 2 3 4 5 6 7 8 9 10 11 12 // Use openssl and provide a private key $filter = new Zend\Filter\Encrypt(array( ’adapter’ => ’openssl’.0. $filter->setKey(’encryption key’). Release 2. Note: You should also note that all settings which be checked when you create the instance or when you call setEncryption(). $filter->setPassphrase(’mypassphrase’).pem’ )).pem’ )). The private key can also be get and set with the related getPrivateKey() and setPrivateKey() methods.pem’ )).Zend Framework 2 Documentation. 1 2 3 4 5 6 7 8 $content = ’04636a6cb8276fad0787a2e187803b6557f77825d5ca6ed4392be702b9754bb3MTIzNDU2Nzg5MDEyMzQ1NgZ+z // use the default adapter that is BlockCipher $filter = new Zend\Filter\Decrypt(). You can get or set the public keys also afterwards with the getPublicKey() and setPublicKey() methods.6 If you used only the encryption key. // of course you can also give the public keys at initiation $filter->setPublicKey(array( ’/public/key/path/first. ’private’ => ’/path/to/mykey/private. it is not a secret. When you want to encode also the keys. you can just use it to decrypt the content. 358 Chapter 79. // of course you can also give the public keys at initiation $filter->setPublicKey(array( ’/public/key/path/first. Encryption with OpenSSL When you have installed the OpenSSL extension you can use the OpenSSL adapter. the BlockCipher is able to decrypt the message because the Vector is stored in the encryption string itself (note that the Vector can be stored in plaintext. then you have to provide a passphrase with the setPassphrase() method. Note: Note that the OpenSSL adapter will not work when you do not provide valid keys. When you want to decode content which was encoded with a passphrase you will not only need the public key. the Vector is only used to improve the randomness of the encryption algorithm). printf("Decrypt: %s\n". ’private’ => ’/path/to/mykey/private. $filter->filter($content)).

when you use OpenSSL you need to give the receiver the encrypted content. Compressing Content Based on the original value. and this is the negative aspect of this feature. $encrypted = $filter->filter(’text_to_be_encoded’). that you have to get the envelope keys after the encryption with the getEnvelopeKey() method.6 At last. print $encrypted. the encrypted value can be a very large string. Encrypt and Decrypt 359 . ’private’ => ’/path/to/mykey/private. you need to get the envelope key to be able to decrypt the previous encrypted value. ’package’ => true )). Zend\Filter\Encrypt allows the usage of compression. ’/public/key/path/second. This can be very annoying when you work with multiple values. the passphrase when have provided one. // of course you can also give the public keys at initiation $filter->setPublicKey(array( ’/public/key/path/first. ’private’ => ’/path/to/mykey/private.pem’ )).0. the encrypted value can now only be decrypted by using Zend\Filter\Encrypt.pem’. $filter->setPassphrase(’mypassphrase’). and the envelope keys for decryption. So our complete example for encrypting content with OpenSSL look like this. ’public’ => ’/public/key/path/public. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // Use openssl and provide a private key $filter = new Zend\Filter\Encrypt(array( ’adapter’ => ’openssl’.pem’. // For decryption look at the Decrypt filter Now the returned value contains the encrypted value and the envelope. $envelope = $filter->getEnvelopeKey(). The default value is FALSE. But. Release 2. You don’t need to get them after the compression. // For decryption look at the Decrypt filter Simplified usage with Openssl As seen before.9.Zend Framework 2 Documentation. To reduce the value 79. To have a simplified usage you can set the package option to TRUE. 1 2 3 4 5 6 7 8 9 10 11 12 // Use openssl and provide a private key $filter = new Zend\Filter\Encrypt(array( ’adapter’ => ’openssl’. print $encrypted.pem’.pem’ )). $encrypted = $filter->filter(’text_to_be_encoded’). This means for you.

Zend Framework 2 Documentation. // of course you can also give the envelope keys at initiation $filter->setEnvelopeKey(array( ’/key/from/encoder/first.pem’.pem’. See the following example: 1 2 3 4 5 6 7 8 9 10 11 // Use openssl and provide a private key $filter = new Zend\Filter\Decrypt(array( ’adapter’ => ’openssl’. then you need to set the same compression settings for decryption as for encryption. ’package’ => true. 1 2 3 4 5 6 7 // Use openssl and provide a private key $filter = new Zend\Filter\Decrypt(array( ’adapter’ => ’openssl’. ’public’ => ’/public/key/path/public. ’target’ => ’\usr\tmp\tmp. Release 2. Otherwise the decryption will fail.pem’ )). Optionally it could be necessary to provide the passphrase for decrypting the keys themself by using the setPassphrase() method.pem’.0. ’public’ => ’/public/key/path/public. Note: Note that the OpenSSL adapter will not work when you do not provide valid keys. ’/key/from/encoder/second. or to an array which sets all wished options for the compression adapter. Note: Decryption with same settings When you want to decrypt a value which is additionally compressed.pem’ )). Standard Filter Classes . // of course you can also give the envelope keys at initiation 360 Chapter 79. ’compression’ => ’bz2’ )).pem’ )). ’private’ => ’/path/to/mykey/private. ’private’ => ’/path/to/mykey/private. ’private’ => ’/path/to/mykey/private. But you need to have all data from the person who encrypted the content.6 The compression option can eighter be set to the name of a compression adapter. ’compression’ => array(’adapter’ => ’zip’. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // Use basic compression adapter $filter1 = new Zend\Filter\Encrypt(array( ’adapter’ => ’openssl’. // Use basic compression adapter $filter2 = new Zend\Filter\Encrypt(array( ’adapter’ => ’openssl’. Decryption with OpenSSL Decryption with OpenSSL is as simple as encryption. ’package’ => true.zip’) )). ’private’ => ’/path/to/mykey/private.pem’.pem’.

$decrypted = $filter->filter(’encoded_text_normally_unreadable’).10.Zend Framework 2 Documentation. This defines the character set to be used in filtering. Note: This option must be set via the $options parameter or the setDoubleEncode() method. // of course you can also give the envelope keys at initiation $filter->setEnvelopeKey(array( ’/key/from/encoder/first. The option key will be accepted as either charset or encoding. See “http://php. • doublequote: Equivalent to the PHP htmlentities native function parameter double_encode. 79.pem’. ENT_QUOTES ENT_NOQUOTES with the default being ENT_COMPAT. Release 2. ’private’ => ’/path/to/mykey/private.pem’. The following constants are accepted: ENT_COMPAT. Basic Usage See the following example for the default behavior of this filter.net/htmlentities” for a list of supported character sets. If set to false existing html entities will not be encoded.10 HtmlEntities Returns the string $value. • charset: Equivalent to the PHP htmlentities native function parameter charset. print $decrypted. converting characters to their corresponding HTML entity equivalents where they exist. ’/key/from/encoder/second.pem’ )). ’/key/from/encoder/second. Our complete example for decrypting the previously encrypted content looks like this. The default is to convert everything (true). Supported Options The following options are supported for Zend\Filter\HtmlEntities: • quotestyle: Equivalent to the PHP htmlentities native function parameter quote_style. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // Use openssl and provide a private key $filter = new Zend\Filter\Decrypt(array( ’adapter’ => ’openssl’. At last.pem’ )).pem’ )). Note: This option can also be set via the $options parameter as a Traversable object or array. $filter->setPassphrase(’mypassphrase’). $filter->setPassphrase(’mypassphrase’). 79. Unlike the PHP native function the default is ‘UTF-8’.6 8 9 10 11 12 $filter->setEnvelopeKey(array( ’/key/from/encoder/first.0. decode the content. This allows you to define what will be done with ‘single’ and “double” quotes. HtmlEntities 361 .

6 1 2 3 $filter = new Zend\Filter\HtmlEntities(). print $filter->filter($input).0. 1 2 3 4 $filter = new Zend\Filter\HtmlEntities(array(’quotestyle’ => ENT_NOQUOTES)). ’"double"’. The following constants are accepted: ENT_COMPAT. 1 2 3 4 $filter = new Zend\Filter\HtmlEntities(). ENT_QUOTES. This can be useful when you want to leave double. print $filter->filter(’<’). Notice that “double” quotes are filtered while ‘single’ quotes are not altered. the two methods setQuoteStyle() and getQuoteStyle() may be used respectively. See “http://php. $input = "A ’single’ and " . Standard Filter Classes .net/htmlentities” for a list of supported character sets. The above example returns A ‘single’ and “double”. Quote Style Zend\Filter\HtmlEntities allows changing the quote style used. See the following example: 1 2 3 4 $filter = new Zend\Filter\HtmlEntities(array(’quotestyle’ => ENT_QUOTES)). 1 2 3 4 $filter = new Zend\Filter\HtmlEntities(array(’quotestyle’ => ENT_COMPAT)). The above example returns A ‘single’ and “double”. $filter->setQuoteStyle(ENT_QUOTES). setDoubleQuote() accepts one boolean parameter $doubleQuote. ’"double"’. Release 2. print $filter->filter($input). $input = "A ’single’ and " . To change or retrieve the doublequote option after instantiation. The above example returns A ‘single’ and “double”. $input = "A ’single’ and " . the two methods setCharSet() and getCharSet() may be used respectively. setQuoteStyle() accepts one parameter $quoteStyle. $filter->setQuoteStyle(ENT_QUOTES). the two methods setDoubleQuote() and getDoubleQuote() may be used respectively. print $filter->filter($input). setCharSet() accepts one parameter $charSet. Helper Methods To change or retrieve the quotestyle after instantiation. 362 Chapter 79. or both types of quotes un-filtered. ENT_NOQUOTES 1 2 3 4 $filter = new Zend\Filter\HtmlEntities().Zend Framework 2 Documentation. Notice that neither “double” or ‘single’ quotes are altered. Notice that ‘single’ as well as “double” quotes are filtered. print $filter->getQuoteStyle(ENT_QUOTES). single. ’"double"’. To change or retrieve the charset after instantiation. print $filter->getQuoteStyle(ENT_QUOTES).

Release 2.0. Zend\Filter\Null will accept all input types and return NULL in the same cases as empty(). // returns null instead of the empty string This means that without providing any configuration. in other words.11. This is often necessary when you work with databases and want to have a NULL value instead of a boolean or any other type. 79. This will return ‘-4’. Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Int().Zend Framework 2 Documentation. 79. $value = ’’.6 1 2 3 4 $filter = new Zend\Filter\HtmlEntities(). if empty() returns a boolean TRUE. Default Behavior Per default this filter works like PHP‘s empty() method. Int 363 . Supported Options There are no additional options for Zend\Filter\Int. print $filter->filter(’-4 is less than 0’). $result = $filter->filter($value). 1 2 3 4 $filter = new Zend\Filter\Null(). then a NULL value will be returned.11 Int Zend\Filter\Int allows you to transform a sclar value which contains into an integer. print $filter->getQuoteStyle(ENT_QUOTES). without any changes. 79.12 Null This filter will change the given input to be NULL if it meets specific criteria. Supported Options The following options are supported for Zend\Filter\Null: • type: The variable type which should be supported. $filter->setQuoteStyle(ENT_QUOTES). Any other value will be returned as is.

79. Zend\Filter\Null::INTEGER )). The following types can be handled: • boolean: Converts a boolean FALSE value to NULL. )).Zend Framework 2 Documentation. you can give an array. Release 2. // converts false and 0 to null $filter = new Zend\Filter\Null( array( Zend\Filter\Null::BOOLEAN.6 Changing the Default Behavior Sometimes it’s not enough to filter based on empty(). ’integer’. To set types afterwards use setType(). int $type ]]]) 364 Chapter 79. • all: Converts all above types to NULL. // converts false and 0 to null $filter = new Zend\Filter\Null( Zend\Filter\Null::BOOLEAN + Zend\Filter\Null::INTEGER ). You can also give a Traversable or an array to set the wished types. you can use constants. • zero: Converts a string containing the single character zero (‘0’) to NULL. Supported Options for NumberFormat Filter The following options are supported for NumberFormat: NumberFormat([ string $locale [. // converts false and 0 to null $filter = new Zend\Filter\Null(array( ’boolean’. • string: Converts an empty string ‘’ to NULL. • integer: Converts an integer 0 value to NULL. (This is the default behavior.) There are several ways to select which of the above types are filtered. Therefor Zend\Filter\Null allows you to configure which type will be converted and which not. or you can give a textual string. int $style [.0. • float: Converts an float 0. You can give one or multiple types and add them.0 value to NULL. See the following examples: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // converts false to null $filter = new Zend\Filter\Null(Zend\Filter\Null::BOOLEAN). It acts as a wrapper for the NumberFormatter class within the Internationalization extension (Intl). • empty_array: Converts an empty array to NULL. Standard Filter Classes .13 NumberFormat The NumberFormat filter can be used to return locale-specific number and percentage strings.

Release 2. or an array of strings for multiple pattern. echo $filter->filter(1234567. it will use the default locale (Locale::getDefault()) Methods for getting/setting the locale are also available: getLocale() and setLocale() • $style: (Optional) Style of the formatting.891" $filter = new \Zend\I18n\Filter\NumberFormat("en_US".23456789E-3" 1 2 3 4 5 6 7 8 9 10 11 79. It can be a string for a single pattern. If unset.0. // Returns "1. Supported Options The following options are supported for Zend\Filter\PregReplace: • pattern: The pattern which will be searched for. it will use Methods for getting/setting the format style are also available: getStyle() and setStyle() • $type: (Optional) The formatting type to use. • replacement: The string which is used as replacement for the matches.80). // Returns "80%" $filter = new \Zend\I18n\Filter\NumberFormat("fr_FR".6 • $locale: (Optional) Locale in which the number would be formatted (locale name. 1 2 3 4 $filter = new Zend\Filter\PregReplace(array( ’pattern’ => ’/bob/’. To set the pattern which will be used as replacement the option replacement has to be used. one of the format style constants.00123456789). ’replacement’ => ’john’.234. echo $filter->filter(0.14. If unset.Zend Framework 2 Documentation. 79. // Returns "1. )). or an array of strings for multiple pattern. If unset. PregReplace 365 . Basic Usage To use this filter properly you must give two options: The option pattern has to be given to set the pattern which will be searched for. it will use NumberFormatter::TYPE_DOUBLE as the default type. NumberFormatter::SCIENTIFIC). NumberFormatter::DEFAULT_STYLE as the default style. NumberFormatter::PERCENT). It can be a string for a single pattern. en_US).567.8912346). echo $filter->filter(0. e.14 PregReplace Zend\Filter\PregReplace performs a search using regular expressions and replaces all found elements.g. Methods for getting/setting the format type are also available: getType() and setType() NumberFormat Filter Usage $filter = new \Zend\I18n\Filter\NumberFormat("de_DE").

/‘ or ‘/. Basic Usage For any given link of pathname its absolute path will be returned. ‘/. References to ‘/. $filtered = $filter->filter($path).. // returns ’/www/mypath’ Non-Existing Paths Sometimes it is useful to get also paths when they don’t exist. ‘/.. // returns ’Hy john!’ You can use getPattern() and setPattern() to set the matching pattern afterwards. ’Hy’)) ->setReplacement(array(’john’. Release 2.15 RealPath This filter will resolve given links and pathnames and returns canonicalized absolute pathnames. On BSD systems Zend\Filter\RealPath doesn’t fail if only the last path component doesn’t exist. You can then either give a FALSE at initiation. if the file does not exist.../non/existing/path’./‘ character. Supported Options The following options are supported for Zend\Filter\RealPath: • exists: This option defaults to TRUE which checks if the given path really exists. $path = ’/www/var/path/.. Standard Filter Classes .. 1 2 3 4 5 6 7 $filter = new Zend\Filter\PregReplace().0. 1 2 3 4 $filter = new Zend\Filter\RealPath(false). $filter->filter($input). Zend\Filter\RealPath will return FALSE on failure. $filter->setMatchPattern(array(’bob’. e. The resulting path will not have any symbolic link. 79.g. $path = ’/www/var/path/./‘ and extra ‘/‘ characters in the input path will be stripped.6 5 6 7 8 $input = ’Hy bob!". ’Bye’)). To set the replacement pattern you can use getReplacement() and setReplacement(). when you want to get the real path for a path which you want to create./. // returns ’Bye john!’ For a more complex usage take a look into PHP‘s PCRE Pattern Chapter.Zend Framework 2 Documentation. 366 Chapter 79. while other systems will return FALSE./‘. 1 2 3 4 5 $filter = new Zend\Filter\RealPath().e. $input = ’Hy bob!"./. $filter->filter($input). $filtered = $filter->filter($path)./mypath’. f. or use setExists() to set it.

17 StringToUpper This filter converts any input to be uppercased. it’s possible to also lowercase them when the mbstring extension is available in your environment.16 StringToLower This filter converts any input to be lowercased.0. Still. Simply set the wished encoding when initiating the StringToLower filter. 79. StringToLower 367 .16. // or do this afterwards $filter->setEncoding(’ISO-8859-1’). 79.6 5 6 // returns ’/www/non/existing/path’ // even when file_exists or realpath would return false 79. Characters from other charsets would be ignored. Or use the setEncoding() method to change the encoding afterwards.Zend Framework 2 Documentation. Release 2. print $filter->filter(’SAMPLE’). Also when you are trying to set an encoding which is not supported by your mbstring extension you will get an exception. Note: Setting wrong encodings Be aware that you will get an exception when you want to set an encoding and the mbstring extension is not available in your environment. // returns "sample" Different Encoded Strings Per default it will only handle characters from the actual locale of your server. 1 2 3 4 5 6 7 8 // using UTF-8 $filter = new Zend\Filter\StringToLower(’UTF-8’). // or give an array which can be useful when using a configuration $filter = new Zend\Filter\StringToLower(array(’encoding’ => ’UTF-8’)). Supported Options The following options are supported for Zend\Filter\StringToLower: • encoding: This option can be used to set an encoding which has to be used. Basic Usage This is a basic example: 1 2 3 4 $filter = new Zend\Filter\StringToLower().

Default Behavior 368 Chapter 79. 1 2 3 4 $filter = new Zend\Filter\StringToUpper(array(’encoding’ => ’UTF-8’)). Release 2. the default behavior will be invoked.0. // or do this afterwards $filter->setEncoding(’ISO-8859-1’). Using different character sets works the same as with StringToLower. print $filter->filter(’ This is (my) content: ’). which is to remove only whitespace from the beginning and end of the string. 79. Standard Filter Classes . print $filter->filter(’Sample’). // returns "SAMPLE" Different Encoded Strings Like the StringToLower filter. Basic Usage This is a basic example for using the StringToUpper filter: 1 2 3 4 $filter = new Zend\Filter\StringToUpper(). Supported Options The following options are supported for Zend\Filter\StringTrim: • charlist: List of characters to remove from the beginning and end of the string.18 StringTrim This filter modifies a given string such that certain characters are removed from the beginning and end. Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\StringTrim().Zend Framework 2 Documentation. Notice that the whitespace characters have been removed. this filter handles only characters from the actual locale of your server. If this is not set or is null.6 Supported Options The following options are supported for Zend\Filter\StringToUpper: • encoding: This option can be used to set an encoding which has to be used. The above example returns ‘This is (my) content:’.

use the setCharList() method. Notice that all newline characters have been removed. All other tags will be stripped from the given content. print $filter->filter(’ This is (my)‘‘\n\r‘‘content: ’). Using Zend\Filter\StripTags to make your site secure by stripping some unwanted tags will lead to unsecure and dangerous code. Supported Options There are no additional options for Zend\Filter\StripNewLines: Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\StripNewLines().Zend Framework 2 Documentation.19 StripNewLines This filter modifies a given string and removes all new line characters within that string. To set the desired character list after instantiation. Supported Options The following options are supported for Zend\Filter\StripTags: • allowAttribs: This option sets the attributes which are accepted. Release 2. • allowTags: This option sets the tags which are accepted. Warning: Be warned that Zend\Filter\StripTags should only be used to strip all available tags. The above example returns ‘This is (my) content:’. print $filter->filter(’ This is (my) content:’). You can also provide a Traversable or an array with a ‘charlist’ key.20 StripTags This filter can strip XML and HTML tags from given content. 79. All other attributes are stripped from the given content.0. 79. The getCharList() return the values set for charlist. Zend\Filter\StripTags must not be used to prevent XSS attacks.6 1 2 3 4 $filter = new Zend\Filter\StringTrim(’:’). // or new Zend\Filter\StringTrim(array(’charlist’ => ’:’)). 79. This filter is no replacement for using Tidy or HtmlPurifier. Notice that the whitespace characters and colon are removed. StripNewLines 369 . The above example returns ‘This is (my) content’.19.

print $filter->filter($input). By providing an array you can set multiple attributes at once. It strips all tags but img. This component does not replace the use of a proper configured html filter. 1 2 3 4 $filter = new Zend\Filter\StripTags(array(’allowAttribs’ => ’src’)).com’ width=’100’>picture</img>". 370 Chapter 79.Zend Framework 2 Documentation. As result you will get the stripped content ‘My content’. Standard Filter Classes .0.com’>link</a>". print $filter->filter(’<B>My content</B>’).com’>link</a>’ as result. Additionally from the img tag all attributes but src will be stripped. See the following example: 1 2 3 $filter = new Zend\Filter\StripTags().6 Basic Usage See the following example for the default behaviour of this filter: 1 2 3 $filter = new Zend\Filter\StripTags(). $input = "A text with <br/> a <img src=’picture.com">no ending tag’). This can be used for example to strip all tags but links from a text. By providing an array you can set multiple tags at once. The above will return ‘This contains’ with the rest being stripped. Warning: Do not use this feature to get a probably secure content. 1 2 3 4 $filter = new Zend\Filter\StripTags(array(’allowTags’ => ’a’)). It strips all tags but the link. Release 2. The above will return ‘A text with a <a href=’link. Allowing Defined Tags Zend\Filter\StripTags allows stripping of all but defined tags. When the content contains broken or partitial tags then the complete following content will be erased. print $filter->filter(’This contains <a href="http://example. The above will return ‘A text with a <img src=’picture. $input = "A text with <br/> a <a href=’link. Allowing Defined Attributes It is also possible to strip all but allowed attributes from a tag.com’>picture</img>’ as result. print $filter->filter($input).

If this is not set the separator will be a space character.1 CamelCaseToDash This filter modifies a given string such that ‘CamelCaseWords’ are converted to ‘camel-case-words’. Supported Options The following options are supported for Zend\Filter\Word\CamelCaseToSeparator: • separator: A separator char. The above example returns ‘this-is-my-content’. Supported Options There are no additional options for Zend\Filter\Word\CamelCaseToDash: Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Word\CamelCaseToDash().2 CamelCaseToSeparator This filter modifies a given string such that ‘CamelCaseWords’ are converted to ‘camel case words’. there are several classes specific to filtering word strings. 371 . 80. print $filter->filter(’ThisIsMyContent’). 80.CHAPTER EIGHTY WORD FILTERS In addition to the standard set of filters.

1 2 3 The above example returns ‘this is my content’. print $filter->filter(’ThisIsMyContent’).0. 80. Supported Options There are no additional options for Zend\Filter\Word\DashToCamelCase: 372 Chapter 80. The above example returns ‘this:is:my:content’.3 CamelCaseToUnderscore This filter modifies a given string such that ‘CamelCaseWords’ are converted to ‘camel_case_words’.Zend Framework 2 Documentation. print $filter->filter(’ThisIsMyContent’). Default Behavior $filter = new Zend\Filter\Word\CamelCaseToSeparator(). Supported Options There are no additional options for Zend\Filter\Word\CamelCaseToUnderscore: Basic usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Word\CamelCaseToUnderscore().4 DashToCamelCase This filter modifies a given string such that ‘words-with-dashes’ are converted to ‘WordsWithDashes’. The above example returns ‘this_is_my_content’. Word Filters . print $filter->filter(’ThisIsMyContent’).6 Basic Usage A basic example of usage is below: 1 2 3 4 $filter = new Zend\Filter\Word\CamelCaseToSeparator(’:’). Release 2. // or new Zend\Filter\Word\CamelCaseToSeparator(array(’separator’ => ’:’)). 80.

5.0. The above example returns ‘this+is+my+content’. // or new Zend\Filter\Word\CamelCaseToSeparator(array(’separator’ => ’+’)). print $filter->filter(’this-is-my-content’). 80. If this is not set the separator will be a space character. Default Behavior $filter = new Zend\Filter\Word\DashToSeparator().6 Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Word\DashToCamelCase().Zend Framework 2 Documentation. print $filter->filter(’this-is-my-content’). 80. 1 2 3 The above example returns ‘this is my content’. Supported Options There are no additional options for Zend\Filter\Word\DashToUnderscore: 80. Supported Options The following options are supported for Zend\Filter\Word\DashToSeparator: • separator: A separator char. Release 2.6 DashToUnderscore This filter modifies a given string such that ‘words-with-dashes’ are converted to ‘words_with_dashes’.5 DashToSeparator This filter modifies a given string such that ‘words-with-dashes’ are converted to ‘words with dashes’. The above example returns ‘ThisIsMyContent’. Basic Usage A basic example of usage is below: 1 2 3 4 $filter = new Zend\Filter\Word\DashToSeparator(’+’). print $filter->filter(’this-is-my-content’). DashToSeparator 373 .

80. print $filter->filter(’this:is:my:content’). Supported Options The following options are supported for Zend\Filter\Word\SeparatorToDash: • separator: A separator char. 80.6 Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Word\DashToUnderscore(). The above example returns ‘this_is_my_content’. 1 2 3 The above example returns ‘ThisIsMyContent’. // or new Zend\Filter\Word\SeparatorToCamelCase(array(’separator’ => ’:’)). If this is not set the separator will be a space character. Default Behavior $filter = new Zend\Filter\Word\SeparatorToCamelCase(). Word Filters . print $filter->filter(’this is my content’). 374 Chapter 80. Supported Options The following options are supported for Zend\Filter\Word\SeparatorToCamelCase: • separator: A separator char. Basic Usage A basic example of usage is below: 1 2 3 4 $filter = new Zend\Filter\Word\SeparatorToCamelCase(’:’).7 SeparatorToCamelCase This filter modifies a given string such that ‘words with separators’ are converted to ‘WordsWithSeparators’. If this is not set the separator will be a space character.Zend Framework 2 Documentation.0. print $filter->filter(’this-is-my-content’).8 SeparatorToDash This filter modifies a given string such that ‘words with separators’ are converted to ‘words-with-separators’. The above example returns ‘ThisIsMyContent’. Release 2.

9. If this is not set the separator will be a dash. print $filter->filter(’this is my content’). print $filter->filter(’this:is:my:content’). • replaceSeparator: The replace separator char. Release 2. 1 2 3 The above example returns ‘this-is-my-content’.6 Basic Usage A basic example of usage is below: 1 2 3 4 $filter = new Zend\Filter\Word\SeparatorToDash(’:’). Default Behavior $filter = new Zend\Filter\Word\SeparatorToDash(). print $filter->filter(’this is my content’). If this is not set the separator will be a space character. The above example returns ‘this-is-my-content’. SeparatorToSeparator 375 .0. print $filter->filter(’this:is:my:content’). // or new Zend\Filter\Word\SeparatorToDash(array(’separator’ => ’:’)). The above example returns ‘this+is+my+content’. Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Word\SeparatorToSeparator(’:’.9 SeparatorToSeparator This filter modifies a given string such that ‘words with separators’ are converted to ‘words-with-separators’. Supported Options The following options are supported for Zend\Filter\Word\SeparatorToSeparator: • searchSeparator: The search separator char. 80. Default Behaviour $filter = new Zend\Filter\Word\SeparatorToSeparator(). ’+’). 80. 1 2 3 The above example returns ‘this-is-my-content’.Zend Framework 2 Documentation.

print $filter->filter(’this_is_my_content’). 376 Chapter 80.10 UnderscoreToCamelCase This filter modifies a given string such that ‘words_with_underscores’ are converted to ‘WordsWithUnderscores’. If this is not set the separator will be a space character. Default Behavior $filter = new Zend\Filter\Word\UnderscoreToSeparator(). The above example returns ‘this+is+my+content’. // or new Zend\Filter\Word\CamelCaseToSeparator(array(’separator’ => ’+’)). print $filter->filter(’this_is_my_content’). Basic usage A basic example of usage is below: 1 2 3 4 $filter = new Zend\Filter\Word\UnderscoreToSeparator(’+’). print $filter->filter(’this_is_my_content’). 1 2 3 The above example returns ‘this is my content’.6 80.11 UnderscoreToSeparator This filter modifies a given string such that ‘words_with_underscorees’ are converted to ‘words with underscorees’. Supported Options There are no additional options for Zend\Filter\Word\UnderscoreToCamelCase: Basic Usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Word\UnderscoreToCamelCase(). Release 2. 80.0. The above example returns ‘ThisIsMyContent’.Zend Framework 2 Documentation. Supported Options The following options are supported for Zend\Filter\Word\UnderscoreToSeparator: • separator: A separator char. Word Filters .

Supported Options There are no additional options for Zend\Filter\Word\UnderscoreToDash: Basic usage A basic example of usage is below: 1 2 3 $filter = new Zend\Filter\Word\UnderscoreToDash(). UnderscoreToDash 377 . print $filter->filter(’this_is_my_content’).12 UnderscoreToDash This filter modifies a given string such that ‘words_with_underscores’ are converted to ‘words-with-underscores’.Zend Framework 2 Documentation. Release 2.12.6 80.0. 80. The above example returns ‘this-is-my-content’.

Release 2. Word Filters .6 378 Chapter 80.Zend Framework 2 Documentation.0.

and then any uppercase characters are converted to lowercase. The default value is 1000. 81. To add a filter that is known by the FilterPluginManager you can use the attachByName() method. Every filter that is used in a FilterChain must be know by this FilterPluginManager. Any object that implements Zend\Filter\FilterInterface may be used in a filter chain. 500). The following code illustrates how to chain together two filters for the submitted username: 1 2 3 4 5 6 7 // Create a filter chain and add filters to the chain $filterChain = new Zend\Filter\FilterChain(). the username is first removed of any non-alphabetic characters. $filterChain->attach(new Zend\Filter\Alpha()) ->attach(new Zend\Filter\StringToLower()). Filters are run in the order they were added to Zend\Filter\FilterChain. a login form accepts a username that should be only lowercase.2 Using the Plugin Manager To every FilterChain object an instance of the FilterPluginManager is attached. In the following example. $filterChain->attach(new Zend\Filter\Alpha()) ->attach(new Zend\Filter\StringToLower(). The first parameter is the name of the filter within the FilterPluginManager. 1 2 3 4 // Create a filter chain and add filters to the chain $filterChain = new Zend\Filter\FilterChain(). In the above example. any uppercase characters are converted to lowercase before any non-alphabetic characters are removed. Zend\Filter\FilterChain provides a simple method by which filters may be chained together. // Filter the username $username = $filterChain->filter($_POST[’username’]). 81. The second parameter takes any options for creating the filter instance.1 Setting Filter Chain Order For each filter added to the FilterChain you can set a priority to define the chain order. alphabetic characters. The third parameter is the priority. 379 . For example.CHAPTER EIGHTYONE FILTER CHAINS Often multiple filters should be applied to some value in a particular order.

Filter Chains . $filterChain->getPluginManager()->setInvokableClass( ’myNewFilter’. $filterChain->attachByName(’alpha’) ->attachByName(’stringtolower’. You can also add your own FilterPluginManager implementation. 500). 380 Chapter 81. $filterChain->setPluginManager(new MyFilterPluginManager()). ’MyCustom\Filter\MyNewFilter’ ). $filterChain->attach(new Zend\Filter\Alpha()) ->attach(new MyCustom\Filter\MyNewFilter()). $filterChain->attach(new Zend\Filter\Alpha()) ->attach(new MyCustom\Filter\MyNewFilter()). The following example shows how to add a custom filter to the FilterPluginManager and the FilterChain.Zend Framework 2 Documentation. Release 2. 1 2 3 4 $filterChain = new Zend\Filter\FilterChain(). array(’encoding’ => ’utf-8’).0. 1 2 3 4 5 6 $filterChain = new Zend\Filter\FilterChain().6 1 2 3 4 // Create a filter chain and add filters to the chain $filterChain = new Zend\Filter\FilterChain().

Otherwise. you’d specify only ‘Alpha‘ or ‘StringToLower‘. Static rules will replace with the text provided.CHAPTER EIGHTYTWO ZEND\FILTER\INFLECTOR Zend\Filter\Inflector is a general purpose tool for rules-based inflection of strings to a given target. $string = ’camelCasedWords’. Transforming MixedCase and camelCaseText to another format $inflector = new Zend\Filter\Inflector(’pages/:page. however. Each variable in the target can have zero or more rules associated with them. // pages/this_is_not_camel_cased. and you want to separate the words using a dash (‘-‘). As an example.html $string = ’this_is_not_camel_cased’. Rules may be either static or refer to a Zend\Filter class. ’StringToLower’). OS policies. instead of referring to them as ‘Zend\Filter\Alpha‘ or ‘Zend\Filter\StringToLower‘. // pages/camel-cased-words. 381 . These are specified by prefixing with a ‘:’: :script. or other reasons. A target is basically a string that defines placeholders for variables you wish to substitute.1 Operation An inflector requires a target and one or more rules. you perform inflection by calling filter() on the object instance. you then pass in an array of key and value pairs corresponding to the variables in the target. As an example. $filtered = $inflector->filter(array(’page’ => $string)). $inflector->setRules(array( ’:page’ => array(’Word\CamelCaseToDash’. Zend\Filter\Inflector implements Zend\Filter\FilterInterface. for readability. An inflector can do this for you. you may find you need to transform MixedCase or camelCasedWords into a path.:suffix’). When calling filter(). you also need to lower case this.html 1 2 3 4 5 6 7 8 9 10 11 12 13 82. you can use any Zend\Filter concrete implementations. $filtered = $inflector->filter(array(’page’ => $string)). Classes are typically specified using a short name indicating the filter name stripped of any common prefix. ’suffix’ => ’html’ )). a class matching the rule provided will be used to inflect the text.

you may want to re-set the target later (for instance. Placeholders take the form of an identifier. To use custom filters.phtml’). to modify the default inflector in core components. followed by a variable name: ‘:script’. To access filters with that prefix but which occur deeper in the hierarchy. Zend\Filter\Inflector . $inflector->setTarget(’layouts/:script. 382 Chapter 82. such as the various Word filters. $filters->addInvokableClass(’mungify’.2 Using Custom Filters Zend\Filter\Inflector uses Zend\Filter\FilterPluginManager to manage loading filters to use with inflection.#sfx’. you will set the target via the constructor.:suffix’. ’#’). you have two choices: reference them by fully qualified class name (e. My\Custom\Filter\Mungify). Release 2. simply strip off the Zend\Filter prefix: 1 2 // use Zend\Filter\Word\CamelCaseToDash as a rule $inflector->addRules(array(’script’ => ’Word\CamelCaseToDash’)). /** * Constructor * @return void */ public function __construct() { $this->_inflector = new Zend\Filter\Inflector().0.. // Via accessor: $inflector->setTargetReplacementIdentifier(’#’). you may wish to have a class member for your class that you can use to keep the inflector target updated – without needing to directly update the target each time (thus saving on method calls). 1 2 $filters = $inflector->getPluginManager(). null. etc.6 82. ’My\Custom\Filter\Mungify’). 82. However. filters registered with Zend\Filter\FilterPluginManager are available. Additionally. You can change the identifier using the setTargetReplacementIdentifier() method. Typically. or passing it as the third argument to the constructor: 1 2 3 4 5 // Via constructor: $inflector = new Zend\Filter\Inflector(’#foo/#bar. By default.g. such as the ViewRenderer or Zend\Layout).Zend Framework 2 Documentation. The filter() method looks for the identifier followed by the variable name being replaced. a colon (‘:’) by default. or manipulate the composed FilterPluginManager instance. setTargetReference() allows you to do this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Foo { /** * @var string Inflector target */ protected $_target = ’foo/:bar/:baz. ‘:path’.3 Setting the Inflector Target The inflector target is a string with some placeholders for variables. setTarget() can be used for this purpose: 1 2 $inflector = $layout->getInflector().

The setStaticRuleReference() method is used to accomplish this: 1 2 3 4 5 6 7 8 9 10 class Foo { /** * @var string Suffix */ protected $_suffix = ’phtml’.4. Release 2. If ‘module’ were added before ‘moduleDir’. either one-byone. ‘module’ will match part of ‘moduleDir’ and process it leaving ‘Dir’ inside of the target uninflected.Zend Framework 2 Documentation. must be added before least specific names. or all-at-once. or names that might contain other rule names. the order is very important. there are two types of rules: static and filter-based. assuming the two rule names ‘moduleDir’ and ‘module’. $inflector->setStaticRule(’suffix’. Much like the target itself.4 Inflection Rules As mentioned in the introduction. Inflection Rules 383 . 82. More specific names.:suffix’). you can also bind a static rule to a reference. Use the setStaticRule() method to set or modify the rule: 1 2 3 4 5 $inflector = new Zend\Filter\Inflector(’:script. For example. return $this. this is often useful when your class uses an inflector internally. } /** * Set target. updates target in inflector * * @param string $target * @return Foo */ public function setTarget($target) { $this->_target = $target. the ‘moduleDir’ rule should appear before module since ‘module’ is contained within ‘moduleDir’. and you don’t want your users to need to fetch the inflector in order to update it. /** * Constructor * @return void 82. but which you want to allow the developer to modify. ’phtml’). } } 82.6 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 $this->_inflector->setTargetReference($this->_target). Note: It is important to note that regardless of the method in which you add rules to the inflector. use them when you have a segment in the target that will typically be static.1 Static Rules Static rules do simple string substitution.0.4. ’php’). allowing you to update a single variable instead of require a method call. // change it later: $inflector->setStaticRule(’suffix’.

new Zend\Filter\StringToLower()).2 Filter Inflector Rules Zend\Filter filters may be used as inflector rules as well. so be careful to register them in an order that makes sense for the data you receive.0. • Filter object. Zend\Filter\Inflector‘s addRules() and setRules() method allow this. These filters are processed in order. • Array. updates suffix static rule in inflector * * @param string $suffix * @return Foo */ public function setSuffix($suffix) { $this->_suffix = $suffix. or a class name segment minus any prefix set in the inflector’s plugin loader (by default. 384 Chapter 82. An array of one or more strings or filter objects as defined above. Any object instance implementing Zend\Filter\FilterInterface may be passed as a filter.6 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 */ public function __construct() { $this->_inflector = new Zend\Filter\Inflector(’:script. Release 2.:suffix’). these are bound to a target variable. return $this. Rules may be added using setFilterRule() (which overwrites any previous rules for that variable) or addFilterRule() (which appends the new rule to any existing rule for that variable). new Zend\Filter\StringToLower() )). $this->_inflector->setStaticRuleReference(’suffix’. ’Word\CamelCaseToDash’). // Set rules en-masse $inflector->setFilterRule(’script’. minus the ‘Zend\Filter‘ prefix). // Set rule to use Zend\Filter\Word\CamelCaseToDash filter $inflector->setFilterRule(’script’. Filters are specified in one of the following ways: • String. 1 2 3 4 5 6 7 8 9 10 11 12 13 $inflector = new Zend\Filter\Inflector(’:script.4. The string may be a filter class name.4. // Add rule to lowercase string $inflector->addFilterRule(’script’. it’s easier to set many rules at once than to configure a single variable and its inflection rules at a time. } /** * Set suffix. unlike static rules. you may define multiple filters to use when inflecting. $this->_suffix).:suffix’). array( ’Word\CamelCaseToDash’.Zend Framework 2 Documentation. Just like static rules. } } 82. Zend\Filter\Inflector . 82.3 Setting Many Rules At Once Typically.

alternately. By default.6 Using a Traversable or an array with Zend\Filter\Inflector You can use a Traversable or an array to set rules and other object state in your inflectors.0. • clearRules() will clear all currently registered rules. • setPluginManager() can be used when you have configured your own Zend\Filter\FilterPluginManager instance and wish to use it with Zend\Filter\Inflector. $index) fetches a single rule for a given variable. you may specify a class name of a class that extends the FilterPluginManager. this can be useful for fetching a specific filter rule for a variable that has a filter chain. • pluginManager specifies the Zend\Filter\FilterPluginManager instance or extension to use for obtaining plugins.5 Utility Methods Zend\Filter\Inflector has a number of utility methods for retrieving and setting the plugin loader.5.Zend Framework 2 Documentation. $index must be passed. • No prefix: static rule. 82. either by passing a Traversable object or an array to the constructor or setOptions(). or just the rules for a single variable. where the rule may be whatever the type of rule accepts (string. • throwTargetExceptionsOn should be a boolean indicating whether or not to throw exceptions when a replacement identifier is still present after inflection. 1 2 3 4 5 6 7 8 9 82. according to the following notation: • ‘:’ prefix: filter rules.’StringToLower’). 82. manipulating and retrieving rules. // Static rule: ’suffix’ => ’phtml’ )). • setThrowTargetExceptionsOn() can be used to control whether or not filter() throws an exception when a given replacement identifier passed to it is not found in the target. or array). • getRule($spec. isThrowTargetExceptionsOn() will tell you what the current value is. ’:action’ => array(’CamelCaseToUnderscore’.6 Each method takes an array of variable and rule pairs. filter object. Variable names accept a special notation to allow setting static rules and filter rules. no exceptions are thrown. and controlling if and when exceptions are thrown. The following settings may be specified: • target specifies the inflection target. getPluginManager() retrieves the currently set one. Utility Methods 385 . Release 2. Setting Multiple Rules at Once // Could also use setRules() with this notation: $inflector->addRules(array( // filter rules: ’:controller’ => array(’CamelCaseToUnderscore’. • getRules($spec = null) can be used to retrieve all registered rules for all variables.’StringToLower’).

Using a Traversable or an array with Zend\Filter\Inflector // With the constructor: $options.6 • targetReplacementIdentifier specifies the character to use when identifying replacement variables in the target string. consistent with addRules(). 1 2 3 4 5 6 7 386 Chapter 82.0. it should consist of keys that specify either values or arrays of values. // Or with setOptions(): $inflector = new Zend\Filter\Inflector(). Zend\Filter\Inflector . Release 2. • rules specifies an array of inflection rules.Zend Framework 2 Documentation. // implements Traversable $inflector = new Zend\Filter\Inflector($options). $inflector->setOptions($options).

The following example demonstrates how to write a custom filter: 1 2 3 4 5 6 7 8 9 10 11 namespace Application\Filter. that may be implemented by user classes.CHAPTER EIGHTYTHREE WRITING FILTERS Zend\Filter supplies a set of commonly needed filters. } } To attach an instance of the filter defined above to a filter chain: 1 2 $filterChain = new Zend\Filter\FilterChain(). 387 . Zend\Filter\FilterInterface defines a single method. but developers will often need to write custom filters for their particular use cases. filter(). The task of writing a custom filter is facilitated by implementing Zend\Filter\FilterInterface. $filterChain->attach(new Application\Filter\MyFilter()). class MyFilter implements Zend\Filter\FilterInterface { public function filter($value) { // perform some transformation upon $value to arrive on $valueFiltered return $valueFiltered.

0.6 388 Chapter 83. Writing Filters . Release 2.Zend Framework 2 Documentation.

which extend from Fieldsets (and thus Elements). Zend\Form\Annotation\AnnotationBuilder can then be used to build the various objects you need. and the related input filter. and one or more hydrator implementations. The default Form implementation is backed by a factory to facilitate extension and ease the process of form creation. detailing the various input filter definitions. and the Captcha element. used to prevent Cross Site Request Forgery attacks. The code related to forms can often spread between a variety of concerns: a form definition. A small number of specialized elements are provided for accomplishing application-centric tasks. As such. an input filter definition. It composes a thin layer of objects representing form elements. • Fieldsets. and/or forms. These accept elements. These include the Csrf element. attributes. • Forms. 389 . They provide data and object binding. fieldsets. used to display and validate CAPTCHAs. To facilitate usage with the view layer. fieldsets. and compose InputFilters. and hydrators that should all be used together. and a small number of methods for binding data to and from the form and attached objects. the Zend\Form component also aggregates a number of form-specific view helpers. To simplify the situation. finding the various bits of code and how they relate can become tedious. which extend from Elements. forms. and use the attributes they compose to render markup. a domain model class. you can also annotate your domain model class. but allow composing other fieldsets and elements.CHAPTER EIGHTYFOUR INTRODUCTION TO ZEND\FORM Zend\Form is intended primarily as a bridge between your domain models and the View Layer. Data binding is done via ZendStdlibHydrator. The Zend\Form component consists of the following objects: • Elements. an InputFilter. which simply consist of a name and attributes. A Factory is provided to facilitate creation of elements.

Release 2. Introduction to Zend\Form .Zend Framework 2 Documentation.0.6 390 Chapter 84.

CHAPTER EIGHTYFIVE FORM QUICK START Forms are relatively easy to create. If you want to simplify your work even more. Zend\Form\Fieldset. Zend\Form\Element. Form validation is as easy as providing an array of data to the setData() method. each element or fieldset requires a name. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 use use use use use use Zend\Captcha. and forms and wiring them together. $message = new Element\Textarea(’message’). $subject = new Element(’subject’). At the bare minimum. $captcha->setCaptcha(new Captcha\Dumb()). 391 . $subject->setAttributes(array( ’type’ => ’text’ )). it will be populated from the validated values. you can simply start creating elements. 85. $subject->setLabel(’Subject’). The form itself will also typically compose an InputFilter– which you can also conveniently create directly in the form via a factory. on successful validation. $name = new Element(’name’). you’ll also provide some attributes to hint to the view layer how it might render the item.1 Programmatic Form Creation If nothing else. $email = new Element\Email(’email’). $name->setAttributes(array( ’type’ => ’text’ )). Zend\InputFilter\Input. Zend\InputFilter\InputFilter. $email->setLabel(’Your email address’). Zend\Form\Form. fieldsets. Individual elements can hint as to what defaults to use when generating a related input for the input filter. you can bind an object to the form. $name->setLabel(’Your name’). $captcha->setLabel(’Please verify you are human’). $message->setLabel(’Message’). typically. $captcha = new Element\Captcha(’captcha’).

$details->add($subject). $form->add($sender). $form->add($message). $form = new Form(’contact’). $send->setAttributes(array( ’type’ => ’submit’ )). 85. using the Factory. $sender->add($email). $form->add($captcha).0. one for the sender information. let’s alter the above slightly. $sender->add($name). // attach all inputs $form->setInputFilter($inputFilter). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $sender = new Fieldset(’sender’). $form->add($subject). $form->add($send). Form Quick Start . $form->add($csrf). Regardles of approach.Zend Framework 2 Documentation. $send = new Element(’send’). and all others $inputFilter = new InputFilter().6 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 $csrf = new Element\Csrf(’security’). $form->add($send). $factory = new Factory(). $details->add($message). $form->add($name). We’ll create two fieldsets.. $nameInput = new Input(’name’). $send->setValue(’Submit’). you can simply pass the configuration to the factory and be done. $details = new Fieldset(’details’). This is particularly nice if you want to store your forms as pure configuration.2 Creation via Factory You can create the entire form. 1 2 3 4 5 6 use Zend\Form\Factory. $form->add($details). Release 2. and another for the message details. ’elements’ => array( 392 Chapter 85. and input filter.. this can be tedious. $form->add($captcha). as you can see. $form = new Form(’contact’). // configure input. As a demonstration of fieldsets. $form = $factory->createForm(array( ’hydrator’ => ’Zend\Stdlib\Hydrator\ArraySerializable’. $form->add($email). $form->add($csrf).

). ). ’options’ => array( ’label’ => ’Your email address’.’. ). array( ’spec’ => array( ’name’ => ’subject’. ). ) ). 85.0. ’attributes’ => array( ’type’ => ’text’ ). ’options’ => array( ’label’ => ’Message’. ). ). array( ’spec’ => array( ’type’ => ’Zend\Form\Element\Captcha’. ).6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 array( ’spec’ => array( ’name’ => ’name’. ). ) ).2. ’attributes’ => array( ’type’ => ’text’. ’name’ => ’captcha’. ) ). array( ’spec’ => array( ’type’ => ’Zend\Form\Element\Textarea’.Zend Framework 2 Documentation. ). ’options’ => array( ’label’ => ’Your name’. ’options’ => array( ’label’ => ’Please verify you are human. ’options’ => array( ’label’ => ’Subject’. ’name’ => ’message’. ). array( ’spec’ => array( ’type’ => ’Zend\Form\Element\Csrf’. ’name’ => ’security’. ’captcha’ => array( ’class’ => ’Dumb’. ). Creation via Factory 393 . ). ). ’name’ => ’email’. array( ’spec’ => array( ’type’ => ’Zend\Form\Element\Email’. Release 2.

If we wanted to use fieldsets. ). ’elements’ => array( array( ’name’ => ’subject’. ).. ’attributes’ => array( ’type’ => ’text’ ). they’d go here. ). fieldsets contain * "elements" and "fieldsets" keys. ’elements’ => array( array( ’name’ => ’name’. Form Quick Start . 394 Chapter 85. Release 2. $factory = new Factory(). we could do the following: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 use Zend\Form\Factory.Zend Framework 2 Documentation. ). ). */ ). ). ). array( ’name’ => ’details’. array( ’type’ => ’Zend\Form\Element\Email’.6 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 array( ’spec’ => array( ’name’ => ’send’. ). ’options’ => array( ’label’ => ’Your email address’. ). ). as we demonstrated in the previous example. ’name’ => ’email’. ’fieldsets’ => array( ).. )). and potentially a "type" * key indicating the specific FieldsetInterface * implementation to use. $form = $factory->createForm(array( ’hydrator’ => ’Zend\Stdlib\Hydrator\ArraySerializable’ ’fieldsets’ => array( array( ’name’ => ’sender’.0. ’attributes’ => array( ’type’ => ’submit’. /* If we had fieldsets. ’options’ => array( ’label’ => ’Your name’. ’value’ => ’Submit’. */ // Configuration to pass on to // Zend\InputFilter\Factory::createInputFilter() ’input_filter’ => array( /* .

Note that the chief difference is nesting. ’captcha’ => array( ’class’ => ’Dumb’. and define your form internally. ’attributes’ => array( ’type’ => ’text’. 85. ’. This has the benefit of allowing a mixture of programmatic and factory-backed creation. ).3 Factory-backed Form Extension The default Form implementation is backed by the Factory. ’attributes’ => array( ’type’ => ’submit’.6 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 ’options’ => array( ’label’ => ’Subject’. ’name’ => ’captcha’. ). otherwise. ). ). ). ). array( ’name’ => ’send’. ’options’ => array( ’label’ => ’Please verify you are human. and usage of significant whitespace. the information is basically the same. ’value’ => ’Submit’. */ ). ’name’ => ’security’. array( ’type’ => ’Zend\Form\Element\Textarea’.. )). Factory-backed Form Extension 395 . ). ). array( ’type’ => ’Zend\Form\Element\Csrf’. // Configuration to pass on to // Zend\InputFilter\Factory::createInputFilter() ’input_filter’ => array( /* . ’elements’ => array( array( ’type’ => ’Zend\Form\Element\Captcha’. ). ’options’ => array( ’label’ => ’Message’. The chief benefits to using the Factory are allowing you to store definitions in configuration. ). ).3. ). Release 2. ). as well as defining 85.Zend Framework 2 Documentation. ). ).. This allows you to extend it.0.

class ContactForm extends Form { protected $captcha. use Zend\Form\Form. public function setCaptcha(CaptchaAdapter $captcha) { $this->captcha = $captcha. ’options’ => array( ’label’ => ’Your email address’. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 namespace Contact. Release 2.6 a form for re-use in your application. use Zend\Captcha\AdapterInterface as CaptchaAdapter. ’options’ => array( 396 Chapter 85. $this->add(array( ’type’ => ’Zend\Form\Element\Textarea’. )). ’attributes’ => array( ’type’ => ’text’. Form Quick Start . ). ).Zend Framework 2 Documentation. ’options’ => array( ’label’ => ’Your name’. from which the appropriate object will be built. ). $this->add(array( ’type’ => ’Zend\Form\Element\Email’. ’options’ => array( ’label’ => ’Message’. } public { // // // function prepareElements() add() can take either an Element/Fieldset instance. ). use Zend\Form\Element. ’name’ => ’captcha’. $this->add(array( ’name’ => ’name’. )). or a specification. $this->add(array( ’name’ => ’subject’. $this->add(array( ’type’ => ’Zend\Form\Element\Captcha’. ). ’options’ => array( ’label’ => ’Subject’. ’name’ => ’email’. ’attributes’ => array( ’type’ => ’text’. )). ). ’name’ => ’message’.0. )).

or // lazy-create it in the getInputFilter() method. ’attributes’ => array( ’type’ => ’submit’. First. which could then have bearing on how elements. you can retrieve the error messages. ’captcha’ => $this->captcha. 1 2 3 4 $filter = $form->getInputFilter(). Validating Forms 397 . 85. // We could also define the input filter here. } } You’ll note that this example introduces a method. ). $rawValues = $filter->getRawValues().4. the form must have an input filter attached. etc. ). In an MVC application. In this case. by accessing the composed input filter. This is done to allow altering and/or configuring either the form or input filter factory instances. Third.Zend Framework 2 Documentation. $form->setInputFilter(new Contact\ContactFilter()). If invalid. you might try: $data = $request->getPost(). $this->add(array( ’name’ => ’send’. )).6 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 ’label’ => ’Please verify you are human. Release 2.’. } You can get the raw data if you want. )). ’value’ => ’Submit’. // Get the data. if any. prepareElements(). allowing us to configure it elsewhere in our application and inject it into the form. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $form = new Contact\ContactForm(). $this->add(new Element\Csrf(’security’)).4 Validating Forms Validating forms requires three steps. 85. it also allows injection of the CAPTCHA adapter. // Validate the form if ($form->isValid()) { $validatedData = $form->getData(). inject one. you validate the form. are created. $nameRawValue = $filter->getRawValue(’name’). you must inject the data to validate into the form. inputs. // If the form doesn’t define an input filter by default.0. Second. // for GET (or query string) data $form->setData($data). // for POST data $data = $request->getQuery(). } else { $messages = $form->getMessages().

If no input or input filter is provided in the input filter for that element. . } return $this->validator. /** * @var ValidatorInterface */ protected $validator. use use use use Zend\Form\Element. here is how the Zend\Form\Element\Color element is defined: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 namespace Zend\Form\Element. you’ll create elements that you expect to behave in the same way on each usage. url. For instance. Zend\InputFilter\InputProviderInterface. the getInputSpecification() method should return data to be used by the input filter factory to create an input.5 Hinting to the Input Filter Often. Release 2. they must implement Zend\InputFilter\InputProviderInterface. ). and the default factory composes an input filter factory. one of the following must occur. and for which you’ll want specific filters or validation as well. color. } 398 Chapter 85. Zend\Validator\ValidatorInterface. Zend\Validator\Regex as RegexValidator. for fieldsets. For elements. Every HTML5 (email.Zend Framework 2 Documentation. In the case of an element. Since the input filter is a separate object. To do so. /** * Get validator * * @return ValidatorInterface */ protected function getValidator() { if (null === $this->validator) { $this->validator = new RegexValidator(’/^#[0-9a-fA-F]{6}$/’). ) elements have a built-in element that use this logic.6 85. which defines a getInputFilterSpecification() method. Form Quick Start . which defines a getInputSpecification() method. these hints will be retrieved and used to create them. . /** Zend * @category Zend_Form * @package @subpackage Element * */ class Color extends Element implements InputProviderInterface { /** * Seed attributes * * @var array */ protected $attributes = array( ’type’ => ’color’. you can have your elements and/or fieldsets hint to the input filter. how can you achieve these latter points? Because the default form implementation composes a factory.0. they must implement Zend\InputFilter\InputFilterProviderInterface.

the difference is that getInputFilterSpecification() must return configuration for an input filter. ).6 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 /** * Provide default input rules for this element * * Attaches an email validator. ’email’ => array( ’required’ => true. ’filters’ => array( array(’name’ => ’Zend\Filter\StringTrim’). array(’name’ => ’Zend\Filter\StringToLower’). ). Release 2.Zend Framework 2 Documentation.0. Hinting to the Input Filter 399 . ). or directly instantiate them. use Zend\InputFilter\InputFilterProviderInterface. } } The above would hint to the input filter to create and attach an input named after the element. ’filters’ => array( array(’name’ => ’Zend\Filter\StringTrim’). ).5. you do very similarly. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 namespace Contact\Form. ’validators’ => array( new Validator\Email(). class SenderFieldset extends Fieldset implements InputFilterProviderInterface { public function getInputFilterSpecification() { return array( ’name’ => array( ’required’ => true. ’required’ => true. ). ’validators’ => array( $this->getValidator(). ). ’filters’ => array( array(’name’ => ’Zend\Filter\StringTrim’). * * @return array */ public function getInputSpecification() { return array( ’name’ => $this->getName(). For fieldsets. ). use Zend\Form\Fieldset. marking it as required. and giving it a StringTrim and StringToLower filters and a Regex validator. ). } } 85. ). Note that you can either rely on the input filter to create filters and validators.

’subject’ => ’[Contact Form] \’sup?’. the following happens: • The composed Hydrator calls extract() on the object. // ’email’ => ’j. $contact[’message’] = ’Type your message here’.6 Binding an object As noted in the intro. • If isValid() is successful (and the bindOnValidate flag is enabled. // ) // only as an ArrayObject } When an object is bound to the form.0. When you bind() an object to the form. and elements re-usable trivially in your applications. $form->bind($contact). and uses the values returned. if setData() has not been previously set. forms in Zend Framework bridge the domain model and the view layer. • If the object implements Zend\InputFilter\InputFilterAwareInterface. ’email’ => ’j. 400 Chapter 85. fieldsets. to populate the value attributes of all elements. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 $contact = new ArrayObject. the form will recursively extract the values. This is easier to understand in practice. $form->setData($data).6 Specifications are a great way to make forms. In fact. Form Quick Start . $form = new Contact\ContactForm.doe@example. • When isValid() is called. calling getData() will return that object by default. the input filter it composes will be used instead of the one composed on the form. Release 2.doe@example. // ’message’ => ’Type your message here’. ). $data = $form->getData(FormInterface::VALUES_AS_ARRAY). the form uses the composed Hydrator to extract values from the object.Zend Framework 2 Documentation. then the Hydrator will be passed the validated values to use to hydrate the bound object. you can pass the FormInterface::VALUES_AS_ARRAY flag to the method. (If you do not want this behavior. and uses those during validation. call setBindOnValidate(FormInterface::BIND_MANUAL)). the Captcha and Csrf elements define specifications in order to ensure they can work without additional user configuration! 85. if ($form->isValid()) { // $contact now looks like: // array( // ’name’ => ’John Doe’.tld’. // form now has default values for // ’subject’ and ’message’ $data = array( ’name’ => ’John Doe’. if any. If a form contains a fieldset that itself contains another fieldset. If you want to return an associative array instead. // ’subject’ => ’[Contact Form] \’sup?’. which is true by default).tld’. $contact[’subject’] = ’[Contact Form] ’. Let’s see that in action. 1 2 use Zend\Form\FormInterface.

$name->getOption(’label’). $form->setAttribute(’action’. We’ve discussed the domain model binding. interface HydratorInterface { /** @return array */ public function extract($object). $form->prepare(). they will inspect the attributes. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <?php // within a view script $form = $this->form. Typically. Rendering 401 .7 Rendering As noted previously. forms are meant to bridge the domain model and view layer. // Render the opening tag echo $this->form()->openTag($form). echo $this->formElementErrors($name). ?></div> <div class="form_element"> <?php $subject = $form->get(’subject’). echo $this->formInput($name). and implementation is as simple as implementing Zend\Stdlib\Hydrator\HydratorInterface. When preparing to render.Zend Framework 2 Documentation. echo $formLabel->closeTag(). These accept the various form objects. and introspect them in order to generate markup.. you will likely want to call prepare(). ?> <div class="form_element"> <?php $name = $form->get(’name’). echo $formLabel->openTag() . but what about the view? The form component ships a set of form-specific view helpers. they may look at other properties and composed objects. ’post’). // Set the method attribute for the form $form->setAttribute(’method’. $subject->getOption(’label’).. The simplest view helpers available are Form. and FormElementErrors. and will likely in the future munge names to allow for scoped[array][notation]. $this->url(’contact/process’)). echo $formLabel->openTag() . 85. $object).0. FormElement. FormLabel. which looks like this: 1 2 3 4 5 6 7 8 namespace Zend\Stdlib\Hydrator. // Get the form label plugin $formLabel = $this->plugin(’formLabel’). public function hydrate(array $data. // Assuming the "contact/process" route exists. This method ensures that certain injections are done.7. Let’s use them to display the contact form. } 85.6 Zend Framework ships several standard hydrators. but in special cases. Release 2.

the element itself using the FormElement helper. or create your own. echo $formLabel->closeTag(). echo $formLabel->openTag() . echo $this->formCaptcha($captcha).Zend Framework 2 Documentation. This view helper automatically renders a label (if present). however. ?> <div class="form_element"> <?php 402 Chapter 85. echo $formLabel->closeTag(). Form Quick Start . While we do not currently provide a singleline form view helper (as this reduces the form customization). ?></div> <div class="form_element"> <?php $captcha = $form->get(’captcha’). First. // Assuming the "contact/process" route exists. $captcha->getOption(’label’). echo $this->formTextarea($message). we use helpers to both open and close the form and label tags. // Render the opening tag echo $this->form()->openTag($form). Finally.. echo $formLabel->openTag() . Here is the previous form.0. echo $this->formElementErrors($captcha). we could easily create a partial view script or a composite helper to reduce boilerplate. Second. note that not all elements are created equal – the CSRF and submit elements don’t need labels or error messages necessarily. the simplest and most recommended way to render your form is by using the FormRow view helper. // Set the method attribute for the form $form->setAttribute(’method’. $form->setAttribute(’action’. echo $formLabel->closeTag(). If you introduce new form view helpers. echo $this->formElementErrors($subject). you’ll need to extend the FormElement helper. $message->getOption(’label’). as well as any errors that could arise. $form->prepare(). there’s a lot of repetition happening here. echo $this->formElementErrors($message). Release 2.6 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 echo $this->formInput($subject). it can only guess what specific form helper to delegate to based on the list it has. However. Third. your view files can quickly become long and repetitive to write. ’post’). ?></div> <?php echo $this->formElement($form->get(’security’)) ?> <?php echo $this->formElement($form->get(’send’)) ?> <?php echo $this->form()->closeTag() ?> There are a few things to note about this. rewritten to take advantage of this helper : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php // within a view script $form = $this->form. to prevent confusion in IDEs and editors when syntax highlighting. ?></div> <div class="form_element"> <?php $message = $form->get(’message’). note that the FormElement helper tries to do the right thing – it delegates actual markup generation to other view helpers. $this->url(’contact/process’))..

?></div> <div class="form_element"> <?php $captcha = $form->get(’captcha’). and hence allowing modern browsers to perform automatic validation.0.6 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 $name = $form->get(’name’). echo $this->formRow($message). Release 2. please note that adding those attributes does not automatically add Zend validators to the form’s input filter. echo $this->formRow($name. ?></div> <?php echo $this->formElement($form->get(’security’)) ?> <?php echo $this->formElement($form->get(’send’)) ?> <?php echo $this->form()->closeTag() ?> Note that FormRow helper automatically prepends the label. ?></div> 85. However. ’options’ => array( ’label’ => ’Your phone number’ ). you can pass an optional parameter to the FormRow view helper : 1 2 3 4 5 <div class="form_element"> <?php $name = $form->get(’name’). **’append’**). echo $this->formRow($subject). 1 2 3 4 5 6 7 8 9 10 11 $form->add(array( ’name’ => ’phoneNumber’. If you want it to be rendered after the element itself.7.1 Taking advantage of HTML5 input attributes HTML5 brings a lot of exciting features. You still need to manually add them. 85. echo $this->formRow($name). ’attributes’ => array( ’type’ => ’tel’ ’required’ => ’required’. Rendering 403 . ]?[0-9]{2}){4}$’ ) )). one of them being a simplified client form validations. View helpers will automatically render those attributes. echo $this->formRow($captcha).Zend Framework 2 Documentation. Adding HTML5 attributes is simple as you just need to add specify the attributes.7. ’pattern’ => ’^0[1-68]([-. ?></div> <div class="form_element"> <?php $message = $form->get(’message’). ?></div> <div class="form_element"> <?php $subject = $form->get(’subject’).

in a JSON object format: @Attributes({"class":"zend_form". $form->setData($data). "subject". ’email’. When your form contains nested fieldsets. ’message’). 1 2 use Zend\Form\FormInterface. • Attributes: specify the form. as client validation can be easily fooled. } If you later want to reset the form to validate all. Release 2. ’subject’. 85. ’lastname’ ) )).6 > Note: although client validation is nice from a user experience point of view. the Csrf. } 85. an input filter for validating it. This annotation requires an associative array of values. You can define the following behaviors with the shipped annotations in Zend\Form: • AllowEmpty: mark an input as allowing an empty value. $form->setValidationGroup(FormInterface::VALIDATE_ALL). Form Quick Start .0.9 Using Annotations Creating a complete forms solution can often be tedious: you’ll create some domain model object. it has to be used in addition with server validation. As an example.Zend Framework 2 Documentation. in this case. a form object for providing a representation for it. 404 Chapter 85. and "message" values $data = $form->getData(). simply pass the FormInterface::VALIDATE_ALL flag to the setValidationGroup() method. if ($form->isValid()) { // Contains only the "name". let’s say we’re re-using our contact form over a web service."type":"text"}). allowing us to perform this operation. Wouldn’t it be nice to have a central place to define all of these? Annotations allow us to solve this problem. if ($form->isValid()) { // Contains only the "firstname" and "lastname" values from the // "profile" fieldset $data = $form->getData(). "email". 1 2 3 4 5 6 $form->setValidationGroup(’name’. This annotation does not require a value. and shouldn’t be validated. Captcha.8 Validation Groups Sometimes you want to validate only a subset of form elements. fieldset. and submit button elements are not of interest. $form->setData($data). you can use an array notation to validate only a subset of the fieldsets : 1 2 3 4 5 6 7 8 9 10 11 12 $form->setValidationGroup(array( ’profile’ => array( ’firstname’. Zend\Form provides a proxy method to the underlying InputFilter‘s setValidationGroup() method. and potentially a hydrator for mapping the form elements and fieldsets to the domain model. or element attributes.

Typically. The simplest way to install Doctrine\Common is if you are using Composer. • Flags: flags to pass to the fieldset or form composing an element or fieldset. so this annotation is mainly present to allow disabling a requirement. Expects an associative array of values. or form. • Options: options to pass to the fieldset or form that are used to inform behavior – things that are not attributes. If you’re not using Composer. • ErrorMessage: specify the error message to return for an element in the case of a failed validation. "options": {"casting":true}}). The annotation expects an associative array: @Options({"label": "Username:"}). and an “options” key pointing to an associatve array of filter options for the constructor: @Filter({"name": "Boolean". • Filter: provide a specification for a filter to use on a given element. Release 2. • Hydrator: specify the hydrator class to use for this given form or fieldset.phar update to install the dependency. Expects a string value indicating the class for the object being composed. Using Annotations 405 . Here’s a simple example. these are usually used to specify the name or priority. A string value is expected. you simply include them in your class and/or property docblocks. "options": {"min":3. you can make them as long or as short as you want depending on what you import. or form. A string value is expected. all elements are required. The annotation expects an associative array: @Flags({"priority": 100}). • InputFilter: specify the input filter class to use for this given form or fieldset. CAPTCHA adapters. fieldset. • Exclude: mark a property to exclude from the form or fieldset. This annotation may be specified multiple times. 1 2 3 4 5 6 7 use Zend\Form\Annotation. Then run php composer. • Type: indicate the class to use for the current element. To use annotations. Expects an associative array of values. etc.0. This annotation does not require a value. Expects a string value.json and add the following line to the require section: "doctrine/common": ">=2.1". "max": 25}}). • Name: specify the name of the current element. By default.9. this is used if a property references another object. with a “name” key pointing to a string filter name. • Input: specify the input class to use for this given element. with a “name” key pointing to a string validator name. fieldset. /** * @Annotation\Name("user") * @Annotation\Hydrator("Zend\Stdlib\Hydrator\ObjectProperty") */ class User 85.Zend Framework 2 Documentation. Annotation names will be resolved according to the import statements in your class. A string value is expected. which contains an annotation parsering engine. This annotation may be specified multiple times. • Required: indicate whether an element is required. e.g. simply update your composer.6 • ComposedObject: specify another object with annotations to parse. and an “options” key pointing to an associatve array of validator options for the constructor: @Validator({"name": "StringLength". as such. A boolean value is expected. which will then be added to your form as an additional fieldset. visit the Doctrine project website for more details on installation. A string value is expected. • Validator: provide a specification for a validator to use on a given element. labels. Note: Form annotations require Doctrine\Common. A string value is expected.

To use the above. and likely a CSRF-protection element. “username” and “email”. The “email” element will be of type Zend\Form\Element\Email. 406 Chapter 85.Zend Framework 2 Documentation. We recommend creating a fieldset with common elements such as these that you can then attach to the form you build via annotations. Note: You’re not done In all likelihood. "options":{"min":1. "options":{"pattern":"/^[a-zA-Z][a-zA-Z0-9_-]{0. $form = $builder->createForm(’User’). and a Regex validator asserting it follows a specific accepted pattern. $builder = new AnnotationBuilder(). we need Zend\Form\Annotation\AnnotationBuilder: 1 2 3 4 use Zend\Form\Annotation\AnnotationBuilder. which uses the hydrator Zend\Stdlib\Hydrator\ObjectProperty. and have the label “Your email address:”. and a label “Username:”. Release 2. At this point.0. The form element itself will have an attribute “type” with value “text” (a text element). you have a form with the appropriate hydrator attached. an input filter with the appropriate inputs. The “username” element will have an associated input that has a StringTrim filter. } The above will hint to the annotation build to create a form with name “user”.24}$/"} * @Annotation\Attributes({"type":"text"}) * @Annotation\Options({"label":"Username:"}) */ public $username. "max":25}}) * @Annotation\Validator({"name":"Regex". That form will have two elements.6 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 { /** * @Annotation\Exclude() */ public $id. you’ll need to add some more elements to the form you construct. and all elements. and two validators: a StringLength validator indicating the username is between 1 and 25 characters. /** * @Annotation\Filter({"name":"StringTrim"}) * @Annotation\Validator({"name":"StringLength". For example. Form Quick Start . /** * @Annotation\Type("Zend\Form\Element\Email") * @Annotation\Options({"label":"Your email address:"}) */ public $email. you’ll want a submit button.

class Product { /** * @var string \*/ protected $name. you may want to add items dynamically in the user interface – a great example is adding tasks to a task list. In some cases.CHAPTER EIGHTYSIX FORM COLLECTIONS Often. namespace Application\Entity. /** * @param string $name * @return Product \*/ public function setName($name) { $this->name = $name. we first need to define some domain objects that we’ll be using. fieldsets or elements in your forms will correspond to other domain objects. To do so. } /** * @return string \*/ 407 . /** * @var int \*/ protected $price. in terms of user interfaces. In this latter case. This document is intended to demonstrate these features. they may correspond to collections of domain objects. /** * @var Brand \*/ protected $brand. return $this. /** * @var array \*/ protected $categories.

Zend Framework 2 Documentation. } /** * @param array $categories * @return Product \*/ public function setCategories(array $categories) { $this->categories = $categories. Form Collections . } /** * @return int \*/ public function getPrice() { return $this->price. } 408 Chapter 86. } /** * @return Brand \*/ public function getBrand() { return $this->brand.0. return $this. } /** * @return array \*/ public function getCategories() { return $this->categories. return $this. } /** * @param int $price * @return Product \*/ public function setPrice($price) { $this->price = $price. Release 2.6 public function getName() { return $this->name. return $this. } /** * @param Brand $brand * @return Product \*/ public function setBrand(Brand $brand) { $this->brand = $brand.

/** * @var string \*/ protected $url.0.Zend Framework 2 Documentation. return $this. } } class Category { /** * @var string \*/ protected $name. } /** * @return string \*/ public function getName() { return $this->name. } /** * @param string $url * @return Brand \*/ public function setUrl($url) { $this->url = $url. } /** * @return string \*/ public function getUrl() { return $this->url. /** * @param string $name * @return Brand \*/ public function setName($name) { $this->name = $name. return $this. Release 2. 409 .6 } class Brand { /** * @var string \*/ protected $name.

’options’ => array( ’label’ => ’Name of the brand’ ). a OneToOne relationship (one product has one brand). $this->add(array( ’name’ => ’name’. this is really simple code. Zend\Form\Fieldset. $this->setHydrator(new ClassMethodsHydrator(false)) ->setObject(new Brand()). Release 2. A Product has two scalar properties (name and price). Zend\InputFilter\InputFilterProviderInterface. class BrandFieldset extends Fieldset implements InputFilterProviderInterface { public function __construct() { parent::__construct(’brand’).6 /** * @param string $name * @return Category \*/ public function setName($name) { $this->name = $name. } } As you can see.0. Here is the Brand fieldset: namespace Application\Form. Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator. ’options’ => array( 410 Chapter 86.Zend Framework 2 Documentation. } /** * @return string \*/ public function getName() { return $this->name. Form Collections .1 Creating Fieldsets The first step is to create three fieldsets. use use use use Application\Entity\Brand. 86. Each fieldset will contain all the fields and relationships for a specific entity. $this->add(array( ’name’ => ’url’. return $this. ’attributes’ => array( ’required’ => ’required’ ) )). and a OneToMany relationship (one product has many categories). ’type’ => ’Zend\Form\Element\Url’.

the Form will automatically iterate through all the field sets it contains. Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator. giving it a ClassMethods hydrator.0. Here is the Category fieldset: namespace Application\Form. } } We can discover some new things here. and the setObject() method. ’attributes’ => array( ’required’ => ’required’ ) )).1.6 ’label’ => ’Website of the brand’ ). indicating that this input is required. You don’t need to manually add filters or validators for this input as that element provides a reasonable input specification. Note that required in the array “attributes” (when elements are added) is only meant to add the “required” attribute to the form markup (and therefore has semantic meaning only). and automatically populate the sub-objects. ) ). the fieldset calls the method setHydrator(). Zend\InputFilter\InputFilterProviderInterface. ’options’ => array( ’label’ => ’Name of the category’ ). Zend\Form\Fieldset. use use use use Application\Entity\Category. Finally. Creating Fieldsets 411 . getInputFilterSpecification() gives the specification for the remaining input (“name”). class CategoryFieldset extends Fieldset implements InputFilterProviderInterface { public function __construct() { parent::__construct(’category’). } /** * @return array \*/ public function getInputFilterSpecification() { return array( ’name’ => array( ’required’ => true.Zend Framework 2 Documentation. $this->setLabel(’Category’). in order to return a complete entity. $this->add(array( ’name’ => ’name’. When the data will be validated. giving it an empty instance of a concrete Brand object. Also notice that the Url element has a type of Zend\Form\Element\Url. $this->setHydrator(new ClassMethodsHydrator(false)) ->setObject(new Category()). 86. Release 2. This information will be used to validate the input field. As you can see.

’options’ => array( ’label’ => ’Name of the product’ ). $this->add(array( 412 Chapter 86. Zend\Form\Fieldset. } } Nothing new here. ’attributes’ => array( ’required’ => ’required’ ) )). } /** * @return array \*/ public function getInputFilterSpecification() { return array( ’name’ => array( ’required’ => true.Zend Framework 2 Documentation. class ProductFieldset extends Fieldset implements InputFilterProviderInterface { public function __construct() { parent::__construct(’product’). Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator. And finally the Product fieldset: namespace Application\Form.6 ’attributes’ => array( ’required’ => ’required’ ) )). $this->setHydrator(new ClassMethodsHydrator(false)) ->setObject(new Product()). ’attributes’ => array( ’required’ => ’required’ ) )). Form Collections . use use use use Application\Entity\Product. ) ). Zend\InputFilter\InputFilterProviderInterface. $this->add(array( ’name’ => ’price’. Release 2. $this->add(array( ’name’ => ’name’. ’options’ => array( ’label’ => ’Price of the product’ ).0.

$this->add(array( ’type’ => ’Zend\Form\Element\Collection’. As you can see. ’count’ => 2. and bound the fieldset to a Brand entity using the setObject() method). * * @return array \*/ public function getInputFilterSpecification() { return array( ’name’ => array( ’required’ => true.Zend Framework 2 Documentation. Release 2. ’name’ => ’brand’.1. This Brand entity will then be used to populate the Product entity by calling the setBrand() method.0. When the form is validated. } /** * Should return an array specification compatible with * {@link Zend\InputFilter\Factory::createInputFilter()}. This is how you handle a OneToOne relationship. and will return a Brand entity (as we have specified a ClassMethods hydrator. The next element shows you how to handle OneToMany relationship.6 ’type’ => ’Application\Form\BrandFieldset’. ’options’ => array( ’label’ => ’Please choose categories for this product’. ’should_create_template’ => true. which is a specialized element to handle such cases. ’validators’ => array( array( ’name’ => ’Float’ ) ) ) ). The type is Zend\Form\Element\Collection. ’name’ => ’categories’. the BrandFieldset will first be populated. This element has a few interesting options: 86. ’target_element’ => array( ’type’ => ’Application\Form\CategoryFieldset’ ) ) )). notice how the brand element is added: we specify it to be of type Application\Form\BrandFieldset. } } We have a lot of new things here! First. the name of the element (“categories”) perfectly matches the name of the property in the Product entity. ). ’options’ => array( ’label’ => ’Brand of the product’ ) )). Creating Fieldsets 413 . ’allow_add’ => true. ’price’ => array( ’required’ => true.

$this->setAttribute(’method’. it will generate a template markup in a <span> element. in order to simplify adding new element on the fly (we will speak about this one later).0. $this->add(array( ’type’ => ’Zend\Form\Element\Csrf’. so good. So here is the form : namespace Application\Form. as it only defines a Product fieldset.2 The Form Element So far. This. they will be completely ignored.6 • count: this is how many times the element (in this case a category) has to be rendered. Release 2. not forms. as well as some other useful fields (CSRF for 414 Chapter 86. ’name’ => ’csrf’ )). use Zend\Form\Form. $this->add(array( ’name’ => ’submit’. an array that describes the element or fieldset that will be used in the collection. $this->add(array( ’type’ => ’Application\Form\ProductFieldset’. We’ve set it to two in this examples. use Zend\InputFilter\InputFilter. But those are field sets. of course. depends on what you want to do. the target_element is a Category fieldset. We now have our field sets in place. • allow_add: if set to true (which is the default). Form Collections . dynamically added elements will be retrieved and validated. } } CreateForm is quite simple. ’value’ => ’Send’ ) )). class CreateProduct extends Form { public function __construct() { parent::__construct(’create_product’). otherwise.Zend Framework 2 Documentation. ’post’) ->setHydrator(new ClassMethodsHydrator(false)) ->setInputFilter(new InputFilter()). ’attributes’ => array( ’type’ => ’submit’. • should_create_template: if set to true. And only Form instances can be validated. ’options’ => array( ’use_as_base_fieldset’ => true ) )). In this case. 86. use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator. • target_element: this is either an element or. as this is the case in this example.

Zend Framework 2 Documentation. Nothing to do in the controllers. in fact. 86. echo $this->form()->openTag($form). $this->url(’home’)) ->prepare(). What’s cool with this approach is that each entity can have its own Fieldset and can be reused.0. and a Submit button). The Controller 415 .4 The View And finally. You describe the elements. 86.6 security. } This is super easy. $product = $form->get(’product’). echo $this->formRow($product->get(’price’)). $brand = $product->get(’brand’). All the magic is done behind the scene. bound to the fieldset that is the base fieldset. $form->bind($product). if ($this->request->isPost()) { $form->setData($this->request->getPost()). You no longer have to add the “username” input to every form that deals with users! 86. the object I bind to you is.3. if ($form->isValid()) { var_dump($product). the view: <?php $form->setAttribute(’action’. Release 2.3 The Controller Now. echo $this->formRow($product->get(’name’)). and validators for each entity only once. $product = new Product().” This will be to true most of the times. the filters. } } return array( ’form’ => $form ). Notice the use_base_fieldset option. let’s create the action in the controller: /** * @return array \*/ public function indexAction() { $form = new CreateProduct(). and the concrete Form instance will only compose those fieldsets. echo $this->formCollection($product->get(’categories’)). This option is here to say to the form: “hey.

If you don’t want the fieldset created. ’template_placeholder’ => ’__placeholder__’. let’s see what it generates when we ask it to create a template: As you can see. collections are wrapped inside a fieldset. You must have a label on every element in order to use this feature. You must call it prior to rendering anything in the view (this function is only meant to be called in views. this is what we get : As you can see. In fact. so __index__ has to be changed to 2. ’options’ => array( ’label’ => ’Please choose categories for this product’. all elements will show errors (this is normal. not with arrays. If you want. If you validate. Of course __index__ (this is the placeholder generated) has to be changed to a valid value. In our case. echo $this->form()->closeTag(). this placeholder (__index__ is the default) can be changed using the template_placeholder option key: $this->add(array( ’type’ => ’Zend\Form\Element\Collection’. the input itself. Release 2. Currently. As soon as the form is valid. you can iterate through the elements in the collection. not in controllers).0. and every item in the collection is itself wrapped in the fieldset. echo $this->formElement($form->get(’submit’)). ’count’ => 2. ’name’ => ’categories’. Zend\Form has this capability. • the FormRow helper renders a label (if present).6 echo $this->formRow($brand->get(’name’)). the bound object is completely filled. as we’ve marked them as required). but with objects! But that’s not all. the Collection element uses label for each item in the collection. ’should_create_template’ => true. echo $this->formHidden($form->get(’csrf’)). 416 Chapter 86. simply add a boolean false as the second parameter of the FormCollection view helper.Zend Framework 2 Documentation. we have 2 elements (categories[0] and categories[1]. A few new things here : • the prepare() method. Form Collections . Often. and errors. First. and render them manually one by one. the collection generates two fieldsets (the two categories) plus a span with a data-template attribute that contains the full HTML code to copy to create a new element in the collection. let’s say that we don’t want only two categories. echo $this->formRow($brand->get(’url’)). If you need more control about the way you render your forms. but we want the user to be able to add other ones at runtime. using the setElementHelper() method on that FormCollection helper instance). • the FormCollection helper will iterate through every element in the collection. forms are not completely static. 86. Here is the result: As you can see. but just the elements within it.5 Adding New Elements Dynamically Remember the should_create_template? We are going to use it now. and render every element with the FormRow helper (you may specify an alternate helper if desired. while the label of the Collection element itself is used as the legend of the fieldset.

query.length. Add the element to the DOM. as we don’t want elements to be added.5. ’count’ => 2.) One small remark about the template. ’should_create_template’ => false. 4. First. count the number of elements we already have. as the indices are zero-based (so. let’s add a small button “Add new category” anywhere in the form: <button onclick="return add_category()">Add a new category</button> The add_category function is fairly simple: 1. Adding New Elements Dynamically 417 . even if new elements are added. ’options’ => array( ’label’ => ’Please choose categories for this product’. template = template. Also. etc. First. This way. Here’s how you do it: $this->add(array( ’type’ => ’Zend\Form\Element\Collection’. 2. Change the placeholder to a valid index. not added to the entity.append(template). Get the template from the span‘s data-template attribute.replace: the example uses currentCount and not currentCount + 1. Release 2. filtering it and retrieving it: Of course. Dojo’s dojo. currentCount).0. } </script> (Note: the above example assumes $() is defined. we don’t need the data template.Zend Framework 2 Documentation. Here is the code: <script> function add_category() { var currentCount = $(’form > fieldset > fieldset’). ’name’ => ’categories’. if we validate the form. it will automatically take into account this new element by validating it. ’allow_add’ => false. if you don’t want to allow adding elements in a collection. return false. you must to set the option allow_add to false. the third one will have the index 2). either. ’target_element’ => array( ’type’ => ’Application\Form\CategoryFieldset’ ) ) )). 3. $(’form > fieldset’). if we have two elements in the collection. they won’t be validated and hence.6 ’target_element’ => array( ’type’ => ’Application\Form\CategoryFieldset’ ) ) )). var template = $(’form > fieldset > span’).replace(/__index__/g. There are some limitations to this capability: 86. and equivalent to jQuery’s $() function.data(’template’). Now.

As an example. if your code specifies count == 2.6 Validation groups for fieldsets and collection Validation groups allow you to validate a subset of fields. 86. A validation group is specified in a Form object (hence. but of course this is not recommended. but you won’t be able to remove any others. We specified in the input filter that the URL is a required field. $product = $form->get(’product’).6 • Although you can add new elements and remove them. the form won’t validate. for instance). echo $this->formHidden($form->get(’csrf’)). echo $this->form()->closeTag(). $this->url(’home’)) ->prepare(). They can be added anywhere (these elements will still be validated and inserted into the entity). use Zend\InputFilter\InputFilter. Let’s update the view to remove the URL input: <?php $form->setAttribute(’action’. this newly added element will be automatically be replaced at the end of the collection. although the Brand entity has a URL property. Release 2. echo $this->formElement($form->get(’submit’)). echo $this->formRow($product->get(’price’)). class CreateProduct extends Form { 418 Chapter 86. you must have at least two elements. use Zend\Form\Form. echo $this->formRow($product->get(’name’)). as a lot of code will be duplicated. you could create a BrandFieldsetWithoutURL fieldset. Our CreateForm now looks like this: namespace Application\Form. This is what we get: The URL input has disappeared. echo $this->form()->openTag($form). we don’t want to user to specify it in the creation form (but may wish to later in the “Edit Product” form. If the initial count is 2. so if the form does not have it. echo $this->formRow($brand->get(’name’)). in the CreateProduct form) by giving an array of all the elements we want to validate. Form Collections . echo $this->formCollection($product->get(’categories’)). In fact. you will be able to add a third one and remove it. you CANNOT remove more elements in a collection than the initial count (for instance. even though we didn’t add it to the view! Of course. it won’t validate. in our case. this is normal.0. but if the validation fails. • Dynamically added elements have to be added at the end of the collection. The solution: validation groups. use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator.Zend Framework 2 Documentation. $brand = $product->get(’brand’). but even if we fill every input.

this is really an edge-case. but don’t validate it for the second one. Now. ’product’ => array( ’name’. $this->add(array( ’type’ => ’Application\Form\ProductFieldset’. as we want it to be validated too (but notice that I didn’t write the submit element. ’categories’ => array( ’name’ ) ) )). You can recursively select the elements you want. This means you cannot say. $this->setAttribute(’method’. 86. There is one simple limitation currently: validation groups for collections are set on a per-collection basis. ’value’ => ’Send’ ) )). ’options’ => array( ’use_as_base_fieldset’ => true ) )). $this->setValidationGroup(array( ’csrf’. the form validates (and the URL is set to null as we didn’t specify it). ’price’. ’name’ => ’csrf’ )).Zend Framework 2 Documentation. ’post’) ->setHydrator(new ClassMethodsHydrator()) ->setInputFilter(new InputFilter()). ’attributes’ => array( ’type’ => ’submit’. Release 2. “validate the name input for the first element of the categories collection. } } Of course. as we don’t care about it).” But.6.6 public function __construct() { parent::__construct(’create_product’). $this->add(array( ’type’ => ’Zend\Form\Element\Csrf’. Validation groups for fieldsets and collection 419 .0. honestly. don’t forget to add the CSRF element. ’brand’ => array( ’name’ ). $this->add(array( ’name’ => ’submit’. not perelement in a collection basis.

Form Collections .0. Release 2.Zend Framework 2 Documentation.6 420 Chapter 86.

)). A Factory is provided to facilitate creation of elements. fieldsets.1 Introduction A set of specialized elements are provided for accomplishing application-centric tasks. You will also typically provide some attributes to hint to the view layer how it might render the item. ’size’ => ’30’. each element or fieldset requires a name. See the Zend\Form Quick Start for more information. forms. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 use Zend\Form\Element. and the related input filter.2 Element Base Class Zend\Form\Element is a base class for all specialized elements and Zend\Form\Fieldset. $username = new Element\Text(’username’). $form = new Form(’my-form’). These include several HTML5 input elements with matching server-side validators.CHAPTER EIGHTYSEVEN FORM ELEMENTS 87. use Zend\Form\Form. $form 421 . and the Captcha element (to display and validate CAPTCHAs). Basic Usage At the bare minimum. $password = new Element\Password(’password’). the Csrf element (to prevent Cross Site Request Forgery attacks). $username ->setLabel(’Username’) ->setAttributes(array( ’class’ => ’username’. )). $password ->setLabel(’Password’) ->setAttributes(array( ’size’ => ’30’. 87.

6 21 22 ->add($username) ->add($password). getValue() Return the value for this element. getLabelAttributes() Return the attributes to use with the label. Form Elements . mixed $value) Set a single element attribute. Return type boolean setAttributes(array|Traversable $arrayOrTraversable) Set many attributes at once. Return type array setOptions(array $options) Set options for an element. respectively. Accepted options are: "label" and "label_attributes". Release 2. setAttribute(string $key. getAttributes() Retrieve all attributes at once. getName() Return the name for this element.Zend Framework 2 Documentation. getAttribute(string $key) Retrieve a single element attribute. getLabel() Return the label content for this element. Return type array|Traversable 422 Chapter 87. which call setLabel and setLabelAttributes. Return type string setLabelAttributes(array $labelAttributes) Set the attributes to use with the label. Public Methods setName(string $name) Set the name for this element. Return type string setLabel(string $label) Set the label content for this element. Return type mixed hasAttribute(string $key) Check if a specific attribute exists for this element. Implementation will decide if this will overwrite or merge. Return type string setValue(string $value) Set the value for this element.0.

form input.Zend Framework 2 Documentation. See the section on Zend CAPTCHA Adapters for more information on what adapters are available.3. if any. $captcha ->setCaptcha(new Captcha\Dumb()) ->setLabel(’Please verify you are human’). use Zend\Form\Element. $form->add($button). $captcha = new Element\Captcha(’captcha’). 87. $button->setLabel(’My Button’) ->setValue(’foo’). $button = new Element\Button(’my-button’). Standard Elements 423 . 87.3 Standard Elements 87. getMessages() Returns a list of validation failure messages. use Zend\Form\Form.2 Captcha Zend\Form\Element\Captcha can be used with forms where authenticated users are not necessary. Basic Usage A CAPTCHA adapter must be attached in order for validation to be included in the element’s input filter specification. 1 2 3 4 5 6 7 8 use Zend\Captcha. Return type array|Traversable 87.3. $form = new Form(’my-form’). It is pairs with one of the Zend/Form/View/Helper/Captcha/* view helpers that matches the type of CAPTCHA adapter in use. It can be used with the Zend\Form\Element\Button extends from ZendFormElement. Release 2. Basic Usage This element automatically adds a type attribute of value button.6 clearAttributes() Clear all attributes for this element.3. 1 2 3 4 5 6 7 8 9 use Zend\Form\Element. but you want to prevent spam submissions. use Zend\Form\Form.0.1 Button Zend\Form\Element\Button represents a button Zend/Form/View/Helper/FormButton view helper. setMessages(array|Traversable $messages) Set a list of messages to report when validation fails.

Basic Usage This element automatically adds a "type" attribute of value "checkbox".0. $form->add(array( ’type’ => ’Zend\Form\Element\Captcha’. If $captcha is an array.3 Checkbox Zend\Form\Element\Checkbox is meant to be paired with the Zend\Form\View\Helper\FormCheckbox for HTML inputs with type checkbox. Release 2. Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 use Zend\Captcha. ’options’ => array( ’label’ => ’Please verify you are human’. ). This element adds an InArray validator to its input filter specification in order to validate on the server if the checkbox contains either the checked value or the unchecked value. $form = new Form(’my-form’). getCaptcha() Return the CAPTCHA adapter for this element. and a CAPTCHA validator. Return type Zend\Captcha\AdapterInterface getInputSpecification() Returns a input filter specification. Return type array 87. Zend\Captcha\Factory::factory() will be run to create the adapter from the array configuration. ’name’ => ’captcha’. setCaptcha(array|Zend\Captcha\AdapterInterface $captcha) Set the CAPTCHA adapter for this element. use Zend\Form\Form. 424 Chapter 87. 1 2 3 4 5 6 7 use Zend\Form\Element. use Zend\Form\Form. $checkbox->setCheckedValue("good"). $checkbox = new Element\Checkbox(’checkbox’). ’captcha’ => new Captcha\Dumb(). $checkbox->setLabel(’A checkbox’). which includes a Zend\Filter\StringTrim filter. Form Elements . )).Zend Framework 2 Documentation.6 9 10 11 $form = new Form(’my-form’). $form->add($captcha). Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element. $checkbox->setUseHiddenElement(true).3.

in addition to the inherited options of Zend\Form\Element <zend.Zend Framework 2 Documentation.0. use_hidden_element is set to true. $form->add(array( ’type’ => ’Zend\Form\Element\Checkbox’. ’use_hidden_element’ => true. ’options’ => array( ’label’ => ’A checkbox’. Therefore.6 8 9 10 11 $checkbox->setUncheckedValue("bad"). which includes a Zend\Validator\InArray to validate if the value is either checked value or unchecked value. setCheckedValue and setUncheckedValue . are: "use_hidden_element". ’name’ => ’checkbox’. $form = new Form(’my-form’).methods. when using custom unchecked value. $form = new Form(’my-form’). setOptions(array $options) Set options for an element of type Checkbox. Using the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 use Zend\Form\Form. setUseHiddenElement(boolean $useHiddenElement) If set to true (which is default).form.element. Return type boolean setCheckedValue(string $checkedValue) Set the value to use when the checkbox is checked. respectively. you must make sure that . Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element . getCheckedValue() Return the value used when the checkbox is checked. getUncheckedValue() Return the value used when the checkbox is unchecked. which call setUseHiddenElement. Accepted options. the view helper will generate a hidden element that contains the unchecked value.3. Return type string setUncheckedValue(string $uncheckedValue) Set the value to use when the checkbox is unchecked. Standard Elements 425 For this to work. useHiddenElement() Return if a hidden element is generated.set-options>‘ . $form->add($checkbox). "checked_value" and "unchecked_value" . ’checked_value’ => ’good’. 87. this option have to be set to true. Release 2. Return type string getInputSpecification() Returns a input filter specification. ’unchecked_value’ => ’bad’ ) )).

setOptions(array $options) Set options for an element of type Collection. you may want to add input (or a set of inputs) multiple times. please refer to ZendCollection tutorial. setAllowAdd. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element . ’should_create_template’ => true. For more information about Collection. Zend\Form\Element\Collection is meant to be paired with the Zend\Form\View\Helper\FormCollection. Basic Usage use Zend\Form\Element. in addition to the inherited options of Zend\Form\Element <zend. Accepted options. $form->add($colors). $form->add(array( ’type’ => ’Zend\Form\Element\Collection’.4 Collection Sometimes. ’target_element’ => new Element\Color() ) )).6 Return type array 87. $colors->setCount(2).Zend Framework 2 Documentation.form. Release 2. $colors->setTargetElement(new Element\Color()). setAllowRemove. either because you don’t want to duplicate code. $colors = new Element\Collection(’collection’). $form = new Form(’my-form’). Form Elements . Those option keys respectively call call setTargetElement.0. $colors->setLabel(’Colors’). use Zend\Form\Form. ’options’ => array( ’label’ => ’Colors’. "count". setCount. "allow_add". setShouldCreateTemplate and setTemplatePlaceholder. "should_create_template" and "template_placeholder".3.set-options>‘ . 426 Chapter 87.methods. for instance). or because you does not know in advance how many elements you need (in the case of elements dynamically added to a form using JavaScript. ’count’ => 2. $form = new Form(’my-form’).element. use Zend\Form\Form. 1 2 3 4 5 6 7 8 9 10 11 Using the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 use Zend\Form\Element. are: "target_element". "allow_remove". $colors->setShouldCreateTemplate(true).

Zend Framework 2 Documentation. Standard Elements 427 .3. getCount() Return the number of times the target element will Zend/Form/View/Helper/FormCollection view helper. When the Collection element will be validated. This non-semantic span element contains a single data-template HTML5 attribute whose value is the whole HTML to copy to create a new element in the form. new elements added dynamically in the form (using JavaScript. The template is indexed using the templatePlaceholder value. new elements added dynamically in the form (using JavaScript. allowRemove() Return if new elements can be dynamically removed from the collection. Return type ElementInterface | null setAllowAdd($allowAdd) If allowAdd is set to true (which is the default). Return type boolean setShouldCreateTemplate($shouldCreateTemplate) If shouldCreateTemplate is set to true (defaults to false).3. 87. ensuring the data is submitted by the user session that generated the form and not by a rogue script. Return type boolean setAllowRemove($allowRemove) If allowRemove is set to true (which is the default). getTemplatePlaceholder() Returns the template placeholder used to index element in the template. for instance) will also be validated and retrieved. for instance) will be allowed to be removed. shouldCreateTemplate() Return if a template should be created. Return type string 87.5 Csrf Zend\Form\Element\Csrf pairs with the Zend\Form\View\Helper\FormHidden to provide protection from CSRF attacks on forms. a <span> element will be generated by the Zend/Form/View/Helper/FormCollection view helper. getTargetElement() Return the target element used by the collection.0.6 setCount($count) Defines how many times the target element will Zend/Form/View/Helper/FormCollection view helper. Zend/Form/FieldsetInterface instance or an array to pass to the form factory. Release 2. Protection is achieved by adding a hash element to a form and verifying it when the form is submitted. allowAdd() Return if new elements can be dynamically added in the collection. Return type boolean setTemplatePlaceholder($templatePlaceholder) Set the template placeholder (defaults to __index__) used to index element in the template. the input filter will be retrieved from this target element and be used to validate each element in the collection. Return type integer be initially rendered by the be initially rendered by the setTargetElement($elementOrFieldset) This function either takes an Zend/Form/ElementInterface.

6 File Zend\Form\Element\File represents a form Zend\Form\View\Helper\FormFile view helper. Return type array setCsrfValidator(CsrfValidator $validator) Override the default CSRF validator by setting another one. ’options’ => array( ’csrf_options’ => array( ’timeout’ => 600 ) ) )). Form Elements . getInputSpecification() Returns a input filter specification.Zend Framework 2 Documentation. ’name’ => ’csrf’. or by using the "csrf_options" key.3. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element. use Zend\Form\Form. getCsrfValidatorOptions() Get the options that are used by the CSRF validator. $form->add(array( ’type’ => ’Zend\Form\Element\Csrf’. getCsrfValidator() Get the CSRF validator. $form->add($csrf). Return type CsrfValidator 87. You can change the options of the CSRF validator using the setCsrfValidatorOptions function. which includes a Zend\Filter\StringTrim filter and a Zend\Validator\Csrf to validate the CSRF value. It can be used with the 428 Chapter 87.6 Basic Usage This element automatically adds a "type" attribute of value "hidden". $form = new Form(’my-form’).0. $csrf = new Element\Csrf(’csrf’). Return type array setCsrfValidatorOptions(array $options) Set the options that are used by the CSRF validator. 1 2 3 4 5 6 7 use Zend\Form\Element. Here is an example using the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 use Zend\Form\Form. file input. Release 2. $form = new Form(’my-form’).

and will set the form’s enctype to multipart/form-data. $form = new Form(’my-form’). 1 2 3 4 5 6 7 use Zend\Form\Element.3. use Zend\Form\Form. Basic Usage This element automatically adds a "type" attribute of value "hidden". Zend\Form\Element\Image extends from ZendFormElement. $form->add($file). use Zend\Form\Form. $hidden->setValue(’foo’). Release 2. Basic Usage This element automatically adds a "type" attribute of value "file". $hidden = new Element\Hidden(’my-hidden’).7 Hidden Zend\Form\Element\Hidden represents a hidden Zend\Form\View\Helper\FormHidden view helper. It can be used with the 87.6 Zend\Form\Element\File extends from ZendFormElement.0. Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 use Zend\Form\Form.3. $form->add(array( ’type’ => ’Zend\Form\Element\Hidden’.8 Image Zend\Form\Element\Image represents a image button form input. Standard Elements 429 . $form->add($hidden). 87.3. Zend\Form\View\Helper\FormImage view helper. 87.Zend Framework 2 Documentation. $file = new Element\File(’my-file’). ’name’ => ’my-hidden’. $form = new Form(’my-file’). 1 2 3 4 5 6 7 8 use Zend\Form\Element. $form = new Form(’my-form’). form input. It can be used with the Zend\Form\Element\Hidden extends from ZendFormElement. ’attributes’ => array( ’value’ => ’foo’ ) )).

$form->add($multiCheckbox). $image->setAttribute(’src’. ’value_options’ => array( ’0’ => ’Apple’.3. ’name’ => ’multi-checkbox’ ’options’ => array( ’label’ => ’What do you like ?’. Using the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 use Zend\Form\Form. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Element. ).6 Basic Usage This element automatically adds a "type" attribute of value "image".Zend Framework 2 Documentation. use Zend\Form\Form. $multiCheckbox->setValueOptions(array( array( ’0’ => ’Apple’.image. Basic Usage This element automatically adds a "type" attribute of value "checkbox" for every checkboxes. This element adds an InArray validator to its input filter specification in order to validate on the server if the checkbox contains values from the multiple checkboxes. ’1’ => ’Orange’. Form Elements . 1 2 3 4 5 6 7 8 use Zend\Form\Element. $form = new Form(’my-form’).url’). $image = new Element\Image(’my-image’). $form->add(array( ’type’ => ’Zend\Form\Element\MultiCheckbox’. // Src attribute is required $form = new Form(’my-form’). ’2’ => ’Lemon’ ) )). Release 2. $multiCheckbox->setLabel(’What do you like ?’). 430 Chapter 87.0. ’2’ => ’Lemon’. ’http://my. use Zend\Form\Form. $multiCheckbox = new Element\MultiCheckbox(’multi-checkbox’). $form->add($image).9 MultiCheckbox Zend\Form\Element\MultiCheckbox is meant to be paired with the Zend\Form\View\Helper\FormMultiCheckbox for HTML inputs with type checkbox. ’1’ => ’Orange’. 87. $form = new Form(’my-form’).

0. $password->setLabel(’Enter your password’). getValueOptions() Return the value options.checkbox. Accepted options. $form->add($password). The array must contain a key => value for every checkbox.11 Radio Zend\Form\Element\Radio is meant to be paired with the Zend\Form\View\Helper\FormRadio for HTML inputs with type radio. use Zend\Form\Form. Zend\Form\View\Helper\FormPassword view helper. 1 2 3 4 5 6 7 8 use Zend\Form\Element.10 Password Zend\Form\Element\Password represents a password form input.3. setOptions(array $options) Set options for an element of type Checkbox. 87. $password = new Element\Password(’my-password’). Basic Usage It can be used with the This element automatically adds a "type" attribute of value "password". Release 2. Basic Usage This element automatically adds a "type" attribute of value "radio" for every radio. Standard Elements 431 . setValueOptions(array $options) Set the value options for every checkbox of the multi-checkbox. This element adds an InArray validator to its input filter specification in order to validate on the server if the value is contains within the radio value elements. in addition to the inherited options of Zend\Form\Element\Checkbox <zend.3. are: "value_options".methods.Zend Framework 2 Documentation.element. Zend\Form\Element\Password extends from ZendFormElement.3.6 14 15 ) )).form.set-options>‘ . which call setValueOptions. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element\Checkbox . 87. $form = new Form(’my-form’). Return type array 87.

use Zend\Form\Form. $select->setValueOptions(array( ’0’ => ’French’. This element adds an InArray validator to its input filter specification in order to validate on the server if the selected value belongs to the values. ’1’ => ’Male’. ’name’ => ’gender’ ’options’ => array( ’label’ => ’What is your gender ?’. $form = new Form(’my-form’).6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Element.0. Form Elements . Using the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Form. Release 2. use Zend\Form\Form. $select = new Element\Select(’language’).3.Zend Framework 2 Documentation.12 Select Zend\Form\Element\Select is meant to be paired with the Zend\Form\View\Helper\FormSelect for HTML inputs with type select. $form->add($radio). $select->setLabel(’Which is your mother tongue?’). ) )). Basic Usage This element automatically adds a "type" attribute of value "select". ). ’1’ => ’Male’. $form->add(array( ’type’ => ’Zend\Form\Element\Radio’. $radio->setLabel(’What is your gender ?’). ’value_options’ => array( ’0’ => ’Female’. ) )). 1 2 3 4 5 6 7 use Zend\Form\Element. Public Methods All the methods from the inherited methods of Zend\Form\Element\MultiCheckbox are also available for this element. 432 Chapter 87. This element can be used as a multi-select element by adding the “multiple” HTML attribute to the element. $radio->setValueOptions(array( array( ’0’ => ’Female’. $radio = new Element\Radio(’gender’). $form = new Form(’my-form’). 87.

’2’ => ’Japanese’. ) )).Zend Framework 2 Documentation. ’name’ => ’language’ ’options’ => array( ’label’ => ’Which is your mother tongue?’. ) )). $select = new Element\Select(’language’). ’3’ => ’Chinese’. $select->setValueOptions(array( ’european’ => array( ’label’ => ’European languages’. 87. Using the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 use Zend\Form\Form. ’1’ => ’English’. $form = new Form(’my-form’). ’empty_option’ => ’Please choose your language’. $form->add(array( ’type’ => ’Zend\Form\Element\Select’. )).0. 1 2 3 4 5 6 7 8 9 10 use Zend\Form\Element. $form->add($select). Standard Elements 433 .3. ’1’ => ’English’. $form = new Form(’my-form’). ’name’ => ’language’ ’options’ => array( ’label’ => ’Which is your mother tongue?’. ’value_options’ => array( ’0’ => ’French’.6 8 9 10 11 12 13 14 ’1’ => ’English’. ’2’ => ’Japanese’. $select->setLabel(’Which is your mother tongue?’). ’2’ => ’Japanese’. Option groups are also supported. ’3’ => ’Chinese’. ’value_options’ => array( ’0’ => ’French’. use Zend\Form\Form. ). ’3’ => ’Chinese’. You just need to add an ‘options’ key to the value options. Release 2. ’options’ => array( ’0’ => ’French’. You can add an empty option (option with no value) using the "empty_option" option: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 use Zend\Form\Form. ). $form = new Form(’language’). $form->add(array( ’type’ => ’Zend\Form\Element\Select’.

Form Elements . Zend\Form\View\Helper\FormSubmit view helper. ). ’options’ => array( ’2’ => ’Japanese’. setOptions(array $options) Set options for an element of type Checkbox.checkbox. ’asian’ => array( ’label’ => ’Asian languages’. respectively. $form = new Form(’language’).13 Submit Zend\Form\Element\Submit represents a submit button form input. in addition to the inherited options of Zend\Form\Element\Checkbox <zend. setEmptyOption() Get the label for the empty option (null if none). Return type array setEmptyOption($emptyOption) Optionally set a label for an empty option (option with no value).3.set-options>‘ .6 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ’1’ => ’Italian’. Basic Usage It can be used with the This element automatically adds a "type" attribute of value "submit". ). 434 Chapter 87. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element . ’3’ => ’Chinese’.form. which call setValueOptions and setEmptyOption. )). ).0. Zend\Form\Element\Submit extends from ZendFormElement. It is set to “null” by default.Zend Framework 2 Documentation. Accepted options. are: "value_options" and "empty_option". ). Return type string 87.methods. which means that no empty option will be rendered. Release 2. $form->add($select). The array must contain a key => value for every checkbox. setValueOptions(array $options) Set the value options for every checkbox of the multi-checkbox.element. getValueOptions() Return the value options.

3. Standard Elements 435 . use Zend\Form\Form.6 1 2 3 4 5 6 7 8 use Zend\Form\Element. Basic Usage use Zend\Form\Element. Release 2. $submit = new Element\Submit(’my-submit’). Zend\Form\View\Helper\FormTextarea view helper. form input. Basic Usage This element automatically adds a "type" attribute of value "text". It can be used with the Zend\Form\Element\Text extends from ZendFormElement. use Zend\Form\Form. $textarea = new Element\Textarea(’my-textarea’). 87.0.14 Text Zend\Form\Element\Text represents a text Zend\Form\View\Helper\FormText view helper. $form = new Form(’my-form’).15 Textarea Zend\Form\Element\Textarea represents a textarea form input. $text->setLabel(’Enter your name’). $form = new Form(’my-form’). $submit->setValue(’Submit Form’). $form = new Form(’my-form’). It can be used with the 1 2 3 4 5 6 7 8 87. use Zend\Form\Form. 1 2 3 4 5 6 7 8 use Zend\Form\Element. $textarea->setLabel(’Enter a description’). $form->add($submit).Zend Framework 2 Documentation. Zend\Form\Element\Textarea extends from ZendFormElement. $form->add($textarea). $form->add($text). 87. $text = new Element\Text(’my-text’).3.3.

use Zend\Form\Form. $color->setLabel(’Background color’). This element adds filters and validators to it’s input filter specification in order to validate HTML5 date input values on the server. ’options’ => array( ’label’ => ’Background color’ ) )).1 Color Zend\Form\Element\Color is meant to be paired with the Zend\Form\View\Helper\FormColo type color‘_.4 HTML5 Elements 87. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element. which includes Zend\Filter\StringTrim and Zend\Filter\StringToLower filters. ’name’ => ’color’.2 Date Zend\Form\Element\Date is meant to be paired with the Zend\Form\View\Helper\FormDate for HTML5 inputs with type date. This element adds filters and a ‘‘Regex validator to it’s input filter spr‘‘ for ‘HTML5 inputs withecification in order to validate a ‘HTML5 valid simple color‘_ value on the server.0. Basic Usage This element automatically adds a "type" attribute of value "color". $form = new Form(’my-form’). Here is the same example using the array notation: 1 2 3 4 5 6 7 8 9 10 use Zend\Form\Form. 1 2 3 4 5 6 7 8 use Zend\Form\Element. $form->add(array( ’type’ => ’Zend\Form\Element\Color’. getInputSpecification() Returns a input filter specification.Zend Framework 2 Documentation. Form Elements . $color = new Element\Color(’color’). $form->add($color). Return type array 87. Release 2.4. 436 Chapter 87. $form = new Form(’my-form’). and a Zend\Validator\Regex to validate the RGB hex format.6 87.4.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Element. getInputSpecification() Returns a input filter specification. ’attributes’ => array( ’min’ => ’2012-01-01’. ’name’ => ’appointment-date’.4. Note: Note: the min. ’options’ => array( ’label’ => ’Appointment Date’ ). // days. max. ’max’ => ’2020-01-01’. // days. and step attributes. Release 2. One difference from Zend\Form\Element\DateTime is that the Zend\Validator\DateStep validator will expect the step attribute to use an interval of days (default is 1 day). $form->add(array( ’type’ => ’Zend\Form\Element\Date’. $form = new Form(’my-form’). $form->add($date). max.0. Otherwise. the default input specification for the element may not contain the correct validation rules. Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Form. $form = new Form(’my-form’). and step attributes should be set prior to calling Zend\Form::prepare(). Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element\DateTime. default step interval is 1 day ) )). use Zend\Form\Form. ’step’ => ’1’. ’step’ => ’1’. HTML5 Elements 437 . $date = new Element\Date(’appointment-date’). which includes Zend\Filter\StringTrim and will add the appropriate validators based on the values from the min. default step interval is 1 day )). $date ->setLabel(’Appointment Date’) ->setAttributes(array( ’min’ => ’2012-01-01’.6 Basic Usage This element automatically adds a "type" attribute of value "date". ’max’ => ’2020-01-01’.Zend Framework 2 Documentation. See getInputSpecification in Zend\Form\Element\DateTime for more information. Return type array 87.

Otherwise.3 DateTime Zend\Form\Element\DateTime is meant to be paired with the Zend\Form\View\Helper\FormDateTime for HTML5 inputs with type datetime. default step interval is 1 min )). Release 2. max.6 87. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element. ’max’ => ’2020-01-01T00:00:00Z’. $dateTime ->setLabel(’Appointment Date/Time’) ->setAttributes(array( ’min’ => ’2010-01-01T00:00:00Z’. $form->add($dateTime). $dateTime = new Element\DateTime(’appointment-date-time’). // minutes. Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Form. ’max’ => ’2020-01-01T00:00:00Z’. use Zend\Form\Form. ’options’ => array( ’label’ => ’Appointment Date/Time’ ). $form->add(array( ’type’ => ’Zend\Form\Element\DateTime’. // minutes. max. ’step’ => ’1’. 438 Chapter 87.0. This element adds filters and validators to it’s input filter specification in order to validate HTML5 datetime input values on the server. Form Elements .4. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Element. ’name’ => ’appointement-date-time’. Basic Usage This element automatically adds a "type" attribute of value "datetime". default step interval is 1 mint ) )). $form = new Form(’my-form’). ’step’ => ’1’. $form = new Form(’my-form’). and step attributes should be set prior to calling Zend\Form::prepare(). Note: Note: the min. ’attributes’ => array( ’min’ => ’2010-01-01T00:00:00Z’. the default input specification for the element may not contain the correct validation rules. which includes Zend\Filter\StringTrim and will add the appropriate validators based on the values from the min.Zend Framework 2 Documentation. getInputSpecification() Returns a input filter specification. and step attributes.

Basic Usage This element automatically adds a "type" attribute of value "datetime-local". $form = new Form(’my-form’). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Element. $form = new Form(’my-form’). a Zend\Validator\GreaterThan validator will be added to ensure the date value is greater than the minimum value. a a Zend\Validator\DateStep validator will be added to ensure the date value is within a certain interval of minutes (default is 1 minute). Return type array 87. // minutes.4.Zend Framework 2 Documentation. default step interval is 1 min )). This element adds filters and validators to it’s input filter specification in order to validate HTML5 a local datetime input values on the server. Release 2. HTML5 Elements 439 . // minutes. ’name’ => ’appointment-date-time’. $form->add(array( ’type’ => ’Zend\Form\Element\DateTimeLocal’.4. $dateTimeLocal = new Element\DateTimeLocal(’appointment-date-time’). $form->add($dateTimeLocal). 87.0. ’step’ => ’1’. Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Form. ’max’ => ’2020-01-01T00:00:00’. If the max attribute is set. $dateTimeLocal ->setLabel(’Appointment Date’) ->setAttributes(array( ’min’ => ’2010-01-01T00:00:00’. step validations will be skipped. default step interval is 1 min ) )). ’options’ => array( ’label’ => ’Appointment Date’ ). a Zend\Validator\LessThanValidator validator will be added to ensure the date value is less than the maximum value. Otherwise. If the step attribute is set to “any”. ’step’ => ’1’.6 If the min attribute is set. use Zend\Form\Form. ’attributes’ => array( ’min’ => ’2010-01-01T00:00:00’. ’max’ => ’2020-01-01T00:00:00’.4 DateTimeLocal Zend\Form\Element\DateTimeLocal is meant to be paired with the Zend\Form\View\Helper\FormDateTimeLocal for HTML5 inputs with type datetime-local.

440 Chapter 87. getInputSpecification() Returns a input filter specification. Release 2.0. use Zend\Form\Form.Zend Framework 2 Documentation. Form Elements . This element adds filters and validators to it’s input filter specification in order to validate HTML5 valid email address on the server. $form = new Form(’my-form’). $email->setLabel(’Email Address’) $form->add($email). // Comma separated list of emails $emails = new Element\Email(’emails’).6 Note: Note: the min.5 Email Zend\Form\Element\Email is meant to be paired with the Zend\Form\View\Helper\FormEmail for HTML5 inputs with type email. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element\DateTime. and step attributes should be set prior to calling Zend\Form::prepare(). the default input specification for the element may not contain the correct validation rules. Return type array 87. $form->add($emails).4. $emails ->setLabel(’Email Addresses’) ->setAttribute(’multiple’. Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 11 use Zend\Form\Form. ’name’ => ’email’. $form->add(array( ’type’ => ’Zend\Form\Element\Email’. max. See getInputSpecification in Zend\Form\Element\DateTime for more information. true). max. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 use Zend\Form\Element. Otherwise. $form = new Form(’my-form’). which includes Zend\Filter\StringTrim and will add the appropriate validators based on the values from the min. ’options’ => array( ’label’ => ’Email Address’ ). )). Basic Usage This element automatically adds a "type" attribute of value "email". and step attributes. // Single email address $email = new Element\Email(’email’).

the default input specification for the element may not contain the correct validation rules. Basic Usage This element automatically adds a "type" attribute of value "month". use Zend\Form\Form. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element. ’attributes’ => array( ’multiple’ => true ) )). default step interval is 1 month )). HTML5 Elements 441 .Zend Framework 2 Documentation. $form = new Form(’my-form’). $month = new Element\Month(’month’). If the multiple attribute is true. ’name’ => ’emails’. ’options’ => array( ’label’ => ’Email Addresses’ ). $form->add($month). ’max’ => ’2020-01’. a Zend\Validator\Explode validator will be added to ensure the input string value is split by commas before validating each email address with Zend\Validator\Regex. Note: Note: the multiple attribute should be set prior to calling Zend\Form::prepare().6 Month Zend\Form\Element\Month is meant to be paired with the Zend\Form\View\Helper\FormMonth for HTML5 inputs with type month.4. ’step’ => ’1’. Otherwise. This element adds filters and validators to it’s input filter specification in order to validate HTML5 month input values on the server. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Element. If the multiple attribute is unset or false.6 12 13 14 15 16 17 18 19 20 21 $form->add(array( ’type’ => ’Zend\Form\Element\Email’. Return type array 87. which includes a Zend\Filter\StringTrim filter. 87. $month ->setLabel(’Month’) ->setAttributes(array( ’min’ => ’2012-01’. // months. getInputSpecification() Returns a input filter specification. and a validator based on the multiple attribute. Release 2.4.0. a Zend\Validator\Regex validator will be added to validate a single email address.

getInputSpecification() Returns a input filter specification. and step attributes should be set prior to calling Zend\Form::prepare(). One difference from Zend\Form\Element\DateTime is that the Zend\Validator\DateStep validator will expect the step attribute to use an interval of months (default is 1 month). This element adds filters and validators to it’s input filter specification in order to validate HTML5 number input values on the server. // months. Basic Usage This element automatically adds a "type" attribute of value "number". 1 2 3 4 5 6 7 8 9 use Zend\Form\Element. the default input specification for the element may not contain the correct validation rules. ’max’ => ’2020-01’.6 Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Form. See getInputSpecification in Zend\Form\Element\DateTime for more information. max. ’attributes’ => array( ’min’ => ’2012-12’. $form = new Form(’my-form’). Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element\DateTime. max. which includes Zend\Filter\StringTrim and will add the appropriate validators based on the values from the min. ’max’ => ’10’. default step interval is 1 month ) )). use Zend\Form\Form.4. and step attributes. Note: Note: the min. Return type array 87.0. $form->add(array( ’type’ => ’Zend\Form\Element\Month’.Zend Framework 2 Documentation. Otherwise. ’step’ => ’1’.7 Number Zend\Form\Element\Number is meant to be paired with the Zend\Form\View\Helper\FormNumber for HTML5 inputs with type number. 442 Chapter 87. $number = new Element\Number(’quantity’). Release 2. ’name’ => ’month’. ’options’ => array( ’label’ => ’Month’ ). $number ->setLabel(’Quantity’) ->setAttributes(array( ’min’ => ’0’. Form Elements .

87. and step attributes. max. a Zend\Validator\GreaterThan validator will be added to ensure the number value is greater than the minimum value. Release 2. max. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element. This element adds filters and validators to it’s input filter specification in order to validate HTML5 range values on the server. The step value should be either “any” or a valid floating point number. $form = new Form(’my-form’). a a Zend\Validator\Step validator will be added to ensure the number value is within a certain interval (default is 1). Return type array 87. ’max’ => ’10’. Otherwise. If the step attribute is set to “any”.Zend Framework 2 Documentation. // default step interval is 1 )).8 Range Zend\Form\Element\Range is meant to be paired with the Zend\Form\View\Helper\FormRange for HTML5 inputs with type range. the default input specification for the element may not contain the correct validation rules. Otherwise. a Zend\Validator\LessThanValidator validator will be added to ensure the number value is less than the maximum value. If the max attribute is set. If the min attribute is set. HTML5 Elements 443 . The max value should be a valid floating point number. ’step’ => ’1’. ’attributes’ => array( ’min’ => ’0’. $form->add($number).4. and step attributes should be set prior to calling Zend\Form::prepare(). step validations will be skipped. $form->add(array( ’type’ => ’Zend\Form\Element\Number’. ’options’ => array( ’label’ => ’Quantity’ ). The min value should be a valid floating point number.0. getInputSpecification() Returns a input filter specification. which includes Zend\Filter\StringTrim and will add the appropriate validators based on the values from the min. ’name’ => ’quantity’. Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Form. // default step interval is 1 ) )).6 10 11 12 13 14 ’step’ => ’1’. Note: Note: the min.4. $form = new Form(’my-form’).

// default minimum is 0 ’max’ => 100. // default minimum is 0 ’max’ => ’100’.6 Basic Usage This element automatically adds a "type" attribute of value "range". Return type array 444 Chapter 87. max. max. $range = new Element\Range(’range’). ’name’ => ’range’. $form = new Form(’my-form’). use Zend\Form\Form. // default maximum is 100 ’step’ => 1 // default interval is 1 ) )). Note: Note: the min. $form->add($range). $form = new Form(’my-form’). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Element. the default input specification for the element may not contain the correct validation rules. // default interval is 1 )).0. getInputSpecification()‘‘ Returns a input filter specification. // default maximum is 100 ’step’ => ’1’.Zend Framework 2 Documentation. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element\Number. See getInputSpecification in Zend\Form\Element\Number for more information. $range ->setLabel(’Minimum and Maximum Amount’) ->setAttributes(array( ’min’ => ’0’. ’attributes’ => array( ’min’ => 0. Form Elements . The Range element differs from Zend\Form\Element\Number in that the Zend\Validator\GreaterThan and Zend\Validator\LessThan validators will always be present. Release 2. and step attributes. Here is with the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Form. ’options’ => array( ’label’ => ’Minimum and Maximum Amount’ ). The default minimum is 1. which includes Zend\Filter\StringTrim and will add the appropriate validators based on the values from the min. and the default maximum is 100. Otherwise. $form->add(array( ’type’ => ’Zend\Form\Element\Range’. and step attributes should be set prior to calling Zend\Form::prepare().

max. ’step’ => ’60’.6 87. the default input specification for the element may not contain the correct validation rules. ’step’ => ’60’. max.Zend Framework 2 Documentation. 87. Release 2. ’options’=> array( ’label’ => ’Time’ ). // seconds. // seconds. Otherwise. $form->add(array( ’type’ => ’Zend\Form\Element\Month’. ’max’ => ’23:59:59’. HTML5 Elements 445 . ’name’ => ’time’. default step interval is 60 seconds )). $form = new Form(’my-form’). $form = new Form(’my-form’). Note: Note: the min. which includes Zend\Filter\StringTrim and will add the appropriate validators based on the values from the min. $time ->setLabel(’Time’) ->setAttributes(array( ’min’ => ’00:00:00’. ’attributes’ => array( ’min’ => ’00:00:00’. and step attributes. and step attributes should be set prior to calling Zend\Form::prepare(). Here is the same example using the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Form.0. default step interval is 60 seconds ) )). ’max’ => ’23:59:59’. See getInputSpecification in Zend\Form\Element\DateTime for more information. $form->add($time).4. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Element. Basic Usage This element automatically adds a "type" attribute of value "time". getInputSpecification() Returns a input filter specification.4. use Zend\Form\Form. This element adds filters and validators to it’s input filter specification in order to validate HTML5 time input values on the server. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element\DateTime. $time = new Element\Month(’time’).9 Time Zend\Form\Element\Time is meant to be paired with the Zend\Form\View\Helper\FormTime for HTML5 inputs with type time.

and a Zend\Validator\Uri to validate the URI string. $form->add($url).4. Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element. This element adds filters and a Zend\Validator\Uri validator to it’s input filter specification for validating HTML5 URL input values on the server. ’name’ => ’webpage-url’. Return type array 87. ’options => array( ’label’ => ’Webpage URL’ ) )).10 Url Zend\Form\Element\Url is meant to be paired with the Zend\Form\View\Helper\FormUrl for HTML5 inputs with type url. Return type array 87. getInputSpecification() Returns a input filter specification. Basic Usage This element automatically adds a "type" attribute of value "url".0. 1 2 3 4 5 6 7 8 use Zend\Form\Element. use Zend\Form\Form. 446 Chapter 87. which includes a Zend\Filter\StringTrim filter. $url = new Element\Url(’webpage-url’). $form = new Form(’my-form’). Form Elements .6 One difference from Zend\Form\Element\DateTime is that the Zend\Validator\DateStep validator will expect the step attribute to use an interval of seconds (default is 60 seconds). Here is the same example using the array notation: 1 2 3 4 5 6 7 8 9 10 use Zend\Form\Form. Release 2. $url->setLabel(’Webpage URL’). This element adds filters and validators to it’s input filter specification in order to validate HTML5 week input values on the server.4. $form->add(array( ’type’ => ’Zend\Form\Element\Url’.Zend Framework 2 Documentation.11 Week Zend\Form\Element\Week is meant to be paired with the Zend\Form\View\Helper\FormWeek for HTML5 inputs with type week. $form = new Form(’my-form’).

$form = new Form(’my-form’). $form = new Form(’my-form’). default step interval is 1 week ) )). ’attributes’ => array( ’min’ => ’2012-W01’. Otherwise. the default input specification for the element may not contain the correct validation rules. One difference from Zend\Form\Element\DateTime is that the Zend\Validator\DateStep validator will expect the step attribute to use an interval of weeks (default is 1 week).0. max. $form->add(array( ’type’ => ’Zend\Form\Element\Week’.Zend Framework 2 Documentation. and step attributes. ’options’ => array( ’label’ => ’Week’ ). $week = new Element\Week(’week’).6 Basic Usage This element automatically adds a "type" attribute of value "week". default step interval is 1 week )). Public Methods The following methods are in addition to the inherited methods of Zend\Form\Element\DateTime. use Zend\Form\Form. ’step’ => ’1’. Note: Note: the min. ’max’ => ’2020-W01’. // weeks. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Zend\Form\Element. ’name’ => ’week’. Return type array 87. $week ->setLabel(’Week’) ->setAttributes(array( ’min’ => ’2012-W01’. $form->add($week). ’step’ => ’1’. which includes Zend\Filter\StringTrim and will add the appropriate validators based on the values from the min. Release 2. max. HTML5 Elements 447 . ’max’ => ’2020-W01’. getInputSpecification() Returns a input filter specification.4. See getInputSpecification in Zend\Form\Element\DateTime for more information. // weeks. and step attributes should be set prior to calling Zend\Form::prepare(). Here is the same example using the array notation: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Zend\Form\Form.

6 448 Chapter 87. Form Elements .0.Zend Framework 2 Documentation. Release 2.

88.render the form elements. ’post’).. // </form> The following public methods are in addition to those inherited from Zend\Form\View\Helper\AbstractHelper.g...add elements and input filter to form. // . // Render the opening tag echo $this->form()->openTag($form)..1 Introduction Zend Framework comes with an initial set of helper classes related to Forms: e.2 Standard Helpers 88.2.. selection box..CHAPTER EIGHTYEIGHT FORM VIEW HELPERS 88.. // Prepare the form elements $form->prepare(). use Zend\Form\Element. See the section on view helpers for more information.. 449 . or plugin. // Within your view. rendering a text input. $form = new Form(). // Render the closing tag echo $this->form()->closeTag().. // Set attributes $form->setAttribute(’action’.. You can use helper.1 Form The Form view helper is used to render a <form> HTML element and its attributes. // <form action="/contact/process" method="post"> // . Basic usage: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 use Zend\Form\Form. classes to perform these behaviors for you.. $this->url(’contact/process’)). or form labels. $form->setAttribute(’method’.

Return type string closeTag() Renders a </form> closing tag. Return type string 88. // Within your view. // </button> /** * Example #3: Override the element label */ echo $this->formButton()->render($element.Zend Framework 2 Documentation.. Return type string closeTag() Renders a </button> closing tag. */ echo $this->formButton($element). Return type string 450 Chapter 88. Basic usage: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 use Zend\Form\Element. /** * Example #1: Render entire button in one shot. $element->setLabel("Reset").. // <button name="my-button" type="button"> echo ’<span class="inner">’ .. $element->getLabel() . // Render the closing tag echo $this->formButton()->closeTag(). // <button name="my-button" type="button">My Content</button> The following public methods are in addition to those inherited from Zend\Form\View\Helper\FormInput.0.2 FormButton The FormButton view helper is used to render a <button> HTML element and its attributes.6 openTag(FormInterface $form = null) Renders the <form> open tag for the $form instance. Release 2.2.. // <button name="my-button" type="button">Reset</button> /** * Example #2: Render button in 3 steps */ // Render the opening tag echo $this->formButton()->openTag($element). ’</span>’. $element = new Element\Button(’my-button’). ’My Content’). openTag($element = null) Renders the <button> open tag for the $element instance. Form View Helpers .

Zend Framework 2 Documentation, Release 2.0.6

render(ElementInterface $element[, $buttonContent = null ]) Renders a button’s opening tag, inner content, and closing tag. Parameters • $element – The button element. • $buttonContent – (optional) The inner content to render. If null, will default to the $element‘s label. Return type string

88.2.3 FormCaptcha
TODO Basic usage:
1 2 3 4 5 6 7 8 9 10 11 12 13

use Zend\Captcha; use Zend\Form\Element; $captcha = new Element\Captcha(’captcha’); $captcha ->setCaptcha(new Captcha\Dumb()) ->setLabel(’Please verify you are human’); // Within your view... echo $this->formCaptcha($captcha); // TODO

88.2.4 FormCheckbox
The FormCheckbox view helper can be used to render a <input type="checkbox"> HTML form input. It is meant to work with the Zend\Form\Element\Checkbox element, which provides a default input specification for validating the checkbox values. FormCheckbox extends from Zend\Form\View\Helper\FormInput. Basic usage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

use Zend\Form\Element; $element = new Element\Checkbox(’my-checkbox’); // Within your view... /** * Example #1: Default options */ echo $this->formCheckbox($element); // <input type="hidden" name="my-checkbox" value="0"> // <input type="checkbox" name="my-checkbox" value="1"> /** * Example #2: Disable hidden element */ $element->setUseHiddenElement(false); echo $this->formCheckbox($element); // <input type="checkbox" name="my-checkbox" value="1">

88.2. Standard Helpers

451

Zend Framework 2 Documentation, Release 2.0.6

21 22 23 24 25 26 27 28 29

/** * Example #3: Change checked/unchecked values */ $element->setUseHiddenElement(true) ->setUncheckedValue(’no’) ->setCheckedValue(’yes’); echo $this->formCheckbox($element); // <input type="hidden" name="my-checkbox" value="no"> // <input type="checkbox" name="my-checkbox" value="yes">

88.2.5 FormCollection
TODO Basic usage: TODO

88.2.6 FormElement
The FormElement view helper proxies the rendering to specific form view helpers depending on the type of the Zend\\Form\\Element that is passed in. For instance, if the passed in element had a type of “text”, the FormElement helper will retrieve and use the FormText helper to render the element. Basic usage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

use Zend\Form\Form; use Zend\Form\Element; // Within your view... /** * Example #1: Render different types of form elements */ $textElement = new Element\Text(’my-text’); $checkboxElement = new Element\Checkbox(’my-checkbox’); echo $this->formElement($textElement); // <input type="text" name="my-text" value=""> echo $this->formElement($checkboxElement); // <input type="hidden" name="my-checkbox" value="0"> // <input type="checkbox" name="my-checkbox" value="1"> /** * Example #2: Loop through form elements and render them */ $form = new Form(); // ...add elements and input filter to form... $form->prepare(); // Render the opening tag echo $this->form()->openTag($form); // ...loop through and render the form elements... foreach ($form as $element) { echo $this->formElement($element); // <-- Magic! echo $this->formElementErrors($element);

452

Chapter 88. Form View Helpers

Zend Framework 2 Documentation, Release 2.0.6

33 34 35 36

} // Render the closing tag echo $this->form()->closeTag();

88.2.7 FormElementErrors
The FormElementErrors view helper is used to render the validation error messages of an element. Basic usage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

use use use use

Zend\Form\Form; Zend\Form\Element; Zend\InputFilter\InputFilter; Zend\InputFilter\Input;

// Create a form $form = new Form(); $element = new Element\Text(’my-text’); $form->add($element); // Create a input $input = new Input(’my-text’); $input->setRequired(true); $inputFilter = new InputFilter(); $inputFilter->add($input); $form->setInputFilter($inputFilter); // Force a failure $form->setData(array()); // Empty data $form->isValid(); // Not valid // Within your view... /** * Example #1: Default options */ echo $this->formElementErrors($element); // <ul><li>Value is required and can&#039;t be empty</li></ul> /** * Example #2: Add attributes to open format */ echo $this->formElementErrors($element, array(’class’ => ’help-inline’)); // <ul class="help-inline"><li>Value is required and can&#039;t be empty</li></ul> /** * Example #3: Custom format */ echo $this->formElementErrors() ->setMessageOpenFormat(’<div class="help-inline">’) ->setMessageSeparatorString(’</div><div class="help-inline">’) ->setMessageCloseString(’</div>’) ->render($element); // <div class="help-inline">Value is required and can&#039;t be empty</div>

88.2. Standard Helpers

453

Zend Framework 2 Documentation, Release 2.0.6

The following public methods are in addition to those inherited from Zend\Form\View\Helper\AbstractHelper. setMessageOpenFormat(string $messageOpenFormat) Set the formatted string used to open message representation. Parameters $messageOpenFormat – The formatted string to use to open the messages. Uses ’<ul%s><li>’ by default. Attributes are inserted here. getMessageOpenFormat() Returns the formatted string used to open message representation. Return type string setMessageSeparatorString(string $messageSeparatorString) Sets the string used to separate messages. Parameters $messageSeparatorString – The string to use to separate the messages. ’</li><li>’ by default. getMessageSeparatorString() Returns the string used to separate messages. Return type string setMessageCloseString(string $messageCloseString) Sets the string used to close message representation. Parameters $messageCloseString – The string to use to close the messages. ’</li></ul>’ by default. getMessageCloseString() Returns the string used to close message representation. Return type string setAttributes(array $attributes) Set the attributes that will go on the message open format. Parameters $attributes – Key value pairs of attributes. getAttributes() Returns the attributes that will go on the message open format. Return type array render(ElementInterface $element[, array $attributes = array() ]) Renders validation errors for the provided $element. Parameters • $element – The element. • $attributes – Additional attributes that will go on the message open format. These are merged with those set via setAttributes(). Return type string Uses Uses

88.2.8 FormFile
TODO Basic usage: TODO

454

Chapter 88. Form View Helpers

Zend Framework 2 Documentation, Release 2.0.6

88.2.9 FormHidden
The FormHidden view helper can be used to render a <input type="hidden"> HTML form input. It is meant to work with the Zend\Form\Element\Hidden element. FormHidden extends from Zend\Form\View\Helper\FormInput. Basic usage:
1 2 3 4 5 6 7 8 9

use Zend\Form\Element; $element = new Element\Hidden(’my-hidden’); $element->setValue(’foo’); // Within your view... echo $this->formHidden($element); // <input type="hidden" name="my-hidden" value="foo">

88.2.10 FormImage
The FormImage view helper can be used to render a <input type="image"> HTML form input. It is meant to work with the Zend\Form\Element\Image element. FormImage extends from Zend\Form\View\Helper\FormInput. Basic usage:
1 2 3 4 5 6 7 8 9

use Zend\Form\Element; $element = new Element\Image(’my-image’); $element->setAttribute(’src’, ’/img/my-pic.png’); // Within your view... echo $this->formImage($element); // <input type="image" name="my-image" src="/img/my-pic.png">

88.2.11 FormInput
The FormInput view helper is used to render a <input> HTML form input tag. It acts as a base class for all of the specifically typed form input helpers (FormText, FormCheckbox, FormSubmit, etc.), and is not suggested for direct use. It contains a general map of valid tag attributes and types for attribute filtering. Each subclass of FormInput implements it’s own specific map of valid tag attributes. The following public methods are in addition to those inherited from Zend\Form\View\Helper\AbstractHelper. render(ElementInterface $element) Renders the <input> tag for the $element. Return type string

88.2.12 FormLabel
The FormLabel view helper is used to render a <label> HTML element and its attributes. If you have a Zend\\I18n\\Translator\\Translator attached, FormLabel will translate the label contents during it’s rendering. Basic usage:

88.2. Standard Helpers

455

Zend Framework 2 Documentation, Release 2.0.6

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

use Zend\Form\Element; $element = new Element\Text(’my-text’); $element->setLabel(’Label’) ->setAttribute(’id’, ’text-id’) ->setLabelAttributes(array(’class’ => ’control-label’)); // Within your view... /** * Example #1: Render label in one shot */ echo $this->formLabel($element); // <label class="control-label" for="text-id">Label</label> echo $this->formLabel($element, $this->formText($element)); // <label class="control-label" for="text-id">Label<input type="text" name="my-text"></label> echo $this->formLabel($element, $this->formText($element), ’append’); // <label class="control-label" for="text-id"><input type="text" name="my-text">Label</label> /** * Example #2: Render label in separate steps */ // Render the opening tag echo $this->formLabel()->openTag($element); // <label class="control-label" for="text-id"> // Render the closing tag echo $this->formLabel()->closeTag(); // </label>

Attaching a translator and setting a text domain:
1 2 3 4 5 6 7 8

// Setting a translator $this->formLabel()->setTranslator($translator); // Setting a text domain $this->formLabel()->setTranslatorTextDomain(’my-text-domain’); // Setting both $this->formLabel()->setTranslator($translator, ’my-text-domain’);

Note: Note: If you have a translator in the Service Manager under the key, ‘translator’, the view helper plugin manager will automatically attach the translator to the FormLabel view helper. See Zend\\View\\HelperPluginManager::injectTranslator() for more information. The following public methods are in addition to those inherited from Zend\Form\View\Helper\AbstractHelper. __invoke(ElementInterface $element = null, string $labelContent = null, string $position = null) Render a form label, optionally with content. Always generates a “for” statement, as we cannot assume the form input will be provided in the $labelContent. Parameters • $element – A form element.

456

Chapter 88. Form View Helpers

Zend Framework 2 Documentation, Release 2.0.6

• $labelContent – If null, will attempt to use the element’s label value. • $position – Append or prepend the element’s label value to the $labelContent. One of FormLabel::APPEND or FormLabel::PREPEND (default) Return type string openTag(array|ElementInterface $attributesOrElement = null) Renders the <label> open tag and attributes. Parameters $attributesOrElement – An array of key value attributes or a ElementInterface instance. Return type string closeTag() Renders a </label> closing tag. Return type string

88.2.13 FormMultiCheckbox
The FormMultiCheckbox view helper can be used to render a group <input type="checkbox"> HTML form inputs. It is meant to work with the Zend\Form\Element\MultiCheckbox element, which provides a default input specification for validating the a multi checkbox. FormMultiCheckbox extends from Zend\Form\View\Helper\FormInput. Basic usage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

use Zend\Form\Element; $element = new Element\MultiCheckbox(’my-multicheckbox’); $element->setValueOptions(array( ’0’ => ’Apple’, ’1’ => ’Orange’, ’2’ => ’Lemon’, )); // Within your view... /** * Example #1: using the default label placement */ echo $this->formMultiCheckbox($element); // <label><input type="checkbox" name="my-multicheckbox[]" value="0">Apple</label> // <label><input type="checkbox" name="my-multicheckbox[]" value="1">Orange</label> // <label><input type="checkbox" name="my-multicheckbox[]" value="2">Lemon</label> /** * Example #2: using the prepend label placement */ echo $this->formMultiCheckbox($element, ’prepend’); // <label>Apple<input type="checkbox" name="my-multicheckbox[]" value="0"></label> // <label>Orange<input type="checkbox" name="my-multicheckbox[]" value="1"></label> // <label>Lemon<input type="checkbox" name="my-multicheckbox[]" value="2"></label>

88.2.14 FormPassword
TODO Basic usage:

88.2. Standard Helpers

457

Zend Framework 2 Documentation, Release 2.0.6

TODO

88.2.15 FormRadio
The FormRadio view helper can be used to render a group <input type="radio"> HTML form inputs. It is meant to work with the Zend\Form\Element\Radio element, which provides a default input specification for validating a radio. FormRadio extends from Zend\Form\View\Helper\FormMultiCheckbox. Basic usage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

use Zend\Form\Element; $element = new Element\Radio(’gender’); $element->setValueOptions(array( ’0’ => ’Male’, ’1’ => ’Female’, )); // Within your view... /** * Example #1: using the default label placement */ echo $this->formRadio($element); // <label><input type="radio" name="gender[]" value="0">Male</label> // <label><input type="radio" name="gender[]" value="1">Female</label> /** * Example #2: using the prepend label placement */ echo $this->formRadio($element, ’prepend’); // <label>Male<input type="checkbox" name="gender[]" value="0"></label> // <label>Female<input type="checkbox" name="gender[]" value="1"></label>

88.2.16 FormReset
TODO Basic usage: TODO

88.2.17 FormRow
TODO Basic usage: TODO

88.2.18 FormSelect
The FormSelect view helper can be used to render a group <input type="select"> HTML form input. It is meant to work with the Zend\Form\Element\Select element, which provides a default input specification for validating a select. FormSelect extends from Zend\Form\View\Helper\FormInput. Basic usage:

458

Chapter 88. Form View Helpers

Zend Framework 2 Documentation, Release 2.0.6

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

use Zend\Form\Element; $element = new Element\Select(’language’); $element->setValueOptions(array( ’0’ => ’French’, ’1’ => ’English’, ’2’ => ’Japanese’, ’3’ => ’Chinese’ )); // Within your view... /** * Example */ echo $this->formSelect($element);

88.2.19 FormSubmit
TODO Basic usage: TODO

88.2.20 FormText
TODO Basic usage: TODO

88.2.21 FormTextarea
TODO Basic usage: TODO

88.2.22 AbstractHelper
The AbstractHelper is used as a base abstract class for Form view helpers, providing methods for validating form HTML attributes, as well as controlling the doctype and character encoding. AbstractHelper also extends from Zend\I18n\View\Helper\AbstractTranslatorHelper which provides an implementation for the Zend\I18n\Translator\TranslatorAwareInterface that allows setting a translator and text domain. The following public methods are in addition to the inherited methods of Zend\I18n\View\Helper\AbstractTranslatorHelper. setDoctype(string $doctype) Sets a doctype to use in the helper. getDoctype() Returns the doctype used in the helper. Return type string setEncoding(string $encoding) Set the translation text domain to use in helper when translating.

88.2. Standard Helpers

459

Zend Framework 2 Documentation, Release 2.0.6

getEncoding() Returns the character encoding used in the helper. Return type string getId() Returns the element id. If no ID attribute present, attempts to use the name attribute. If name attribute is also not present, returns null. Return type string or null

88.3 HTML5 Helpers
88.3.1 FormColor
The FormColor view helper can be used to render a <input type="color"> HTML5 form input. It is meant to work with the Zend\Form\Element\Color element, which provides a default input specification for validating HTML5 color values. FormColor extends from Zend\Form\View\Helper\FormInput. Basic usage:
1 2 3 4 5 6 7 8

use Zend\Form\Element; $element = new Element\Color(’my-color’); // Within your view... echo $this->formColor($element); // <input type="color" name="my-color" value="">

88.3.2 FormDate
The FormDate view helper can be used to render a <input type="date"> HTML5 form input. It is meant to work with the Zend\Form\Element\Date element, which provides a default input specification for validating HTML5 date values. FormDate extends from Zend\Form\View\Helper\FormDateTime. Basic usage:
1 2 3 4 5 6 7 8

use Zend\Form\Element; $element = new Element\Date(’my-date’); // Within your view... echo $this->formDate($element); // <input type="date" name="my-date" value="">

88.3.3 FormDateTime
The FormDateTime view helper can be used to render a <input type="datetime"> HTML5 form input. It is meant to work with the Zend\Form\Element\DateTime element, which provides a default input specification for validating HTML5 datetime values. FormDateTime extends from Zend\Form\View\Helper\FormInput. Basic usage:

460

Chapter 88. Form View Helpers

Zend Framework 2 Documentation, Release 2.0.6

1 2 3 4 5 6 7 8

use Zend\Form\Element; $element = new Element\DateTime(’my-datetime’); // Within your view... echo $this->formDateTime($element); // <input type="datetime" name="my-datetime" value="">

88.3.4 FormDateTimeLocal
The FormDateTimeLocal view helper can be used to render a <input type="datetime-local"> HTML5 form input. It is meant to work with the Zend\Form\Element\DateTimeLocal element, which provides a default input specification for validating HTML5 datetime values. FormDateTimeLocal extends from Zend\Form\View\Helper\FormDateTime. Basic usage:
1 2 3 4 5 6 7 8

use Zend\Form\Element; $element = new Element\DateTimeLocal(’my-datetime’); // Within your view... echo $this->formDateTimeLocal($element); // <input type="datetime-local" name="my-datetime" value="">

88.3.5 FormEmail
The FormEmail view helper can be used to render a <input type="email"> HTML5 form input. It is meant to work with the Zend\Form\Element\Email element, which provides a default input specification with an email validator. FormEmail extends from Zend\Form\View\Helper\FormInput. Basic usage:
1 2 3 4 5 6 7 8

use Zend\Form\Element; $element = new Element\Email(’my-email’); // Within your view... echo $this->formEmail($element); // <input type="email" name="my-email" value="">

88.3.6 FormMonth
The FormMonth view helper can be used to render a <input type="month"> HTML5 form input. It is meant to work with the Zend\Form\Element\Month element, which provides a default input specification for validating HTML5 date values. FormMonth extends from Zend\Form\View\Helper\FormDateTime. Basic usage:
1 2 3 4 5

use Zend\Form\Element; $element = new Element\Month(’my-month’); // Within your view...

88.3. HTML5 Helpers

461

Zend Framework 2 Documentation, Release 2.0.6

6 7 8

echo $this->formMonth($element); // <input type="month" name="my-month" value="">

88.3.7 FormNumber
TODO Basic usage: TODO

88.3.8 FormRange
TODO Basic usage: TODO

88.3.9 FormSearch
TODO Basic usage: TODO

88.3.10 FormTel
TODO Basic usage: TODO

88.3.11 FormTime
The FormTime view helper can be used to render a <input type="time"> HTML5 form input. It is meant to work with the Zend\Form\Element\Time element, which provides a default input specification for validating HTML5 time values. FormTime extends from Zend\Form\View\Helper\FormDateTime. Basic usage:
1 2 3 4 5 6 7 8

use Zend\Form\Element; $element = new Element\Time(’my-time’); // Within your view... echo $this->formTime($element); // <input type="time" name="my-time" value="">

88.3.12 FormUrl
TODO Basic usage: TODO

462

Chapter 88. Form View Helpers

Zend Framework 2 Documentation, Release 2.0.6

88.3.13 FormWeek
The FormWeek view helper can be used to render a <input type="week"> HTML5 form input. It is meant to work with the Zend\Form\Element\Week element, which provides a default input specification for validating HTML5 week values. FormWeek extends from Zend\Form\View\Helper\FormDateTime. Basic usage:
1 2 3 4 5 6 7 8

use Zend\Form\Element; $element = new Element\Week(’my-week’); // Within your view... echo $this->formWeek($element); // <input type="week" name="my-week" value="">

88.3. HTML5 Helpers

463

Zend Framework 2 Documentation, Release 2.0.6

464

Chapter 88. Form View Helpers

CHAPTER

EIGHTYNINE

OVERVIEW OF ZEND\HTTP
89.1 Overview
Zend\Http is a primary foundational component of Zend Framework. Since much of what PHP does is web-based, specifically HTTP, it makes sense to have a performant, extensible, concise and consistent API to do all things HTTP. In nutshell, there are several parts of Zend\Http: • Context-less Request and Response classes that expose a fluent API for introspecting several aspects of HTTP messages: – Request line information and response status information – Parameters, such as those found in POST and GET – Message Body – Headers • A Client implementation with various adapters that allow for sending requests and introspecting responses.

89.2 Zend\Http Request, Response and Headers
The Request, Response and Headers portion of the Zend\Http component provides a fluent, object-oriented interface for introspecting information from all the various parts of an HTTP request or HTTP response. The two main objects are Zend\Http\Request and Zend\Http\Response. These two classes are “context-less”, meaning that they model a request or response in the same way whether it is presented by a client (to send a request and receive a response) or by a server (to receive a request and send a response). In other words, regardless of the context, the API remains the same for introspecting their various respective parts. Each attempts to fully model a request or response so that a developer can create these objects from a factory, or create and populate them manually.

465

Zend Framework 2 Documentation, Release 2.0.6

466

Chapter 89. Overview of Zend\Http

CHAPTER

NINETY

THE REQUEST CLASS
90.1 Overview
The Zend\Http\Request object is responsible for providing a fluent API that allows a developer to interact with all the various parts of an HTTP request. A typical HTTP request looks like this:
-------------------------| METHOD | URI | VERSION | -------------------------| HEADERS | -------------------------| BODY | --------------------------

In simplified terms, the request consists of a method, URI and HTTP version number which together make up the “Request Line.” Next come the HTTP headers, of which there can be 0 or more. After that is the request body, which is typically used when a client wishes to send data to the server in the form of an encoded file, or include a set of POST parameters, for example. More information on the structure and specification of a HTTP request can be found in RFC-2616 on the W3.org site.

90.2 Quick Start
Request objects can either be created from the provided fromString() factory, or, if you wish to have a completely empty object to start with, by simply instantiating the Zend\Http\Request class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

use Zend\Http\Request; $request = Request::fromString(<<<EOS POST /foo HTTP/1.1 \r\n HeaderField1: header-field-value1 HeaderField2: header-field-value2 \r\n\r\n foo=bar& EOS ); // OR, the completely equivalent $request = new Request();

467

Zend Framework 2 Documentation, Release 2.0.6

16 17 18 19 20 21 22

$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’);

90.3 Configuration Options
No configuration options are available.

90.4 Available Methods
Request::fromString Request::fromString(string $string) A factory that produces a Request object from a well-formed HTTP Request string. Returns Zend\Http\Request setMethod setMethod(string $method) Set the method for this request. Returns Zend\Http\Request getMethod getMethod() Return the method for this request. Returns string setUri setUri(string|Zend\Uri\Http $uri) Set the URI/URL for this request; this can be a string or an instance of Zend\Uri\Http. Returns Zend\Http\Request getUri getUri() Return the URI for this request object. Returns Zend\Uri\Http getUriString getUriString() Return the URI for this request object as a string. Returns string setVersion setVersion(string $version) Set the HTTP version for Request::VERSION_11). Returns Zend\Http\Request getVersion getVersion() Return the HTTP version for this request. Returns string 468 Chapter 90. The Request Class this object, one of 1.0 or 1.1 (Request::VERSION_10,

Zend Framework 2 Documentation, Release 2.0.6

setQuery setQuery(Zend\Stdlib\ParametersInterface $query) Provide an alternate Parameter Container implementation for query parameters in this object. (This is NOT the primary API for value setting; for that, see getQuery()). Returns Zend\Http\Request getQuery getQuery(string|null $name, mixed|null $default) Return the parameter container responsible for query parameters or a single query parameter. Returns string, Zend\Stdlib\ParametersInterface, or null depending on value of $name argument. setPost setPost(Zend\Stdlib\ParametersInterface $post) Provide an alternate Parameter Container implementation for POST parameters in this object. (This is NOT the primary API for value setting; for that, see getPost()). Returns Zend\Http\Request getPost getPost(string|null $name, mixed|null $default) Return the parameter container responsible for POST parameters or a single POST parameter. Returns string, Zend\Stdlib\ParametersInterface, or null depending on value of $name argument. getCookie getCookie() Return the Cookie header, this is the same as calling $request->getHeaders()->get(‘Cookie’);. Returns Zend\Http\Header\Cookie setFiles setFiles(Zend\Stdlib\ParametersInterface $files) Provide an alternate Parameter Container implementation for file parameters in this object, (This is NOT the primary API for value setting; for that, see getFiles()). Returns Zend\Http\Request getFiles getFiles(string|null $name, mixed|null $default) Return the parameter container responsible for file parameters or a single file parameter. Returns string, Zend\Stdlib\ParametersInterface, or null depending on value of $name argument. setHeaders setHeaders(Zend\Http\Headers $headers) Provide an alternate Parameter Container implementation for headers in this object, (this is NOT the primary API for value setting, for that see getHeaders()). Returns Zend\Http\Request getHeaders getHeaders(string|null $name, mixed|null $default) Return the container responsible for storing HTTP headers. This container exposes the primary API for manipulating headers set in the HTTP request. See the section on Zend\Http\Headers for more information. Returns Zend\Http\Headers if $name is null. Returns Zend\Http\Header\HeaderInterface or ArrayIterator if $name matches one or more stored headers, respectively. setMetadata setMetadata(string|int|array|Traversable $spec, mixed $value) Set message metadata.

90.4. Available Methods

469

Zend Framework 2 Documentation, Release 2.0.6

Non-destructive setting of message metadata; always adds to the metadata, never overwrites the entire metadata container. Returns Zend\Http\Request getMetadata getMetadata(null|string|int $key, null|mixed $default) Retrieve all metadata or a single metadatum as specified by key. Returns mixed setContent setContent(mixed $value) Set request body (content). Returns Zend\Http\Request getContent getContent() Get request body (content). Returns mixed isOptions isOptions() Is this an OPTIONS method request? Returns bool isGet isGet() Is this a GET method request? Returns bool isHead isHead() Is this a HEAD method request? Returns bool isPost isPost() Is this a POST method request? Returns bool isPut isPut() Is this a PUT method request? Returns bool isDelete isDelete() Is this a DELETE method request? Returns bool isTrace isTrace() Is this a TRACE method request? Returns bool isConnect isConnect() Is this a CONNECT method request? Returns bool

470

Chapter 90. The Request Class

Zend Framework 2 Documentation, Release 2.0.6

isPatch isPatch() Is this a PATCH method request? Returns bool isXmlHttpRequest isXmlHttpRequest() Is this a Javascript XMLHttpRequest? Returns bool isFlashRequest isFlashRequest() Is this a Flash request? Returns bool renderRequestLine renderRequestLine() Return the formatted request line (first line) for this HTTP request. Returns string toString toString() Returns string __toString __toString() Allow PHP casting of this object. Returns string

90.5 Examples
Generating a Request object from a string use Zend\Http\Request; $string = "GET /foo HTTP/1.1\r\n\r\nSome Content"; $request = Request::fromString($string); $request->getMethod(); $request->getUri(); $request->getUriString(); $request->getVersion(); $request->getContent(); // // // // // returns returns returns returns returns Request::METHOD_GET Zend\Uri\Http object ’/foo’ Request::VERSION_11 or ’1.1’ ’Some Content’

1 2 3 4 5 6 7 8 9 10

Retrieving and setting headers use Zend\Http\Request; use Zend\Http\Header\Cookie; $request = new Request(); $request->getHeaders()->get(’Content-Type’); // return content type $request->getHeaders()->addHeader(new Cookie(array(’foo’ => ’bar’))); foreach ($request->getHeaders() as $header) { echo $header->getFieldName() . ’ with value ’ . $header->getFieldValue(); }

1 2 3 4 5 6 7 8 9

90.5. Examples

471

Zend Framework 2 Documentation, Release 2.0.6

Retrieving and setting GET and POST values use Zend\Http\Request; $request = new Request(); // getPost() and getQuery() both return, by default, a Parameters object, which extends ArrayObject $request->getPost()->foo = ’Foo value’; $request->getQuery()->bar = ’Bar value’; $request->getPost(’foo’); // returns ’Foo value’ $request->getQuery()->offsetGet(’bar’); // returns ’Bar value’

1 2 3 4 5 6 7 8 9

Generating a formatted HTTP Request from a Request object use Zend\Http\Request; $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’); echo $request->toString(); /** Will produce: POST /foo HTTP/1.1 HeaderField1: header-field-value1 HeaderField2: header-field-value2 foo=bar */

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

472

Chapter 90. The Request Class

CHAPTER

NINETYONE

THE RESPONSE CLASS
91.1 Overview
The Zend\Http\Response class is responsible for providing a fluent API that allows a developer to interact with all the various parts of an HTTP response. A typical HTTP Response looks like this:
--------------------------| VERSION | CODE | REASON | --------------------------| HEADERS | --------------------------| BODY | ---------------------------

The first line of the response consists of the HTTP version, status code, and the reason string for the provided status code; this is called the Response Line. Next is a set of headers; there can be 0 or an unlimited number of headers. The remainder of the response is the response body, which is typically a string of HTML that will render on the client’s browser, but which can also be a place for request/response payload data typical of an AJAX request. More information on the structure and specification of an HTTP response can be found in RFC-2616 on the W3.org site.

91.2 Quick Start
Response objects can either be created from the provided fromString() factory, or, if you wish to have a completely empty object to start with, by simply instantiating the Zend\Http\Response class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

use Zend\Http\Response; $response = Response::fromString(<<<EOS HTTP/1.0 200 OK HeaderField1: header-field-value HeaderField2: header-field-value2 <html> <body> Hello World </body> </html> EOS); // OR

473

Zend Framework 2 Documentation, Release 2.0.6

16 17 18 19 20 21 22 23 24 25 26 27 28

$response = new Response(); $response->setStatusCode(Response::STATUS_CODE_200); $response->getHeaders()->addHeaders(array( ’HeaderField1’ => ’header-field-value’, ’HeaderField2’ => ’header-field-value2’, ); $response->setContent(<<<EOS <html> <body> Hello World </body> </html> EOS);

91.3 Configuration Options
No configuration options are available.

91.4 Available Methods
Response::fromString Response::fromString(string $string) Populate object from string Returns Zend\Http\Response renderStatusLine renderStatusLine() Render the status line header Returns string setHeaders setHeaders(Zend\Http\Headers $headers) Provide an alternate Parameter Container implementation for headers in this object. (This is NOT the primary API for value setting; for that, see getHeaders().) Returns Zend\Http\Request getHeaders getHeaders() Return the container responsible for storing HTTP headers. This container exposes the primary API for manipulating headers set in the HTTP response. See the section on Zend\Http\Headers for more information. Returns Zend\Http\Headers setVersion setVersion(string $version) Set the HTTP version for Request::VERSION_11). Returns Zend\Http\Request. getVersion getVersion() Return the HTTP version for this request Returns string this object, one of 1.0 or 1.1 (Request::VERSION_10,

474

Chapter 91. The Response Class

0. Available Methods 475 . Release 2.Zend Framework 2 Documentation.6 setStatusCode setStatusCode(numeric $code) Set HTTP status code Returns Zend\Http\Response getStatusCode getStatusCode() Retrieve HTTP status code Returns int setReasonPhrase setReasonPhrase(string $reasonPhrase) Set custom HTTP status message Returns Zend\Http\Response getReasonPhrase getReasonPhrase() Get HTTP status message Returns string isClientError isClientError() Does the status code indicate a client error? Returns bool isForbidden isForbidden() Is the request forbidden due to ACLs? Returns bool isInformational isInformational() Is the current status “informational”? Returns bool isNotFound isNotFound() Does the status code indicate the resource is not found? Returns bool isOk isOk() Do we have a normal.4. OK response? Returns bool isServerError isServerError() Does the status code reflect a server error? Returns bool isRedirect isRedirect() Do we have a redirect? Returns bool isSuccess isSuccess() Was the response successful? Returns bool 91.

null|mixed $default) Retrieve all metadata or a single metadatum as specified by key Returns mixed setContent setContent(mixed $value) Set message content Returns Zend\Stdlib\Message getContent getContent() Get message content Returns mixed toString toString() Returns string 91. Release 2. mixed $value) Set message metadata Non-destructive setting of message metadata. The Response Class .5 Examples Generating a Response object from a string use Zend\Http\Response.6 decodeChunkedBody decodeChunkedBody(string $body) Decode a “chunked” transfer-encoded body and return the decoded text Returns string decodeGzip decodeGzip(string $body) Decode a gzip encoded message (when Content-encoding = gzip) Currently requires PHP with zlib support Returns string decodeDeflate decodeDeflate(string $body) Decode a zlib deflated message (when Content-encoding = deflate) Currently requires PHP with zlib support Returns string setMetadata setMetadata(string|int|array|Traversable $spec.Zend Framework 2 Documentation. $request = Response::fromString(<<<EOS HTTP/1.0.0 200 OK HeaderField1: header-field-value HeaderField2: header-field-value2 <html> <body> 1 2 3 4 5 6 7 8 476 Chapter 91. never overwrites the entire metadata container. always adds to the metadata. Returns Zend\Stdlib\Message getMetadata getMetadata(null|string|int $key.

0. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 91.Zend Framework 2 Documentation. $response->setContent(<<<EOS <html> <body> Hello World </body> </html> EOS). $response->getHeaders()->addHeaders(array( ’HeaderField1’ => ’header-field-value’.6 9 10 11 12 Hello World </body> </html> EOS). ). Generating a formatted HTTP Response from a Response object use Zend\Http\Response. ’HeaderField2’ => ’header-field-value2’. $response->setStatusCode(Response::STATUS_CODE_200). Release 2. Examples 477 .5. $response = new Response().

6 478 Chapter 91.0.Zend Framework 2 Documentation. Release 2. The Response Class .

CHAPTER NINETYTWO THE HEADERS CLASS 92.example. $headers = Zend\Http\Headers::fromString($headerString). Zend\Http\Headers can also extract headers from a string: 1 2 3 4 5 6 7 8 9 10 11 $headerString = <<<EOB Host: www.2 Quick Start The quickest way to get started interacting with header objects is by getting an already populated Headers container from a request or response object. 1 2 3 4 5 6 7 8 // $client is an instance of Zend\Http\Client // You can retrieve the request headers by first retrieving // the Request object and then calling getHeaders on it $requestHeaders = $client->getRequest()->getHeaders(). 479 . // The same method also works for retrieving Response headers $responseHeaders = $client->getResponse()->getHeaders().1 Overview The Zend\Http\Headers class is a container for HTTP headers. it will be implemented as a Zend\Http\Header\GenericHeader instance. The Zend\Http\Header\* classes are the domain specific implementations for the various types of Headers that one might encounter during the typical HTTP request. The Headers container will lazily load actual Header objects as to reduce the overhead of header specific parsing. It is typically accessed as part of a Zend\Http\Request or Zend\Http\Response getHeaders() call. If a header of unknown type is encountered. 92.com Content-Type: text/html Content-Length: 1337 EOB. // $headers is now populated with three objects // (1) Zend\Http\Header\Host // (2) Zend\Http\Header\ContentType // (3) Zend\Http\Header\ContentLength Now that you have an instance of Zend\Http\Headers you can manipulate the individual headers it contains using the provided public API methods outlined in the “Available Methods” section. See the below table for a list of the various HTTP headers and the API that is specific to each header type.

3 Configuration Options No configuration options are available. Returns Zend\Http\Headers addHeader addHeader(Zend\Http\Header\HeaderInterface $header) Add a Header to this container. or as a single string ‘name: value’ This method allows for lazy-loading in that the parsing and instantiation of Header object will be delayed until they are retrieved by either get() or current(). either in name => value. Returns Zend\Http\Headers removeHeader removeHeader(Zend\Http\Header\HeaderInterface $header) Remove a Header from the container Returns bool clearHeaders clearHeaders() Clear all headers Removes all headers from queue Returns Zend\Http\Headers 480 Chapter 92. The Headers Class . in order.6 92. 92. string $fieldValue) Add a raw header line. lazyload and inject map if necessary.0. in the current instance.4 Available Methods Headers::fromString Headers::fromString(string $string) Populates headers from string representation Parses a string for headers. and aggregates them. Returns Zend\Loader\PluginClassLocator addHeaders addHeaders(array|Traversable $headers) Add many headers at once Expects an array (or Traversable object) of type/value pairs. primarily as strings until they are needed (they will be lazy loaded). Returns Zend\Http\Headers setPluginClassLoader setPluginClassLoader(Zend\Loader\PluginClassLocator $pluginClassLoader) Set an alternate implementation for the plugin class loader Returns Zend\Http\Headers getPluginClassLoader getPluginClassLoader() Return an instance of a Zend\Loader\PluginClassLocator.Zend Framework 2 Documentation. Release 2. Returns Zend\Http\Headers addHeaderLine addHeaderLine(string $headerFieldNameOrLine. for raw values see addHeaderLine() and addHeaders().

Returns string toArray toArray() Return the headers container as an array Returns array forceLoading forceLoading() By calling this. If all headers have not been parsed. it will force parsing and loading of all headers.Zend Framework 2 Documentation. Release 2. after this count() will be accurate Returns bool 92. Available Methods 481 . iterate.4.6 get get(string $name) Get all headers of a certain name/type Returns false| Zend\Http\Header\HeaderInterface| ArrayIterator has has(string $name) Test for existence of a type of header Returns bool next next() Advance the pointer for this object as an interator Returns void key key() Return the current key for this object as an interator Returns mixed valid valid() Is this iterator still valid? Returns bool rewind rewind() Reset the internal pointer for this object as an iterator Returns void current current() Return the current value for this iterator. If you need an exact count. lazy loading it if need be Returns Zend\Http\Header\HeaderInterface count count() Return the number of headers in this container. it is up to the concrete classes to prepend with the appropriate status/request line. Returns int toString toString() Render all headers at once This method handles the normal iteration of headers. actual count could increase if MultipleHeader objects exist in the Request/Response.0.

6 92.Zend Framework 2 Documentation. The Headers Class .0.The age in delta seconds getAllowedMethods() / setAllowedMethods() .5 Zend\Http\Header\* Base Methods fromString fromString(string $headerLine) Factory to generate a header object from a string Returns Zend\Http\Header\GenericHeader getFieldName getFieldName() Retrieve header field name Returns string getFieldValue getFieldValue() Retrieve header field value Returns string toString toString() Cast to string as a well formed HTTP header line Returns in form of “NAME: VALUE\r\n” Returns string 92. Release 2.6 List of HTTP Header Types Class Name Accept AcceptCharset AcceptEncoding AcceptLanguage AcceptRanges Age Allow AuthenticationInfo Authorization CacheControl Connection ContentDisposition ContentEncoding ContentLanguage ContentLength ContentLocation ContentMD5 ContentRange ContentType Cookie Date Etag Additional Methods N/A N/A N/A N/A getRangeUnit() / setRangeUnit() .The range unit of the accept ranges header getDeltaSeconds() / setDeltaSeconds() .An array of allowed methods N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A Extends \ArrayObject setEncodeValue() / getEncodeValue() .Whether or not to encode values N/A N/A 482 Chapter 92.

6 Class Name Expect Expires From Host IfMatch IfModifiedSince IfNoneMatch IfRange IfUnmodifiedSince KeepAlive LastModified Location MaxForwards Pragma ProxyAuthenticate ProxyAuthorization Range Referer Refresh RetryAfter Server SetCookie TE Trailer TransferEncoding Upgrade UserAgent Vary Via Warning WWWAuthenticate Additional Methods N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A getName() / setName() .Zend Framework 2 Documentation.7 Examples Retrieving headers from a Zend\Http\Headers object // $client is an instance of Zend\Http\Client $response = $client->send().0.7. Returns boolean ‘‘TRUE‘‘ if at least // one matching header found. and ‘‘FALSE‘‘ otherwise $headers->has(’Content-Type’). $headers = $response->getHeaders().The cookie value getExpires() / setExpires() N/A N/A N/A N/A N/A N/A N/A N/A N/A 92. Examples 483 . 1 2 3 4 5 6 7 8 9 10 11 12 There are three possibilities for the return value of the above call to the get method: 92.The cookie name getValue() / setValue() . // We can check if the Request contains a specific header by // using the ‘‘has‘‘ method. // We can retrieve all instances of a specific header by using // the ‘‘get‘‘ method: $contentTypeHeaders = $headers->get(’Content-Type’). Release 2.

or we can pass the entire header as the only argument $headers->addHeaderLine(’Content-Type: text/html’). // We can also pass the header name as the array key and the // header content as that array key’s value ’Content-Type’ => ’text/html’). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Removing headers from a Zend\Http\Headers object We can remove all headers of a specific type using the removeHeader method. get will return false. The Headers Class . // We can directly add any object that implements Zend\Http\Header\HeaderInterface $typeHeader = Zend\Http\Header\ContentType::fromString(’Content-Type: text/html’). either // passing the header name and value as separate arguments. )). get will return an ArrayIterator containing one Zend\Http\Header\ContentType instance per header. // We can add headers using the raw string representation. ’text/html’). // We can also add headers in bulk using addHeaders. Zend\Http\Header\ContentType. Adding headers to a Zend\Http\Headers object $headers = new Zend\Http\Headers(). $headers->addHeaderLine(’Content-Type’. • If only one Content-Type header was set in the Request. Release 2. get will return an instance of • If more than one Content-Type header was set in the Request. which accepts // an array of individual header definitions that can be in any of // the accepted formats outlined below: $headers->addHeaders(array( // An object implementing Zend\Http\Header\HeaderInterface Zend\Http\Header\ContentType::fromString(’Content-Type: text/html’)...0. iterate over the collection // and remove each one individually if ($matches instanceof ArrayIterator) { foreach ($headers as $header) { $headers->removeHeader($header)..6 • If no Content-Type header was set in the Request. // A raw header string ’Content-Type: text/html’. // . $headers->addHeader($typeHeader). which accepts a single object implementing Zend\Http\Header\HeaderInterface 1 2 3 4 5 6 7 8 9 10 11 // $headers is a pre-configured instance of Zend\Http\Headers // We can also delete individual headers or groups of headers $matches = $headers->get(’Content-Type’).Zend Framework 2 Documentation. } 484 Chapter 92. // If more than one header was found.

remove it directly } elseif ($matches instanceof Zend\Http\Header\HeaderInterface) { $headers->removeHeader($header). Examples 485 .6 12 13 14 15 16 17 18 19 // If only a single header was found. Release 2.Zend Framework 2 Documentation. 92.7. we can clear all the headers currently stored in // the container by calling the clearHeaders() method $matches->clearHeaders().0. } // In addition to this.

0.Zend Framework 2 Documentation. Release 2.6 486 Chapter 92. The Headers Class .

CHAPTER NINETYTHREE HTTP CLIENT . Both can be left out. and an array or Zend\Config\Config object containing configuration options. and set later using the setUri() and setConfig() methods. Note: Zend\Http\Client uses Zend\Uri\Http to validate URLs. array( ’maxredirects’ => 0.OVERVIEW 93. $client->setUri(’http://example. Zend\Http\Client supports the most simple features expected from an HTTP client. See the Zend\Uri manual page for more information on the validation process. $client->setOptions($config). ’timeout’ => 30 )). which provides access to the response’s headers and body (see this section). // You can also pass a Zend\Config\Config object to set the client’s configuration $config = Zend\Config\Factory::fromFile(’httpclient. $client->setOptions(array( ’maxredirects’ => 0.1 Overview Zend\Http\Client provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests.org’). // This is actually exactly the same: $client = new Client(). Successful requests (and most unsuccessful ones too) return a Zend\Http\Response object. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 use Zend\Http\Client.2 Quick Start The class constructor optionally accepts a URL as its first parameter (can be either a string or a Zend\Uri\Http object). $client = new Client(’http://example. ’timeout’ => 30 )). 487 .ini’). 93.org’. as well as some more complex features such as HTTP authentication and file uploads.

Setting these parameters is optional.3 Configuration Options The constructor and setOptions() method accept an associative array of configuration parameters. 93.6 93.Overview . HTTP Client . it is seperated from ->send() to preserve logic and readability Returns Zend\Http\Client getAdapter getAdapter() Retrieve the connection adapter Returns Zend\Http\Client\Adapter\AdapterInterface setRequest setRequest(Zend\Http\Request $request) Set request object Returns void getRequest getRequest() Get Request object Returns Zend\Http\Request getLastRawRequest getLastRawRequest() Get the last request (as a string) Returns string setResponse setResponse(Zend\Http\Response $response) Set response Returns Zend\Http\Client getResponse getResponse() Get Response object Returns Zend\Http\Response 488 Chapter 93. array|Traversable $config) Constructor Returns void setOptions setOptions(array|Traversable $config = array ()) Set configuration parameters for this HTTP client Returns Zend\Http\Client setAdapter setAdapter(Zend\Http\Client\Adapter|string $adapter) Load the connection adapter While this method is not called more than once for a client. or a Zend\Config\Config object.0.Zend Framework 2 Documentation.4 Available Methods __construct __construct(string $uri. as they all have default values. Release 2.

0. Release 2. string $boundary) Set the encoding type and the boundary (if any) Returns void getEncType getEncType() Get the encoding type Returns type setRawBody setRawBody(string $body) Set raw body (for advanced use cases) Returns Zend\Http\Client setParameterPost setParameterPost(array $post) Set the POST parameters Returns Zend\Http\Client setParameterGet setParameterGet(array $query) Set the GET parameters Returns Zend\Http\Client getCookies getCookies() Return the current cookies Returns array 93.6 getLastRawResponse getLastRawResponse() Get the last response (as a string) Returns string getRedirectionsCount getRedirectionsCount() Get the redirections count Returns integer setUri setUri(string|Zend\Http\Zend\Uri\Http $uri) Set Uri (to the request) Returns Zend\Http\Client getUri getUri() Get uri (from the request) Returns Zend\Uri\Http setMethod setMethod(string $method) Set the HTTP method (to the request) Returns Zend\Http\Client getMethod getMethod() Get the HTTP method Returns string setEncType setEncType(string $encType.4. Available Methods 489 .Zend Framework 2 Documentation.

string $maxAge = null.Overview . response. string $type = ’basic’) Create a HTTP authentication “Authorization:” header according to the specified user. Returns Zend\Http\Client resetParameters resetParameters() Reset all the HTTP parameters (auth.0. etc) Returns void dispatch dispatch(Zend\Stdlib\RequestInterface $request.request. string $expire = null. Zend\Stdlib\ResponseInterface $response= null) Dispatch HTTP request Returns Response 490 Chapter 93. password and authentication method. string $version = null) Add a cookie Returns Zend\Http\Client setCookies setCookies(array $cookies) Set an array of cookies Returns Zend\Http\Client clearCookies clearCookies() Clear all the cookies Returns void setHeaders setHeaders(Zend\Http\Headers|array $headers) Set the headers (for the request) Returns Zend\Http\Client hasHeader hasHeader(string $name) Check if exists the header type specified Returns boolean getHeader getHeader(string $name) Get the header value of the request Returns string|boolean setStream setStream(string|boolean $streamfile = true) Set streaming for received data Returns Zend\Http\Client getStream getStream() Get status of streaming for received data Returns boolean|string setAuth setAuth(string $user.6 addCookie addCookie(ArrayIterator|SetCookie|string $cookie. string $path = null. boolean $httponly = true. string $value = null. Release 2. HTTP Client . boolean $secure = false. string $password.cookies.Zend Framework 2 Documentation. string $domain = null.

mixed $value. string $filename = null. $request = new Request(). you need to manually set the Content-Type ($ctype) or it will default to application/octet-stream. $client = new Client(’http://example. these are all defined Zend\Http\Request::METHOD_POST and so on. string $ctype = null) Set a file to upload (using a POST request) Can be used in two ways: 1. use Zend\Http\Request.5. string $name. string $formname. Release 2.6 send send(Zend\Http\Request $request) Send HTTP request Returns Response setFileUpload setFileUpload(string $filename. the default request method is GET (see the above example). This can be either GET.2 Using Request Methods Other Than GET For convenience.1 Performing a Simple GET Request Performing simple HTTP requests is very easily done using the setRequest() and dispatch() methods: 1 2 3 4 5 6 7 use Zend\Http\Client. array $headers = array ( )) Encode data to a multipart/form-data part suitable for a POST request. Returns string 93. $client->setRequest($request).Zend Framework 2 Documentation.$filename is sent as the file name. 93. Examples 491 . $response = $client->dispatch().5.0.5. TRACE. Will try to guess the content type using mime_content_type(). POST.org’). One of these methods is setMethod which refers to the HTTP Method.5 Examples 93. HEAD.html.w3. 2. but $data is sent as the file contents and no file is read from the file system. In this case. DELETE. The request object can be configured using his methods as shown in the Zend\Http\Request manual page. If no method is specified. PUT. as class constants: Zend\Http\Request::METHOD_GET. 1 See RFC 2616 -http://www. OPTIONS or CONNECT as defined by the HTTP protocol 1 . string $data = null. the method set by the last setMethod() call is used. Returns Zend\Http\Client removeFileUpload removeFileUpload(string $filename) Remove a file to upload Returns boolean encodeFormData encodeFormData(string $boundary.org/Protocols/rfc2616/rfc2616. $data is null (default): $filename is treated as the name if a local file which will be read and sent. 93. $data is set . If setMethod() was never called.

com/index. $client = new Client(’http://example. This method takes the GET parameters as an associative array of name => value GET variables. $response = $client->dispatch(). ’made_in’ => ’Mexico’. and can be done either by specifying them as part of the URL. which is identical to the setParameterGet() method in structure. $request = new Request(). one of them with several values $client->setParameterPost(array( ’language’ => ’es’. or by using the setParameterGet() method.4 Setting POST Parameters While GET parameters can be sent with every request method.php?knight=lancelot’).3 Setting GET parameters Adding GET parameters to an HTTP request is quite simple. // This is equivalent to setting a URL in the Client’s constructor: $client->setUri(’http://example. ’middle_name’ => ’Bending’. )). use Zend\Http\Request. ’last_name’ => ’Rodríguez’. POST parameters are simply ignored. $client = new Client().org’). $client = new Client(). // Performing a POST request $request->setMethod(Request::METHOD_POST).5. ’selection’ => array(45. 93. 1 2 3 4 5 6 7 8 9 use Zend\Http\Client. you can set both GET and POST parameters. 1 2 3 4 5 6 7 8 9 10 11 12 13 use Zend\Http\Client.5. 93. 492 Chapter 93. Note that when sending POST requests. and can be done with the setParameterPost() method. Adding POST parameters to a request is very similar to adding GET parameters. setting POST parameters on a non-POST request will not trigger an error. // Adding several parameters with one call $client->setParameterGet(array( ’first_name’ => ’Bender’. HTTP Client . On the other hand. 80) )). $client->setRequest($request).Zend Framework 2 Documentation. Release 2.Overview .6 1 2 3 4 5 6 7 8 9 10 use Zend\Http\Client. // Setting several POST parameters. POST parameters are only sent in the body of POST requests.0. 32. ’country’ => ’ar’. Unless the request is a POST request. rendering it useless.

Zend Framework 2 Documentation.5.test. $request->setMethod(’POST’). ’bar’). $request = new Request().0. Examples 493 .5 A Complete Example 1 2 3 4 5 6 7 8 9 10 11 12 13 use Zend\Http\Request.6 93. $response = $client->dispatch($request). Release 2. $client = new Client().5. $request->getPost()->set(’foo’.com’). $request->setUri(’http://www. use Zend\Http\Client. if ($response->isSuccess()) { // the POST was successful } 93.

0.Overview . HTTP Client .6 494 Chapter 93. Release 2.Zend Framework 2 Documentation.

using the Zend\Http\Client->setAdapter() method. as well as writing requests and reading responses.CHAPTER NINETYFOUR HTTP CLIENT .1 Overview Zend\Http\Client is based on a connection adapter design. the Zend\Http\Client class provides four built-in connection adapters: • Zend\Http\Client\Adapter\Socket (default) • Zend\Http\Client\Adapter\Proxy • Zend\Http\Client\Adapter\Curl • Zend\Http\Client\Adapter\Test The Zend\Http\Client object’s adapter connection adapter is set using the ‘adapter’ configuration option. You can also set the adapter later. The Socket adapter is based on PHP‘s built-in fsockopen() function. and with the same interface. Currently.2 The Socket Adapter The default connection adapter is the Zend\Http\Client\Adapter\Socket adapter . you can set the ‘adapter’ configuration option to a string containing the adapter’s name (eg.this adapter will be used unless you explicitly set the connection adapter. The connection adapter is the object in charge of performing the actual connection to the server. without the need to extend or replace the entire HTTP client class. that can be set using 495 . and does not require any special extensions or compilation flags. ‘Zend\Http\Client\Adapter\Socket’) or to a variable holding an adapter object (eg. new Zend\Http\Client\Adapter\Socket).CONNECTION ADAPTERS 94. 94. and you can create and extend the default connection adapters to suite your special needs. This connection adapter can be replaced. The Socket adapter allows several extra configuration options Zend\Http\Client->setOptions() or passed to the client constructor. When instantiating the client object.

6 Table 94. Note: HTTPS SSL Stream Parameters ssltransport.Zend Framework 2 Documentation.example. Release 2.but in most use cases. you might need to change them if the server you are connecting to requires special client setup. ‘sslv2’. ‘tls’) port sslcert Path to a PEM encoded SSL certificate sslpassphrase Passphrase for the SSL certificate file sslveriWhether to verify the SSL peer fypeer sslcapath Path to SSL certificate directory sslallowWhether to allow self-signed certificates selfsigned ssluseconEnables proxied connections to use SSL even if text the proxy connection itself does not. $response = $client->send().1: Zend\Http\Client\Adapter\Socket configuration parameters Parameter Description Expected Type boolean string string string string string string boolean Default Value FALSE ssl NULL NULL NULL NULL NULL FALSE persistent Whether to use persistent TCP connections ssltransSSL transport layer (eg. Additionally. HTTP Client . // The following request will be sent over a TLS secure connection. sslcert and sslpassphrase are only relevant when connecting using HTTPS. It is recommended to use persistent TCP connections only if you connect to the same server very frequently. $config). If so.com’. Note: Persistent TCP Connections Using persistent TCP connections can potentially speed up HTTP requests . Changing the HTTPS transport layer // Set the configuration parameters $config = array( ’adapter’ => ’Zend\Http\Client\Adapter\Socket’. and are sure that the server is capable of handling a large number of concurrent connections. ’ssltransport’ => ’tls’ ). when using persistent connections it is recommended to enable Keep-Alive HTTP requests as described in the configuration section. In any case you are encouraged to benchmark the effect of persistent connections on both the client speed and server load before using this option.Connection Adapters . you should read the sections about SSL transport layers and options here.otherwise persistent connections might have little or no effect. // Instantiate a client object $client = new Zend\Http\Client(’https://www.0. will have little positive effect and might overload the HTTP server you are connecting to. 1 2 3 4 5 6 7 8 9 10 11 The result of the example above will be similar to opening a TCP connection using the following PHP command: 496 Chapter 94. While the default SSL settings should work for most applications.

You can access the stream context using the following methods of Zend\Http\Client\Adapter\Socket: • setStreamContext($context) Sets the stream context to be used by the adapter. Release 2. • getStreamContext() Get the stream context of the adapter. The Socket Adapter 497 . stream_context_set_option($context.example. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 94. // do not accept invalid or self-signed SSL certificates ’verify_peer’ => true. $options). and set it. // Now. This allows the user to pass specific options and parameters to the TCP stream.3:50505’ ). and to the SSL wrapper in case of HTTPS connections. // Method 1: pass the options array to setStreamContext() $adapter->setStreamContext($options).com’. $client->setAdapter($adapter). You can then set or get the value of different context options using regular PHP stream context functions. // Method 3: get the default stream context and set the options on it $context = $adapter->getStreamContext().0.2. ’allow_self_signed’ => false.1 Customizing and accessing the Socket adapter stream context Zend\Http\Client\Adapter\Socket provides direct access to the underlying stream context used to connect to the remote server. $adapter->setStreamContext($context). Can accept either a stream context resource created using the stream_context_create() PHP function.6 fsockopen(’tls://www.Zend Framework 2 Documentation. $client = new Zend\Http\Client().1. in the same format provided to this function.2. // Capture the peer’s certificate ’capture_peer_cert’ => true ) ). perform the request $response = $client->send(). Setting stream context options for the Socket adapter // Array of options $options = array( ’socket’ => array( // Bind local socket side to a specific interface ’bindto’ => ’10. // Method 2: create a stream context and pass it to setStreamContext() $context = stream_context_create($options). or an array of stream context options. will create a default stream context and return it. If no stream context was set. 443) 94. Providing an array will create a new stream context using these options. ’ssl’ => array( // Verify server side certificate. // Create an adapter object and attach it to the HTTP client $adapter = new Zend\Http\Client\Adapter\Socket().2.

echo $opts[’ssl’][’peer_certificate’].which is sometimes needed for security or performance reasons. only basic authentication (Zend\Http\Client::AUTH_BASIC) is supported. // Instantiate a client object $client = new Zend\Http\Client(’http://www. proxy_user and proxy_pass are only required if your proxy server requires you to authenticate. if required Proxy HTTP authentication type Expected Type string integer string string string Example Value ‘proxy.2. ’proxy_pass’ => ’bananashaped’ ). a default stream context will be created. you can leave these two options out. if your proxy server requires authentication.if your proxy listens on a different port you must set this one as well. If no context is set before performing HTTP requests with the Socket adapter.1. Providing these will add a ‘Proxy-Authentication’ header to the request.Zend Framework 2 Documentation.Connection Adapters .com’ or ‘10. Release 2.only the connection is made through an HTTP proxy server instead of a direct connection to the target server. $config). the client will fall back to a direct connection using Zend\Http\Client\Adapter\Socket. This context resource could be accessed after performing any requests using the getStreamContext() method. 1 2 3 4 5 6 7 8 9 10 11 498 Chapter 94. you can now access the context again $opts = stream_context_get_options($adapter->getStreamContext()).3’ 8080 (default) or 81 ‘shahar’ or ‘’ for none (default) ‘secret’ or ‘’ for none (default) ZendHttpClient::AUTH_BASIC (default) proxy_host should always be set . if required Proxy password.example. ’proxy_host’ => ’proxy.myhost. Using Zend\Http\Client behind a proxy server // Set the configuration parameters $config = array( ’adapter’ => ’Zend\Http\Client\Adapter\Proxy’. ’proxy_port’ => 8000.zend. If your proxy does not require authentication. HTTP Client . proxy_port defaults to ‘8080’ . proxy_auth sets the proxy authentication type.3 The Proxy Adapter The Zend\Http\Client\Adapter\Proxy adapter is similar to the default Socket adapter . Possibly values are similar to the ones accepted by the Zend\Http\Client::setAuth() method. ’proxy_user’ => ’shahar.int.e’.2: ZendHttpClient configuration parameters Parameter proxy_host proxy_port proxy_user proxy_pass proxy_auth Description Proxy server address Proxy server TCP port Proxy user name. in addition to the default ‘adapter’ option: Table 94. Note: Note that you must set any stream context options before using the adapter to perform actual requests.0. Using the Proxy adapter requires several additional configuration parameters to be set.if it is not set. 94.com’.com’.6 36 37 38 39 // If everything went well. Currently. This allows usage of Zend\Http\Client behind proxy servers .

Transfering Files by Handle You can use cURL to transfer very large files over HTTP by filehandle. ’curloptions’ => array(CURLOPT_FOLLOWLOCATION => true). CURLOPT_INFILESIZE => $putFileSize ) )).4. 94. $value). "r").. It supports secure connections. ). the connection will fall back to a regular direct connection. Release 2. The cURL Adapter 499 . $client->setMethod(’PUT’).6 12 13 // Continue working. $client->send(). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $putFileSize = filesize("filepath").4 The cURL Adapter cURL is a standard HTTP client library that is distributed with many operating systems and can be used in PHP via the cURL extension. This allows you to easily write your application in a way that allows a proxy to be used optionally. 94. $adapter->setOptions(array( ’curloptions’ => array( CURLOPT_INFILE => $putFileHandle. $client->setAdapter($adapter). proxy. You can get access to the Curl handle by calling $adapter->getHandle(). 1 2 3 4 5 By default the cURL adapter is configured to behave exactly like the Socket Adapter and it also accepts the same configuration parameters as the Socket and Proxy adapters. You can also change the cURL options by either specifying the ‘curloptions’ key in the constructor of the adapter or by calling setCurlOption($name. you can use the stream context access method (see this section) to set stream context options on Proxy connections as demonstrated above. It offers functionality for many special cases which can occur for a HTTP client and make it a perfect choice for a HTTP adapter. $config). $putFileHandle = fopen("filepath". Note: Since the proxy adapter inherits from Zend\Http\Client\Adapter\Socket. The $name key corresponds to the CURL_* constants of the cURL extension. if proxy_host is not set or is set to a blank string. $client = new Zend\Http\Client($uri. all sorts of authentication mechanisms and shines in applications that move large files around between servers.Zend Framework 2 Documentation.0. Setting cURL options $config = array( ’adapter’ => ’Zend\Http\Client\Adapter\Curl’. As mentioned.. $client = new Zend\Http\Client(). according to a configuration parameter. $adapter = new Zend\Http\Client\Adapter\Curl().

$response = $client->send(). ’ xmlns:wfw="http://wellformedweb. it’s not possible to use setResponse() alone because there’s no opportunity to set the next response(s) your program might need before returning to the caller.0. You can write your application to use Zend\Http\Client..com’. 1 2 3 4 5 500 Chapter 94. "Content-type: text/xml" . Then... setResponse().1/">’ . ’<?xml version="1. For example.1 200 OK" . HTTP Client . // Set the expected response $adapter->setResponse( "HTTP/1. for example in your unit testing suite.example. The Zend\Http\Client\Adapter\Test adapter provides an additional method. array( ’adapter’ => $adapter )). Testing Against Multiple HTTP Response Stubs // Instantiate a new adapter and client $adapter = new Zend\Http\Client\Adapter\Test().org/dc/elements/1. ’<rss version="2. array( ’adapter’ => $adapter )). the server’s response. it is very hard to test code that relies on HTTP connections. // . For this reason. which represents an HTTP response as either text or a Zend\Http\Response object. which is not always available.org/CommentAPI/"’ . ’ <channel>’ . etc. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 The above example shows how you can preset your HTTP client to return the response you need. testing an application that pulls an RSS feed from a remote server will require a network connection. you can replace the default adapter with a Test adapter (a mock object). allowing you to run tests without actually performing server connections. ’ <title>Premature Optimization</title>’ . your Test adapter will always return this response. without even performing an actual HTTP request. ’ xmlns:content="http://purl. "\r\n" .com’. you can continue testing your own code. continue parsing $response.0/modules/content/"’ .6 94. the Zend\Http\Client\Adapter\Test adapter is provided.org/rss/1.Connection Adapters . "\r\n" .0" encoding="UTF-8"?>’ . This method takes one parameter. Once set. // and so on. ’ xmlns:dc="http://purl. "\r\n" . without being dependent on a network connection.0" ’ . In this case. $client = new Zend\Http\Client(’http://www. ’</rss>’). Testing Against a Single HTTP Response Stub // Instantiate a new adapter and client $adapter = new Zend\Http\Client\Adapter\Test(). Release 2. and just for testing purposes. the test would continue to check how the application parses the XML in the response body..5 The Test Adapter Sometimes. Sometimes. In this case. $client = new Zend\Http\Client(’http://www. a single method call to an object can result in that object performing multiple HTTP transactions.Zend Framework 2 Documentation.example.

. // Force the next request to fail with an exception $adapter->setNextRequestWillFail(true). If more requests are made than the number of responses stored.com’. inject the HTTP client containing the adapter into your object under test and test its behavior. ’ <body><p>.5.Zend Framework 2 Documentation. we expect that the redirect will be followed and we configure the test adapter to help us test this.6 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // Set the first expected response $adapter->setResponse( "HTTP/1. Depending on your application. // Set the next successive response $adapter->addResponse( "HTTP/1. If you need the adapter to fail on demand you can use setNextRequestWillFail($flag). After configuring the test adapter.1 200 OK" .1 302 Found" . In the example above. ’ <head><title>Moved</title></head>’ . "Content-Type: text/html" . ’ <head><title>My Pet Store Home Page</title></head>’ . "\r\n" . Forcing the adapter to fail // Instantiate a new adapter and client $adapter = new Zend\Http\Client\Adapter\Test(). "\r\n" . ’<html>’ . $client = new Zend\Http\Client(’http://www. Release 2. "\r\n" . // inject the http client object ($client) into your object // being tested and then test your object’s behavior below The setResponse() method clears any responses in the Zend\Http\Client\Adapter\Test‘s buffer and sets the first response that will be returned. This can be useful when our application caches content from an external site (in case the site goes down) and you want to test this feature. ’<html>’ .example. ’</html>’). 1 2 3 4 5 6 7 8 9 10 11 12 94. array( ’adapter’ => $adapter )). "\r\n" . The method will cause the next call to connect() to throw an Zend\Http\Client\Adapter\Exception\RuntimeException exception. try { // This call will result in a Zend\Http\Client\Adapter\Exception\RuntimeException $client->request(). ’</html>’). following a redirect may or may not be desired behavior. "\r\n" . The responses will be replayed in the order that they were added. The initial 302 response is set up with the setResponse() method and the 200 response to be returned next is added with the addResponse() method. "\r\n" . ’ <body><p>This page has moved. "Location: /"