Etienne Kneuss

Insane

I'm currently working on a scala compiler plugin that performs interprocedural, compositional effect and pointer analysis on arbitrary scala programs!

Feel free to check out Insane on github!

Phantm

In short, Phantm is a type checker for PHP applications, but it does also much more!

PHP

I sporadically contributes to the core of PHP for quite a while now, see my patch repository.

SPL Datastructures updated

Mon, 12 May 2008

Here is some news about data structures available in SPL:

  • There finally is documentation for SplDoublyLinkedList, SplStack and SplQueue.
  • "New" classes: SplHeap (abstract), SplMaxHeap, SplMinHeap and SplPriorityQueue, documentation of those classes is in progress.

Here is an example of a simple but task scheduler using SplPriorityQueue:

$q = new SplPriorityQueue;

$q->insert('a', 1);
$q->insert('b', 4);
// ...
$q->insert('z', 2);

foreach($q as $task) {
    // .. process task ..
    echo $task."\n";

    // ... add new tasks ..
    if ($task == 'b') {
        $q->insert('c', 3);
    }
}

/* Output:
 * b
 * c
 * z
 * a
 */

This implementation is really efficient as the underlying data structure of SplPrioritiyQueue is a Heap, which allows insertions and extractions in O(log2(N)).

New datastructures in SPL

Wed, 16 January 2008

New datastructures made their way into SPL recently:

  • SplDoublyLinkedList

as long with two childs:

  • SplStack
  • SplQueue

Those structures implement Iterator, ArrayAccess and Countable which makes them easy to handle. There are also multiple ways to iterate through them.

More datastructures will get implemented in the future. The goal is to implement quite every basic datastructure along with algorithms related to them. SPL could then be used as an object oriented replacement for ADT.

Late Static Bindings Explained

Fri, 24 August 2007

Introduction

Late Static Binding (LSB, yes, not LSD) is an OO feature that is meant to be implemented in PHP 6, and maybe even backported to PHP 5. This article will describe what LSB is, what problems it's supposed to solve and how.

Update: LSB finally got commited in HEAD, this article now describes the way it currently works if you try out a snapshot. The behavior is supposed to remain the same in the future.

What is Late Static Binding

Currently, static references to the current class, like self or CLASS are resolved using the class in which the function belongs, as in where it was defined:

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        self::who();
    }
}
class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test(); // A

LSB tries to solve that problem by introducing a keyword that references the class that was initially called at runtime. Basically, a keyword that would allow you to reference B from test() in the previous example. It was decided not to introduce a new keyword but rather use static that was already reserved.

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who();
    }
}
class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test(); // B

Some people describe static:: as the $this-> resolution for static calls, this is not true as $this-> follows the rules of inheritance while static:: doesn't.

Examples

Most basic example:

class TestClass {

   protected static function who() {
        echo __CLASS__."\n";
   }

   public static function test() {
       return static::who();
   }
}

class ChildClass1 extends TestClass {

   protected static function who() {
        echo __CLASS__."\n";
   }
}

class ChildClass2 extends TestClass {}

TestClass::test();   // TestClass
ChildClass1::test(); // ChildClass1
ChildClass2::test(); // TestClass

It can also be used in a non-static context:

class TestChild extends TestParent {
    public function __construct() {
        static::who();
    }

    public function test() {
        $o = new TestParent();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}

class TestParent {
    public function __construct() {
        static::who();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}
$o = new TestChild; // TestChild
$o->test();         // TestParent

Fully resolved static calls with no fall backs will break the resolution of the late static binding.

class A {
    public static function foo() {
        static::who();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}

class B extends A {
    public static function test() {
        A::foo();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}

B::test(); // A

Edge Cases

Because of the way scopes are traversed, and that no breaks are enforced for internal hooks, it means that static:: would work the same way even with a fallback that occurs on them, i.e. __get(), __set(), ...

class A {

   protected static function who() {
        echo __CLASS__."\n";
   }

   public function __get($var) {
       return static::who();
   }
}

class B extends A {

