Type safety in PHP

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ronald Raygun

    Type safety in PHP

    If I have a function that expects first argument to be of type (class
    foo) and second argument to be of type class foobar,how do I check/
    ensure that I have been passed the right parameter types?

    In C++, it would be done something luike this:

    void Func(const foo& foo_objectRef, const foobar& foobar_objectRe f)

    How can I enforce the requirement that only these data types can be
    passed to the function Func above?

    Since PHP is loosely typed, I suspect that there is no way of enforcing
    this kind of type integrity, - so in case I can't enforce this - how can
    I atleast check that I have not been passed a string (for example), when
    I am expecting an object of type foo or foobar?
  • Rik Wasmus

    #2
    Re: Type safety in PHP

    On Sat, 03 May 2008 16:37:40 +0200, Ronald Raygun <invalid@domain .com
    wrote:
    If I have a function that expects first argument to be of type (class
    foo) and second argument to be of type class foobar,how do I check/
    ensure that I have been passed the right parameter types?
    >
    In C++, it would be done something luike this:
    >
    void Func(const foo& foo_objectRef, const foobar& foobar_objectRe f)
    >
    How can I enforce the requirement that only these data types can be
    passed to the function Func above?
    >
    Since PHP is loosely typed, I suspect that there is no way of enforcing
    this kind of type integrity, - so in case I can't enforce this - how can
    I atleast check that I have not been passed a string (for example), when
    I am expecting an object of type foo or foobar?
    Since PHP5 you can require a certain kind of object (or an array):

    <?php
    //Classes
    class Foo {
    function bar(Foo $foo, Foobar $foo = null){
    echo "Works\n";
    }
    }
    class Bar extends Foo{}
    interface Foobar{}
    class Foz implements Foobar{}
    class Baz{}

    //Errors to exceptions
    function _error_handler( $errno,$errstr) {
    if($errno & error_reporting ()) throw new Exception($errs tr);
    return true;
    }
    set_error_handl er('_error_hand ler');

    //Illustration
    $foo = new Foo();

    try{$foo->bar(new Foo());}
    catch (Exception $e){ echo "Doesn't work.\n";}

    try{$foo->bar(new Bar());}
    catch (Exception $e){ echo "Doesn't work.\n";}

    try{$foo->bar(new Baz());}
    catch (Exception $e){ echo "Doesn't work.\n";}

    try{$foo->bar(new Foo(),new Foz());}
    catch (Exception $e){ echo "Doesn't work.\n";}

    try{$foo->bar(new Foo(),null);}
    catch (Exception $e){ echo "Doesn't work.\n";}

    try{$foo->bar(new Foo(),new Baz());}
    catch (Exception $e){ echo "Doesn't work.\n";}
    ?>
    Result:

    Works
    Works
    Doesn't work.
    Works
    Works
    Doesn't work.

    Manual:

    --
    Rik Wasmus

    Comment

    • Ronald Raygun

      #3
      Re: Type safety in PHP



      Rik Wasmus wrote:
      On Sat, 03 May 2008 16:37:40 +0200, Ronald Raygun <invalid@domain .com>
      wrote:
      >
      >If I have a function that expects first argument to be of type (class
      >foo) and second argument to be of type class foobar,how do I check/
      >ensure that I have been passed the right parameter types?
      >>
      >In C++, it would be done something luike this:
      >>
      >void Func(const foo& foo_objectRef, const foobar& foobar_objectRe f)
      >>
      >How can I enforce the requirement that only these data types can be
      >passed to the function Func above?
      >>
      >Since PHP is loosely typed, I suspect that there is no way of
      >enforcing this kind of type integrity, - so in case I can't enforce
      >this - how can I atleast check that I have not been passed a string
      >(for example), when I am expecting an object of type foo or foobar?
      >
      >
      Since PHP5 you can require a certain kind of object (or an array):
      >
      <?php
      //Classes
      class Foo {
      function bar(Foo $foo, Foobar $foo = null){
      echo "Works\n";
      }
      }
      class Bar extends Foo{}
      interface Foobar{}
      class Foz implements Foobar{}
      class Baz{}
      >
      //Errors to exceptions
      function _error_handler( $errno,$errstr) {
      if($errno & error_reporting ()) throw new Exception($errs tr);
      return true;
      }
      set_error_handl er('_error_hand ler');
      >
      //Illustration
      $foo = new Foo();
      >
      try{$foo->bar(new Foo());}
      catch (Exception $e){ echo "Doesn't work.\n";}
      >
      try{$foo->bar(new Bar());}
      catch (Exception $e){ echo "Doesn't work.\n";}
      >
      try{$foo->bar(new Baz());}
      catch (Exception $e){ echo "Doesn't work.\n";}
      >
      try{$foo->bar(new Foo(),new Foz());}
      catch (Exception $e){ echo "Doesn't work.\n";}
      >
      try{$foo->bar(new Foo(),null);}
      catch (Exception $e){ echo "Doesn't work.\n";}
      >
      try{$foo->bar(new Foo(),new Baz());}
      catch (Exception $e){ echo "Doesn't work.\n";}
      ?>
      Result:
      >
      Works
      Works
      Doesn't work.
      Works
      Works
      Doesn't work.
      >
      Manual:
      http://nl2.php.net/manual/en/languag...ypehinting.php
      Thanks for the clarification!

      Comment

      • Gordon

        #4
        Re: Type safety in PHP

        On May 3, 3:37 pm, Ronald Raygun <inva...@domain .comwrote:
        If I have a function that expects first argument to be of type (class
        foo) and second argument to be of type class foobar,how do I check/
        ensure that I have been passed the right parameter types?
        >
        In C++, it would be done something luike this:
        >
        void Func(const foo& foo_objectRef, const foobar& foobar_objectRe f)
        >
        How can I enforce the requirement that only these data types can be
        passed to the function Func above?
        >
        Since PHP is loosely typed, I suspect that there is no way of enforcing
        this kind of type integrity, - so in case I can't enforce this - how can
        I atleast check that I have not been passed a string (for example), when
        I am expecting an object of type foo or foobar?
        PHP 4 would require to use gettype (), get_class () and/or is_a ()
        inside your function to verify the type of the item passed to your
        function.

        PHP 5 would still require a gettype () for language primitives, but
        for objects and arrays you can use type hinting to restrict the type
        of argument passed to your function. For example if you want your
        function to only work on PDO objects you could do something like:

        function doSomethingWith Pdo (PDO $item)

        An error will be raised if you try passing it something that isn't a
        PDO object.

        You can also use type hinting with interfaces, which is really useful
        if you want a function that will operate on a range of different
        classes in a uniform way.

        interface DoesSomething
        {
        ...
        }

        class A implements DoesSomething
        {
        }
        class B implements DoesSomething
        {
        }
        class C
        {
        }

        function doSomething (DoesSomething $item)

        You can use doSomething with items of class A or B, but trying to use
        it with an item of class C will raise an error.

        Comment

        • Alexey Kulentsov

          #5
          Re: Type safety in PHP

          Ronald Raygun wrote:
          ....
          >
          Thanks for the clarification!
          And you can write you own class to check primitive types. Examples of
          using:

          <code>
          ....
          /// Get nested node by name attribute
          /**
          * @param $node parent node
          * @param $name name attribute value
          * @return target node or null if not found
          */
          function getByName($node ,$name)
          {
          chk::args('DOME lement',A_STRIN G);

          ....
          /// Get existing in game child objects
          /**
          * @param $parentId parent object id or object itself
          * @param $classId class id or class name
          * @return game object
          */
          function getChilds($pare ntId,$classId)
          {
          chk::args(A_INT |A_OBJECT,A_INT |A_STRING);
          ....
          </code>

          debug_backtrace () used in chk::args() ?? check arguments and make good
          error message.

          I hope in future they will add type hinting for all cases.

          Comment

          Working...