Zendframework 3 Sample
Zendframework 3 Sample
Michael Romer
This book is for sale at http://leanpub.com/zendframework
This version was published on 2016-07-07
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing
process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and
many iterations to get reader feedback, pivot until you have the right book and build traction once
you do.
2016 Michael Romer
Contents
Early Access Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Introduction . . . . . . . . . . . . . . . .
Who is this book for? . . . . . . . . .
Structure of this book . . . . . . . . .
How you can best work with this book
Found a bug? . . . . . . . . . . . . . .
Conventions used in this book . . . .
Code examples . . . . . . . . . . .
Command line . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
2
3
3
3
3
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
6
6
6
6
6
8
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
10
10
11
12
13
16
17
18
19
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
.
.
.
.
.
Introduction
Welcome to the latest and greatest version of Zend Framework! Like earlier version of the
framework, Zend Framework 3 aims to further simplify developing web applications using PHP.
Zend Framework 3 allows you to write even more robust, maintainable and extendable enterpriseready PHP applications. It provides you a way to better organize your application code and ships
with many additional utility components making a developers life easier.
When browsing the official framework website (https://framework.zend.com/), you might notice
that Zend Framework 3 usually is just Zend Framework over there. Why is this? Since the
Framework, now in its third version, has completely been decoupled into individual components
with their very own lifecycle, it just makes no real sense to version the overall Framework anymore.
That said, Zend Framework 3 in fact is more a marketing term, while the Framework itself now is
simply named Zend Framework.
Zend Framework 3 keeps a lot of good stuff that was introduced with Zend Framework 2 and at the
same time improves on its weaknesses. It also ships with brand new ideas, components and tools.
Introduction
official documentation serves well as a compendium for experienced developers, but is not really
appropriate for use whilst becoming familiar with the subject. Instead, the books objective is to
serve as an (indispensible) reference work for further detailed questions achieving required basic
understanding.
It is structured such that you can read it from the beginning to the end, and that is what you should
do. We will begin with an overview of the Framework, first looking at essential concepts and ideas
forming its essence and differentiating it from its predecessors. On the way, we will repeatedly also
look to the left and right, becoming familiar with the Framework conditions, for example ideas
and discussions behind Frameworks development. Then elucidate the Frameworks most important
components and relationships; peek at how a HTPP request is processed; write our first bit of code;
and an excursion into the Framework environment. We will examine the most important third-party
modules. Modules are a large part of the magic of Zend Framework 3, like it also was already the
case with version 2. Modules can greatly accelerate and simplify application development. Also with
the implementation of the so-called middleware approach now in Zend Framework 3, a new way
of re-using code has been set-up.
Found a bug?
Have you found a bug in the text or code? Please email me at [email protected]. I am thankful
for your feedback and support.
Introduction
Command line
When a command has to be executed on the command line, this is symbolised by a preceding dollar
sign ($) . The visual feedback of the command is indicated by a preceding greater than sign (>).
Example:
1
2
$ php composer.phar
> Composer version 1.1.3 2016-06-26 15:42:08
Additional components
zend-code: Extensions to the PHP Reflection API, static code scanning, and code generation.
zend-component-installer: Composer plugin for injecting modules and configuration providers
into application configuration.
zend-db: Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations.
zend-debug: Safely dump debug information to HTML.
zend-di: Automated dependency injection and instance manager.
zend-http: HTTP message and header abstractions, and HTTP client implementation. (Not a
PSR-7 implementation.)
zend-loader: Autoloading and plugin loading strategies.
Getting started
Since Zend Framework 3 essentially is just a compilation of components, one may ask how to kick
in gear? How to glue individual components together to actually get a fully functional app?
Well, you have different options:
We will walk through each of these approaches, mainly as a learning exercise. Later on, you will
always want to use the skeleton applications (think: templates) for your real projects. Why? First off,
wiring up the most fundamental components of Zend Framework 3 to actually produce a running
app involves certain boilerplate code which can and should be re-used, so simply just dont waste
your time on this. Furthermore, the skeleton applications include several smart solutions to deal
with generic problems, like generating the application config. Even if you consider yourself a PHP
pro, you still might benefit from the code available in the skeleton apps.
However, as you will see, you dont have to use the skeleton apps.
Loading zend-expressive
First thing you will need to do is create a new project folder on your disk. If you have PHP 5.4
or newer installed on your system, you may want to serve your app using the built-in web server,
which essentially means, you can create the folder anywhere on your local disk. If you like run
Apache or another web server software on your machine, just make sure to create the new folder in
a location available to your web server.
Within that folder create a file called composer.json with the following contents:
1
2
3
4
{
"require": {
"zendframework/zend-expressive": "^1.0"
},
scripts: {
1
2
3
$ wget https://getcomposer.org/composer.phar
Alternatively, you may want to download composer manually and place it in your app folder.
10
11
Phar-Archive
A Phar Archive provides the option of making a PHP application available in the form
of a single file. If one looks at the Composer-Repository at GitHub, it becomes clear that
composer does not consist of a single file, as one might think, but that its components are
merely bundled in a Phar Archive for distribution of the application.
Composer
Composer today is the de facto standard for PHP Dependency Management. The idea behind the
composer is as simple as it is ingenious. A configuration file contains a definition of other code
libraries that an application depends on and from where the respective library can be obtained. In
this case, the application depends on Zend Framework 3s zend-expressive component, as can be
seen by looking in the file composer.json:
1
2
3
4
{
"require": {
"zendframework/zend-expressive": "^1.0"
},
The following command downloads zend-expressive, integrates it in the (empty) application and all
components classes are made available instantly by PHPs autoloading feature:
1
2
And thats it! You know have zend-expressive installed in your project.
https://github.com/composer/composer
http://www.hardened-php.net/suhosin/
getcomposer.org/
12
Bootstrapping
Next up is creating a bootstrapping script called index.php. Every request handled by your app will
first go through this php file, no matter what the request URL looks like.
In your application root folder, create a new subfolder called public. Within public, create the
index.php with the following contents:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
use Zend\Expressive\AppFactory;
chdir(dirname(__DIR__));
require 'vendor/autoload.php';
$app = AppFactory::create();
$app->get('/ping', function ($request, $response, $next) {
$response->getBody()->write('Pong!');
return $response;
});
$app->pipeRoutingMiddleware();
$app->pipeDispatchMiddleware();
$app->run();
Lets walk through the most important pieces of index.php. The statement
1
require 'vendor/autoload.php';
$app = AppFactory::create();
a new Expressive app object is created via its factory. $app now acts as the topmost object, in fact
representing the entire app.
Now we make the app respond to a specific URL path:
13
1
2
3
4
If a GET request is made to /ping, the function given is executed, which in turn for now just sends
back Pong! to the browser. Lets skip the other details of index.php for a minute. We will come
back to it soon.
With
1
$app->run();
the actual request processing is kicked off. At this stage, your application folder should look like this:
public
index.php
vendor
zendframework
(more folders go here)
composer.json
composer.lock
composer.phar
What this does is telling composer to actually run a script defined by you. Remember this piece of
text in composer.json from above?
1
2
3
"scripts": {
"serve": "php -S 0.0.0.0:8080 -t public/"
}
This configuration actually makes the command serve invoke PHPs internal web server on
localhost, port 8080. The document root is configured to be subfolder public, which is exactly
where the index.php file is stored.
(Infos using Apache to follow)
If you open http://localhost:8080/ping in a browser now, you will see an error:
1
2
14
The reason for the error is, that zend-expressive actually depends on two other components which
must be present as well:
A dependency injection (DI) container, e.g. zend-servicemanager
A router, e.g. zend-router
Before we elaborate on what these components actually do and how they work, lets add them to
our app to make it finally run. First, we extend the composer.json file like so:
1
2
3
4
5
6
7
8
9
10
{
"require": {
"zendframework/zend-expressive": "^1.0",
"zendframework/zend-servicemanager": "^3.0",
"zendframework/zend-expressive-zendrouter": "^1.1"
},
"scripts": {
"serve": "php -S 0.0.0.0:8080 -t public/"
}
}
Lastly, we need to instantiate a router and a DI container within index.php and use both when
creating the app object:
1
2
3
4
5
6
{:lang="php"}
// [..]
$serviceManager = new ServiceManager();
$router = new ZendRouter();
$app = AppFactory::create($serviceManager, $router);
// [..]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
use Zend\Expressive\AppFactory;
use Zend\ServiceManager\ServiceManager;
use Zend\Expressive\Router\ZendRouter;
chdir(dirname(__DIR__));
require 'vendor/autoload.php';
$serviceManager = new ServiceManager();
$router = new ZendRouter();
$app = AppFactory::create($serviceManager, $router);
$app->get('/ping', function ($request, $response, $next) {
$response->getBody()->write('Hello, world!');
return $response;
});
$app->pipeRoutingMiddleware();
$app->pipeDispatchMiddleware();
$app->run();
Hello, world!
And thats it! A first sign of life from your app. Congratulations!
15
16
17
18
19
Acknowledgements
The cover picture was taken from Freepik. Thanks guys!
20