Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strategy for developing namespaced and non-namespaced versions of same PHP code

I'm maintaining library written for PHP 5.2 and I'd like to create PHP 5.3-namespaced version of it. However, I'd also keep non-namespaced version up to date until PHP 5.3 becomes so old, that even Debian stable ships it ;)

I've got rather clean code, about 80 classes following Project_Directory_Filename naming scheme (I'd change them to \Project\Directory\Filename of course) and only few functions and constants (also prefixed with project name).

Question is: what's the best way to develop namespaced and non-namespaced versions in parallel?

  • Should I just create fork in repository and keep merging changes between branches? Are there cases where backslash-sprinkled code becomes hard to merge?

  • Should I write script that converts 5.2 version to 5.3 or vice-versa? Should I use PHP tokenizer? sed? C preprocessor?

  • Is there a better way to use namespaces where available and keep backwards compatibility with older PHP?


Update: Decided against use of namespaces after all.

like image 832
Kornel Avatar asked Dec 02 '09 22:12

Kornel


People also ask

What is the main purpose of Namespacing in PHP?

Namespaces are qualifiers that solve two different problems: They allow for better organization by grouping classes that work together to perform a task. They allow the same name to be used for more than one class.

Can a program have multiple namespaces?

You can have the same name defined in two different namespaces, but if that is true, then you can only use one of those namespaces at a time. However, this does not mean you cannot use the two namespace in the same program. You can use them each at different times in the same program.

Is php namespace case sensitive?

Note: Namespace names are case-insensitive. Note: The Namespace name PHP , and compound names starting with this name (like PHP\Classes ) are reserved for internal language use and should not be used in the userspace code.


2 Answers

I don't think preprocessing the 5.3 code this is a great idea. If your code is functionally identical in both PHP 5.2 and 5.3 with the exception of using namespaces, instead of underscore-separated prefixes, why use namespaces at all? In that case it sounds to me like you want to use namespaces, for the sake of using namespaces..

I do think you'll find that as you migrate to namespaces, you will start to 'think a bit differently' about organizing your code.

For this reason, I strongly agree with your first solution. Create a fork and do backports of features and bugfixes.

Good luck!

like image 78
Evert Avatar answered Oct 11 '22 09:10

Evert


This is a followup to my previous answer:

The namespace simulation code got quite stable. I already can get symfony2 to work (some problems still, but basically). Though there is still some stuff missing like variable namespace resolution for all cases apart from new $class.

Now I wrote a script which will iterate recursively through a directory and process all files: http://github.com/nikic/prephp/blob/master/prephp/namespacePortR.php


Usage Instructions

Requirements for your code to work

Your classnames mustn't contain the _ character. If they do, classnames could get ambiguous while converting.

Your code mustn't redeclare any global functions or constants within a namespace. Thus it is ensured that all your code may be resolved at compile-time.

Basically these are the only restrictions to your code. Though I should note that in a default configuration the namespacePortR will not resolve things like $className = 'Some\\NS\\Class'; new $className, because it would require inserting additional code. It's better that this is patched up later (either manually or using an automated patching system.)

Configuration

As we have made the assumption that no global function or constant is redeclared in a namespace you must set the assumeGlobal class constant in the namespace listener. In the same file set the SEPARATOR constant to _.

In the namespacePortR change the configuration block to satisfy your needs.


PS: The script may be provided a ?skip=int option. This tells it to skip the first int files. You should not need it, if you have set the override mode to intelligent.

like image 44
NikiC Avatar answered Oct 11 '22 09:10

NikiC