Type hinting for scalar types As you're probably aware, PHP doesn't support type hinting for scalar types.
I feel this might be good practice to build into my framework, although I'm aware some of you might disagree seeing as PHP is a loosely-typed language.

But I'd like some feedback on the implementation of this.
Do you think it's efficient, pointless? Or could it be achieved in a better way?

This works by causing an error.
By specifying a typehint (integer), PHP is expecting a class/object called "integer", so it's giving an error as we are passing a "real integer"/scalar value".

Giving this error,


  Argument 1 passed to test() must be an instance of integer, integer given.


So with a custom error handler function, I can use preg_match() to find the expected &amp; given types, and just compare them via the name.

The code

&lt;?php

ini_set('display_errors', 'on');
error_reporting(E_ALL);

function typehint($level, $message){

    if($level == E_RECOVERABLE_ERROR){ 

        if(preg_match('/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/', $message, $match)){ 
            if($match[4] == $match[5]){
                return true;
             }
        }                 
    } 

    return false; 
} 

set_error_handler('typehint');

function test(integer $value){
    var_dump($value);   
}

for($int = 0; $int &lt; 1000; $int++){
    test(23);
}

?&gt;


It seems to work ok, but I'm not sure if using preg_match() on every function argument is a good idea?

Here's the benchmarks, on 1000 function calls. (1 typeint per function)

Type-hinting        No Type-hinting
0.015               0.0017
0.0169              0.002
0.0172              0.002
0.0148              0.0019
0.0159              0.0029
0.0157              0.0019
0.0149              0.0018
0.0161              0.0029
0.0167              0.002
0.0173              0.0018
0.0149              0.0019
0.0156              0.0019
0.0153              0.0029
0.0182              0.0023
0.0151              0.0029
0.0163              0.0017
0.0179              0.0018
0.0159              0.0018
0.0154              0.0027
0.0149              0.0023

Average             Average
0.016               0.002155


So just after some thoughts on this really... good or bad?

EDIT:
Using strstr() seems to be a little quicker, although I have to specify what types to check for. Which is a small number anyway. Average time: 0.009595.

function typehint($level, $message){

    if($level == E_RECOVERABLE_ERROR){ 

        $integer = 'must be an instance of integer, integer given';
        $string = 'must be an instance of string, string given';

        if(strstr($message, $integer) !== false OR strstr($message, $string) !== false){
            return true;
        }
    } 

    return false; 
}
"So just after some thoughts on this really... good or bad?"

Bad, really bad, I'm afraid. You're trying to make the language do something it doesn't want to do, or even: can't do. You're gluing feathers to a fish's fins, and throwing it up into the air, so it can mimic a bird's behaviour.
Your test code shows a dramatic decrease of speed (after switching to strstr, still ~5 times slower than usual). And you're only testing your code with valid input. Besides, have you even checked if you can get this function to return what it needs to return, and to Where?

The simple fact of the matter is this: each function call with your improvised (hacked) type-hints will issue an error, even if the type is correct.
It will, however, issue a notice in these cases, too:

function test(integer $foo)
{
    return $foo;
}
test('123');


How will you recover from this error? Are you going to add:

if (settype($argument, $expected) == $argument)
{
    call_user_func_array($function, array($argument));
}


to your error handler? and how are you going to deal with functions that take arrays of ints, or what if the user passes null?
There's just too many things to consider here.

Your approach also poses problems when you scale things up a little: Have you thought about what would happen if you used this code in tandem with a framework, that uses namespaces, sets all sorts of handlers all over the place, and uses complicated autoloading trickery?
Even simple autoloading would mean that PHP sets out to look for this integer class. That means calling the autoloader, when that turns out to be unsuccessfull, PHP will of course use the include paths, and a lot of I/O disk access is the result. Disk I/O is a speed killer, as we all know.

Note that lookups of files that aren't found are not cached!, so each type-hint will result in disk access. Whomever is hosting this code, if it ever got used in even a medium traffic site, will not be happy.
Perhaps this has changed with PHP5.5, but most hosting services are yet to upgrade.

Each function call, in your simple example, is already approx. 5 times slower than a normal one. Add the overhead of a custom autoloader, several layers of error/exception handlers to that, and you'll see the avg time per function call drop even more (probably converging on the initial times you had). Simply because autoloaders often access the disk, too, with file_exists calls, using the include path to scan for files who's name resembles that of the class that needs to be loaded, only to fail, and have PHP do the same disk operations again.
Then, like the example I listed: getting ints from a db, or user input means that these numbers are all passed around as strings, but are perfectly castable/usable as integers.

Suppose you were able to get the called function, cast the arguments accordingly and call the function again, what would happen? Well, the function gets called again, so another error is triggered, and your handler, which is now the caller of the function will be called twice.
Of course, the second time, owing your intervention, the types will match this time, but that's 4 function calls (5 including call_user_func_array) + 2 errors being raised to complete a single call:

Original caller           /-&gt;fails, PHP====\\
 \\              //``!AUTOLOADER!``&lt;=\\    ||
  \\             ||                   \\   \/
   \=======&gt; function -------&gt; error   \==&gt;DISK I/O !!TWICE!! per call
    \|            /\              \\
    ??            ||               \==&gt; handler, type checking + casts
    ||            ||                    ||   /\
    ||            ||call_user_func_array||    |
    ??            |======================|    |
    ||                 \\    error2           |
    ||                  \----------------------
    ||                         ||
    ??                         \/
    ||      suppose it returns, still disk I/O and
    ||                                         ||
    ||           good luck getting back there  //
    \\=========================================/


An that's just assuming no intern gets the brilliant brain-wave to actually create a string or integer class or interface!

Even if you manage to get all of this working, a recoverable error isn't guaranteed to have anything to do with your special-case type-hints. Your handler was created with a specific type of error in mind, which -logic dictates- should be an E_USER_NOTICE.

Of course, you can't force the language to emit such an error when a non-custom error is encountered.

Ah well, you could try to work on this a bit more, if you want to, but I'd say you're better of spending that time to refactoring your functions like so:

/**
 * my test func - EXPECTS INTEGER
 * Any decent IDE uses these doc-blocks
 * @param int $integer
 * @return int
 **/
function test($int)
{
    $int = (int) $int;//cast to be sure
    //code
    return ++$int;
}


That'd be a better way to spend your time, and just ensure people you work with have a decent IDE, that parses the doc-blocks.