Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

AST + Better Reflection (PHP Benelux 2016 Unconference)

819 views

Published on

Better Reflection is an awesome new library that uses magical time-warp techniques* (*actual magic or time-warp not guaranteed) to improve on PHP’s built-in reflection by providing additional functionality. In this talk we’ll briefly explore the cool features of Better Reflection, and how you can use Better Reflection in your projects to maximise your reflection-fu.

Published in: Technology
  • Be the first to comment

AST + Better Reflection (PHP Benelux 2016 Unconference)

  1. 1. AST + Better Reflection James Titcumb PHP Benelux 2016 Unconference
  2. 2. James Titcumb www.jamestitcumb.com www.roave.com www.phphants.co.uk www.phpsouthcoast.co.uk @asgrim Who is this guy?
  3. 3. Reflection
  4. 4. © 1937 Disney’s Snow White - disneyscreencaps.com
  5. 5. ● Structure ● Metadata ● Values ● Type introspection ● Modification Reflection
  6. 6. How does it work?
  7. 7. GET_REFLECTION_OBJECT_PTR(ce); lc_name = zend_str_tolower_dup(name, name_len); if ((ce == zend_ce_closure && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) || zend_hash_str_exists(&ce->function_table, lc_name, name_len)) { efree(lc_name); RETURN_TRUE; } else { efree(lc_name); RETURN_FALSE; }
  8. 8. Okay. What now?
  9. 9. github.com/ /BetterReflection Better Reflection!
  10. 10. What?
  11. 11. Why?
  12. 12. How?
  13. 13. Magic of the AST
  14. 14. source: http://goo.gl/HORwLQ
  15. 15. WTF is AST?
  16. 16. use PhpParserParserFactory; $parser = (new ParserFactory) ->create(ParserFactory::PREFER_PHP7); print_r($parser->parse( file_get_contents('ast-demo-src.php') ));
  17. 17. <?php echo "Hello world";
  18. 18. AST `-- Echo statement `-- String, value "Hello world"
  19. 19. <?php echo "Hello " . "world";
  20. 20. AST `-- Echo statement `-- Concat |-- Left | `-- String, value "Hello " `-- Right `-- String, value "world"
  21. 21. AST to Reflection
  22. 22. Benefits?
  23. 23. ReflectionProperty->getDocBlockTypes() Types!
  24. 24. Using Better Reflection
  25. 25. $reflection = new ReflectionClass( 'BetterReflectionTestFixtureExampleClass' ); $this->assertSame( 'ExampleClass', $reflection->getShortName() );
  26. 26. $reflection = ReflectionClass::createFromName( 'BetterReflectionTestFixtureExampleClass' ); $this->assertSame( 'ExampleClass', $reflection->getShortName() );
  27. 27. // In ReflectionClass : public static function createFromName($className) { return ClassReflector::buildDefaultReflector()->reflect($className); } // In ClassReflector : public static function buildDefaultReflector() { return new self(new AggregateSourceLocator([ new PhpInternalSourceLocator(), new EvaledCodeSourceLocator(), new AutoloadSourceLocator(), ])); }
  28. 28. AutoloadSourceLocator ReflectionClass::createFromName(new MyClass) replace stream wrapper disable error handling call “class_exists” restore stream wrapper restore error handling store attempted filename load DO NOT LOAD FILE! return stored filename Read file and parse AST!
  29. 29. (don’t try this at home kids!) Some voodoo...
  30. 30. class MyClass { public function foo() { return 5; } }
  31. 31. // Create the reflection first // ***BEFORE*** class is loaded $classInfo = ReflectionClass::createFromName('MyClass');
  32. 32. // Override the body...! $methodInfo = $classInfo->getMethod('foo'); $methodInfo->setBody(function () { return 4; });
  33. 33. // Save the class and require it $classCode = (new CodePrinter())->prettyPrint([$classInfo->getAst()]); $tmpFile = tempnam(sys_get_temp_dir(), 'br-monkey-patching'); file_put_contents($tmpFile, '<?php ' . $classCode); require_once($tmpFile); unlink($tmpFile);
  34. 34. // Now create an instance, and call the function... $c = new MyClass(); var_dump($c->foo()); // will be 4!!!
  35. 35. What’s in it for me?
  36. 36. The future...
  37. 37. ● DONE Currently: rewriting the internals ○ SourceLocators “might” return some code ?! ● DONE Returning AST/Code for method/fn Ideas/plans - DONE
  38. 38. ● WIP More compatibility core reflection ● WIP Reflect core fns with default params ○ This is not currently possible with core reflection ● WIP Modification & exporting ● WIP Reflecting on closures Ideas/plans - WIP
  39. 39. ● Adding a getColumn() function ● PHP 7 compatibility ● @inheritDoc traversal (to inherit type hints) ● Make it faster Ideas/plans
  40. 40. ¯_(ツ)_/¯
  41. 41. github.com/ /BetterReflection Better Reflection
  42. 42. Any questions? :) https://joind.in/talk/9a5d8 James Titcumb @asgrim

×