29
Practical ZF1 to ZF2 Migration: Lessons from the Field Clark Everetts, Zend Technologies, Inc. Sunshine PHP Uncon

Sunshine php practical-zf1-zf2-migration

Embed Size (px)

DESCRIPTION

One thing we do at Zend is provide consulting services to companies around the world, and many of those consulting engagements involve planning migrations from ZF1 to ZF2. Learn some techniques that we have found work quite well to help ease that migration effort and answer questions like "What are the low hanging fruit? How can I reuse ZF1 resources in a ZF2 application?" We shows the codez!

Citation preview

Page 1: Sunshine php practical-zf1-zf2-migration

Practical ZF1 to ZF2 Migration:Lessons from the Field

Clark Everetts,Zend Technologies, Inc.

Sunshine PHP Uncon

Page 2: Sunshine php practical-zf1-zf2-migration

2

What are we going to talk about?

Getting from Here to Here

Higher-Level(ROI, Organizational, Planning, Goals, Constraints)

Lower-Level(Coding Suggestions, Tools, Resources, Best Practices)

Suggestions / Best Practices

Page 3: Sunshine php practical-zf1-zf2-migration

3

•Clark Everetts– Professional Services Consultant for Zend Technologies– Onsite and Remote Consulting – Linux, IBM iSeries, Windows

● Software Architecture Audits and Code Reviews● Performance Audits● Continuous Delivery Assessments

– Online / Onsite Training in PHP, ZF, Studio, Server, etc.– SmartStarts: Training and Onsite Guided Development

•Past Life: Independent Consultant (2002 - 2012)– Web Sites and Web Applications– Contract Instructor for Zend

•Past, Past Life: Contractor for US Army and NASA (1990 - 2002)– Interceptor Ground Control Software; Green Screen Db Applications

– Space Station: Real-time, Embedded Software; Science Platforms, Life Support

Who am I?

Page 4: Sunshine php practical-zf1-zf2-migration

4

•Your role: Manager, developer, stakeholder/decision-maker?

•Size: Small to large companies; small to large dev teams

•Have you migrated applications from ZF1 to ZF2?

•Migrating now? How far along in the process are you?

•What challenges did you face / are you facing?

•What tools did you use, or wish existed?

•What did you do before you started?

•Did you expect to accomplish anything besides “the

migration?”

Who are You?

Page 5: Sunshine php practical-zf1-zf2-migration

What (I think) You Want to Know

•Available Tools? How much do they do?

•Low-hanging fruit; most difficulties?

•Cost/Benefit? Expected gains?

– Short-term?

– Long-term?

– When not to migrate?

•How to plan a migration; what factors affect the planning?

•Developer skills / skill levels required?

•Budget, schedule is expected for a given project size?

•Other resources?

Page 6: Sunshine php practical-zf1-zf2-migration

6

•Zend's Collective Experience– Planning, Guiding, Implementing Migrations

Where this talk comes from

Page 7: Sunshine php practical-zf1-zf2-migration

7

The Prospect of Migration...

Page 8: Sunshine php practical-zf1-zf2-migration

8

•Write new ZF2 application from scratch?

•Run ZF1 and ZF2 side-by-side?– Use ZF2 components in existing ZF1 application

– Use ZF1 components in new ZF2 application

– Some URLs (existing capabilities) ZF1, with other URLs (entirely new features) implemented in ZF2

– Convert models, controllers, utility functions, helpers, etc.

•Which ZF2 components are easiest to use in a ZF1 app?

Decisions, decisions...

Page 9: Sunshine php practical-zf1-zf2-migration

More Decisions!

•New URLs for new features of application: can do in ZF2, but will likely rely upon existing ZF1 models, helpers, etc., especially if you took the effort to make those components reusable in the first place

•Build and test ZF2 version and then cut over from old site to new one, or iterate existing ZF1 production site into a new ZF2-based site?

•Select a minimum PHP version – PHP 5.3.3 is minimum for ZF2; current are 5.5.4 and 5.4.20. PHP

5.3.27+ will receive only security fixes through much of 2014 (Zend supports PHP 5.2 for Enterprise customers on particular product versions; will continue to support PHP 5.3)

– Consider most recent PHP version you can; this implies parallel migrations (PHP version as well as ZF2), Look at http://php.net/ChangeLog-5.php for removal of /changes to legacy features and new capabilities

– Consider impact to other PHP apps on the server

Page 10: Sunshine php practical-zf1-zf2-migration

10

No One Migration Strategy to Rule Them All

There is no single, one-size-fits all, “correct” migration path for all applications and organizations.

Many factors, including project size, team size and experience with ZF1 and ZF2, structure and quality of the ZF1 codebase, all affect the path to take.

* http://ligh7bulb.deviantart.com/

*

Page 11: Sunshine php practical-zf1-zf2-migration

Remember the Planned Migration Layer?

•Remember the planned Migration Layer?– Was to allow ZF1 code to run on the ZF2 “engine”

