I believe the cleanest solution that we could implement would be using
the type casting with "Type" objects.
I experimented with this for a couple of months, a couple of weeks ago. In
opinion, it does not work well. I am guessing developers at java also figured
the same since they still also have primitive types. Aside from the mentioned
performance cost, it results in ugly and clumsy code. Not to mention you need
to cast the objects into primitive types if you wish to use the variables
with PHP functions.
function random(Integer $max, Integer $min)
{
$n = rand($min->getInteger(), $max->getInteger());
return $n;
}
Implementing the __toString() method in the classes helps a little but not
much.
And really, if you think about it, just adding support to scalar type hinting
solves the hold issue, thus making this sort of solution pointless and a pit
hole wasted energy and time.
Is there any reason we can't at least add "scalar" and
"resource" (and possibly "object" for generic objects) to typehints?
This sounds like, at least, a partial victory to adding proper type hinting to
PHP but in my mind it is not enough. I have counted that about a quarter of
all type hints that I would make is about matching the argument's type to
scalar. The rest are about separating specific scalars from each other. In
most cases integer and boolean.
I would probably end up not using type hinting at all, just to save the users
of my API from the confusion and just do the type checks myself inside my
methods.
Thinking about this, simply because we all know PHP CAN type
juggle, there is no need for any errors/warnings/notices on scalar
types. It will be up to the API developer to make sure appropriate
values are supplied (if necessary), so this reduces the type checking.
In other words, it is not "in the spirit of PHP" to enable strict type
hinting. I can understand this argument, but I still disagree heavily with
this approach.
- It is not consistent with the way that Array and Object type hinting works.
While you might make the argument that it is not an issue because you cannot
implicitly cast those types, it does create an annoying (yet another) magic
behavior thing in PHP that people need to learn and remember. If anything, it
will confuse new users, which I believe a lot of people were concerned about.
Essentially, if it is necessary (and most of the time it is) to validate the
value beyond just the type, you might as well do the casting at the same time
as you validate.
- The reason people are asking for type hinting for scalars is specifically
to move some of the responsibility from the API developer to the user of the
API and it is not an unreasonable request. After all, if person A has a
program that asks for user input, the best place for validation is not in the
class that person B wrote. The values should be validated in the program that
asked for the input. Since the validation is necessary, person A can easily
cast the type of the input at the end of the process, before he passes it to
the class.
E.g.
function validate($input)
{
// validate the input
// return false if it was not valid
// otherwise return a properly cast value
}
$input = $_GET['var1'];
$input = validate($input)
if(! empty($input)) {
doSomething($input);
}
This seems like a perfectly logical division of labor. The validator validates
and casts and the library class acts on the proper input.
Tomi Kaistila
PHP Developer
I believe the cleanest solution that we could implement would be using
the type casting with "Type" objects.
I experimented with this for a couple of months, a couple of weeks ago. In
opinion, it does not work well. I am guessing developers at java also figured
the same since they still also have primitive types. Aside from the mentioned
performance cost, it results in ugly and clumsy code. Not to mention you need
to cast the objects into primitive types if you wish to use the variables
with PHP functions.function random(Integer $max, Integer $min)
{
$n = rand($min->getInteger(), $max->getInteger());
return $n;
}Implementing the __toString() method in the classes helps a little but not
much.
But the syntax is longer ("$a = 5" vs "$a = new Integer(5)"), and if you
have a large application with hundreds of integers it starts to add up.
Performance is also much worse when using objects for every variable.
And really, if you think about it, just adding support to scalar type hinting
solves the hold issue, thus making this sort of solution pointless and a pit
hole wasted energy and time.Is there any reason we can't at least add "scalar" and
"resource" (and possibly "object" for generic objects) to typehints?
This sounds like, at least, a partial victory to adding proper type hinting to
PHP but in my mind it is not enough. I have counted that about a quarter of
all type hints that I would make is about matching the argument's type to
scalar. The rest are about separating specific scalars from each other. In
most cases integer and boolean.
Better than nothing.
I would probably end up not using type hinting at all, just to save the users
of my API from the confusion and just do the type checks myself inside my
methods.Thinking about this, simply because we all know PHP CAN type
juggle, there is no need for any errors/warnings/notices on scalar
types. It will be up to the API developer to make sure appropriate
values are supplied (if necessary), so this reduces the type checking.
In other words, it is not "in the spirit of PHP" to enable strict type
hinting. I can understand this argument, but I still disagree heavily with
this approach.
- It is not consistent with the way that Array and Object type hinting works.
While you might make the argument that it is not an issue because you cannot
implicitly cast those types, it does create an annoying (yet another) magic
behavior thing in PHP that people need to learn and remember. If anything, it
will confuse new users, which I believe a lot of people were concerned about.Essentially, if it is necessary (and most of the time it is) to validate the
value beyond just the type, you might as well do the casting at the same time
as you validate.
- The reason people are asking for type hinting for scalars is specifically
to move some of the responsibility from the API developer to the user of the
API and it is not an unreasonable request. After all, if person A has a
program that asks for user input, the best place for validation is not in the
class that person B wrote. The values should be validated in the program that
asked for the input. Since the validation is necessary, person A can easily
cast the type of the input at the end of the process, before he passes it to
the class.E.g.
function validate($input)
{
// validate the input
// return false if it was not valid
// otherwise return a properly cast value
}$input = $_GET['var1'];
$input = validate($input)if(! empty($input)) {
doSomething($input);
}This seems like a perfectly logical division of labor. The validator validates
and casts and the library class acts on the proper input.Tomi Kaistila
PHP Developer
But the syntax is longer ("$a = 5" vs "$a = new Integer(5)"), and if you
have a large application with hundreds of integers it starts to add up.
Performance is also much worse when using objects for every variable.
I agree. That is what I meant by "ugly" and "clumsy" in my last post.
This sounds like, at least, a partial victory to adding proper type
hinting to PHP but in my mind it is not enough. I have counted that about
a quarter of all type hints that I would make is about matching the
argument's type to scalar. The rest are about separating specific scalars
from each other. In most cases integer and boolean.Better than nothing.
No, it is not. It is actually better to not fix it at all, if you cannot fix
it properly. Especially in this case when the feature has already once been
left "unfinished".
The benefit is zero for me, if when I need to hint a boolean and can only hint
a scalar. In that case, I will still have to do the validating myself. I
might as well leave the type hinting out all together, instead of waste
resources for having first PHP check that it is a scalar and then my own code
to check that it is a boolean.
Actually, if I can only hint "scalar" in general, I am essentially telling the
users of my API that they should be ready for two types of errors. That which
occurs when the argument is not a scalar and that which occurs when it is not
a boolean. One will be a PHP error and the second will be an exception. Would
be easier on them if I do not use type hinting at all in that case.
I say, do it properly or do not do it at all.
Tomi Kaistila
PHP Developer
But the syntax is longer ("$a = 5" vs "$a = new Integer(5)"), and if you
have a large application with hundreds of integers it starts to add up.
Performance is also much worse when using objects for every variable.
I agree. That is what I meant by "ugly" and "clumsy" in my last post.This sounds like, at least, a partial victory to adding proper type
hinting to PHP but in my mind it is not enough. I have counted that about
a quarter of all type hints that I would make is about matching the
argument's type to scalar. The rest are about separating specific scalars
from each other. In most cases integer and boolean.Better than nothing.
No, it is not. It is actually better to not fix it at all, if you cannot fix
it properly. Especially in this case when the feature has already once been
left "unfinished".The benefit is zero for me, if when I need to hint a boolean and can only hint
a scalar. In that case, I will still have to do the validating myself. I
might as well leave the type hinting out all together, instead of waste
resources for having first PHP check that it is a scalar and then my own code
to check that it is a boolean.Actually, if I can only hint "scalar" in general, I am essentially telling the
users of my API that they should be ready for two types of errors. That which
occurs when the argument is not a scalar and that which occurs when it is not
a boolean. One will be a PHP error and the second will be an exception. Would
be easier on them if I do not use type hinting at all in that case.
Ok, but a scalar becomes useful for a couple of important things.
Scalars are all displayable values, that can be stored in a db,
outputted, etc. The scalar type hint prevents errors related to objects,
resources, and arrays attempting to be stored in the db or echoed.
I say, do it properly or do not do it at all.
Tomi Kaistila
PHP Developer
Ok, but a scalar becomes useful for a couple of important things.
Scalars are all displayable values, that can be stored in a db,
outputted, etc. The scalar type hint prevents errors related to objects,
resources, and arrays attempting to be stored in the db or echoed.
True, but honestly I do not see a whole lot of use for this. In a word, it is
very limited. Too limited to be truly useful in my opinion. It is simple
statistics; there is more need for specific types than scalars in general,
when using type hinting.
I do agree that it is a good idea to allow for type hinting scalars in
general, but it should not be considered a solution. It is more like a
comfortable add-on.
And to be frank, this really feels like a secondary price (bronze at most). If
pressed I would go bold say that this really feels like a screw. A way of
saying that we went out of our way to fix this feature that was limited by
adding a seemingly useful attribute to it, but in the end still leaving the
feature limited and not really fixing anything.
Tomi Kaistila
PHP Developer
Ok, but a scalar becomes useful for a couple of important things.
Scalars are all displayable values, that can be stored in a db,
outputted, etc. The scalar type hint prevents errors related to objects,
resources, and arrays attempting to be stored in the db or echoed.
True, but honestly I do not see a whole lot of use for this. In a word, it is
very limited. Too limited to be truly useful in my opinion. It is simple
statistics; there is more need for specific types than scalars in general,
when using type hinting.I do agree that it is a good idea to allow for type hinting scalars in
general, but it should not be considered a solution. It is more like a
comfortable add-on.And to be frank, this really feels like a secondary price (bronze at most). If
pressed I would go bold say that this really feels like a screw. A way of
saying that we went out of our way to fix this feature that was limited by
adding a seemingly useful attribute to it, but in the end still leaving the
feature limited and not really fixing anything.
A useful addon is better than none though, regardless. I agree this is
not a full solution, but I'd rather have 3 type hints than 2.
Tomi Kaistila
PHP Developer
Hi,
I am still wondering if we ever going to get a summary of this
"discussion".
regards,
Lukas