My talk will be about ZF3, the most waited release of ZF for the last 4 years that were spent on development, features it brings and drawbacks of migration of existing ZF2 application to new rails comes with. Components, PSR-7, and Middleware
6. ServiceLocator - DI
Provides integration for zend-di within
zend-servicemanager
"zendframework/zend-servicemanager-di": "*"
7. ServiceLocator - build everything
public function build($name, array $options = null)
{
// We never cache when using "build"
$name = isset($this->resolvedAliases[$name]) ?
$this->resolvedAliases[$name] : $name;
return $this->doCreate($name, $options);
}
$serviceLocator->build(‘Customer’, [‘name’ => ‘Joe’]); // Joe
$serviceLocator->build(‘Customer’, [‘name’ => ‘Mike’]); // Mike
Never caches custom object builder through ServiceLocator
8. ServiceLocatorAwareInterface - has gone ...
PluginManagerLocator - removed
You have to inject all your dependencies!
final class AuthentificationController extends AbstractActionController
{
private $service = $service;
public function __construct(AuthentificationService $service)
{
$this->service = $service;
}
}
30. Expressive
composer create-project zendframework/zend-expressive-skeleton expressive
Which router do you want to use?
[1] Aura.Router
[2] FastRoute
[3] Zend Router
Which container do you want to use for dependency injection?
[1] Aura.Di
[2] Pimple
[3] Zend ServiceManager
Which template engine do you want to use?
[1] Plates
[2] Twig
[3] Zend View
composer serve
31. Expressive
$app = AppFactory::create();
$app->get('/', $blogApp);
$app->post('/trackback', 'TrackBack');
$app->put('/post/{id}', 'ReplacePost')
->setOptions([
'tokens' => [ 'id' => 'd+' ],
]);
$app->delete('/post/{id}', 'DeletePost')
->setOptions([
'tokens' => [ 'id' => 'd+' ],
]);
$app->patch('/trackback');
$app->get('/api', function($req, $res, $next) {
return new JsonResponse(['ack' => time()]);
});
$app->run();
You can reach the same through config!
32. Expressive
namespace AppAction;
class MyAction
{
public function __invoke($request, $response, callable $next)
{
$query = $request->getQueryParams();
$message = $query['message'];
return $response->getBody()->write(
'My very unique message ' . $message
);
}
}
Which error handler do you want to use during development?
[1] Whoops
[n] None of the above
34. Expressive - ErrorHandling
"filp/whoops": "*"
● Flexible, stack-based error handling
● No required dependencies
● Simple API for dealing with exceptions, trace frames
& their data
● Includes handlers for different response formats
(JSON, XML, SOAP)
42. Tests - straight from the heart manual
class AlbumControllerTest extends AbstractHttpControllerTestCase
{
public function setUp()
{
$this->setApplicationConfig(include 'config/application.config.php');
parent::setUp();
}
public function testAlbum()
{
$this->dispatch('/album');
$this->assertResponseStatusCode(200);
}
}
43. Tests - straight from the heart manual
class AlbumControllerTest extends AbstractHttpControllerTestCase
{
public function setUp()
{
$this->setApplicationConfig(include 'config/application.config.php');
parent::setUp();
}
public function testAlbum()
{
$this->dispatch('/album');
$this->assertResponseStatusCode(200);
}
}
44. Tests - works
class RedirectControllerTest extends TestCaseController
{
public function testRedirectNonAuthAction()
{
$controller = new RedirectController();
(new EnvironmentBuilder($this))->build($controller, []);
$res = $controller->redirectAction();
$this->assertEquals(['/analytic/metric?ga=redirect-wrong'], $res);
}
}
45. Tests - works
public function testRedirectAuthAndViewReffererAction()
{
$controller = new RedirectController();
(new EnvironmentBuilder($this))->build($controller, [
['name' => 'Request',
'options' => [
'query' => ['refferer' => 'http://x.com/zzz'],
'server' => ['HTTP_HOST' => 'x.com'],
],
],
]);
$view = $controller->redirectAction();
$this->assertInstanceOf('ZendViewModelViewModel', $view);
$this->assertEquals('http://x.com/zzz', $view->refferer);
}