Guide to PHP SecurityQuicksearchCalendar
|
Wednesday, July 1. 2009Type hinting for PHP 5.3
For a few years now at work we've been using a patched version of PHP, one those patching featuring type hinting. Over time this proved to be a very handy feature that allows for a much more readable code and introduces a language based validation layer to ensure that the right data types are getting to your functions and methods. It also caught numerous bugs due to functions returning or passing un-expected values. Best of all this feature does not require any changes on the part of opcode caches (essential component for PHP performance) and allows for simple deployment.
I and other people have tried a number of times in the past to introduce type hinting into stock PHP, but unfortunately have never been successful. On a general level most people agree it would be a good idea to have, since it is an optional feature and does not introduce any regressions, heck you can even mix type hinted code with the non-type hinted one. The "PROBLEM" has always been combining of PHP's typeless nature with type hinting, which is where the consensus has been difficult (impossible) to reach. To illustrate the problem let's consider the following: function foo(int $bar) {} Some people would expect that passing "1" (string containing number 1) would be accepted by function foo() and not raise any type errors, since in PHP typically, numbers within strings are considered to be perfectly valid numbers ("1" + "1" == 2). Hence the conflict, some people (I am a part of that group) think that type hinting should be strict, while others think it should be more permissive to be inline with PHP's fluid nature. With introduction of PHP 5.3 and free day in the middle of the week (Happy Canada Day to all Canucks) I've decided to port my internal patch to 5.3 and introduce a new 'feature' to it to hopefully bridge the divide. I've added a IS_NUMERIC (numeric) type hint that allows the script author to designate a parameter as having to be number, meaning input of type boolean, long or float as well as strings containing purely numbers will be accepted. This means if were to rewrite my previous function as: function foo(numeric $bar) {} Then calling foo("112"); would perfectly valid. To further extend basic type hinting support I've also added IS_SCALAR (scalar) type hint that allows a parameter to be designated as scalar, which means it'll accept any boolean, float, string or integer value. The patch is available here: http://ia.gd/patch/type_hint_53.txt I've also posted it to the internals list in the hope of gathering enough support on the part of PHP developers and users to have it added to 5.3 and future releases of PHP. It should be noted that this is not the first idea for type hints, that credit goes to Hannes Magnusson who had posted a similar patch on the internals list back in 2006. Also, back in 2008 Felipe Pena wrote a complete RFC on type hinting with patches and even test. Trackbacks
Scalar type hints in PHP
Ilia recently brought up the topic of scalar type hints again. I would love scalar type hints, but a sensible implementation is not easy. I summarize some approaches in this post and talk about the problems they raise.
Weblog: schlitt.info - php, photography and private stuff
Tracked: Jul 02, 04:34 Comments
Display comments as
(Linear | Threaded)
See also http://www.php.net/manual/en/book.spl-types.php
PHP is already a GREAT scripting language, but once it gets support for type hinting, static classes and class properties (like the ones in C#) and it would damn near be silly to use any other web scripting language. It would retain the flexible nature that most non-developers need and just enough advanced programming features that would allow for us more seasoned developers to write more sophisticated applications.
This looks fine, but I'm having second thoughts about it. By introducing IS_NUMERIC, you're allowed to pass "12.5" and pass, while with INT you couldn't pass 12.5 (I'm guessing here, because I can't test it yet). If it so, this is a subtle but important difference, because IS_NUMERIC doesn't solve the problem when user wants an integer, whether it be a real int or a string value with int.
IS_NUMERIC from my side is a compromise that is needed for really loose code that still wants to use some form of type hinting. If you are going to say that 1 == "1" should you not also say that 1 == 1.0?
This would be extremely cool to have in PHP and very useful too. Here's hoping you can convince everyone!
This is actually interesting. Never thought about having more detailed type hints. alnum, alpha, cntrl, digit, etc. from the ctypes comes to mind.
How about support for custom types? LOL. TypeHint::add('alnum', function($mixed) { return ctype_alnum($mixed); }); Now thats fun to think about I think;)
Very nice Illia.
I'm of your opinion : I would like a strict type hinting in PHP, but the balanced solution you provided throught that patch seems very nice. Anyway I agree that PHP really needs a full support of type hinting, the PHPGroup should really move to such an idea. Think about the actual situation, we have only a piece of type hinting, which lead to a ridiculous situation not helping PHP's fame.
This would be a godsend in my opinion. When you are coding userlevel code, you may want the flexibility and quick-and-dirty stuff that a dynamic language allows - this does not hold strongly for libraries and frameworks with a clearly defined purpose.
Do you know what I'm also missing: an "arrayish" type hint - something that would accept either the array type or the ArrayAccess interface. The only way to do that now, is to leave the parameter untyped... Anyway, good job, I think this is the way to go.
I am thrilled to see some activity wrt type hints. At the same time, I'm disappointed that people keep confusing type hinting and data validation. If they want a function to accept anything that looks like a number, boolean, etc... they should use ext/filter instead.
One thing about the patch, I can't compile the latest CVS with it: /root/src/php5/ext/reflection/php_reflection.c: In function '_parameter_string': /root/src/php5/ext/reflection/php_reflection.c:681: error: 'struct _zend_arg_info' has no member named 'array_type_hint' /root/src/php5/ext/reflection/php_reflection.c: In function 'zim_reflection_parameter_isArray': /root/src/php5/ext/reflection/php_reflection.c:2277: error: 'struct _zend_arg_info' has no member named 'array_type_hint' Anyway, thanks for restarting that discussion
I completely agree with what you are saying about type hinting vs. data validation, but there are some cases where you might want to accept both an int and a string with only numbers in it, and this patch tries to address those situations.
I've updated the patch, I mistakenly only did a diff of the Zend/ directory missing the changes inside ext/reflection. This is now corrected.
Thanks for the quick response. I've patched my copy with the updated patch and unsurprisingly it worked just fine.
Great! I like it a lot! Now if that would only ever make it to the core ...
Might not get in the core quickly. Maybe an intermediate solution could be to verify parameter types through PHPUnit : http://techblog.wimgodden.be/2009/06/21/usin-phpunit-to-verify-parameter-types/
Ilia, I also feel that if you give an int hint, that what your really want to assure is that what will given is of type int. I heartily agree that you do not want to accept a value like "" for an int.
There are cases in which you want to be sure that at least a numeric vale (including "") is supplied, and this is why the idea of loose type hints is perfect! I would like to add the idea of typed arrays. IDE's would benefit from this as weel, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=170968 e.g. phplint provides a convenient syntax for annotating arrays http://www.icosaedro.it/phplint/phpdoc.html#types array - index can be both integers and strings, elements mixed array[] - index can be both integers and strings, elements mixed array[int]string - array of strings with int index array[int][int]float - matrix of floating-point numbers array[string]mixed - associative array of generic values array[]SomeClass - array of objects of the class SomeClass, the keys can be both integer numbers and strings Please let me know your thougts on this!
I need to add something to my statement to make it less confusing:
"There are cases in which you want to be sure that at least a numeric vale (including "") is supplied, and this is why the idea of +++ adding extra +++ loose type hints is perfect!" So supporting both numeric and int is a good idea imho.
Excellent!
Let us know where can we cast our votes, it should be in the core as optional feature. I was hoping for that day to come for a few years now, i really cant wait! Thanks
Please no, not optional. Hell, all those optional things drive regular php programmers crazy. One host disables this, the other that.
If you do not want to use it, just don't. Type hints are optional, so no one is forced.
Hi Ilia - AWSOME!
starting on my first PHP project after having lived in the world of Java for a while, I would sooo appreciate comprehensive type hinting support in PHP. Unfortunately, until your Type Hinting extension can make it into the PHP core (and even then!) I suspect that the added functionality may face criticism from some, as a result of a possible impact on overall runtime performance. I have not yet had a chance to comb through your implementation - hence my, possibly ignorant question: How easily would your extension support the enabling/disabling of enhanced Type Hinting functionality? For some of us, a reasonable compromise may be to use it during the development/debug cycle, but disable it in a reasonable 'stable' production setting that may be 'speed sensitive'. (E.g. by setting a global/ static variable that controls whether your, likely complex, validation code gets executed).
It's great, i'm ok with U !
Your type hinting extension must be into PHP core ! Thkx 4 all !
I recently had to work without type hinting for a bit. I felt like a caveman. It was terrible.
hi ilia
http://wiki.php.net/rfc/typecheckingstrictandweak i think that is a good idea! absolutely! - + api is not so clear but ! ? are totally good i hope to see this soon in php 5.3 .. 5.4 |
ArchivesCategoriesSyndicate This BlogBlog Administration |
|||||||||||||||||||||||||||||||||||||||||||||||||










Comments