Hi,
I am currently working on my final project of my undergraduate study and the project is about type safety in PHP. One aspect of the project examines the opinion of the PHP community on this topic.

I now need your help. I would be very glad, if you could take 5 – 20 minutes to fill in my online survey: http://www.q-set.co.uk/q-set.php?sCode=PGSKQCJUWZVK

I will publish the deliverables of my project under an open source license. Thus you contribute automatically to an open source project if you fill in the form 🙂

Thanks for your help
Robert Stoll

    8 days later

    Just filled it in, I realise how difficult it can be sometimes to get a large enough pool of data for university coursework.

      Hi, Robert, and welcome to PHPBuilder!

      I found the concept interesting, if a tad on the political side 😉

      survey wrote:

      2. Should the following improvement for type safety be made?

      public function setName(string name) {

      I'd say it should be optional, but that option wasn't available here 😉

      survey wrote:

      A context for templates is introduces.

      I'm fairly certain you meant to use the past tense here?

      survey wrote:

      securer web applications

      Sounds a bit odd. How about "Improved security and robustness in web applications."

      Hopefully not keeping others from participating, I also found the second set of questions rather awkward, as my opinion hadn't changed at that point.

      The IDE section was interesting.

      Note that for US participants, "College Degree and Bachelors' Degree" will, generally, be synonymous.

      Good luck with your project!

        @ Sheridan
        Thank you very much

        dalecosp;11021527 wrote:

        I found the concept interesting, if a tad on the political side 😉

        I know, can be quite controversial. But that's ok 🙂

        dalecosp;11021527 wrote:
        survey wrote:

        2. Should the following improvement for type safety be made?
        PHP Code:
        public function setName(string name) {

        I'd say it should be optional, but that option wasn't available here 😉

        Hm... I have not given this option because types for parameters are already optional, but maybe it would have been better to give that option as well.

        dalecosp;11021527 wrote:
        survey wrote:

        securer web applications

        Sounds a bit odd. How about "Improved security and robustness in web applications."

        Thanks for your suggestion

        dalecosp;11021527 wrote:

        Hopefully not keeping others from participating, I also found the second set of questions rather awkward, as my opinion hadn't changed at that point.

        Since not everyone get the same questions (depending on the answers given) I would like to know, which kind of questions you are talking about?

        dalecosp;11021527 wrote:

        Note that for US participants, "College Degree and Bachelors' Degree" will, generally, be synonymous.

        Thank you, I didn't know that

        dalecosp;11021527 wrote:

        Good luck with your project!

        thanks

          rstoll;11021601 wrote:

          Since not everyone get the same questions (depending on the answers given) I would like to know, which kind of questions you are talking about?

          Hopefully I can explain 🙂

          After I was asked ("does knowing about this change your thoughts"), [around #9 or #10, I think], I was then asked the exact same questions; six or seven of them, I think. As I hadn't changed my mind, I didn't see the point in being asked the same questions again. Perhaps I didn't understand something I clicked, and it went back and began again?

            oh no... that's exactly not what I wanted 🙁 Those questions should have been skipped when you choose no your opinion hasn't changed.
            Thank you for your hint.

              dalecosp;11021645 wrote:

              Hopefully I can explain 🙂

              After I was asked ("does knowing about this change your thoughts"), [around #9 or #10, I think], I was then asked the exact same questions; six or seven of them, I think. As I hadn't changed my mind, I didn't see the point in being asked the same questions again. Perhaps I didn't understand something I clicked, and it went back and began again?

              hm... I just tested it, probably you have used the back button, since I do not get the same questions again, if I choose no for the question: "Would you have answered the previous questions differently if you had had the above information?"

                Well ... the problem with that theory is that the question numbers continued to increment as expected. :eek:

                  Ah... I see. That's true, unfortunatley that's how the survey web application is implemented. But I can activate a page number in addition next to the question numbers (already done now). This way it is more obvious that some questions have been skipped. Thank you for your hint. I think that's helpfull for the participants.

                    I tried to take your survey several times, but it kept restarting at random points. I got about halfway through.

                    I think many of the examples you give are over-simplified: you often ask "if x should be done to improve type safety" - but you don't necessarily explain how x will be implemented.

                    For example,

                    public function whatever( string $str ){ /*...*/ }

                    What does [font=monospace]string[/font] do?

                    ...Does it throw an exception if [font=monospace]$str[/font] is not a string (which could come to pass under any number of coincidences in a loosely typed language like PHP)?

                    ...Does it cast [font=monospace]$str[/font] to a string?

                    ...Does it cast [font=monospace]$str[/font] to a string, but only if [font=monospace]$str == (string)$str[/font]?
                    (...BTW, this is the answer I would have chosen)

                    ...What about
                    [indent]

                    public function whatever( string $str="default" ){ /*...*/ }

                    Is [font=monospace]$str[/font] given the value "default" if it is not a string?
                    Or only if it is not provided?[/indent]

                    On several questions, I found it difficult to choose an accurate/meaningful answer because of ambiguities like these.


                    Regarding templates, I think the best (simplest, most obvious) solution would be to create a template object and pass (or [font=monospace]use[/font]?) the desired variables directly to it.


                    Dynamic typing is a benefit, not a shortcoming. Full type safety would completely break many PHP applications. I'm not advocating that backwards-compatibility should be the deciding factor, and while a measure of type safety (or perhaps type hinting and stricter control over type coercion is what I really mean) would be beneficial, it could also lead to unnecessarily complex code.

                    As an example, [font=monospace]$GET[/font] and [font=monospace]$POST[/font] are always initially strings - do you intend to initially cast them to a "best fit" type? According to what rules? Or would one be forced to write constructs like

                    function whatever( int $int ){ /*...*/ }
                    $result = whatever( ((integer)$_GET['userInt']) );

                    ?

                      traq;11021687 wrote:

                      ...Does it cast [font=monospace]$str[/font] to a string, but only if [font=monospace]$str == (string)$str[/font]?
                      (...BTW, this is the answer I would have chosen)

                      As I would have also chosen.

                        Derokorian;11021691 wrote:

                        As I would have also chosen.

                        Have you read this (I don't remember where I was pointed to this; it may have even been here (on phpbuilder), so my apologies if we've already had this discussion)?

                          traq;11021687 wrote:

                          I think many of the examples you give are over-simplified: you often ask "if x should be done to improve type safety" - but you don't necessarily explain how x will be implemented.

                          Fair enough. I see what you mean and I see, that it is difficult to choose an option if one think about it as you have done. I have explicitly left out any implementation, since the survey would be even longer with it and honestly, I think now that it is already too long, I should have shorten the survey a little bit. First of all I have thought about implementing a very strict model which would have needed an explicit casting. For instance a method call would have been

                          int $a = 1;foo( (string) $a);

                          However, I have made some speed tests and have realised, that explicit casting is slower in PHP than the PHP intern casting. For instance:

                          $a = 1; 
                          $b = (int) "1"; 
                          $c = $a + $b;

                          is slower than

                          $a = 1; 
                          $b = "1";
                           $c = $a + $b;

                          Therefore I am not yet sure how I am going to implement it.

                          traq;11021687 wrote:

                          ...Does it cast $str to a string, but only if $str == (string)$str?
                          (...BTW, this is the answer I would have chosen)

                          I am not sure if I really get what you mean. Take your example with an integer. For instance:

                          function foo(int $i){
                            echo $i;
                          }
                          $a = "a";
                          foo($a); //output = 0 since $a == (int) $a;
                          

                          Is this really what you want? Or would your behaviour only be applied to strings?

                          traq;11021687 wrote:

                          Regarding templates, I think the best (simplest, most obvious) solution would be to create a template object and pass (or [font=monospace]use[/font]?) the desired variables directly to it.

                          I agree, that would be the simplest way, but I believe developers are still heavely relying on templates (including other files). I mean, it is already possible to use objects instead of including files (needless to say that classes will also be included at a certain point) but one like including files without context more than defining classes and using them. I undestand them, since including files is quite convenient.

                          traq;11021687 wrote:

                          Dynamic typing is a benefit, not a shortcoming. Full type safety would completely break many PHP applications. I'm not advocating that backwards-compatibility should be the deciding factor, and while a measure of type safety (or perhaps type hinting and stricter control over type coercion is what I really mean) would be beneficial, it could also lead to unnecessarily complex code.

                          I absolutely agree. Type-safe code leeds often to more complex code than unsafe code. I think one good point in my approach is, that I introduce TSPHP at a higher level. PHP is still available as it is now and for certain web applications it is more appropriate to use PHP rather than TSPHP. And since TSPHP is translated into PHP one can develop his component in TSPHP and another one show use PHP can use the component (unfortunatley not the other way round - but if TSPHP is usefull as I expect it to be then I will probably also develop a type inference system which transforms PHP into TSPHP as far as possible). However, especially bigger projects which underlies many changes (over the years) are quite painfull to maintain, because refactorings for PHP is poorly supported by IDEs and quite error prone. If you have done ones a refactoring in type-safe languages you exactly now what I mean. And in my opinion refactoring is very essential to keep your code quality high over the years and changes.

                          traq;11021687 wrote:

                          As an example, [font=monospace]$GET[/font] and [font=monospace]$POST[/font] are always initially strings - do you intend to initially cast them to a "best fit" type? According to what rules? Or would one be forced to write constructs like

                          function whatever( int $int ){ /*...*/ }
                          $result = whatever( ((integer)$_GET['userInt']) );

                          ?

                          Well, as said above, first of all I intended to implement a very strict model, but now I guess I will accept some operator overloadings. For instance

                          string $b="1";
                           int $a = 1 + $b;
                          

                          will be valid, since + automatically casts strings to integers. However, I am not yet sure how I will implement it for parameters. I was thinking about a strict model (thus (integer)$_GET['userInt']; whould be necessary) but with the option of an automatic casting. Anyway, I haven't made final decision yet.

                            rstoll;11021699 wrote:
                            $a = 1; 
                            $b = (int) "1"; 
                            $c = $a + $b;

                            is slower than

                            $a = 1; 
                            $b = "1";
                             $c = $a + $b;

                            I have to correct myself. Explicit casting is as fast as implicit casting.
                            Nevertheless, I will support operator overloading as mentioned and I will be strict on parameters but with the possibility to activate automatic casting.

                            traq;11021693 wrote:

                            Have you read this

                            The syntax for the automatic casting could therefore be

                            function foo((int) $i){}

                            but maybe also something more obvious as

                            function foo(cast int $i)
                              rstoll;11021699 wrote:

                              I am not sure if I really get what you mean. Take your example with an integer. For instance:

                              function foo(int $i){
                                echo $i;
                              }
                              $a = "a";
                              foo($a); //output = 0 since $a == (int) $a;
                              

                              Is this really what you want? Or would your behaviour only be applied to strings?

                              What I would expect is that since $a != (int) $a that this usage would not produce 0 but instead produce a Fatal error, much like that which would result from the following:

                              function TrimPost(BlogPost $post) {
                                 $post['body'] = substr($post['body'], 0, 200);
                                 return $post;
                              }
                              $a = new User();
                              TrimPost($a);
                              // Catchable fatal error: Argument 1 passed to TrimPost() must be an instance of BlogPost, instance of User given, called in /path/to/file.php on line ## and defined in /path/to/file.php on line ##
                              

                                I, too, tried to keep backwards compatibility in mind for every answer I gave on the survey.

                                One of my ideas was to by default make type violations an E_NOTICE/E_WARNING level error but to also add an option to error_reporting that would elevate these to catchable fatal errors.

                                EDIT: I should add... I came up with this idea without thinking of the approach Derokorian described (and/or what was described on the page traq linked to in post #12). I'm still on the fence as to which way I like better.

                                  Derokorian;11021707 wrote:

                                  What I would expect is that since $a != (int) $a that this usage would not produce 0 but instead produce a Fatal error

                                  Right:

                                  function intOnly( int $int ){}
                                  intOnly( "a" );
                                  /*
                                  (int)"a" = 0
                                  "a" != 0
                                  throw error
                                  */
                                  intOnly( "1" );
                                  /*
                                  (int)"1" = 1
                                  1 == 1
                                  okay
                                  */
                                  # intOnly( "1thing" ); # strike that. better example:
                                  intOnly( true );
                                  /*
                                  (int)true = 1
                                  ...?
                                  yeah... that's where it gets muddy.
                                  */
                                  bradgrafelman;11021711 wrote:

                                  One of my ideas was to by default make type violations an E_NOTICE/E_WARNING level error but to also add an option to error_reporting that would elevate these to catchable fatal errors.

                                  Hadn't thought of that. Good possibility.

                                    As far as I'm concerned, if you specify...

                                    function foo(boolean $bar) { ... }
                                    

                                    ...and call it as...

                                    foo(1);
                                    

                                    ...it should throw an exception, just as it would if you type-hinted with "Array" or any class name. Automatically converting it to the desired type would not be "type safety", to my mind.

                                    However, note any such implementation would now mean you could not call any of your classes "boolean" or any other implemented type names (which may already be reserved words?), or if you did, you could not use that class's name as a type-hint any more -- not that I'd generally want to call any of my classes that, but I suppose you could define classes to represent different data types as a way to implement type safety, by allowing you to type-hint with those class names?

                                    Oh well, guess I'm just glad I've never really had an issue with PHP's loose typing (or whatever it's technically called?).

                                      NogDog;11021795 wrote:

                                      As far as I'm concerned, if you specify...

                                      function foo(boolean $bar) { ... }
                                      

                                      ...and call it as...

                                      foo(1);
                                      

                                      ...it should throw an exception, just as it would if you type-hinted with "Array" or any class name. Automatically converting it to the desired type would not be "type safety", to my mind.

                                      Agreed - just a little muddy, since (for example) 1 and 0 are so synonymous with TRUE and FALSE.
                                      But where would you draw the line? Should "5" (a string) fail where an integer is required?

                                        traq;11021799 wrote:

                                        Agreed - just a little muddy, since (for example) 1 and 0 are so synonymous with TRUE and FALSE.
                                        But where would you draw the line? Should "5" (a string) fail where an integer is required?

                                        In my mind, yes, since type-hinting means you only want to accept parameters of the specified type. If, instead, you want the normal loose typing, then simply do not type-hint for it (or embed your own type-checking/-swapping mechanism at the beginning of the function definition if you want something in between strict type-checking and no type-checking). But like I said, I'm not going to loose any sleep over it for now. 🙂

                                        Hmm...now I'm imagining a class full of methods for various sorts of type-checking...darn you all, I have other things that need doing!

                                        function enforceInteger(&$value)
                                        {
                                            if(is_int($value)) {
                                                return true;
                                            }
                                            elseif((int)$value == $value) {
                                                $value = (int) $value;
                                                return true;
                                            }
                                            throw new TypeException("Not an integer");
                                        }
                                        

                                        🆒