– Work started during ZF2 betas; too much change between beta releases to keep such a tool current

– Emulating ZF1 behaviour in ZF2 would have taken unacceptable amount of developer time away from ZF2 development

•Though many people desired it, a full Migration Layer isn't strictly necessary– PHP 5.3 Namespaces– Migration: tedious, but not as hard as you think

● Depends on the code you're starting with!● Fat controllers w/ data access, business logic, HTML :-(

Page 12: Sunshine php practical-zf1-zf2-migration

Some Tools Exist to Help

•ZF2 Documentation Pagehttp://framework.zend.com/manual/2.2/en/migration/overview.html

● GitHub: EvanDotPro/zf-2-for-1

ZF2 Form View Helpers, could be extended to other features

Check out the forks, which have more features.

– Not for the long-term; it is a deliberately temporary solution!

• GitHib: prolic/HumusMvcSkeletonApplication

integrates ModuleManager and ServiceManager into ZF1 application

See http://www.sasaprolic.com/2012/10/when-migration-to-zend-framework-2.html

Page 13: Sunshine php practical-zf1-zf2-migration

13

ZF1 Compatibility Module - Overview

•Custom ZF2 Module that you write – simple, straightforward

•Use existing ZF1-based application resources with minimal initial code rewrite:

– Database

– Translation

– Session

•That is, Any Zend_Application_Resource plugin

•Obtain and use these resources as ZF2 Services via ServiceManager

•Only for Application-wide, “global” resources

Page 14: Sunshine php practical-zf1-zf2-migration

14

The Prospect of Migration...

Paint the picture of a transformation the audience will see during the talk.Give them someone to “root” for; the audience is the Hero of the story.

Starting to Feel Better?

Page 15: Sunshine php practical-zf1-zf2-migration

15

•What you do depends on what you want– Delay a complete rewrite

● Phased approach, reusing much of your ZF1 code– Refactor and clean up “bad” code

•Smaller Application, perhaps non mission-critical– Rewrite, use as a learning experience for a larger

migration effort

Planning

Page 16: Sunshine php practical-zf1-zf2-migration

16

// config/application.config.php

'modules' => array(

'Application',

'Zf1', // <-- your ZF1 compatibility module

// you will add other modules to the list as you progress

),

// remainder of config array

ZF1 Compatibility Module – Add Module to config

Page 17: Sunshine php practical-zf1-zf2-migration

17

// module/Zf1/Module.php

namespace Zf1;

use Zend\ModuleManager\Feature\AutoloaderProviderInterface;

use Zend\Mvc\MvcEvent;

class Module implements AutoloaderProviderInterface

