Integrating with Zend's OpenID

The Zend Framework has a pretty good OpenID library. I was looking for a library written for PHP5 (strict), and this seemed like a good choice..

The Zend library requires a storage backend to record and cache some of the information, and it was very easy to implement a custom one for our database layer. There's a bunch of good examples are available on the documentation page (although they were slightly outdated with the current api and did contain sql injection problems..).

The only drawback I saw was that there was a hard dependency on the Zend frameworks' Session system. I didn't want to write an adapter for our own platform, so ended up overriding the 'verify' and '_checkId' methods to simply use PHP's built-in $_SESSION array.

The odd thing was that the changes I made to the OpenId_Consumer class only set stuff in the session, but I didn't find anything that actually retrieved those values.

On a completely off-topic note, I just got my copy of High Performance MySQL, and I'm pretty excited to read it :)

Upcoming features in PHP 5.3

PHP 5.3 alpha1 just got released yesterday, and I thought this might be a good time to list some of the new things that are coming, and how it could benefit you. Even though its a minor release, a lot of new features made it in and from a marketing standpoint it should have really been 6.0, if you'd ask me.

Namespaces

A subject touched and trialed many times in PHP, namespaces. This feature has been responsible for the longest discussions on PHP-DEV, but finally a consensus has arrived on how this is going to work.

The biggest benefit namespaces will provide is shortening of long classnames. To make sure that your class libraries can plug into foreign code, it has always been recommended to prefix your classes, for example "Zend_DB_Connection". This can however lead to very long names. Namespaces fixes this by grouping classes together. The full-on classname becomes Zend::DB:Connection, and by placing 'use Zend::DB' on top of your code, the 'Connection' class can be referenced with just that name.

Example:

  1. <?php
  2.  
  3. // The class file
  4. namespace Zend::DB;
  5.  
  6. class Connection {
  7.  
  8.    function foo() {
  9.  
  10.       echo 'bar';
  11.  
  12.    }
  13.  
  14. }  
  15. ?>

  1. <?php
  2.  
  3. require 'Zend/DB/Connection.php';
  4.  
  5. use Zend::DB::Connection;
  6.  
  7. $connection = new Connection();
  8. $connection->foo();
  9.  
  10. ?>

Using namespaces, its also possible to alias classnames.

  1. <?php
  2.  
  3. use Zend::DB::Connection as MyConnection;
  4.  
  5. $connection = new MyConnection();
  6.  
  7. ?>

Furthermore, constants and functions can also be namespaced, but they cannot be directly imported. This means that if you create a function 'myFunction' in the 'Connection' file mentioned earlier, you cannot import Zend::DB:myFunction, but you can import Zend::DB and reference the function as DB:myFunction().

It is recommended to always place your 'use' statements on the beginning of any file, and they will be in effect for the complete file. Note that (AFAIK) this is the first language feature in PHP where the filename holds relevance to the execution, and this can cause some issues for people who like to concatenate their sourcefiles for faster loading. This holds true for both the 'namespace' and the 'use' statements.

Documentation is available, but it is warned it could be out of date.

Late static bindings

Not a really descriptive name from an end-user point of view, but this feature adds some more flexibility in class inheritance.

In short: when you reference a different method or property in a class belonging to a parent class using the self:: keyword the called class would no longer have a static reference to the calling class, as self:: references the current class and not the class from which it was called from. This basically adds method overriding to static methods calls. If this is still kind of cryptic, the best example can be found in the manual.

__callStatic

Using the magic function __call, calls to undefined methods could be intercepted and handled in a different way. PHP 5.3 adds __callStatic, which adds the same functionality to static method calls.

Example:

  1. <?php
  2.  
  3. class MyClass {
  4.  
  5.   static function __callStatic($name, $arguments) {
  6.  
  7.     echo "Hi! You just called the method '$name', but it doesn't exist. Perhaps you mistyped";
  8.  
  9.   }
  10.  
  11. }
  12.  
  13. MyClass::unknownMethod('hii!');
  14.  
  15. ?>

Of course, there's better usages than lame error messages. (documentation)

Closures

My personal favourite. Closures (or: Lambda functions) allow you to create in-line functions. Many languages already have this feature, and if you ever did any javascript programming, you probably already used it without knowing about it.

Example:

  1. <?php
  2.  
  3. $myFunction = function() {
  4.  
  5.   echo "Hello world!";
  6.  
  7. }
  8.  
  9. $myFunction();
  10.  
  11. ?>

Before, this could only be achieved with create_function, which is pretty much an eval() function with lipstick (and a really bad idea).

The variable type of a closure is an object of the class 'Closure', so it can also be used for type-hinting and validation.

  1. <?php
  2.  
  3.   function setSomeEvent(Closure $myClosure) {
  4.  
  5.   }
  6.  
  7. ?>

PHP closures also allow referencing variables from the namespace it was created, with the 'use' keyword.

  1. <?php
  2.  
  3.   $prefix = 'hello';
  4.  
  5.   $myClosure = function($name) use ($prefix) {
  6.  
  7.      echo $prefix, ' ', $name;
  8.  
  9.   }
  10.  
  11.   $myClosure('your mom'); // Guess the output doesn't actually makes sense, but you get the idea
  12.  
  13. ?>

Documentation is not part of the manual yet, but can be found on the php wiki

__invoke

