Skip to content

Zend’s new namespace converter

Dear Reader,

Short version

If you have a library of code you want to convert to PHP 5.3 namespaces and it follows the Zend class naming standard, this tool will do the grunt work for you. Clone the repo using git or just grab the archive and start playing with it.

The fun version

RALPH! That’s how these conversations usually start. I can feel Ralph cringe over IM every time I do that too. (And I can see Matthew smiling reading this because it used to be MATTHEW!) Ralph Schindler is one of 2 full-time Zend employees whose job it is to work on the Zend Framework. (Yeah, awesome job if you can get it!) Ralph works on a lost of stuff but my favorite is Zend_Tool. Every time Ralph releases a new version of Zend_Tool, he and I end up having an extended debugging session making sure that my zf twitter client still works.

The other day however Ralph released something new. He announced that he had written a tool to take a library using the Zend (and PEAR?) standard for class naming – My_Class_Name is actually My\Class\Name.php – and convert them to PHP 5.3 namespaces.

It’s actually a pretty cool little tool, especially if you have a large library you want to convert.

I ran it on a part of the Zend Framwork, Zend_Acl, and it worked correctly, well after I sent up the Ralph signal and he fixed the issue with it running on Windows. (This is exactly what I love about working in the PHP community. If something doesn’t work, or you don’t understand something there are hundreds of people out there that will help you. If all else fails, you can grab he code, dig in and figure out what is going wrong. If Microsoft ever figures this secret out, open source could be in real trouble!) :)

Testing the tool

The command I used to test was this:

D:\tmp\PHPTools\bin>php php-namespacer.php -l=d:\tmp\Zend -o=d:\tmp\newlib -m=d:\tmp\newlib

Here are the steps I took to setup and test.

  1. To keep from accidentally screwing up my copy of ZF, I copied just the Zend\ACL and Zend\Acl.php into it’s own directory, d:\tmp\zend
  2. I stripped out all the .svn directories from my test copy before running. This is no longer necessary as Ralph has set it up to ignore them now.
  3. I ran the command shown above. It created the d:\tmp\newlib directory for me since it didn’t actually exist.

The only option I didn’t use was the -p option. If you have a large library and only want to convert a section or sections of it, you can specify them with the -p option. In my test case above, if I had used the entire Zend Framework, I could have used -p=Acl to limit it to just the Acl. As an aside, even though you specify a single area to work, it does seem to scan the entire Zend Framework. I'm not sure if this is an oversight or on purpose.

The output

The first things I noticed was that it moved Acl.php into the Acl directory for me. Opening the new Acl.php, I saw that it had not only added the namespace for me but had also added the phpdocblock also.

/**
 * @namespace
 */
namespace Acl;

So far so good. The only other file in the Acl directory now was the Exception as the other classes that had matching directories has also been moved into their respective directories. The Exception had the same namespace and docblock.

Digging a little deeper, I opened up Acl\Role\Role.php.

/**
 * @namespace
 */
namespace Acl\Role;

Ok, this was interesting. each sub-directory becomes a sub-namespace. I'll be honest and admit that I've not done a lot of thinking on this so I can't say this is a good or bad thing. I can say that I expected all the files to remain in the same namespace. As I said, I don't know if it's good or bad, I do know that this is by design though.

Nothing is completed without an ugly XML file

The final thing the tool will do is write out an XML mapping file for you. This monster is always named PHPNamespacer-MappedClasses.xml and you have the option (-m) of deciding where the file is put. If you don't specify a location the mapper file is not output. This is a sample of what is in the file.

<MappedClasses libraryPath="D:\tmp">
   <MappedClass>
      <originalRelativeFilePath>Zend\Acl\Assert\Interface.php</originalRelativeFilePath>
      <originalClassName>Zend_Acl_Assert_Interface</originalClassName>
      <newRelativeFilePath>Zend/Acl/Assert/AssertInterface.php</newRelativeFilePath>
      <newNamespace>Zend\Acl\Assert</newNamespace>
      <newClassName>AssertInterface</newClassName>
      <newFullyQualifiedName>Zend\Acl\Assert\AssertInterface</newFullyQualifiedName>
   </MappedClass>

