Successfully reported this slideshow.
Your SlideShare is downloading. ×

Mirror, mirror on the wall (Nomad PHP US 2015)

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 46 Ad

Mirror, mirror on the wall (Nomad PHP US 2015)

Download to read offline

Have you ever used PHP’s built in reflection, only to find you can’t do quite what you wanted? What about finding types for parameters or properties? What about reflecting on classes that aren’t loaded, so that you can modify them directly? 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.

Have you ever used PHP’s built in reflection, only to find you can’t do quite what you wanted? What about finding types for parameters or properties? What about reflecting on classes that aren’t loaded, so that you can modify them directly? 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.

Advertisement
Advertisement

More Related Content

Viewers also liked (20)

More from James Titcumb (20)

Advertisement

Recently uploaded (20)

Mirror, mirror on the wall (Nomad PHP US 2015)

  1. 1. Mirror, Mirror on the Wall James Titcumb NomadPHP December 2015
  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. (don’t try this at home kids!) Some voodoo...
  29. 29. class MyClass { public function foo() { return 5; } }
  30. 30. // Create the reflection first // ***BEFORE*** class is loaded $classInfo = ReflectionClass::createFromName('MyClass');
  31. 31. // Override the body...! $methodInfo = $classInfo->getMethod('foo'); $methodInfo->setBody(function () { return 4; });
  32. 32. // 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);
  33. 33. // Now create an instance, and call the function... $c = new MyClass(); var_dump($c->foo()); // will be 4!!!
  34. 34. What’s in it for me?
  35. 35. The future...
  36. 36. ● DONE Currently: rewriting the internals ○ SourceLocators “might” return some code ?! ● DONE Returning AST/Code for method/fn Ideas/plans - DONE
  37. 37. ● 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
  38. 38. ● Adding a getColumn() function ● PHP 7 compatibility ● @inheritDoc traversal (to inherit type hints) ● Make it faster Ideas/plans
  39. 39. ¯_(ツ)_/¯
  40. 40. github.com/ /BetterReflection Better Reflection
  41. 41. Any questions? :) https://joind.in/16523 James Titcumb @asgrim

×