PHP Interoperability with PPI Framework

PHP Interoperability with PPI Framework

475493db5519a08372c9367d879ef9ad?s=128

Vítor Brandão

August 23, 2015
Tweet

Transcript

  1. THE PHP INTEROPERABILITY THE PHP INTEROPERABILITY FRAMEWORK FRAMEWORK

  2. PAUL DRAGOONIS PAUL DRAGOONIS Lead developer of PPI Software Consultant

    from Scotland Using PHP since 2001 PHP community guy, internals, and @dr4goonis php.net PHP- FIG VÍTOR BRANDÃO VÍTOR BRANDÃO PPI co-lead dev Born in ☼ Portugal, currently in ☂ England bundles, , 2PHP ports QA at @noiselabs NoiseLabs Consulting Ltd Sf2 ZF2 Python Gentoo Linux
  3. OUR MESSAGE OUR MESSAGE Frameworks are very powerful! but.. they

    come at a cost How you use them and depend on them. That's what's important
  4. TODAY TODAY Showing you how to unleash the power of

    not just 1 framework, but many! How that bene ts you, your team and your project
  5. FRAMEWORK POWER! FRAMEWORK POWER! Power is de ned by: Speed

    Flexibility Eco-system
  6. POWER COMES AT A COST POWER COMES AT A COST

    WHAT IS THE COST? WHAT IS THE COST? Vendor lock-in! (technical debt) This means: Limited technology stack Limited team experience Limited POWER!!!
  7. COMMON PATH OF STARTING A PROJECT COMMON PATH OF STARTING

    A PROJECT Step 1: customer tells you what they want (kind of) Step 2: you choose a framework/toolkit that suits that project Step 3: you build it
  8. WHAT HAPPENS NEXT? WHAT HAPPENS NEXT? Step 4: customer changes

    their mind on what they want Step 5: the tool you chose in the beginning, is no longer the most relevant one Step 6: you can't switch because you're locked into that vendor Step 7: you stick with the tool because it's too di cult to switch to the correct tool
  9. CAN'T SWITCH? WHY? CAN'T SWITCH? WHY? Existing frameworks force a

    1-to-1 relationship between your app and the framework vendor. You are tightly coupled to the framework that your app was built on. You can't move your code between your Symfony apps and Laravel apps
  10. IT'S NOT YOUR FAULT! IT'S NOT YOUR FAULT! You're not

    psychic! You cannot predict the future but, you can prepare for it :-) PPI will help you with this
  11. IT DOESN'T HAVE TO BE THIS WAY IT DOESN'T HAVE

    TO BE THIS WAY PPI prepares you for change. It's DESIGNED for change. Why? Your app code belongs to you, not to your framework. You're in charge!
  12. P.P.I.? P.P.I.? Hmm... what does PPI stand for? Not much,

    but let's try! PHP Phramework Interoperability
  13. WHAT IS PPI? WHAT IS PPI? It's not a framework

    but, you can use it like a framework Really, it's a framework delivery engine It delivers core parts of frameworks to your app Individually, to the modules of your app
  14. WHAT YOU CAN USE PPI AS? WHAT YOU CAN USE

    PPI AS? An engine that you can boot() up. This engine can be called as middleware, or booted, from inside existing apps i.e: Wordpress, Drupal, Legacy App A command line app A full-stack framework to dispatch() HTTP requests
  15. USING FRAMEWORKS DIRECTLY USING FRAMEWORKS DIRECTLY

  16. USING FRAMEWORKS IN PPI USING FRAMEWORKS IN PPI

  17. USING FRAMEWORKS IN PPI USING FRAMEWORKS IN PPI

  18. OBJECT MEDIATION OBJECT MEDIATION NO ABSTRACTION! :-) NO ABSTRACTION! :-)

    No added abstraction on top of existing framework.
  19. TECHNICAL PART BEGINS :-) TECHNICAL PART BEGINS :-)

  20. POWERED BY SOLID COMPONENTS POWERED BY SOLID COMPONENTS

  21. WHAT'S INSIDE THE PPI ENGINE? WHAT'S INSIDE THE PPI ENGINE?

    composer.json: "require": { "psr/log": "~1.0", "symfony/class-loader": "~2.7", "symfony/dependency-injection": "~2.7", "symfony/config": "~2.7", "symfony/console": "~2.7", "symfony/debug": "~2.7", "symfony/finder": "~2.7", "symfony/yaml": "~2.7", "zendframework/zend-eventmanager": "~2.3", "zendframework/zend-modulemanager": "~2.3", "zendframework/zend-servicemanager": "~2.3", "zendframework/zend-loader": "~2.3", "symfony/templating": "~2.7", "symfony/framework-bundle": "~2.7", "psr/http-message": "^0.11", "symfony/http-foundation": "~2.7", "symfony/http-kernel": "~2.7", "symfony/routing": "~2.7", "symfony-cmf/routing": "1.3.0" }
  22. PPI IS MODULAR BY DESIGN PPI IS MODULAR BY DESIGN

    You only need to add what you need composer.json "ppi/smarty-module": "~1.0", "ppi/twig-module": "~1.0", "ppi/mustache-module": "~1.0" "ppi/laravel-routing": "~1.0" "ppi/aura-routing": "~1.0" "ppi/symfony-routing": "~1.0" "ppi/datasource-module": "~1.0", // LaravelDB, Eloquent, Doctrine ..etc "ppi/cache-module": "~1.0"
  23. PPI MODULE WITH ROUTERS PPI MODULE WITH ROUTERS

  24. PPI MODULE WITH TEMPLATING ENGINES PPI MODULE WITH TEMPLATING ENGINES

  25. MODULE1 REST API MODULE MODULE1 REST API MODULE

  26. None
  27. MODULE2 MVC FULL STACK APP MODULE2 MVC FULL STACK APP

  28. None
  29. MODULE3 MVC FULL STACK APP MODULE3 MVC FULL STACK APP

  30. None
  31. PSR'S PSR'S Spearhead PHP-FIG concepts and ideas with a real-life

    usage for these standards. We built our own interop layers rst, then backport them to PHP-FIG. A friendly environment for swappable 3rd-party components.
  32. PSR - WHAT'S IN // WHAT'S COMING? PSR - WHAT'S

    IN // WHAT'S COMING?
  33. PPI IS A PSR-AWARE FRAMEWORK PPI IS A PSR-AWARE FRAMEWORK

    You can easily add more libraries into the mix when they implement a PSR. When consuming frameworks like (ZF2, SF2, Aura2) - that don't support PSR-X yet - PPI bridges the gap for you.
  34. PSR-7: REQUEST INTERFACE PSR-7: REQUEST INTERFACE composer.json: "require": { "psr/http-message":

    "~1.0" } PPI/Framework/Http/Request.php use Psr\Http\Message\RequestInterface; use Symfony\Component\HttpFoundation\Request as SymfonyHttpRequest; /** * HTTP messages consist of requests from a client to a server and * responses from a server to a client. This interface defines the * methods common to each. */ class Request extends SymfonyHttpRequest implements RequestInterface { public function withBody(StreamInterface $body) { $new = clone $this; $new->stream = $body; return $new; } }
  35. PSR-7: REQUEST INTERFACE IN PSR-7: REQUEST INTERFACE IN CONTROLLERS CONTROLLERS

    composer.json: <?php namespace Application\Controller; use PPI\Framework\Module\Controller as BaseController; use Psr\Http\Message\RequestInterface; class Mycontroller extends BaseController { public function indexAction(RequestInterface $request) { if ('POST' === $request->getMethod()) { // do POST stuff } } }
  36. PSR-6: CACHING INTERFACE PSR-6: CACHING INTERFACE In production for over

    2 years now. namespace PPI\CacheModule\Cache\Driver; use PPI\CacheModule\Cache\CacheItem; use PPI\CacheModule\Cache\CacheInterface; class RedisCache implements CacheInterface { // ... } Drivers: APC, Disk, Memcached, Memory, Xcache.
  37. CONTAINER INTERFACE CONTAINER INTERFACE namespace PPI\Framework\ServiceManager; use Symfony\Component\DependencyInjection\ContainerInterface; use Zend\ServiceManager\ServiceManager

    as BaseServiceManager; /** * ServiceManager implements the Service Locator design pattern. * * The Service Locator is a service/object locator, tasked with retrieving other * objects. We borrow this one from Zend Framework 2. */ class ServiceManager extends BaseServiceManager implements ContainerInterface { /** * Register a service with the locator. */ public function set($name, $service, $shared = true) { return $this->setService($name, $service, $shared); } }
  38. ROUTER INTERFACE? ROUTER INTERFACE? In PPP 2.1, using a Chained

    Router Will push a interface in upcoming releases
  39. PPI ROUTER PPI ROUTER We made a routing interoperability layer

    (Routing PSR?). Mediate routing and request information from PPI to Aura (for example). If a Routing PSR is created, we get to throw away a lot of code
  40. None
  41. PRACTICAL EXAMPLES PRACTICAL EXAMPLES USING PPI USING PPI

  42. INSTALLATION INSTALLATION 21st century. Use composer: Step 1: $ composer

    create-project -sdev --no-interaction \ ppi/skeleton-app /var/www/skeleton and for your convenience: Step 2 $ vagrant up ppi-lamp and now...
  43. SKELETON APP SKELETON APP

  44. $ APP/CONSOLE $ APP/CONSOLE

  45. APP CONFIGURATION APP CONFIGURATION app/ ├── FrameworkRequirements.php ├── check ├──

    config │ ├── base │ │ ├── app.php │ │ ├── app.yml │ │ ├── datasource.php │ │ └── datasource.yml │ ├── dev │ │ ├── app.php │ │ └── app.yml │ └── prod │ ├── app.php │ └── app.yml ├── console ├── init.php └── views ├── base.html.php ├── base.html.smarty └── base.html.twig
  46. ZF-LIKE CONFIGURATION ZF-LIKE CONFIGURATION app.php <?php $config = []; $config['framework']

    = [ 'templating' => ['engines' => ['php', 'smarty', 'twig')] , 'skeleton_module' => ['path' => './utils/skeleton_module'] ]; $config['datasource'] => [ 'connections' = require __DIR__ . '/datasource.php' ]; $config['modules'] = require __DIR__ . 'modules.php'; return $config;
  47. SYMFONY-LIKE YAML SYMFONY-LIKE YAML app.yml imports: - { resource: datasource.yml

    } - { resource: modules.yml } framework: templating: engines: ["php", "smarty", "twig"] skeleton_module: path: "./utils/skeleton_module" monolog: handlers: main: type: stream path: %app.logs_dir%/%app.environment%.log level: debug
  48. FRONT CONTROLLER FRONT CONTROLLER public/index.php <?php require_once 'app/init.php'; // Set

    the environment $env = getenv('PPI_ENV') ?: 'dev'; $debug = getenv('PPI_DEBUG') !== '0' && $env !== 'prod'; // Create and configure the Application $app = new PPI\Framework\App(array( 'environment' => $env, 'debug' => $debug, 'rootDir' => realpath(__DIR__.'/../app') )); $app->loadConfig($app->getEnvironment().'/app.php'); // Just Boot, no HTTP $app->boot() // OR: Handle requests $app->run();
  49. MODULE STRUCTURE MODULE STRUCTURE MyModule | ├── Module.php ├── resources

    │ ├── config │ │ └── config.yml │ ├── routes │ │ ├── aura.php │ │ └── symfony.yml │ │ └── laravel.php │ └── views │ └── index │ ├── index.html.mustache │ ├── index.html.php │ ├── index.html.smarty │ └── index.html.twig └── src ├── Services │ └── DomainClass.php ├── Controller │ ├── Index.php
  50. ROUTING DEFINED PER MODULE ROUTING DEFINED PER MODULE class Module

    extends AbstractModule implements ModuleInterface { public function getRoutes() { return $this->loadAuraRoutes(__DIR__ . '/resources/routes/aura.php'); return $this->loadSymfonyRoutes(__DIR__ . '/resources/routes/symfony.yml'); return $this->loadLaravelRoutes(__DIR__ . '/resources/routes/laravel.php'); } }
  51. PROGRESS PROGRESS PPI is ready for you to build projects

    in. Release 2.1 is in alpha now and your feedback is welcome.
  52. PPI HELPS YOUR PROJECT & YOUR TEAMS PPI HELPS YOUR

    PROJECT & YOUR TEAMS You no longer need a narrow skillset, but nd good developers You become exposed to new frameworks and new toolsets You are exible and not bound to one single stack You take your code from project to project with ease .. so much more ..
  53. RECAP RECAP PPI prepares you for change. It's DESIGNED for

    change.
  54. None
  55. None
  56. https://joind.in/15049 THANK YOU BOSTON. THANK YOU BOSTON. Questions?

  57. | Northeast PHP 2015 @ppi_framework Please Rate Our Talk! Documentation:

    Gitter: Twitter: Email: or IRC: https://joind.in/15049 http://docs.ppi.io gitter.im/ppi/framework @ppi_framework paul@ppi.io vitor@ppi.io #ppi at freenode