   protected static function who() {
        echo __CLASS__."\n";
   }
}

$b = new B;
$b->foo; // B

The same principle applies to handlers, as long as they are defined and called within valid scopes.

Introduction

From what I have seen in many tutorials or in IRC discussions, I must say that the usage of the [L] (or Last) modifier has become some sort of a standard, a flag that everyone should put there "just in case", as it can't be harmful. This often demonstrates bad understanding on how apache's mod_rewrite internally works. I'll try to explain why [L] should be used wisely, and especially in which cases you shouldn't use it at all.

Truth about the Last modifier

Let's focus on rewriteRules in a per-directory context (a .htaccess file for example), which sadly represents the majority of mod_rewrite's uses. In this context, the [L] flag won't force the rewrite to stop, it will only triggers the internal sub-request at this point. But the sub-request may get through a set of rewriteRules defined in a per-directory context again, meaning that the rewrite of the current URL may not be finished.

Let's consider a simple example:

# /path/to/webroot/.htaccess
RewriteEngine on
rewriteRule a b [L]
rewriteRule b c

Most people would think that when requesting /a, the internally requested file would be /b because of the [L] flag. Well, it's not. The last requested file will actually be /c. To understand why, you need to understand how mod_rewrite handles a request in a per-directory context.

How mod_rewrite works

First, there is an important difference between a set of rewriteRules in a per-directory context and one placed in a more general context like in the httpd.conf file. The way mod_rewrite will work is determined by the context in which the rewriteRules are defined. Because mod_rewrite was ment to rewrite URLs to files, it won't be able to directly handle requests in a .htaccess file, where the requests will have already been translated to files. For that reason, mod_rewrite will try to translate them back to URLs and use them in an internal sub request, which will restart the API phases. Read [http://httpd.apache.org/docs/2.2/rewrite/rewrite_tech.html#InternalAPI API Phases] for more details on that subject.

It means that when an url is rewritten in a per-directory context, it will trigger a sub-request, wich may be rewritten again, and again.

Applying that to the example, we get:

1st sub-request - Trying to apply the pattern "a" to "a": match -> rewrite to "b".
1st sub-request - L flag used: trigger internal sub-request with the rewritten url.
2nd sub-request - Trying to apply the pattern "a" to "b": no match.
2nd sub-request - Trying to apply the pattern "b" to "b": match -> rewrite to "c".
2nd sub-request - Reaching the end, url was rewritten, trigger internal sub-request with the rewritten url..
3rd sub-request - Trying to apply the pattern "a" to "c": no match.
3rd sub-request - Trying to apply the pattern "b" to "c": no match.
3rd sub-request - Reaching the end, url was not rewritten: serve the file.

Pitfalls [[# pitfalls]]

A common pitfall is a rewriteRule that ends in an infinite loop. For example:

# /path/to/webroot/.htaccess
RewriteEngine on
rewriteRule ^(.*)$ page_$1.php

Let's say we request bar, it will get rewritten to page_bar.php which will get rewritten to page_page_bar.php.php and so on. Adding a [L] flag here won't help at all. There are multiple solutions here. One would be to write your rewriteRules in a more general context. Another solution would be to ensure that mod_rewrite won't get in an infinite loop. You could either use a rewriteCond or simply modify the pattern so it can't match the rewritten url.

Where [L] shouldn't be used

As a general rule, don't use [L] flag when you're defining only one rewriteRule, it's useless. Additionally, don't use [L] when another rewriteRule in the file is able to match the rewritten url. Doing so will only give more work to the rewrite engine. To demonstrate that, let's consider the first example without any [L] flag:

1st sub-request - Trying to apply the pattern "a" to "a": match -> rewrite to "b".
1st sub-request - Trying to apply the pattern "b" to "b": match -> rewrite to "c".
1st sub-request - Reaching the end, url was rewritten, trigger internal sub-request with the rewritten url.
2nd sub-request - Trying to apply the pattern "a" to "c": no match.
2nd sub-request - Trying to apply the pattern "b" to "c": no match.
2nd sub-request - Reaching the end, url was not rewritten: serve the file.

It would require only two sub-requests for the same result. In that case, the [L] flag is better left out.

Conclusions

I hope this little explanantion will help people in understanding how the [L] (Last) flag and more generally mod_rewrite works in a per-directory context. Additionnaly you should never define a set of rewriteRules in a per-directory context, as it will be slower and you may run into the kind of troubles explained above.

I commited a patch to docweb, some days back, to allow the generation of the complete package of phpt files. Those phpt files were generated from doc examples.

The main use of those phpt files was to have an easy way to check examples used in the documentation. Along with a php script analyzing the results and Hannes' great testing environment, I was able to generate a summary of the examples failing:

The results are quite interresting:

  • 251 tests were generated
  • 126 (50%) passed the checks
  • 23 (9%) tests failed because of a missing extension
  • 102 (41%) tests failed because of an error in the example (11% of them were caused by whitespace issues only)

There is thus potentially 80-90 examples in the documentation that contain errors!

Let the massive example bug squashing party begin !