$30 off During Our Annual Pro Sale. View Details »

Typed PHP

Typed PHP

Strings, arrays and numbers are second-class citizens in PHP-land. This talk describes how they can be extended to work like objects, and how clean and consistent APIs can be introduced so that you can be proud of your PHP code again.

Christopher Pitt

December 19, 2014
Tweet

More Decks by Christopher Pitt

Other Decks in Programming

Transcript

  1. Typed PHP

    View Slide

  2. 1. PHP types

    View Slide

  3. Weak types
    ⌁ declare/assign variables without a type
    ⌁ change variable type any time

    View Slide

  4. Weak types
    $user = 1;
    // ...and then
    $user = "Chris";

    View Slide

  5. Zval
    ⌁ stores variable and type data
    ⌁ ...also garbage collection information

    View Slide

  6. Zval
    struct _zval_struct {
    zvalue_value value;
    zend_uint refcount__gc;
    zend_uchar type;
    zend_uchar is_ref__gc;
    };

    View Slide

  7. Equality
    ⌁ double-equals coerces types
    ⌁ triple-equals is probably what you want

    View Slide

  8. Equality
    true == 1; // true
    true === 1; // false

    View Slide

  9. Type hinting
    ⌁ helps prevent type errors
    ⌁ unsupported for scalar types

    View Slide

  10. Type hinting
    function map(array $items, callable $apply) {
    // ...call $apply on each item
    }

    View Slide

  11. Type hinting
    function shorten($string, $length) {
    assert(is_string($string));
    assert(is_integer($length));
    // ...reduce $string to $length
    }

    View Slide

  12. 2. Inconsistencies

    View Slide

  13. Underscores and abbreviations
    ⌁ 98 string functions
    ⌁ 30 with underscores, 68 without
    ⌁ 55 with abbreviations, 43 without

    View Slide

  14. Argument order
    ⌁ array is needle/haystack
    ⌁ string is haystack/needle
    ⌁ ...except when it's not

    View Slide

  15. Argument order
    array_filter(array $items, callable $apply);
    array_map(callable $apply, array $items);
    array_reduce(array $items, callable $apply);

    View Slide

  16. Argument order
    strstr($haystack, $needle);
    explode($needle, $haystack);
    str_replace($needle, $replace, $haystack);

    View Slide

  17. Return values
    ⌁ not always what you think
    ⌁ manual isn't always clear

    View Slide

  18. Return values
    preg_match returns 1 if a pattern matches a given
    subject, 0 if a pattern does not match a given
    subject. Or false if there was an error.

    View Slide

  19. Return values
    preg_match returns 1 if a pattern matches a given
    subject, 0 if a pattern does not match a given
    subject. Or false if there was an error.

    View Slide

  20. Return values
    Oh, and by the way: "This function may return
    Boolean FALSE, but may also return a non-
    Boolean value which evaluates to FALSE..."

    View Slide

  21. Return values
    Oh, and by the way: "This function may return
    Boolean FALSE, but may also return a non-
    Boolean value which evaluates to FALSE..."

    View Slide

  22. 3 .Boxing

    View Slide

  23. Boxing
    ⌁ classes wrap primatives
    ⌁ special construction
    ⌁ special deconstruction

    View Slide

  24. Boxing
    class StringObject {
    protected $data;
    public function __construct($data) {
    $this->data = $data;
    }

    View Slide

  25. Boxing
    public function value() {
    return $this->data;
    }
    }

    View Slide

  26. Boxing
    $string = new StringObject("hello world");
    $string->value(); // "hello world"
    function value(StringObject $string) {
    return $string->value();
    }

    View Slide

  27. Boxing
    ⌁ requires special construction and deconstruction
    ⌁ allows type-hinting

    View Slide

  28. 4. Scalar types

    View Slide

  29. Scalar types
    ⌁ classes wrap primatives (again)
    ⌁ automatic constrution
    ⌁ automatic deconstruction

    View Slide

  30. Scalar types
    class StringObject {
    public function length() {
    return strlen($this);
    }
    }

    View Slide

  31. Scalar types
    register_primitive_type_handler(
    "string", "StringObject"
    );
    $string = "hello world";
    $string->length(); // 11

    View Slide

  32. Scalar types
    ⌁ automatic construction and deconstruction
    ⌁ doesn't allow type-hinting
    ⌁ can't opt-out

    View Slide

  33. 5. SPL types

    View Slide

  34. SPL types
    ⌁ classes wrap primatives (again)
    ⌁ special constrution
    ⌁ automatic deconstruction

    View Slide

  35. SPL types
    class StringObject extends SplString {
    public function length() {
    return strlen($this);
    }
    }

    View Slide

  36. SPL types
    $string = new StringObject("hello world");
    "big " . $string; // "big hello world"

    View Slide

  37. SPL types
    ⌁ special construction
    ⌁ automatic deconstruction
    ⌁ allows type-hinting
    ⌁ must opt-in

    View Slide

  38. SPL types
    This is my favourite!

    View Slide

  39. 6. Optional types

    View Slide

  40. Optional types
    ⌁ classes wrap classes
    ⌁ reduce type checking
    ⌁ reduce errors

    View Slide

  41. Optional types
    $user = User::find(1);
    if ($user !== null) $address = $user->address();
    if ($address !== null) $city = $address->city();
    if ($city !== null) $forecast = $city->forecast();
    print "Your forecast: " . $forecast;

    View Slide

  42. Optional types
    $user = User::find(1);
    if ($user !== null) $address = $user->address();
    if ($address !== null) $city = $address->city();
    if ($city !== null) $forecast = $city->forecast();
    print "Your forecast: " . $forecast;

    View Slide

  43. Optional types
    $user = new Optional(User::find(1));
    $user
    ->address()->city()->forecast()
    ->value(function($forecast) {
    print "Your forecast: " . $forecast;
    });

    View Slide

  44. Optional types
    It gets alot better than that...but no time!

    View Slide

  45. 7. Learning more

    View Slide

  46. Learning more
    ⌁ Anthony Ferrara @ircmaxell
    ⌁ Igor Wiedler @igorwhiletrue
    ⌁ Christopher Pitt @assertchris
    ⌁ joind.in/talk/view/13094

    View Slide