I am a full-time PHP developer responsible for maintaining several large
enterprise applications, as well as a number of libraries and personal apps.
I have been following the scalar type proposals quite closely, as along with
return type declarations, scalar types have the potential to reduce errors,
simplify API documentation, and improve static code analysis.

I am in favor of Anthony's Scalar Type Declarations RFC, for two simple reasons:

1. It doesn't change the behavior of existing weak types.

PHP has long had an emphasis on backwards compatibility, and I'm worried that
those not in favor of strict types are treating backwards compatibility more
recklessly than they otherwise would in their fervor to avoid two ways of
handling scalar types. In my experience dealing with large enterprise apps,
however, there are hundreds of places where code relies on GET/POST parameters
being automatically trimmed when passed to a function expecting an integer.
The current coercive proposal would deprecate this and later make it an error.
To avoid these notices/errors when upgrading, developers may take the "easy"
route of casting any input passed to a function expecting an int or float.
This is the same "too strict may lead to too lax" problem pointed out by the
coercive RFC itself. There's a reason that integer handling was actually
*relaxed* back in PHP 5.1 (see 
http://php.net/manual/en/migration51.integer-parameters.php).
Why suddenly make the default more strict again?

I am not against tightening up some of the default weak conversions (e.g. to
not allow "99 bugs" for an int type), but in my opinion this should be done
very carefully, and separately from any scalar type declaration proposal.
Major changes to the casting rules have the potential to seriously harm PHP 7
adoption, especially in enterprises with large amounts of legacy code. The
Scalar Type Declarations v0.5 RFC has the advantage here because it "just
works" when type hints are added to existing code in the default weak mode.

2. Strict types are important in some cases.

When it comes to authentication and financial calculations (a couple of areas
I routinely deal with) it is extremely important that errors are caught and
fixed early in the development process. In financial or security-sensitive
code, I would *want* any value with the wrong type (even a string like "26")
to be flagged as an error when passed to a function expecting an integer.

The option for type-based (rather than value-based) validation is equally
important when it comes to return types. Unless I have missed something, the
"Coercive Types for Function Arguments" RFC currently doesn't deal with return
types at all (they aren't mentioned in the RFC). Would it handle scalar return
types the same way as it does function arguments? If I declare a function to
return an int, and I return a string instead (even if the string is numeric),
there are many cases where it would be an unintentional error. And if it
errors depending on the value, rather than the type, it often wouldn't be
possible to catch the problem statically.

Here's a simple example of the advantage offered by strict types and static
analysis in the Scalar Type Declarations v0.5 RFC:

<?php
declare(strict_types=1);

function getCustomerName(int $customerId): string
{
    // look up customer name from database and return
}

function getInvoiceByCustomer(int $customerId): Invoice
{
    // retrieve invoice data and return object
}

$id = filter_input(INPUT_GET, 'customer_id', FILTER_VALIDATE_INT);

if ($id === false) {
    echo 'Customer ID must be an integer';
} else {
    $customer = getCustomerName($id);
    $invoice = getInvoiceByCustomer($customer);
    // display invoice
}

Strict types + static analysis can tell you that this will fail (because it's
based purely on types, and a string is being passed to a function expecting
an integer). Coercive typing cannot statically tell you that it will fail,
because it doesn't know whether the string passed to `getInvoiceByCustomer`
is acceptable as an integer without also knowing its value.

To those who are worried that the addition of a strict mode will split the
community into separate camps, I would say "It's too late!" The community has
already been split over this issue for years. Conceptually, the optional
strict mode proposed in Anthony's RFC is not very different from == vs. ===,
or `in_array` with the $strict argument set to true. And I certainly am
glad that PHP offers these options!

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

Reply via email to