Here's one thing to consider.  Right now casting/type-autoconversion
is inconsistent at best.  Let me show you what I mean:

If I add 1 to a variable, the variable is converted based on the
standard http://us2.php.net/manual/en/language.types.type-juggling.php
type juggling rules, but the variable is attempted to be converted to
a numeric type if it is not already one (based on the string
conversion to numbers rules:
http://us2.php.net/manual/en/language.types.string.php#language.types.string.conversion
)...  I will refer to this as "Numeric Type Juggling" as we go on.
Note that objects cannot be used in this manner today, as they do not
implement the get() object handler, so they are converted to int(1) in
this context (which is defined as undefined by documentation).  Also
note, that the string is cast to a number destructively.  So if you do
1 + "foo", you'll get 1 back without error or warning.

If I use a variable in a string context, the type juggling rules still
apply, but this time converting to a string if it is not already one.
This I think is the most straight forward (and sanest) of all the type
rules.  I will refer to this as "String Type Juggling" as we go
forward.  Note that object can be used in this context now, based on
the __toString method.

If I use a variable in a boolean context, the type juggling rules
still apply.  So I can do if (array()), and the array will be
internally cast to a boolean to be evaluated.  Let's call this
"Boolean Type Juggling"...

If I cast a variable to an array, it follows a standard conversion
policy which is documented here:
http://us2.php.net/manual/en/language.types.array.php#language.types.array.casting
I'll call this "Array Type Juggling"...

If I pass a variable to an internal function that expects a string
type, the "String Type Juggling" rules apply.

If I pass a variable to an internal function that expects a class, it
will convert the variable to a string, and then lookup the class to
see if it's valid.  This is the same as String Type Juggling...

If I cast a variable to an object, it follows the documented casting
rules.  Let's call this "Object Type Juggling".

If I pass a variable to an external function that expects a class,
let's call this "Object Hinted Type Juggling"...

If I pass a variable to an internal function that expects a callback,
it will try to see if it's a valid callback by running logic if it's a
String, Array or Object.  Other types are ignored and error out.
Let's call this "Callback
That's where the sanity ends...

If I pass a variable to an internal function that expects an integer
or float, some weird things happen. If the argument is a float, it's
cast to an integer.  If it's an integer, null, or boolean, it's
converted directly to an integer.  But if it's an array, object or
resource, it causes an error.  Up to now, it seems sane and right
inline with "Numeric Type Juggling".  Except that strings behave
differently.  If the string is numeric (passes the is_numeric() test),
then the string will be cast to an integer and proceed as expected.
But if it is not, a warning is thrown and the internal function errors
out.  This is quite different than "Numeric Type Juggling", so I'll
call it "Numeric Internal Parameter Type Juggling".

If I pass a variable to an internal function that expects a boolean,
it sort-of works.  I can pass integers, strings, floats, and booleans,
and have normal type conversion rules apply.  But if I pass in an
array, object or resource, then it will error out.  So the type
juggling rules work for primitives, but not for complex types, which
is different from "Boolean Type Juggling", so we'll call it "Boolean
Internal Parameter Type Juggling".

If I pass a variable to an internal function that expects an array, it
will error out if not.  It will not even attempt a cast, which is
quite different from "Array Type Juggling".  So let's call this "Array
Internal Parameter Type Juggling" (even though it doesn't juggle
anything)...

If I pass a variable to an internal function that expects a hash table
it can conditionally accept an object (as long as the hash table param
is defined as a capital H).  This is even more different than arrays,
so "Hash Table Internal Parameter Type Jugging"...

If I pass a variable to an internal function that expects an object,
it will error if it's not an object with no casting attempt.  Let's
call this "Object Internal Parameter Type Juggling".


So in reality, there are tons of different rules and cases on how this
happens.

But the odd thing is that while we can wrap internal functions, we
cannot use the same casting rules as they can.  So writing a wrapper
for substr is non-trivial.  You **HAVE** to:

function mysubstr($string, $from, $to = 0) {
    if (!is_numeric($from)) {
        throw new Exception('From Must Be Numeric');
    }
    if (!is_numeric($to)) {
        throw new Exception('To Must Be Numeric');
    }
    return substr($string, $from, $to);
}

Otherwise your code will possibly throw errors.

So to bring consistency in, what I would like to do is have the
ability to add the same type hints (with the same casting rules) that
zend_parse_parameters has into userland code.  So, have the ability to
do:

function (string $string, int $from, int $to = 0) {
}

And have the exact same functionality occur as happens with internal
functions.  That will do two things: make internal code and user-land
code behave consistently when it comes to type juggling, and make it
easier to extend internal functionality transparently without tons of
boilerplate code...

Thoughts?

Anthony


On Thu, Mar 1, 2012 at 6:10 AM, Kiall Mac Innes <ki...@managedit.ie> wrote:
> On Thu, Mar 1, 2012 at 9:00 AM, Lester Caine <les...@lsces.co.uk> wrote:
>
>> Both provide something that a large number of people did not or do not
>> want anything to do with.
>>
>
> I disagree - The majority of PHP developers I've discussed this with are
> in favor of adding *something *like this. Do a majority want this? I have
> no idea and, I honestly don't believe you do either.
>
>
>> Namespace was forced on us in much the same way you are currently trying
>> to force this on us.
>>
>
> Forced? Nobody is forcing anything. Discussions are happening, and possibly
> a vote in the future. This is the farthest thing from being forced IMO.
>
>
>> Many people who were pursuaded that namespace was a good idea are now
>> realising that it wasn't and was the thin end of wedge which this
>> discussion is once again trying to force open.
>>
>
> Many of the popular frameworks have made the changes, or are planning to
> make the changes, needed to take advantage of namespaces. This, to me,
> suggests a general acceptable of namespaces.
>
> Also - I'm yet to hear a single complaint about namespaces
> - although again, I've not talked to every PHP developer!
>
> (Well.. No complaints other than the namespace separator being a '\' that
> is)
>
>
>> I have no objections to 'object orientated' as that is how I have always
>> used PHP, but the BULK of the data I am handling is simply strings which
>> 'magically' get converted to the format I need. I don't see any use for
>> 'type hinting' in any form since I NEED to check if a string I get in has
>> the right data in before I store it in a database field. I don't need to
>> throw some random error which needs handling ... I just handle the errors
>> in line as I process the data. My framework helps to ensure what I get in
>> is right in the first place anyway, so even the in-line checks are probably
>> redundant nowadays!
>>
>
> I can certainly agree with you here - have I ever absolutely NEEDED this?
> Nope. Would it get it the way of writing code in certain situations? Yup.
>
> But - Does that mean it's not generally useful? Nope!
>
> Kiall

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

Reply via email to