I know as Ralph refines the tool he will elaborate on the XML and what the mapping is designed to be used for. For now, it's just enough to know that if you like the way it generates sub-namespaces, you can safely leave off the -m option and not generate the XML.

All the help you get

Beyon Ralph's original post (linked above) and this blog, the only other help you get is to call the script with the -h flag. Doing so will output the following:

This tool is intended to be used to namespace previously prefixed library
code developed with a PEAR/ZF coding standard in place.  It will attempt
to find all class names and convert them to namespaces.  Furthermore, it
will attempt to find any references to those classes in method signatures,
and body code, and docblocks and convert those to known translations.

Usage:
    (Option should be passed in a form that php's getopt() can parse.)
    php path/to/Namespace/Namespacer.php [options]

Options:
    -h, --help
        This help screen.
    -l, --lib, --library-directory
        The library directory to iterate, this would be the same directory
        you would anticipate registered as an include_path.
    -d, --dir, --directory-filter
        The part of the library directory you want to operate on.
    -o, --out, --output-path
        If supplied, this directory will be where converted files are
        written to.
    -p, --prefix, --prefixes
        The base prefix to mind when converting.  Can be comma separated
        list.
    -m, --map, --map-path
        The directory where an xml file will be produced that will list
        the file and class translations that were used.

Notes:
    * library and directory are separate entities b/c library will be
      first scanned to identify all names in general usage. Directory
      will be used to filter out the relative path that is to be
      considered the working set of file that the converter should
      convert.

fClose()

This is a good first effort and I want to thank both Zend and Ralph for this contribution. As it's stored in GitHub and I am ASSUMING it is released under an OS licenses (it's not actually in the code so I can't be sure) you can go grab it, fork it and start helping to make it better. Ralph hasn't stated whether he will accept patches or not but I can't help but think that he would appreciate any help he can get. :)

Until next time,
I <3 |<
=C=

7 thoughts on “Zend’s new namespace converter

  1. Just for clarification, there are THREE of us employed by Zend to work on ZF — myself, Ralph, and Alexander Veremyev. And yes, it *is* a good gig. :)

    The XML file we’re hoping to use to assist in migration automation. We’re doing several passes over the framework, starting with core components and gradually moving outward to the MVC. The hope is that we can manipulate this file to reflect manual changes we made, and then when those classes are encountered later down the line, the appropriate substitutions will be made. Additionally, end-users may be able to use this information to help migrate code they have that consumes ZF components.

  2. We tend to miss the third leg of the ZF tripod. I don’t even think I’ve ever communicated with him directly. You guys keeping him locked up in a basement or something? ;)

    Has anyone worked on how to use this to migrate unit tests? I look upon the tool as something like a refactoring utility. I want me tests to pass after it’s completed, or have some way to pinpoint test failures for manual intervention. Will be testing it on several large bodies of code later this evening.

    Not suggesting Ralph get that done this evening. But, if you have Alexander in the basement idle…

  3. Yes – I’m hoping to have the tool also assist with refactoring unit tests, as right now we’re doing it manually – and it’s a bit tedious. Technically, the data we need is captured in the classmap file; just need some code that can take that and apply it to existing code elsewhere. Once we have that, we also have the start of a code migration tool for users.

    As for Alex, he’s based in St Petersberg, and hopefully he’ll be more visible as we step up the migration process. :-)

  4. Interesting. Does this mean I could do the following:

    1. Use the tool to convert the latest ZF release and a client project to using namespaces
    2. When ZF 2.0 is final I can run the tool again with the then updated XML on the client code and it will work with ZF 2.0

    ?

    If so, absolutely awesome, exactly what I was hoping for.

  5. Pingback: Zend Framework News » Blog Archive » Namensraumkonvertierer für das Zend Framework
  6. @John That’s pretty much what I was thinking. Not sure it would be quite as clear cut, but the XML output can form the basis of additional migration tools customised per project as needed.

Comments are closed.