
Making PHP Safer - jromma
http://tech.blog.box.com/2014/01/making-php-safer-introducing-augmented-types/
======
kijin
Type hinting for scalar types has been on and off the TODO list for PHP for a
while now. PHP already has type hinting for arrays and objects, but not for
scalar types like int, float, and string. It's been on the roadmap forever but
nobody seems to know when the feature will actually land in a stable release.

That's because type hinting for built-in scalar types is more difficult than
it sounds in a dynamic language like PHP. There's been a lot of debate about
what to do, for example, when you pass '123' (string) to a function that
requires an integer, or even worse, when you pass 123 (integer) to a function
that requires a float. Do you throw an error, as strongly typed languages do,
or do you quietly convert that integer to the equivalent float, as PHP has
always done? Or do you try to convert first and only throw an error when you
can't? Above all, how do you do this without giving up all the benefits of
being a dynamic language in the first place? Note that this problem has
nothing to do with the '01' == 1 issue. Things can get messy even with
reasonably straightforward conversions like '123' = 123 = 123.0.

The problem is compounded by the fact that even built-in libraries don't know
how to make use of built-in types. For example, if you use PDO to select a row
from MySQL where the 'id' field is an integer, and you write something like
($row->id === 42), you get false because all the fields are returned as
strings. Meanwhile, the PostgreSQL driver returns boolean values as 't' and
'f' (string), not true and false (bool). This is retarded. I'm a big fan of
the improvements since PHP 5.3, but both the language and the standard library
still have a long way to go.

~~~
ciarand
First, you're right - the core library and API does have a long way to go.
Imo, we need a new major version (6) so we can break backwards compatibility
for some of this craziness.

But as for the annotations, the most compelling argument I've seen is to make
it string (===). If you supply "123" and the method signature requires an int,
it should throw an exception. If you don't want that, don't include the
typehint.

That also gives the option for something like a "~number" typehint if
necessary, but I don't care about that. I want strict type checking, anything
less than that does not solve the core problem.

~~~
wvenable
I disagree. Strict type hinting would be ridiculous in PHP and lead to a lot
of unnecessary and unsafe casting.

nikic goes through all the scalar type hint options here:

[http://nikic.github.io/2012/03/06/Scalar-type-hinting-is-
har...](http://nikic.github.io/2012/03/06/Scalar-type-hinting-is-harder-than-
you-think.html)

Strict weak type hinting seems like the most realistic and pragmatic choice
except I would add a cast to make sure the type is actually an `int` in the
function.

~~~
krapp
It would be nice if you had an option, like

    
    
       function foo(weak int $i)
    

for weak type hinting, and

    
    
       function foo(int $i)
    

for strict. The arguments for weak type hinting make sense but sometimes you
don't want any ambiguity.

~~~
kijin
Or something like "numeric" that allows both int and float, as well as any
string that would pass the test of is_numeric(). It would be just like class
inheritance: int and float would be treated as subtypes of "numeric".

------
davidkuridza
Having this enabled in development and testing environments sounds like a good
idea to me, any thoughts? Will definitely try it out locally asap.

~~~
p4lindromica
That is what we do at Box.

------
bovermyer
I hate annotations in PHP. They feel very tacked-on. I'd much rather see
actual enforced typing in the language.

This is a step in the right direction, but it doesn't go far enough, in my
opinion.

~~~
mildtrepidation
In a very literal sense, everything in PHP is tacked on. It's a conglomeration
of crap. You could replace "crap" with something more politically correct in
that sentence, but it could not possibly be more literally correct.

Annotations. Namespaces. There is nothing in PHP that was not an afterthought.
While it could technically be considered "unfair" to criticize the language in
that respect, the total failure to push it in any rational direction in the
last decade or two says nothing about the language, but speaks volumes about
the people in charge of it.

PHP is a horrible, horrible failure. Not a failure in the sense that it
doesn't work; it does. It does what it was and is intended to. But it does
that in such an absolutely shitty way, and with such a grotesque mountain of
horrid workarounds and terrible hacks that are sometimes called features, that
there is no excuse for the way this language has evolved.

It works. And it's used all over the place. But that doesn't make it good. If
the road to hell is paved with good intentions, then PHP is the express route.

~~~
markdown
Thank goodness there are people in this world who care more about shipping
than about perfection.

Thank goodness there are people who have thicker skin than I, and release FOSS
to the world despite comments like yours.

~~~
frowaway001
And if others listened to people like you, we would all still live on trees.

------
encoderer
Reading this, wishing Facebook's Hack lang was OSS so I could really have a
chance to sink my teeth in and compare/contrast these tools.

Edit: Clarity

~~~
jazzdan
Facebook's Hack lang is open source, though not publicly documented. This
commit points out a lot of the implementation and test files:
[https://github.com/facebook/hhvm/commit/db9577b1409b74293fd9...](https://github.com/facebook/hhvm/commit/db9577b1409b74293fd91d39455fe7ef3d4d0a7c)

~~~
encoderer
Fascinating! I had no clue.

------
jtreminio
I sure had no idea Box uses PHP.

~~~
_delirium
Does anyone have a rough census of what top websites use? I've had this same
reaction, but more than once with PHP: I know now that at least Box,
Wikipedia, and Facebook use PHP.

~~~
semerda
Facebook doesn't use PHP the way other companies do. They ship & run binaries
via HipHop/HipHop Virtual Machine (HHVM) in production. Other companies which
use Facebook as an excuse (justification) to use PHP in production ship
standard PHP scripts into Production and think they are doing the same thing
Facebook does.

~~~
_delirium
True, although didn't that happen only after many years of them using regular
PHP in production? IIRC, HipHop dev only really got going in the 2010s.

~~~
semerda
True, although that was after four failed attempts to move away from PHP and
realizing due to incumbent inertia they had to find an alternative solution.
Enter HipHop. I am sure that today if they had to start over, PHP would not
even be considered ;-) My main point is that in "today's times" using Facebook
as a excuse (reason) for opting for PHP is not a wise move.

------
psaintla
I'd really like to know why they chose to do this instead of trying to make
spltypes and type hinting more robust. Annotations seem like an ugly way of
doing this.

~~~
sentiental
One of the authors here. We didnt want to change the AST in a way that would
be backwards incompatible with vanilla PHP. There is some luxury in being able
to turn off this extension when needed. We also have a large enough existing
codebase that switching to SPL types everywhere was a non-starter. Our goal
here was partly to be able to use PHP's native types and still get some good
coverage.

Phpdoc may not seem ideal, and it's not, but it has afforded some significant
flexibility

~~~
psaintla
Thank you for your response, that's good reasoning and I definitely see it
works well for your use case. It just seems as if multiple companies are
coming up with solutions to work around deficiencies in PHP which is causing
fragmentation in the language. That's not going to stop me from using this
extension in a new project I'm starting though. Are there any areas of this
extension you'd like to see improved since I find the best way for me to
understand an extension internally is to work on it.

------
thaJeztah
Sounds very promising, will definitely give this a spin. Hopefully something
like this will make its way into PHP by default.

