SlideShare a Scribd company logo
1 of 104
Download to read offline
@asgrim
Kicking off with Zend Expressive
and Doctrine ORM
James Titcumb
ConFoo Vancouver 2017
Follow along (optional): https://github.com/asgrim/book-library
$ whoami
James Titcumb
www.jamestitcumb.com
www.roave.com
@asgrim
@asgrim
What is Zend Expressive?
@asgrim
Layers of an Expressive application
Expressive
Stratigility
Diactoros
PSR-7 Interface
DIRouter Template
Your Application
@asgrim
Layers of an Expressive application
Expressive
Stratigility
Diactoros
PSR-7 Interface
DIRouter Template
Your Application
@asgrim
PSR-7
HTTP Message Interfaces
@asgrim
HTTP Request
POST /yvr2017/foo HTTP/1.1
Host: confoo.ca
foo=bar&baz=bat
@asgrim
HTTP Response
HTTP/1.1 200 OK
Content-Type: text/plain
This is the response body
@asgrim
Layers of an Expressive application
Expressive
Stratigility
Diactoros
PSR-7 Interface
DIRouter Template
Your Application
@asgrim
Zend Diactoros
PSR-7 implementation
@asgrim
Node http.Server using Diactoros
$server = ZendDiactorosServer::createServer(
function ($request, $response, $done) {
return $response->getBody()->write('hello world');
},
$_SERVER,
$_GET,
$_POST,
$_COOKIE,
$_FILES
);
$server->listen();
@asgrim
Layers of an Expressive application
Expressive
Stratigility
Diactoros
PSR-7 Interface
DIRouter Template
Your Application
@asgrim
Zend Stratigility
Creating & dispatching middleware pipelines
@asgrim
So what is “middleware”?
@asgrim
Middleware in the middle
function(Request $request, DelegateInterface $delegate) : Response
{
// ... some code before ...
$response = $delegate->process($request);
// ... some code after ...
return $response;
}
@asgrim
Some people call it an onion
SessionInitialisingMiddleware
AuthenticationMiddleware
ThingyMiddleware
DashboardAction
@asgrim
Some people call it an onion
SessionInitialisingMiddleware
AuthenticationMiddleware
ThingyMiddleware
DashboardAction
@asgrim
Some people call it an onion
SessionInitialisingMiddleware
AuthenticationMiddleware
ThingyMiddleware
DashboardAction
@asgrim
http-interop/http-middleware
(work in progress)
@asgrim
Middleware using MiddlewareInterface
<?php
declare(strict_types=1);
namespace AppMiddleware;
use InteropHttpServerMiddlewareDelegateInterface;
use InteropHttpServerMiddlewareMiddlewareInterface;
use PsrHttpMessageResponseInterface;
use PsrHttpMessageServerRequestInterface;
final class MyMiddleware implements MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
DelegateInterface $delegate
) : ResponseInterface {
return $delegate->process($request);
}
}
@asgrim
Double-pass middleware
public function __invoke(
Request $request,
Response $response,
callable $next
): Response {
return $next($request, $response);
}
!!! DEPRECATED !!!
@asgrim
Modifying the response
function(Request $request, DelegateInterface $delegate) : Response
{
$response = $delegate->process($request);
return $response->withHeader(
'X-Clacks-Overhead',
'GNU Terry Pratchett'
);
}
@asgrim
Pipe all the things!
$pipe = new ZendStratigilityMiddlewarePipe();
$pipe->pipe($logUncaughtErrorsMiddleware);
$pipe->pipe($sessionInitialisingMiddleware);
$pipe->pipe($authenticationMiddleware);
$pipe->pipe('/', $indexActionMiddleware);
$pipe->pipe(new NotFoundHandler(...));
@asgrim
LogErrorsCaughtMiddleware
function(Request $request, DelegateInterface $delegate) : Response
{
try {
return $delegate->process($request);
} catch (Throwable $throwable) {
// Log the error, handle it with error page etc.
return new JsonResponse(
[
'message' => $throwable->getMessage(),
],
500
);
}
}
@asgrim
SessionInitialisingMiddleware
function(Request $request, DelegateInterface $delegate) : Response
{
session_start();
return $delegate->process($request);
}
@asgrim
function(Request $request, DelegateInterface $delegate) : Response
{
if (!$this->doSomeOAuthCheck($request)) {
return new JsonResponse(
[
'message' => 'Invalid OAuth token',
],
403
);
}
return $delegate->process($request);
}
AuthenticationMiddleware
@asgrim
IndexActionMiddleware
function(Request $request, DelegateInterface $delegate) : Response
{
// ... some code ...
return new JsonResponse($someData, 200);
}
@asgrim
Layers of an Expressive application
Expressive
Stratigility
Diactoros
PSR-7 Interface
DIRouter Template
Your Application
@asgrim
Zend Expressive
One Ring to bring them all and in the darkness bind them.
@asgrim
Routing
@asgrim
container-interop
@asgrim
Optionally, templating
@asgrim
Piping and Routing
@asgrim
Zend Framework 2/3
What of them?
@asgrim
Middleware vs MVC
@asgrim
Using ZF components
in Expressive
@asgrim
Module.php
class Module
{
public function getConfig()
{
return include __DIR__ . '/../config/module.config.php';
}
}
@asgrim
ConfigProvider
@asgrim
ConfigProvider
namespace ZendForm;
class ConfigProvider
{
public function __invoke()
{
return [
'dependencies' => $this->getDependencyConfig(),
'view_helpers' => $this->getViewHelperConfig(),
];
}
}
@asgrim
ConfigProvider#getDependencyConfig()
public function getDependencyConfig()
{
return [
'abstract_factories' => [
FormAbstractServiceFactory::class,
],
'aliases' => [
'ZendFormAnnotationFormAnnotationBuilder' => 'FormAnnotationBuilder',
AnnotationAnnotationBuilder::class => 'FormAnnotationBuilder',
FormElementManager::class => 'FormElementManager',
],
'factories' => [
'FormAnnotationBuilder' => AnnotationAnnotationBuilderFactory::class,
'FormElementManager' => FormElementManagerFactory::class,
],
@asgrim
ZendForm’s Module.php (for Zend Framework)
class Module
{
public function getConfig()
{
$provider = new ConfigProvider();
return [
'service_manager' => $provider->getDependencyConfig(),
'view_helpers' => $provider->getViewHelperConfig(),
];
}
}
@asgrim
config/autoload/zend-form.global.php
<?php
return (new ZendFormConfigProvider())->__invoke();
@asgrim
Layers of an Expressive application
Expressive
Stratigility
Diactoros
PSR-7 Interface
DIRouter Template
Your Application
@asgrim
Getting started
with Zend Expressive
@asgrim
https://github.com/asgrim/book-library
@asgrim
Expressive Skeleton
@asgrim
Expressive installer - start
$ composer create-project zendframework/zend-expressive-skeleton book-library
Installing zendframework/zend-expressive-skeleton (2.0.4)
- Installing zendframework/zend-expressive-skeleton (2.0.4): Downloading (100%)
Created project in book-library-2
> ExpressiveInstallerOptionalPackages::install
Setting up optional packages
Setup data and cache dir
Removing installer development dependencies
@asgrim
Expressive installer - structure
What type of installation would you like?
[1] Minimal (no default middleware, templates, or assets; configuration only)
[2] Flat (flat source code structure; default selection)
[3] Modular (modular source code structure; recommended)
Make your selection (2):
@asgrim
Modular structure
zend-config-aggregator
@asgrim
Modular structure
zend-config-aggregator
@asgrim
Flat or Modular?
@asgrim
Default modular structure
src/
MyModule/
src/
ConfigProvider.php
Action/
Entity/
Middleware/
templates/
test/
@asgrim
Expressive installer - container?
Which container do you want to use for dependency injection?
[1] Aura.Di
[2] Pimple
[3] Zend ServiceManager
Make your selection or type a composer package name and version (Zend ServiceManager):
@asgrim
Expressive installer - router?
Which router do you want to use?
[1] Aura.Router
[2] FastRoute
[3] Zend Router
Make your selection or type a composer package name and version (FastRoute):
@asgrim
Expressive installer - template?
Which template engine do you want to use?
[1] Plates
[2] Twig
[3] Zend View installs Zend ServiceManager
[n] None of the above
Make your selection or type a composer package name and version (n):
@asgrim
Expressive installer - whoops?
Which error handler do you want to use during development?
[1] Whoops
[n] None of the above
Make your selection or type a composer package name and version (Whoops):
@asgrim
Expressive installer - run it!
$ composer serve
> php -S 0.0.0.0:8080 -t public/ public/index.php
[Thu Sep 1 20:29:33 2016] 127.0.0.1:48670 [200]: /favicon.ico
{
"welcome": "Congratulations! You have installed the zend-expressive skeleton application.",
"docsUrl": "https://docs.zendframework.com/zend-expressive/"
}
@asgrim
Create the endpoints
@asgrim
Book entity
class Book
{
/**
* @var string
*/
private $id;
/**
* @var bool
*/
private $inStock = true;
public function __construct()
{
$this->id = (string)Uuid::uuid4();
}
@asgrim
Book entity
class Book
{
/**
* @return void
* @throws AppEntityExceptionBookNotAvailable
*/
public function checkOut()
{
if (!$this->inStock) {
throw ExceptionBookNotAvailable::fromBook($this);
}
$this->inStock = false;
}
@asgrim
Book entity
class Book
{
/**
* @return void
* @throws AppEntityExceptionBookAlreadyStocked
*/
public function checkIn()
{
if ($this->inStock) {
throw ExceptionBookAlreadyStocked::fromBook($this);
}
$this->inStock = true;
}
@asgrim
FindBookByUuidInterface
interface FindBookByUuidInterface
{
/**
* @param UuidInterface $slug
* @return Book
* @throws ExceptionBookNotFound
*/
public function __invoke(UuidInterface $slug): Book;
}
@asgrim
CheckOutAction
public function process(ServerRequestInterface $request, DelegateInterface $delegate): JsonResponse
{
try {
$book = $this->findBookByUuid->__invoke(Uuid::fromString($request->getAttribute('id')));
} catch (BookNotFound $bookNotFound) {
return new JsonResponse(['info' => $bookNotFound->getMessage()], 404);
}
try {
$book->checkOut();
} catch (BookNotAvailable $bookNotAvailable) {
return new JsonResponse(['info' => $bookNotAvailable->getMessage()], 423);
}
return new JsonResponse([
'info' => sprintf('You have checked out %s', $book->getId()),
]);
}
@asgrim
Config vs Programmatic Pipe
'middleware_pipeline' => [
'routing' => [
'middleware' => [
AppMiddlewareErrorCatchingMiddleware::class,
ApplicationFactory::ROUTING_MIDDLEWARE,
HelperUrlHelperMiddleware::class,
PSR7SessionsStoragelessHttpSessionMiddleware::class,
AppMiddlewareAuthenticationMiddleware::class,
ApplicationFactory::DISPATCH_MIDDLEWARE,
],
'priority' => 1,
],
@asgrim
Config vs Programmatic Pipe
$app->pipe(AppMiddlewareErrorCatchingMiddleware::class);
$app->pipeRoutingMiddleware();
$app->pipe(ZendExpressiveHelperUrlHelperMiddleware::class);
$app->pipe(PSR7SessionsStoragelessHttpSessionMiddleware::class);
$app->pipe(AppMiddlewareAuthenticationMiddleware::class);
$app->pipeDispatchMiddleware();
@asgrim
Injecting config into programmatic pipeline
final class BookRoutesConfigProvider
{
public function __invoke()
{
return [
'routes' => [
[
'name' => 'check-out',
'path' => '/book/{id}/check-out',
'middleware' => AppActionCheckOutAction::class,
'allowed_methods' => ['GET'],
],
[
'name' => 'check-in',
'path' => '/book/{id}/check-in',
'middleware' => AppActionCheckInAction::class,
'allowed_methods' => ['GET'],
],
],
];
}
@asgrim
Injecting config into programmatic pipeline
$app->injectRoutesFromConfig((new BookRoutesConfigProvider())());
$app->injectPipelineFromConfig((new BookPipelineConfigProvider())());
@asgrim
Adding some ORM
@asgrim
Your application
Doctrine quick overview
DB
DBAL
ORM
(EntityManager)
Entities
Finders,
Services,
...
@asgrim
container-interop-doctrine
@asgrim
Installation
$ composer require dasprid/container-interop-doctrine
Using version ^1.0 for dasprid/container-interop-doctrine
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing dasprid/container-interop-doctrine (1.0.0): Loading from cache
Package http-interop/http-middleware is abandoned, you should avoid using it.
Use http-interop/http-server-middleware instead.
Writing lock file
Generating autoload files
$
@asgrim
config/autoload/doctrine.global.php
<?php
declare(strict_types = 1);
use DoctrineORMEntityManagerInterface;
use ContainerInteropDoctrineEntityManagerFactory;
return [
'dependencies' => [
'factories' => [
EntityManagerInterface::class => EntityManagerFactory::class,
],
],
];
@asgrim
'doctrine' => [
'connection' => [
'orm_default' => [
'driver_class' => PDOPgSqlDriver::class,
'params' => [
'url' => 'postgres://user:pass@localhost/book_library',
],
],
],
'driver' => [
'orm_default' => [
'class' => MappingDriverChain::class,
'drivers' => [
// ... and so on ...
config/autoload/doctrine.global.php
@asgrim
'doctrine' => [
'connection' => [
'orm_default' => [
'driver_class' => PDOPgSqlDriver::class,
'params' => [
'url' => 'postgres://user:pass@localhost/book_library',
],
],
],
'driver' => [
'orm_default' => [
'class' => MappingDriverChain::class,
'drivers' => [
// ... and so on ...
config/autoload/doctrine.global.php
@asgrim
<?php
declare(strict_types = 1);
use DoctrineORMEntityManagerInterface;
use DoctrineORMToolsConsoleHelperEntityManagerHelper;
use SymfonyComponentConsoleHelperHelperSet;
$container = require __DIR__ . '/container.php';
return new HelperSet([
'em' => new EntityManagerHelper(
$container->get(EntityManagerInterface::class)
),
]);
config/cli-config.php
@asgrim
Annotating the Entities
@asgrim
/**
* @ORMEntity
* @ORMTable(name="book")
*/
class Book
{
/**
* @ORMId
* @ORMColumn(name="id", type="guid")
* @ORMGeneratedValue(strategy="NONE")
* @var string
*/
private $id;
src/App/Entity/Book.php
@asgrim
/**
* @ORMEntity
* @ORMTable(name="book")
*/
class Book
{
/**
* @ORMId
* @ORMColumn(name="id", type="guid")
* @ORMGeneratedValue(strategy="NONE")
* @var string
*/
private $id;
src/App/Entity/Book.php
@asgrim
public function __invoke(UuidInterface $id): Book
{
/** @var Book|null $book */
$book = $this->repository->find((string)$id);
if (null === $book) {
throw ExceptionBookNotFound::fromUuid($id);
}
return $book;
}
src/App/Service/Book/DoctrineFindBookByUuid.php
@asgrim
try {
$this->entityManager->transactional(function () use ($book) {
$book->checkOut();
});
} catch (BookNotAvailable $bookNotAvailable) {
return new JsonResponse(['info' => $bookNotAvailable->getMessage()], 423);
}
src/App/Action/CheckOutAction.php
@asgrim
Generate the schema
$ vendor/bin/doctrine orm:schema-tool:create
ATTENTION: This operation should not be executed in a production
environment.
Creating database schema...
Database schema created successfully!
$
@asgrim
Insert some data
INSERT INTO book (id, name, in_stock) VALUES (
'1c06bec9-adae-47c2-b411-73b1db850e6f',
'The Great Escape',
true
);
@asgrim
/book/1c06bec9-adae-47c2-b411-.../check-out
{"info":"You have checked out The Great Escape"}
@asgrim
/book/1c06bec9-adae-47c2-b411-.../check-in
{"info":"You have checked in The Great Escape"}
@asgrim
Automatic Flushing Middleware
@asgrim
FlushingMiddleware
public function process(Request $request, DelegateInterface $delegate)
{
$response = $delegate->process($request);
if ($this->entityManager->isOpen()) {
$this->entityManager->flush();
}
return $response;
}
@asgrim
FlushingMiddleware
public function process(Request $request, DelegateInterface $delegate)
{
$response = $delegate->process($request);
if ($this->entityManager->isOpen()) {
$this->entityManager->flush();
}
return $response;
}
@asgrim
FlushingMiddleware
public function process(Request $request, DelegateInterface $delegate)
{
$response = $delegate->process($request);
if ($this->entityManager->isOpen()) {
$this->entityManager->flush();
}
return $response;
}
@asgrim
Add to pipeline
/** @var ZendExpressiveApplication $app */
$app->pipe(ZendStratigilityMiddlewareOriginalMessages::class);
$app->pipe(ZendStratigilityMiddlewareErrorHandler::class);
$app->pipe(ZendExpressiveHelperServerUrlMiddleware::class);
$app->pipe(AppMiddlewareErrorCatchingMiddleware::class);
$app->pipeRoutingMiddleware();
$app->pipe(AppMiddlewareFlushingMiddleware::class);
$app->pipe(ZendExpressiveMiddlewareImplicitHeadMiddleware::class);
$app->pipe(ZendExpressiveMiddlewareImplicitOptionsMiddleware::class);
$app->pipe(ZendExpressiveHelperUrlHelperMiddleware::class);
$app->pipe(PSR7SessionsStoragelessHttpSessionMiddleware::class);
$app->pipe(AppMiddlewareAuthenticationMiddleware::class);
$app->pipeDispatchMiddleware();
$app->pipe(ZendExpressiveMiddlewareNotFoundHandler::class);
@asgrim
Doing more with
middleware
@asgrim
Authentication
@asgrim
public function process(
ServerRequestInterface $request,
DelegateInterface $delegate
) : Response {
$queryParams = $request->getQueryParams();
// DO NOT DO THIS IN REAL LIFE
// It's really not secure ;)
if (!array_key_exists('authenticated', $queryParams)
|| $queryParams['authenticated'] !== '1') {
return new JsonResponse(['error' => 'You are not authenticated.'], 403);
}
return $delegate->process($request);
}
Create the middleware
@asgrim
public function process(
ServerRequestInterface $request,
DelegateInterface $delegate
) : Response {
$queryParams = $request->getQueryParams();
// DO NOT DO THIS IN REAL LIFE
// It's really not secure ;)
if (!array_key_exists('authenticated', $queryParams)
|| $queryParams['authenticated'] !== '1') {
return new JsonResponse(['error' => 'You are not authenticated.'], 403);
}
return $delegate->process($request);
}
Create the middleware
@asgrim
public function process(
ServerRequestInterface $request,
DelegateInterface $delegate
) : Response {
$queryParams = $request->getQueryParams();
// DO NOT DO THIS IN REAL LIFE
// It's really not secure ;)
if (!array_key_exists('authenticated', $queryParams)
|| $queryParams['authenticated'] !== '1') {
return new JsonResponse(['error' => 'You are not authenticated.'], 403);
}
return $delegate->process($request);
}
Create the middleware
@asgrim
public function process(
ServerRequestInterface $request,
DelegateInterface $delegate
) : Response {
$queryParams = $request->getQueryParams();
// DO NOT DO THIS IN REAL LIFE
// It's really not secure ;)
if (!array_key_exists('authenticated', $queryParams)
|| $queryParams['authenticated'] !== '1') {
return new JsonResponse(['error' => 'You are not authenticated.'], 403);
}
return $delegate->process($request);
}
Create the middleware
@asgrim
Helios
composer require dasprid/helios
@asgrim
PSR7-Session
composer require psr7-sessions/storageless
@asgrim
public function __invoke(ContainerInterface $container, $_, array $_ = null)
{
$symmetricKey = 'do-not-store-this-key-in-git-store-it-in-configuration-instead-please';
$expirationTime = 1200; // 20 minutes
return new SessionMiddleware(
new SignerHmacSha256(),
$symmetricKey,
$symmetricKey,
SetCookie::create(SessionMiddleware::DEFAULT_COOKIE)
->withSecure(false) // false on purpose, unless you have https locally
->withHttpOnly(true)
->withPath('/'),
new Parser(),
$expirationTime,
new SystemCurrentTime()
);
}
Factory the middleware
@asgrim
/** @var ZendExpressiveApplication $app */
$app->pipe(ZendStratigilityMiddlewareOriginalMessages::class);
$app->pipe(ZendStratigilityMiddlewareErrorHandler::class);
$app->pipe(ZendExpressiveHelperServerUrlMiddleware::class);
$app->pipe(AppMiddlewareErrorCatchingMiddleware::class);
$app->pipeRoutingMiddleware();
$app->pipe(AppMiddlewareFlushingMiddleware::class);
$app->pipe(ZendExpressiveMiddlewareImplicitHeadMiddleware::class);
$app->pipe(ZendExpressiveMiddlewareImplicitOptionsMiddleware::class);
$app->pipe(ZendExpressiveHelperUrlHelperMiddleware::class);
$app->pipe(PSR7SessionsStoragelessHttpSessionMiddleware::class);
$app->pipe(AppMiddlewareAuthenticationMiddleware::class);
$app->pipeDispatchMiddleware();
$app->pipe(ZendExpressiveMiddlewareNotFoundHandler::class);
Add middleware to pipe
@asgrim
$session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);
$session->set('counter', $session->get('counter', 0) + 1);
Session is stored in Request
@asgrim
$skills++;
@asgrim
To summarise...
● PSR-7 is the foundation for this!
● Diactoros is just a PSR-7 implementation
● Stratigility is a middleware pipeline: the main bit
● Expressive is a glue for everything
● DoctrineModule can be used (with some fiddling)
● container-interop-doctrine makes Doctrine work easier
● Middleware all the things!
● Similar concepts in other frameworks (e.g. Slim)
@asgrim
Useful references
● https://github.com/asgrim/book-library
● https://framework.zend.com/blog/2017-03-13-expressive-2-migration.html
● https://framework.zend.com/blog/2017-03-30-expressive-config-routes.html
● https://mwop.net/blog/2016-05-16-programmatic-expressive.html
● https://docs.zendframework.com/zend-expressive/
● https://docs.zendframework.com/zend-expressive/cookbook/autowiring-routes-and-pipelines/
● https://docs.zendframework.com/zend-expressive/cookbook/passing-data-between-middleware/
● http://www.masterzendframework.com/zend-expressive-introduction/
Any questions?
James Titcumb
@asgrim

More Related Content

What's hot

Crafting Quality PHP Applications: an overview (PHPSW March 2018)
Crafting Quality PHP Applications: an overview (PHPSW March 2018)Crafting Quality PHP Applications: an overview (PHPSW March 2018)
Crafting Quality PHP Applications: an overview (PHPSW March 2018)James Titcumb
 
Best practices for crafting high quality PHP apps - PHP UK 2019
Best practices for crafting high quality PHP apps - PHP UK 2019Best practices for crafting high quality PHP apps - PHP UK 2019
Best practices for crafting high quality PHP apps - PHP UK 2019James Titcumb
 
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)James Titcumb
 
Best practices for crafting high quality PHP apps (Bulgaria 2019)
Best practices for crafting high quality PHP apps (Bulgaria 2019)Best practices for crafting high quality PHP apps (Bulgaria 2019)
Best practices for crafting high quality PHP apps (Bulgaria 2019)James Titcumb
 
Best practices for crafting high quality PHP apps (php[world] 2019)
Best practices for crafting high quality PHP apps (php[world] 2019)Best practices for crafting high quality PHP apps (php[world] 2019)
Best practices for crafting high quality PHP apps (php[world] 2019)James Titcumb
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)Joshua Warren
 
Driving Design with PhpSpec
Driving Design with PhpSpecDriving Design with PhpSpec
Driving Design with PhpSpecCiaranMcNulty
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)James Titcumb
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012Nicholas Zakas
 
Bringing modern PHP development to IBM i (ZendCon 2016)
Bringing modern PHP development to IBM i (ZendCon 2016)Bringing modern PHP development to IBM i (ZendCon 2016)
Bringing modern PHP development to IBM i (ZendCon 2016)James Titcumb
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusIgnacio Martín
 
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)James Titcumb
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.xRyan Szrama
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)James Titcumb
 
Beyond MVC: from Model to Domain
Beyond MVC: from Model to DomainBeyond MVC: from Model to Domain
Beyond MVC: from Model to DomainJeremy Cook
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkVance Lucas
 
Effecient javascript
Effecient javascriptEffecient javascript
Effecient javascriptmpnkhan
 

What's hot (20)

Crafting Quality PHP Applications: an overview (PHPSW March 2018)
Crafting Quality PHP Applications: an overview (PHPSW March 2018)Crafting Quality PHP Applications: an overview (PHPSW March 2018)
Crafting Quality PHP Applications: an overview (PHPSW March 2018)
 
Best practices for crafting high quality PHP apps - PHP UK 2019
Best practices for crafting high quality PHP apps - PHP UK 2019Best practices for crafting high quality PHP apps - PHP UK 2019
Best practices for crafting high quality PHP apps - PHP UK 2019
 
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
 
Best practices for crafting high quality PHP apps (Bulgaria 2019)
Best practices for crafting high quality PHP apps (Bulgaria 2019)Best practices for crafting high quality PHP apps (Bulgaria 2019)
Best practices for crafting high quality PHP apps (Bulgaria 2019)
 
Best practices for crafting high quality PHP apps (php[world] 2019)
Best practices for crafting high quality PHP apps (php[world] 2019)Best practices for crafting high quality PHP apps (php[world] 2019)
Best practices for crafting high quality PHP apps (php[world] 2019)
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Step objects
Step objectsStep objects
Step objects
 
TDD with PhpSpec
TDD with PhpSpecTDD with PhpSpec
TDD with PhpSpec
 
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
 
Driving Design with PhpSpec
Driving Design with PhpSpecDriving Design with PhpSpec
Driving Design with PhpSpec
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012
 
Bringing modern PHP development to IBM i (ZendCon 2016)
Bringing modern PHP development to IBM i (ZendCon 2016)Bringing modern PHP development to IBM i (ZendCon 2016)
Bringing modern PHP development to IBM i (ZendCon 2016)
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - Limenius
 
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.x
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
Beyond MVC: from Model to Domain
Beyond MVC: from Model to DomainBeyond MVC: from Model to Domain
Beyond MVC: from Model to Domain
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-Framework
 
Effecient javascript
Effecient javascriptEffecient javascript
Effecient javascript
 

Similar to Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)

Kicking off with Zend Expressive and Doctrine ORM (PHP MiNDS March 2018)
Kicking off with Zend Expressive and Doctrine ORM (PHP MiNDS March 2018)Kicking off with Zend Expressive and Doctrine ORM (PHP MiNDS March 2018)
Kicking off with Zend Expressive and Doctrine ORM (PHP MiNDS March 2018)James Titcumb
 
Kicking off with Zend Expressive and Doctrine ORM (PHP South Africa 2018)
Kicking off with Zend Expressive and Doctrine ORM (PHP South Africa 2018)Kicking off with Zend Expressive and Doctrine ORM (PHP South Africa 2018)
Kicking off with Zend Expressive and Doctrine ORM (PHP South Africa 2018)James Titcumb
 
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)James Titcumb
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)James Titcumb
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Sven Ruppert
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...King Foo
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.jsdavidchubbs
 
Taming Deployment With Smart Frog
Taming Deployment With Smart FrogTaming Deployment With Smart Frog
Taming Deployment With Smart FrogSteve Loughran
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Jesus Manuel Olivas
 
Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015Sven Ruppert
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with ExpressAaron Stannard
 
sMash at May NYPHP UG
sMash at May NYPHP UGsMash at May NYPHP UG
sMash at May NYPHP UGProject Zero
 
Divide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.jsDivide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.jsSebastian Springer
 
Distributed Traceability in AWS - Life of a Transaction
Distributed Traceability in AWS - Life of a TransactionDistributed Traceability in AWS - Life of a Transaction
Distributed Traceability in AWS - Life of a TransactionAmazon Web Services
 
Ростислав Михайлив "Zend Framework 3 - evolution or revolution"
Ростислав Михайлив "Zend Framework 3 - evolution or revolution"Ростислав Михайлив "Zend Framework 3 - evolution or revolution"
Ростислав Михайлив "Zend Framework 3 - evolution or revolution"Fwdays
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLsintelliyole
 
Whoops! Where did my architecture go?
Whoops! Where did my architecture go?Whoops! Where did my architecture go?
Whoops! Where did my architecture go?Oliver Gierke
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST APICaldera Labs
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5Darren Craig
 

Similar to Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017) (20)

Kicking off with Zend Expressive and Doctrine ORM (PHP MiNDS March 2018)
Kicking off with Zend Expressive and Doctrine ORM (PHP MiNDS March 2018)Kicking off with Zend Expressive and Doctrine ORM (PHP MiNDS March 2018)
Kicking off with Zend Expressive and Doctrine ORM (PHP MiNDS March 2018)
 
Kicking off with Zend Expressive and Doctrine ORM (PHP South Africa 2018)
Kicking off with Zend Expressive and Doctrine ORM (PHP South Africa 2018)Kicking off with Zend Expressive and Doctrine ORM (PHP South Africa 2018)
Kicking off with Zend Expressive and Doctrine ORM (PHP South Africa 2018)
 
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.js
 
Taming Deployment With Smart Frog
Taming Deployment With Smart FrogTaming Deployment With Smart Frog
Taming Deployment With Smart Frog
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...
 
Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 
sMash at May NYPHP UG
sMash at May NYPHP UGsMash at May NYPHP UG
sMash at May NYPHP UG
 
Divide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.jsDivide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.js
 
Distributed Traceability in AWS - Life of a Transaction
Distributed Traceability in AWS - Life of a TransactionDistributed Traceability in AWS - Life of a Transaction
Distributed Traceability in AWS - Life of a Transaction
 
Ростислав Михайлив "Zend Framework 3 - evolution or revolution"
Ростислав Михайлив "Zend Framework 3 - evolution or revolution"Ростислав Михайлив "Zend Framework 3 - evolution or revolution"
Ростислав Михайлив "Zend Framework 3 - evolution or revolution"
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
 
Whoops! Where did my architecture go?
Whoops! Where did my architecture go?Whoops! Where did my architecture go?
Whoops! Where did my architecture go?
 
Express node js
Express node jsExpress node js
Express node js
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST API
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 

More from James Titcumb

Living the Best Life on a Legacy Project (phpday 2022).pdf
Living the Best Life on a Legacy Project (phpday 2022).pdfLiving the Best Life on a Legacy Project (phpday 2022).pdf
Living the Best Life on a Legacy Project (phpday 2022).pdfJames Titcumb
 
Tips for Tackling a Legacy Codebase (ScotlandPHP 2021)
Tips for Tackling a Legacy Codebase (ScotlandPHP 2021)Tips for Tackling a Legacy Codebase (ScotlandPHP 2021)
Tips for Tackling a Legacy Codebase (ScotlandPHP 2021)James Titcumb
 
Climbing the Abstract Syntax Tree (Midwest PHP 2020)
Climbing the Abstract Syntax Tree (Midwest PHP 2020)Climbing the Abstract Syntax Tree (Midwest PHP 2020)
Climbing the Abstract Syntax Tree (Midwest PHP 2020)James Titcumb
 
Climbing the Abstract Syntax Tree (php[world] 2019)
Climbing the Abstract Syntax Tree (php[world] 2019)Climbing the Abstract Syntax Tree (php[world] 2019)
Climbing the Abstract Syntax Tree (php[world] 2019)James Titcumb
 
Climbing the Abstract Syntax Tree (PHP Russia 2019)
Climbing the Abstract Syntax Tree (PHP Russia 2019)Climbing the Abstract Syntax Tree (PHP Russia 2019)
Climbing the Abstract Syntax Tree (PHP Russia 2019)James Titcumb
 
Climbing the Abstract Syntax Tree (ScotlandPHP 2018)
Climbing the Abstract Syntax Tree (ScotlandPHP 2018)Climbing the Abstract Syntax Tree (ScotlandPHP 2018)
Climbing the Abstract Syntax Tree (ScotlandPHP 2018)James Titcumb
 
Climbing the Abstract Syntax Tree (PHP Developer Days Dresden 2018)
Climbing the Abstract Syntax Tree (PHP Developer Days Dresden 2018)Climbing the Abstract Syntax Tree (PHP Developer Days Dresden 2018)
Climbing the Abstract Syntax Tree (PHP Developer Days Dresden 2018)James Titcumb
 
Climbing the Abstract Syntax Tree (Southeast PHP 2018)
Climbing the Abstract Syntax Tree (Southeast PHP 2018)Climbing the Abstract Syntax Tree (Southeast PHP 2018)
Climbing the Abstract Syntax Tree (Southeast PHP 2018)James Titcumb
 
Climbing the Abstract Syntax Tree (PHP UK 2018)
Climbing the Abstract Syntax Tree (PHP UK 2018)Climbing the Abstract Syntax Tree (PHP UK 2018)
Climbing the Abstract Syntax Tree (PHP UK 2018)James Titcumb
 
Climbing the Abstract Syntax Tree (Forum PHP 2017)
Climbing the Abstract Syntax Tree (Forum PHP 2017)Climbing the Abstract Syntax Tree (Forum PHP 2017)
Climbing the Abstract Syntax Tree (Forum PHP 2017)James Titcumb
 
Dip Your Toes in the Sea of Security (IPC Fall 2017)
Dip Your Toes in the Sea of Security (IPC Fall 2017)Dip Your Toes in the Sea of Security (IPC Fall 2017)
Dip Your Toes in the Sea of Security (IPC Fall 2017)James Titcumb
 
Climbing the Abstract Syntax Tree (IPC Fall 2017)
Climbing the Abstract Syntax Tree (IPC Fall 2017)Climbing the Abstract Syntax Tree (IPC Fall 2017)
Climbing the Abstract Syntax Tree (IPC Fall 2017)James Titcumb
 
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)James Titcumb
 
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)James Titcumb
 
Get Started with RabbitMQ (CoderCruise 2017)
Get Started with RabbitMQ (CoderCruise 2017)Get Started with RabbitMQ (CoderCruise 2017)
Get Started with RabbitMQ (CoderCruise 2017)James Titcumb
 
Dip Your Toes in the Sea of Security (CoderCruise 2017)
Dip Your Toes in the Sea of Security (CoderCruise 2017)Dip Your Toes in the Sea of Security (CoderCruise 2017)
Dip Your Toes in the Sea of Security (CoderCruise 2017)James Titcumb
 

More from James Titcumb (16)

Living the Best Life on a Legacy Project (phpday 2022).pdf
Living the Best Life on a Legacy Project (phpday 2022).pdfLiving the Best Life on a Legacy Project (phpday 2022).pdf
Living the Best Life on a Legacy Project (phpday 2022).pdf
 
Tips for Tackling a Legacy Codebase (ScotlandPHP 2021)
Tips for Tackling a Legacy Codebase (ScotlandPHP 2021)Tips for Tackling a Legacy Codebase (ScotlandPHP 2021)
Tips for Tackling a Legacy Codebase (ScotlandPHP 2021)
 
Climbing the Abstract Syntax Tree (Midwest PHP 2020)
Climbing the Abstract Syntax Tree (Midwest PHP 2020)Climbing the Abstract Syntax Tree (Midwest PHP 2020)
Climbing the Abstract Syntax Tree (Midwest PHP 2020)
 
Climbing the Abstract Syntax Tree (php[world] 2019)
Climbing the Abstract Syntax Tree (php[world] 2019)Climbing the Abstract Syntax Tree (php[world] 2019)
Climbing the Abstract Syntax Tree (php[world] 2019)
 
Climbing the Abstract Syntax Tree (PHP Russia 2019)
Climbing the Abstract Syntax Tree (PHP Russia 2019)Climbing the Abstract Syntax Tree (PHP Russia 2019)
Climbing the Abstract Syntax Tree (PHP Russia 2019)
 
Climbing the Abstract Syntax Tree (ScotlandPHP 2018)
Climbing the Abstract Syntax Tree (ScotlandPHP 2018)Climbing the Abstract Syntax Tree (ScotlandPHP 2018)
Climbing the Abstract Syntax Tree (ScotlandPHP 2018)
 
Climbing the Abstract Syntax Tree (PHP Developer Days Dresden 2018)
Climbing the Abstract Syntax Tree (PHP Developer Days Dresden 2018)Climbing the Abstract Syntax Tree (PHP Developer Days Dresden 2018)
Climbing the Abstract Syntax Tree (PHP Developer Days Dresden 2018)
 
Climbing the Abstract Syntax Tree (Southeast PHP 2018)
Climbing the Abstract Syntax Tree (Southeast PHP 2018)Climbing the Abstract Syntax Tree (Southeast PHP 2018)
Climbing the Abstract Syntax Tree (Southeast PHP 2018)
 
Climbing the Abstract Syntax Tree (PHP UK 2018)
Climbing the Abstract Syntax Tree (PHP UK 2018)Climbing the Abstract Syntax Tree (PHP UK 2018)
Climbing the Abstract Syntax Tree (PHP UK 2018)
 
Climbing the Abstract Syntax Tree (Forum PHP 2017)
Climbing the Abstract Syntax Tree (Forum PHP 2017)Climbing the Abstract Syntax Tree (Forum PHP 2017)
Climbing the Abstract Syntax Tree (Forum PHP 2017)
 
Dip Your Toes in the Sea of Security (IPC Fall 2017)
Dip Your Toes in the Sea of Security (IPC Fall 2017)Dip Your Toes in the Sea of Security (IPC Fall 2017)
Dip Your Toes in the Sea of Security (IPC Fall 2017)
 
Climbing the Abstract Syntax Tree (IPC Fall 2017)
Climbing the Abstract Syntax Tree (IPC Fall 2017)Climbing the Abstract Syntax Tree (IPC Fall 2017)
Climbing the Abstract Syntax Tree (IPC Fall 2017)
 
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
 
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
 
Get Started with RabbitMQ (CoderCruise 2017)
Get Started with RabbitMQ (CoderCruise 2017)Get Started with RabbitMQ (CoderCruise 2017)
Get Started with RabbitMQ (CoderCruise 2017)
 
Dip Your Toes in the Sea of Security (CoderCruise 2017)
Dip Your Toes in the Sea of Security (CoderCruise 2017)Dip Your Toes in the Sea of Security (CoderCruise 2017)
Dip Your Toes in the Sea of Security (CoderCruise 2017)
 

Recently uploaded

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 

Recently uploaded (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 

Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)