{

public function getAutoloaderConfig()

{

$zf1path = getenv('ZF1_PATH'); // SetEnv in Apache vhost/.htaccess

if (!$zf1path) { throw new \Exception('Define ZF1 library path'); }

/// more coming...

ZF1 Compatibility Module – Autoload ZF1 Classes

Page 18: Sunshine php practical-zf1-zf2-migration

18

// module/Zf1/Module.php getAutoloaderConfig()

return array(

'Zend\Loader\StandardAutoloader' => array (

'namespaces' => array(

__NAMESPACE__ => __DIR__ . '/src/' . str_replace('\\', '/', __NAMESPACE__)

),

'prefixes' => array('Zend' => $zf1path)

)

);

ZF1 Compatibility Module – Autoload ZF1 (cont.)

Page 19: Sunshine php practical-zf1-zf2-migration

19

// module/Zf1/config/module.config.php

'service_manager' => array (

'factories' => array(

'zf1-db' => 'Zf1\Service\Factory\Database',

'zf1-translate'=> 'Zf1\Service\Factory\Translate',

// other ZF1-based resources...

),

'aliases' => array (

'translate' => 'zf1-translate',

)

)

ZF1 Compat. Module – Resources become Services

Page 20: Sunshine php practical-zf1-zf2-migration

20

ZF1 Compat. Module – Factories to Create Services

namespace Zf1\Service\Factory;

use Zend\ServiceManager;

class Database implements ServiceManager\FactoryInterface {

public function createService( ServiceManager\ServiceLocatorInterface $serviceLocator ) { $config = $serviceLocator->get('config'); $adapter = \Zend_Db::factory( $config['zf1-db']['adapter'], $config['zf1-db']['params'] ); return $adapter; }}

Page 21: Sunshine php practical-zf1-zf2-migration

21

ZF1 Compatibility Module – Register the Services

// module/Zf1/Module.php public function onBootstrap(MvcEvent $e){ $services = $e->getApplication()->getServiceManager(); $dbAdapter = $services->get('zf1-db'); \Zend_Db_Table_Abstract::setDefaultAdapter($dbAdapter);

// Perhaps your views need config. For now, in views, access config// directly via registry. Later, use code that injects config into view $config = $services->get('config'); \Zend_Registry::set('config', Util::arrayToObject($config));

// In audits, we often find ZF1 models accessing the db via registry// What you see here is not “best practice,” but a baby step toward// injecting this dependency in a later phase of migration $database = $services->get('zf1-db'); \Zend_Registry::set('database', $database);

$services = $e->getApplication()->getServiceManager(); \Zend_Registry::set('session', $services->get('auth')->getStorage()->read());}

Page 22: Sunshine php practical-zf1-zf2-migration

22

ZF1 Compatibility Module – Review

•Temporary, stop-gap measure for reusing ZF1 resources

•Avoids major up-front rewrite

•Obtain and use these resources as ZF2 Services via ServiceManager:

– Add it to the list of modules used by your ZF2 app

– Set up autoloading to find ZF1 library

– Identify Resources as Services to the ServiceManager

– Write Factories to create the services

– Register the Services

•Only for Application-wide, “global” resources

•Remember: This Module will GO AWAY in a later phase!

Page 23: Sunshine php practical-zf1-zf2-migration

23

General Migration Practices - MWOP

• Do as much as practical to separate your business logic OUT of your controllers. Controllers should be thin, and primarily gather arguments to pass to the domain model, and then gather the response to pass on to the view.

• Try to remove use of plugins such as "ActionStack" and "Forward" whenever possible. The latter has an equivalent in ZF2 but operates slightly differently; ActionStack is unnecessary, as you can directly call on other controllers more easily in ZF2.

• Rewrite a module at a time; this will help you identify patterns for migration, and give you confidence as you go forward.

• Make sure you identify any dependencies on other modules early, so you can migrate cleanly. Avoids major up-front rewrite.

• This talk shows how you can map ZF1 "application resources" as services in ZF2.

• A module to bootstrap ZF1 config, autoloading, and resources makes it easier to re-use resources written for ZF1 inside a ZF2 app; the bulk of the work of migration will then be in the MVC, particularly in controllers and forms.

Page 24: Sunshine php practical-zf1-zf2-migration

24

The Prospect of Migration...

How are you feeling?

Page 25: Sunshine php practical-zf1-zf2-migration

25

Reusing ZF1 Configuration - Overview

•ZF1 Configuration – .ini, .xml, .json, .yaml

•ZF2 Configuration – arrays

•Reuse existing ZF1 configuration files in ZF2 application

Page 26: Sunshine php practical-zf1-zf2-migration

26

Reusing ZF1 Configuration - .ini files

// module/SomeModule/Module.phppublic function getConfig (){ $path = __DIR__ . '/config/config.ini'; $config = new \Zend_Config_Ini($path, $section); $oldConfig = $config->toArray();

if (defined('ZF1_COMPAT')) { $oldConfig['zf1-db'] = $oldConfig['db']; } // Fix 1: for the database options $dbParams = array ('driver' => $oldConfig['db']['adapter']); $dbParams = array_merge($dbParams, $oldConfig['db']['params']); $oldConfig['db'] = $dbParams; $phpConfig = include __DIR__ . '/config/module.config.php'; return array_merge($oldConfig, $phpConfig);}

Page 27: Sunshine php practical-zf1-zf2-migration

27

Reuse ZF1 Models - Autoloading

// module/SomeModule/Module.phppublic function getAutoloaderConfig (){ return array( 'Zend\Loader\ClassMapAutoloader' => array( __DIR__ . '/autoload_classmap.php' ), 'Zend\Loader\StandardAutoloader' => array ( 'namespaces' => array( // if we're in a namespace deeper than one level we need to // fix the \ in the path __NAMESPACE__ => __DIR__ . '/src/' . str_replace('\\', '/', __NAMESPACE__) ), 'prefixes' => array(// This goes away in later phase 'Model' => __DIR__ .'/src/' . str_replace('\\', '/', __NAMESPACE__) . '/Model', ) ) );}

Page 28: Sunshine php practical-zf1-zf2-migration

28

Reuse ZF1 Models – Merge config with ZF2 config

// module/SomeModule/Module.phppublic function getConfig (){ include __DIR__ . '/config/config.php'; $path = __DIR__ . '/config/config.ini'; $config = new \Zend_Config_Ini($path, $section); $oldConfig = $config->toArray(); if (defined('ZF1_COMPAT')) { $oldConfig['zf1-db'] = $oldConfig['db']; } // database options from db section of config.ini $dbParams = array('driver' => $oldConfig['db']['adapter']); $dbParams = array_merge($dbParams, $oldConfig['db']['params']); $oldConfig['db'] = $dbParams; $phpConfig = include __DIR__ . '/config/module.config.php'; return array_merge($oldConfig, $phpConfig);}

Opportunity for refactoring

Page 29: Sunshine php practical-zf1-zf2-migration

Thank You!Please give constructive feedback at

https://joind.in/talk/view/10680

Email: [email protected]://github.com/clarkphp

Twitter: @clarkphp