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.

061e3bae4ce4234a2194d20a382e5d19?s=128

Christopher Pitt

December 19, 2014
Tweet

Transcript

  1. Typed PHP

  2. 1. PHP types

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

    variable type any time
  4. Weak types $user = 1; // ...and then $user =

    "Chris";
  5. Zval ⌁ stores variable and type data ⌁ ...also garbage

    collection information
  6. Zval struct _zval_struct { zvalue_value value; zend_uint refcount__gc; zend_uchar type;

    zend_uchar is_ref__gc; };
  7. Equality ⌁ double-equals coerces types ⌁ triple-equals is probably what

    you want
  8. Equality true == 1; // true true === 1; //

    false
  9. Type hinting ⌁ helps prevent type errors ⌁ unsupported for

    scalar types
  10. Type hinting function map(array $items, callable $apply) { // ...call

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

    $string to $length }
  12. 2. Inconsistencies

  13. Underscores and abbreviations ⌁ 98 string functions ⌁ 30 with

    underscores, 68 without ⌁ 55 with abbreviations, 43 without
  14. Argument order ⌁ array is needle/haystack ⌁ string is haystack/needle

    ⌁ ...except when it's not
  15. Argument order array_filter(array $items, callable $apply); array_map(callable $apply, array $items);

    array_reduce(array $items, callable $apply);
  16. Argument order strstr($haystack, $needle); explode($needle, $haystack); str_replace($needle, $replace, $haystack);

  17. Return values ⌁ not always what you think ⌁ manual

    isn't always clear
  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.
  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.
  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..."
  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..."
  22. 3 .Boxing

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

    deconstruction
  24. Boxing class StringObject { protected $data; public function __construct($data) {

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

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

    function value(StringObject $string) { return $string->value(); }
  27. Boxing ⌁ requires special construction and deconstruction ⌁ allows type-hinting

  28. 4. Scalar types

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

    ⌁ automatic deconstruction
  30. Scalar types class StringObject { public function length() { return

    strlen($this); } }
  31. Scalar types register_primitive_type_handler( "string", "StringObject" ); $string = "hello world";

    $string->length(); // 11
  32. Scalar types ⌁ automatic construction and deconstruction ⌁ doesn't allow

    type-hinting ⌁ can't opt-out
  33. 5. SPL types

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

    ⌁ automatic deconstruction
  35. SPL types class StringObject extends SplString { public function length()

    { return strlen($this); } }
  36. SPL types $string = new StringObject("hello world"); "big " .

    $string; // "big hello world"
  37. SPL types ⌁ special construction ⌁ automatic deconstruction ⌁ allows

    type-hinting ⌁ must opt-in
  38. SPL types This is my favourite!

  39. 6. Optional types

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

    ⌁ reduce errors
  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;
  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;
  43. Optional types $user = new Optional(User::find(1)); $user ->address()->city()->forecast() ->value(function($forecast) {

    print "Your forecast: " . $forecast; });
  44. Optional types It gets alot better than that...but no time!

  45. 7. Learning more

  46. Learning more ⌁ Anthony Ferrara @ircmaxell ⌁ Igor Wiedler @igorwhiletrue

    ⌁ Christopher Pitt @assertchris ⌁ joind.in/talk/view/13094