PHP 5.3 also adds another magic method, allowing you to treat your own objects as if they were closures.

  1. <?php
  2.  
  3. class MyCustomClosure {
  4.  
  5.    function __invoke() {
  6.  
  7.       echo "I'm not really a closure, but you can treat me as such\n";
  8.  
  9.    }
  10.  
  11. }
  12.  
  13. $closure = new MyCustomClosure();
  14. $closure();
  15.  
  16. ?>

My #1 feature request is to make sure both classes using __invoke and actual closures implement an interface, this would allow us to easily identify an object as invokable. (e.g.: an Invokable or Callable inteface). This has been requested on the PHP internals mailing list, as we speak.

Phar

Phar is PHP's answer to java's JAR files. A PHAR file is a compressed archive and can contain a complete PHP application. This is really cool, as it would allow utilities like PHPMyAdmin to be distributed and used as a single file.

I'm quite excited to use this and see widespread adoption across ISP's. The best part is that you don't need the extension to make use of it, but it will run better and faster if it is.

When it is installed, it will allow referencing files from the phar using for example:

  1. <?php
  2.  
  3.   file_get_contents('phar:/full/path/to/pharfile.phar/mydata');
  4.   require 'phar:/full/path/to/pharfile.phar/myscript.php';
  5.  
  6. ?>

More extensions

  • intl, an internationalization library (not enabled by default).
  • fileinfo, has been around for a while, but because its enabled by default now we can finally rely on it being there.
  • sqlite3, enabled by default! yay!

  • MySQLND, which is a drop-in replacement for the common MySQL driver for PHP. The 'ND' stands for 'Native Driver', which means its tightly built around the PHP engine and can give you some performance boosts.

Other language improvements

The ternary (?:) operator's 'true' clause is now optional, this means that:

  1. <?php
  2.  
  3. $myVar = $value1?$value1:$value2;
  4.  
  5. ?>

Can be shortened to:

  1. <?php
  2.  
  3. $myVar = $value1?:$value2;
  4.  
  5. ?>

Also, 'NOWDOC' is introduced. NOWDOC works like HEREDOC, except that variables aren't evaluated and is treated as a 'single quoted string' in PHP.

  1. <?php
  2.  
  3. // This will echo a literal '$myVar'
  4. // Note that syntax highlighting will break, as this blog runs on PHP 5.2
  5.  
  6. echo <<<'DATA'
  7. $myVar
  8. DATA;
  9.  
  10. ?>

Other significant additions

  • date_add(), date_sub(), date_diff() and their OOP equivalents.
  • A garbage collector! No documentation on this yet.
  • Lots of new SPL classes, such as SplStack, and SqlQueue.
  • The __DIR__ constant, which can be used as a replacement to the often used: dirname(__FILE__). This allows for example easy file-inclusion and could be optimized by for example APC, which was not easily possible with dirname(__FILE__).
  • New process control functions, for example allowing you to catch process signals from the operation systems while avoiding the (now depreciated) declare(ticks=1) statement.

Conclusion

Its great to see PHP is an alive language, and especially language improvements such as closures and namespaces bring PHP on par with other popular scripting languages. This stuff definitely makes me a happy person. We won't be using 5.3 in production, as we'll want to wait till 5.3.1 for things to stabilize a little bit, but I hope that day arrives soon.

Subversion 1.5 for debian Etch

The Subversion team released version 1.5 recently, with some really tight features such as changelist and merge tracking.

In our shop we standardized on Debian, and it's very likely going to take till 5.0 (lenny) until we get access. Normally I would just do a compile from source, but since this will have to be done on multiple servers, I decided to backport subversion from Lenny to create a nice little .deb package.

Here are my steps, (tested on just my machine, so please try at your own risk).

  1. We'll start off by creating a directory for this process.
    1. mkdir subversion

  2. Next, download the source packages from the debian packages site.. They're on the right.
  3. Now, unzip them.

    1. gunzip subversion_1.5.0dfsg1-4.diff.gz
    2. tar xfvz subversion_1.5.0dfsg1.orig.tar.gz
  4. The first file was patch with debian specific changes, we'll need to apply this patch to the source tree.

    1. patch -p0 < subversion_1.5.0dfsg1-4.diff
  5. Enter the source directory

    1. cd subversion-1.5.0dfsg1/
  6. We'll need to change some file permissions to make this work.

    1. chmod 755 debian/rules
  7. Now we switch to the root user, because we need to install some dependencies.

    1. # Assuming you're root
    2. apt-get build-dep subversion
    3. apt-get install python-all-dev libneon26-dev quilt libsasl2-dev fakeroot debhelper
  8. Switch back from root to your normal user.
  9. I've had some issues making creating the java hooks. To get around this, we'll need to disable them. Do this by opening the 'debian/rules' file and change the line that says 'ENABLE_JAVAHL' to no. For me this was on line 21.

    1. ENABLE_JAVAHL := no
  10. Now we can get started building the package.

    1. dpkg-buildpackage -rfakeroot -uc -b -d

  11. Compiling!
  12. If everything went well, you should have ended up with about 10 .deb packages in the directory right above the source directory. You can simply install all of them with:

    1. dpkg -i *.deb
 1

About

My name is Evert, and I've been writing semi-regularly on this blog since 2006.

I'm currently available for contract work.

more info.

Subscribe

Dropbox

Dropbox is a simple cross-platform online backup and sync application. The first 2GB of space is free, and both you and me get an extra 250MB extra space if you sign up through this link.