Re-reading the previous discussion, it seems like the functionality that
people wanted was to have an optional typed argument. 

In converting the .NET Framework library over to PHP, there are many
instances where having optional typed params would have been handy. The
Framework makes heavy use of interfaces, usually implemented as overloaded
methods. When implementing it in PHP I had to make use of func_num_args()
and func_get_args() etc.. to simulate the overloading. As I convert the
classes over to an extension, I am able to define the method arguments as
optional and be of a certain type if they are passed. It would be nice to
have similar functionality in userland.

The quick solution is to have =null override the zend_verify_arg_type
is_null check, but then this lets users pass null as a value and you lose
your type hint.

The solution I proposed makes use of the current method of making parameters
optional, BUT it would still be a runtime error to pass NULL to the
function.
 
1. It doesn't add new keywords to the language
2. There is no "magic", it would be a runtime error to pass null.
3. It does change the "expected" functionality of $obj=default, but it is
limited to the scope of type hints.
4. Doesn't affect BC (since they can't use a default now)
5. It allows optional typed parameters
6. You still have to check for null
7. Downside - you cant pass optional params after the first one.


I patched my code base to see if it would work and it does but it's not an
elegant solution. Basically, inside the vm_handler for ZEND_RECV_INIT, if no
parameter was passed and null has been specified as the default, then it
calls an extended zend_verify_arg_type_ex and passes an allow_null param to
override the IS_NULL check. So now, the code below works as spec'd out
above. Typed optional params that cannot be null.

<?

class Object
{
    public function Method(Object $o=null, Object $p=null)
    {
        if (!is_null($o)) echo 'Got Object'.PHP_EOL;
            else echo 'Empty Param'.PHP_EOL;
    }
}

$a = new Object();
$a->Method($a);
$a->Method($a, $a);
$a->Method();
$a->Method(null); <-- Error, null not allowed
$a->Method(null, $a); <-- Can't get to second argument since null can not be
passed

?>

#>php -n -f test.php

Got Object
Got Object
Empty Param
Fatal error: Argument 1 must not be null in
E:\php5\php5cvs\php5\Debug_TS\test.php on line 5


Bob Silva


-----Original Message-----
From: Cristiano Duarte [mailto:[EMAIL PROTECTED] 
Sent: Saturday, October 16, 2004 4:02 PM
To: [EMAIL PROTECTED]
Subject: RE: [PHP-DEV] Type hints with null default values

Robert Silva wrote:

> PHP doesn't have a concept of a "null" reference though. So to say that
> every other language allows it is not a valid argument. The other
> languages allow it because the language supports it. And that seems to be
> what the arguments against it centered around.
> 
> I think a compromise would be to allow the argument to be optional but
> still enforce the type hint. What this doesn't address fully is multiple
> optional type hinted arguments.
> 
> function A(ZObj $arg2=null, ZObj $arg3=null) {}
> 
> How would you pass $arg3 if you didn't have anything to pass for $arg2.
> Maybe that's just an inherent restriction of the language...to pass $arg3,
> you have to pass a ZObj as $arg2.
Since PHP doesn't support explicit method overloading, we should support
some form of telling the function that $arg2 wasn't passed. This problem can
be solved with named parameters instead os positional ones, but someone
suggested it a long ago and, at that moment, it would not be feasible.

> 
> Someone else suggested adding null references to the language:
> 
> ZObj $obj = null;
> 
> But I don't think that is the right solution either not to mention the
> nightmare of actually implementing it.
It was supported before(until May), isn't it ? 


IMHO, what we have now is "not null typehints" so what's the matter if we
accept "not null typehints" when we have this construction:

function A(ZObj $arg2, ZObj $arg3) {}

and "null typehints" with this:

function A(ZObj $arg2=null, ZObj $arg3=null) {}

as we supported before(except that with the first construction nulls are not
allowed). Maybe I'm "blind" but I can't see the problem that Marcus pointed
anymore. If I can remember, he wants a way to enforce typehints not
allowing nulls: construction-1 does it.
I really need optional typehints and construction-2 supports it.
IMHO, everybody would be happy. 
Any comments ?

Regards,

Cristiano Duarte

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to