mirror, mirror on the wall (phpem unconf 2015)
TRANSCRIPT
![Page 1: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/1.jpg)
Mirror, Mirror on the WallJames Titcumb
PHPem Unconference 2015
![Page 2: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/2.jpg)
James Titcumbwww.jamestitcumb.comwww.roave.comwww.phphants.co.ukwww.phpsouthcoast.co.uk@asgrim
Who is this guy?
![Page 3: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/3.jpg)
Reflection
![Page 4: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/4.jpg)
![Page 5: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/5.jpg)
© 1937 Disney’s Snow White - disneyscreencaps.com
![Page 6: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/6.jpg)
![Page 7: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/7.jpg)
● Structure● Metadata● Values● Type introspection● Modification
Reflection
![Page 8: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/8.jpg)
How does it work?
![Page 9: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/9.jpg)
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;
}
![Page 10: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/10.jpg)
Okay. What now?
![Page 11: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/11.jpg)
github.com/ /BetterReflection
Better Reflection!
![Page 12: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/12.jpg)
![Page 13: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/13.jpg)
What?
![Page 14: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/14.jpg)
Why?
![Page 15: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/15.jpg)
How?
![Page 16: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/16.jpg)
Magic of the AST
![Page 17: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/17.jpg)
source: http://goo.gl/HORwLQ
![Page 18: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/18.jpg)
WTF is AST?
![Page 19: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/19.jpg)
use PhpParser\ParserFactory;
$parser = (new ParserFactory)
->create(ParserFactory::PREFER_PHP7);
print_r($parser->parse(
file_get_contents('ast-demo-src.php')
));
![Page 20: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/20.jpg)
<?php
echo "Hello world";
![Page 21: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/21.jpg)
AST
`-- Echo statement
`-- String, value "Hello world"
![Page 22: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/22.jpg)
<?php
echo "Hello " . "world";
![Page 23: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/23.jpg)
AST
`-- Echo statement
`-- Concat
|-- Left
| `-- String, value "Hello "
`-- Right
`-- String, value "world"
![Page 24: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/24.jpg)
AST to Reflection
![Page 25: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/25.jpg)
Benefits?
![Page 26: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/26.jpg)
ReflectionProperty->getDocBlockTypes()
Types!
![Page 27: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/27.jpg)
Using Better Reflection
![Page 28: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/28.jpg)
$reflection = new ReflectionClass(
'BetterReflectionTest\Fixture\ExampleClass'
);
$this->assertSame(
'ExampleClass',
$reflection->getShortName()
);
![Page 29: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/29.jpg)
$reflection = ReflectionClass::createFromName(
'BetterReflectionTest\Fixture\ExampleClass'
);
$this->assertSame(
'ExampleClass',
$reflection->getShortName()
);
![Page 30: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/30.jpg)
// 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(),
]));
}
![Page 31: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/31.jpg)
(don’t try this at home kids!)
Some voodoo...
![Page 32: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/32.jpg)
![Page 33: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/33.jpg)
class MyClass
{
public function foo()
{
return 5;
}
}
![Page 34: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/34.jpg)
// Create the reflection first
// ***BEFORE*** class is loaded
$classInfo = ReflectionClass::createFromName('MyClass');
![Page 35: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/35.jpg)
// Override the body...!
$methodInfo = $classInfo->getMethod('foo');
$methodInfo->setBody(function () {
return 4;
});
![Page 36: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/36.jpg)
// 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);
![Page 37: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/37.jpg)
// Now create an instance, and call the function...
$c = new MyClass();
var_dump($c->foo()); // will be 4!!!
![Page 38: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/38.jpg)
![Page 39: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/39.jpg)
What’s in it for me?
![Page 40: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/40.jpg)
The future...
![Page 41: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/41.jpg)
● DONE Currently: rewriting the internals○ SourceLocators “might” return some code ?!
● DONE Returning AST/Code for method/fn
Ideas/plans - DONE
![Page 42: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/42.jpg)
● 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
![Page 43: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/43.jpg)
● Adding a getColumn() function● PHP 7 compatibility● @inheritDoc traversal (to inherit type hints)● Make it faster
Ideas/plans
![Page 44: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/44.jpg)
¯\_(ツ)_/¯
![Page 45: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/45.jpg)
github.com/ /BetterReflection
Better Reflection
![Page 46: Mirror, mirror on the wall (PHPem Unconf 2015)](https://reader033.vdocuments.site/reader033/viewer/2022052705/588a02c21a28ab0f388b6db7/html5/thumbnails/46.jpg)
Any questions? :)
https://joind.in/15485James Titcumb @asgrim