Upgrading Zend Framework from version X to version Y - php

Whenever I upgrade Zend Framework I study the changelogs ( http://framework.zend.com/changelog ) but still feel like I am going through a bit of leap of faith to ensure my application does not break.
So far, I have not really had any problems. A large amount of the application is under unit test and web test. But, tests do not have 100% coverage so the whole process of upgrading ZF is still a bit unnerving.
So the Question is...
Where would I be able to find definitive information on interface changes and 'backwards compatibility breaks' when upgrading from 'ZF version X' to 'ZF version Y'?
Also if anyone has any general upgrade tips on upgrading vendor code smoothly then that would be of interest.
i.e.
Do you write a set of unit tests to work on all framework components used by your app?
Also any specific tips on upgrading from ZF 1.8 to 1.11 would be welcomed in comments.

ZF's has a strict release policy
A major release may contain any changes, including bug fixes, backwards compatible features and functionality enhancements, and backwards incompatible releases.
A minor release may only contain backwards compatible changes, including bug fixes and backwards compatible features and functionality enhancements.
A mini release may only contain bug fixes. Note that no new features, functionality enhancements, or API changes are allowed whatsoever. The framework should look and behave the same across mini releases.
The release notes usually contain information about changes that are not backwards compatible. And as you can see, those may only happen between major releases, which is from ZF1 to ZF2, but not from ZF1.8 to ZF1.11.
Now, just because the may not happen, doesnt mean they dont happen, but from my experience all changes were backwards compatible. I remember they changed the autoloader and static Filter invocation in some previous version. ZF would continue to work as usual, but raise deprecation notices. So you are encouraged to take action then, but it won't break your application if you don't.
Basically, as long as your application is Unit-Tested, you should not have any (or very little) problems updating. Update, run your test, if something breaks, fix. Push the updated release to your development and see if it has any notices or warnings.
If you really, really want to know all the changes, then do an SVN Diff between your old version and the version you want to update to.

Related

Does updating dependencies break backwards compatibility (semver major version change)?

Let's say I publish a new library Foo v1.0.0 which requires php 5.6 as a dependency.
Now I would like to use some of the newer language constructs in php 7.0 internally within some of the method implementations. However, my entire public API (method names, parameters, returns, etc.) remain unchanged.
Following semver, what version number should I now release?
It seems to me that requiring a new major platform dependency will break backwards compatibility for existing users running php 5.6 who will not be able to simply upgrade with composer update so it should now be v2.0.0. On the other hand, because nothing has changed about my exposed API, I feel like this should instead just be a patch v1.0.1
No, you got wrong what backward compatibility means. If your library's API remains unchanged then it may be just new major version but it is still backward compatible, which means upgrading does not require changes in code using your library. Requiring PHP 7 is just requirement but it got nothing with compatibility.
Other projects I saw usually do major number bump but that's mostly because they only changed requirements but also did some changes to benefit from i.e. new PHP functionalities. So ask yourself if you will really benefit from just requiring PHP 7 or it will be sort of cosmetic change or code cleanup. It also depends how many users your change would really affect.
EDIT
Requiring PHP 7 is sometimes huge change as many people are still on 5.x and don't want or can't upgrade yet and while it is not the backward compatibility issue here, I'd make it 2.0.0 to clearly indicate this change as major.

How to version-control different features within one web application?

We have some web applications, and now these websites are being upgraded, not for the first time, but it is becoming very dificult to control the version for the users and for the developers.
We have many clients, some of they are running the same application, but they need to pay for upgrades. But, not all clients pay for upgrades, and because this we have some clients running one version and another clients running another version.
We have two ways, and we are researching for a third way:
Put the version in the path, like this: www\project\version\system-files
But this way became confusing for some users, because for they the URL became: www.website.com/app-version, and when the system is upgraded, the URL change.
Put the version in the function, like this: function V1_functionX()
When the function need to be upgraded, we create a new function called V2_functionX. But, this create a "fat" website, and the team did some mistakes during development, because we don't have "one development version", but "many versions to develop", and some functions are used in more than one website.
The very first way was abandoned a long time ago. We developed the web application, and "closed the version", and all requests was included in the upgraded version, that version when finished was "closed" too. But this was too slow too made corrections and deploy "small upgrades"
We talked about the way in another companies: they "shutdown" the website to upgrade the system. This will be probably our way.
But, if anyone have another idea to not shutdown a website for upgrade the application, we will be glad to listen.
Note: this is not about SVN.
You say you have different versions of your applications that must be maintained for different clients. I expect you don't need me to tell you this adds significantly to the complexity of your overall system, and thus your first priority is to reduce the number of versions you are maintaining in parallel.
API services have the same problem: a new version with more features is offered, but the old one needs to be maintained to give the new version time to stabilise and to give users sufficient time to upgrade their code. Your difficulty is similar. The first question I would therefore ask is whether it is possible to maintain only two versions.
If that is not possible, try at least minimising the number of concurrent versions: where a new version must be created, you need to encourage users to migrate from one version to another. (You've said you cannot unify your users onto one version, but without further information about your exact use-case, it is not possible to offer an independent view on that). So, perhaps one approach is to never maintain more than, say, five versions.
There are a number of strategies you can take to mitigate the complexity of the system you now have. Firstly, consider separating your code into a "core" of features that all versions absolutely must have. This will be common to all versions, so that if you fix a bug here, all clients benefit from the fix. This might be a visible feature (e.g. a product editing screen) or a framework feature (e.g. force SSL during checkout).
Your core libraries and client-specific functions could then reside in a set of libraries like so:
/project/core
/project/versions/1/Class.php
/project/versions/1.1/Class.php
/project/versions/2/Class.php
/project/versions/2.1.1/Class.php
/project/versions/...
(Class.php is of course an example - in practise there would be many class files here, each named appropriately.)
In this way, you do not need to call functions with a V1_ prefix, since that will require the replication of your version choosing code in a lot of places. It is much better to just load the library pertaining to the correct version, and as long as the function names are the same across all versions, you can just use the function name and your library loader will take care of the rest.
Another approach is to use plugins, like WordPress does. Where a plugin is added, it modifies some core functionality by adding new or different behaviour. The "middleware" design pattern may be useful here - the Slim framework (and undoubtedly others) uses this approach to add pre- or post-call hooks to an existing route handler, and thus offers a clean mechanism to edit existing functionality in a variety of combinations.
To summarise, your current situation is not just a management problem, but will cost you in slow development time and additional debugging. Whilst the above approaches will still be necessary to reduce some of the complexity, consider also:
forcing laggard clients to upgrade to one of your currently supported versions
giving an upgrade to laggard clients to the oldest possible supported version for free
Some additional thoughts based on new information. I had pondered whether splitting the code into separate repositories would help, one for each client. However I wonder if there is no guarantee that they would; even if you pull core features in using Composer, or a Git submodule, there is still the possibility of divergence between your latest core and your earliest client code. At some point your worst laggard client is going to hold back development on the core.
You can always leave this client on an abandoned version, but if they spot a bug, it is not worth back-porting a fix from your latest core, since that will cause you all the compatibility headaches you've been trying to avoid. Either they upgrade to a minimum client version that works with the latest core (and pay to do so if necessary) or they tolerate the bug indefinitely.
You've mentioned that each client gets his or her own database. That is helpful, up to a point, since it means that client versions are not entirely constrained with database schema decisions that have been forced by the core. However, this will still have a knock-on effect on how much code you can move to the core.
For example, let us assume that you have seven clients, and six of them have a User entity that has an email address, to handle password change requests (one client has a User entity without this field). This means that, if the awkward schema may not change, the core cannot assume that an email address is available. (In this trivial case it might be cheaper to upgrade the odd-one-out for free, so that more code can go in the core, rather than maintaining such a standard thing as a version enhancement).
Given the level of complexity, and since it sounds like you are maintaining this for the long term, I think you should set up some unit and functional tests. You'll need to split these into "core" and "per version" as well. If you find a bug, regardless of whether it is caused by feature versioning or not, write a failing test, and then fix it. You'll then have - at least in theory - a way to check if a change will impact on a particular client's version in a way you did not envisage.
We have this at my work :
Local dev website(SVN)
dev server where all developer test
Preprod where everything is Ok
Prod (rsync from preprod)
The rsync between 2 server is super fast, when we do a major update its in less than 5s

PHP 6.0 - Roadmap?

With the recent announcement that PHP 6 development has been halted, I'm confused as to what the PHP 5.x and 6.x road map includes.
The current version of PHP is 5.3.2.
There were quite a few significant features to come in PHP 6.0, such as:
APC include for automatic bytecode caching
Unicode support
etc..
Question: What is the new road map of PHP given 6.0 has been canceled? What major features will be available next and in what release?
Features:
Unicode support;
APC opcode cache as standard;
Removal of several deprecated features (eg magic quotes, register globals, the ereg library and safe mode).
No firm date has been set. Anything you read is purely conjecture.
You may want to read Future of PHP 6. PHP6 has somewhat stalled, particularly on the Unicode issues. Just to set the level of your expectations, people have been discussing PHP6 since at least 2006.
Here's an article I read recently on the matter: Resetting PHP 6
It goes into some detail the cause of the delay.
Horizontal code reuse!
Actually, I'm surprised it's not mentioned yet, it's the biggest feature IMO.
Basically, it's a way to ease code reuse, by adding methods to classes without inheriting from another class. It's similar to multiple inheritance, but avoids the diamond problem.
Unicode branch is on hold for now. Nobody knows what happens with it yet, until there's a good plan how to proceed. The trunk branch - probably to be named 5.4 (or, less probably, 6) - is being actively developed, is to feature significant performance improvements, traits (already in) and some other goodies you can find on http://wiki.php.net/rfc/ or directly from the SVN NEWS file. It would probably be released reasonably soon, but no set dates yet.
P.S. "active development" also means "don't rely on anything you see there too much yet unless you are ready for big changes without notice". Consider yourself warned :)
The recent release of PHP 5.3 included most of what was originally desirable about PHP6. At last year's Zendcon there was a presentation titled "State of PHP 6", you can see the slides of this presentation here: http://zmievski.org/files/talks/zendcon-2009/php-code-ideas-people.pdf

Is there a fork of PHP4?

Has anybody forked PHP4 to continue support for this version?
EDIT: This isn't a question about migrating to PHP5.
As far as I know - no. PHP5 is pretty good with backwards compatibility and you should not run PHP4 on any publicly facing webserver if security is even a little bit important to you.
I would estimate that PHP5 is 99% backwards compatible. Here is a blog post with typical (small) issues you might run into, usually the way that functions behave in corner cases. Two other resources you might want to look at are Migrating from PHP 4 to PHP 5 in the PHP manual and the PHP5 Migration Appendix, particularly the backwards incompatible changes.
To sum it up: you will need to test in a detailed manner after migration. Most of the things will work, but some might fail in corner cases. Some things can be fixed by tweaking the php.ini, some need a few changes. In general, applications written for PHP4 are less secure than those written for PHP5, because some security features didn't exist or were not widely used. So something like mod_security or PHPIDS (or both) should also be considered.
There have been no known forks of PHP4 to continue its support.
PHP4's code is pretty large, and with all its extensions it would be a pretty large project to support as a legacy application.

Framework updates how long do you wait?

In a development team how long do you think you should wait to implement the latest stable version of Framework?
I am asking about different Frameworks we are using Zend Framework, HTMLPurifier, jQuery and jQuery UI.
After a release how long do you wait to update your framework(s)?
If it's revision release (x.y.z -> x.y.z+1), you should deploy it ASAP, because it usually related to bug fix. For example list of fixes from ZF 1.7.7 → 1.7.8.
Standard versioning scheme is «major».«minor».«revision». Change in revision number usually means a bug fix. Change in minor version number, means minor change, usually backwards compatible. Change in major version is significant change, that might not be backwards compatible. See also: Software versioning (wiki).
That depends somewhat on if any of the changes in the framework will require code to be reworked or not. If no, there's less reason to put off an upgrade, and it should be done more or less immediately. If yes, the upgrade may not ever happen without a more compelling argument.
I always use the latest and greatest of everything. Whenever I run into trouble, which I very rarely do, it's relatively easy to find what has changed.
I usually start updating framework even before it becomes final. But then when framework becomes final I immediately replace pre-RTM version with the final one, make final changes in my application and publish it right away (put it into production).
If you start working on new framework integration only AFTER it's RTM release you risk to complete it and some time later hear that a new RIM was released, which is not good.

Categories