School of PHP Magic

School of PHP Magic

"The closer you are, the less you see"

How often do you think you know a lot about PHP magic? And what if I tell you that you just did not look carefully? After all, the more you think that you know everything, the easier it is to deceive you. Look carefully, because the closer you are, the less you see.

The school of PHP magic opens its doors. Let's run beyond the established boundaries of OOP rules and make the impossible possible. And who knows, maybe you will love this magic: magic methods, non-standard ways of accessing properties, changing contexts, aspect-oriented programming, streaming filters, and more.

E7af3ef8e48a800cd2eedae073104c1a?s=128

Alexander Lisachenko

May 17, 2019
Tweet

Transcript

  1. School of PHP Magic Alexander Lisachenko

  2. ‣ Head of Web Development at Alpari (RU) Forex Broker

    ‣ Have worked with computers since 7 years old ‣ Clean code advocate, guru in enterprise architecture ‣ Author of the aspect-oriented framework Go! AOP 
 http://go.aopphp.com About me: 2 lisachenko lisachenko
  3. Moscow PHP User Group 3

  4. Moscow PHP User Group 3

  5. 4 «The closer you think you are, the less you'll

    actually see.»
  6. The Trick 5

  7. The Trick 5

  8. The Trick 6 …an action that is intended to deceive,

    either as a way of cheating someone, or as a joke or form of entertainment
  9. 7 One of the trickiest programming language.

  10. 8 Magic equipment

  11. 9 Magic equipment

  12. 9 Magic equipment __construct(), __destruct(), __clone(),

  13. 9 Magic equipment __construct(), __destruct(), __clone(), __call(), __callStatic(),

  14. 9 Magic equipment __construct(), __destruct(), __clone(), __call(), __callStatic(), __get(), __set(),

    __isset(), __unset(),
  15. 9 Magic equipment __construct(), __destruct(), __clone(), __call(), __callStatic(), __get(), __set(),

    __isset(), __unset(), __sleep(), __wakeup(),
  16. 9 Magic equipment __construct(), __destruct(), __clone(), __call(), __callStatic(), __get(), __set(),

    __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(),
  17. 9 Magic equipment __construct(), __destruct(), __clone(), __call(), __callStatic(), __get(), __set(),

    __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __debugInfo()
  18. 10 Magic equipment

  19. 10 Magic equipment declare(ticks=1)

  20. 10 Magic equipment declare(ticks=1) debug_backtrace()

  21. 10 Magic equipment declare(ticks=1) debug_backtrace() unset(), isset()

  22. 10 Magic equipment declare(ticks=1) debug_backtrace() unset(), isset() by-reference passing

  23. 10 Magic equipment declare(ticks=1) debug_backtrace() unset(), isset() by-reference passing bound

    closures
  24. 10 Magic equipment declare(ticks=1) debug_backtrace() unset(), isset() by-reference passing bound

    closures Reflection API
  25. 10 Magic equipment declare(ticks=1) debug_backtrace() unset(), isset() by-reference passing bound

    closures Reflection API StreamWrapper API
  26. 11 So, let’s start our magic!

  27. 11

  28. 12 Rule #1 of magic…

  29. 12 Rule #1 of magic…

  30. 12

  31. 13 …always be the smartest guy in the room.

  32. 13 …always be the smartest guy in the room.

  33. 13

  34. 14 Trick #1: Impossible comparison

  35. 14 Trick #1: Impossible comparison

  36. 14 Trick #1: Impossible comparison

  37. 15 Trick #1.1: Not-a-number

  38. 15 Trick #1.1: Not-a-number

  39. 16 Trick #1.2: Constant redefinition

  40. 16 Trick #1.2: Constant redefinition

  41. 17 Trick #1.3: Tick handler

  42. 17 Trick #1.3: Tick handler

  43. 18 Trick #2.1: Magic expressions

  44. 18 Trick #2.1: Magic expressions

  45. 18 Trick #2.1: Magic expressions

  46. 19 True?

  47. 20 False?

  48. 21

  49. 22 Trick #2.1: Operator precedence

  50. 22 Trick #2.1: Operator precedence Top priority

  51. 23 Trick #2.2: Magic expressions

  52. 23 Trick #2.2: Magic expressions

  53. 23 Trick #2.2: Magic expressions

  54. 23 Trick #2.2: Magic expressions

  55. 24 Trick #2.2: Magic expressions

  56. 24 Trick #2.2: Magic expressions 1) $factory will be used

    as a class name for «new»
  57. 24 Trick #2.2: Magic expressions 1) $factory will be used

    as a class name for «new» 2) Parse error will be thrown
  58. 24 Trick #2.2: Magic expressions 1) $factory will be used

    as a class name for «new» 2) Parse error will be thrown 3) Result of method $factory->build() will be used
  59. 24 Trick #2.2: Magic expressions 1) $factory will be used

    as a class name for «new» 2) Parse error will be thrown 3) Result of method $factory->build() will be used 4) Value of property $factory->build will be used
  60. 25 Trick #2.2: Magic expressions

  61. 25 Trick #2.2: Magic expressions

  62. 26 Trick #2.2: Operator precedence

  63. 26 Trick #2.2: Operator precedence

  64. 27 Trick #2.3: Magic expressions

  65. 27 Trick #2.3: Magic expressions

  66. 27 Trick #2.3: Magic expressions

  67. 28 Trick #2.3: Loophole in parser

  68. 29

  69. 29 What is magic?

  70. 29 What is magic? Focused deception.

  71. 29 What is magic? Focused deception. But deception meant to

    entertain.
  72. 29 What is magic? Focused deception. But deception meant to

    entertain. Try to remember next one card…
  73. 29

  74. 30

  75. 30

  76. 31 I am bad magician :) But let me try…

  77. 31 I am bad magician :) But let me try…

  78. 32 Trick #3: Breaking the rules

  79. 32 Trick #3: Breaking the rules

  80. 32 Trick #3: Breaking the rules

  81. 33

  82. 33 Who knows how to do this?

  83. 33 Who knows how to do this? Who knows two

    solutions?
  84. 33 Who knows how to do this? Who knows two

    solutions? Who knows three solutions?
  85. 33 Who knows how to do this? Who knows two

    solutions? Who knows three solutions? Who knows more than three?
  86. 34 Trick #3.1: Reflection way

  87. 34 Trick #3.1: Reflection way

  88. Trick #3.2: Bound closure 35

  89. Trick #3.2: Bound closure 35

  90. Trick #3.2: Bound closure 35

  91. Trick #3.3: Unserialisation trick 36

  92. Trick #3.3: Unserialisation trick 36

  93. Trick #3.3: Unserialisation trick 36

  94. Trick #3.3: Unserialisation trick 36

  95. Trick #3.4: Can you find it? 37

  96. Trick #3: doctrine/instantiator package 38 composer show doctrine/instantiator --all name

    : doctrine/instantiator descrip. : A small, lightweight utility to instantiate objects in PHP without invoking their constructors keywords : constructor, instantiate type : library license : MIT License (MIT)
  97. Trick #4: Intercepting property access 39

  98. Trick #4: Intercepting property access 39

  99. Trick #4: Intercepting property access 39

  100. Trick #4: Intercepting property access 39

  101. Trick #4.1: Add magic… getter! 40

  102. Trick #4.1: Add magic… getter! 40

  103. Trick #4.2: Use previous trick! 41

  104. Trick #4.2: Use previous trick! 41

  105. Trick #4.3: Unset this private field 42

  106. Trick #4.3: Unset this private field 42

  107. Trick #4.4: Call private constructor 43

  108. Trick #4.4: Call private constructor 43

  109. Trick #4: Result 44

  110. Trick #4: leedavis/altr-ego package 45 composer show leedavis81/altr-ego --all name

    : leedavis81/altr-ego descrip. : Access an objects protected / private properties and methods keywords : php, break scope versions : dev-master, v1.0.2, v1.0.1, v1.0.0 type : library license : MIT License (MIT)
  111. Trick #5: Immutable objects in PHP? 46

  112. Trick #5: Immutable objects in PHP? 46

  113. Trick #5: Immutable objects in PHP? 46

  114. 47 True?

  115. 48 False?

  116. 49 Trick #5.1: Immutable object in PHP

  117. 50 Trick #5.1: Immutable object in PHP

  118. 50 Trick #5.1: Immutable object in PHP Unfortunately, you can’t

    even read it!
  119. 51 Trick #5.2: Immutable object in PHP

  120. 51 Trick #5.2: Immutable object in PHP

  121. 52

  122. 52 What if we use previous tricks?

  123. 52 What if we use previous tricks? Intercept properties.

  124. 52 What if we use previous tricks? Intercept properties. Securely

    store values of properties.
  125. 52 What if we use previous tricks? Intercept properties. Securely

    store values of properties. Provide read-only API.
  126. 52 What if we use previous tricks? Intercept properties. Securely

    store values of properties. Provide read-only API.
  127. 52 What if we use previous tricks? Intercept properties. Securely

    store values of properties. Provide read-only API.
  128. 52 What if we use previous tricks? Intercept properties. Securely

    store values of properties. Provide read-only API.
  129. 53

  130. 53 Secure place for values:

  131. 53 Secure place for values: Global variables

  132. 53 Secure place for values: Global variables Public properties

  133. 53 Secure place for values: Global variables Public properties Protected

    properties
  134. 53 Secure place for values: Global variables Public properties Protected

    properties Private properties
  135. 53 Secure place for values: Global variables Public properties Protected

    properties Private properties Private static properties
  136. 53 Secure place for values: Global variables Public properties Protected

    properties Private properties Private static properties Static variables in functions
  137. 53 Secure place for values: Global variables Public properties Protected

    properties Private properties Private static properties Static variables in functions
  138. 54 Trick #5.2: Secure value storage

  139. 54 Trick #5.2: Secure value storage

  140. 55 Trick #5.2: Use it by-reference

  141. 55 Trick #5.2: Use it by-reference

  142. 56 Trick #5.2: Set state implementation

  143. 56 Trick #5.2: Set state implementation

  144. Trick #5.2: Applying object state 57

  145. Trick #5.2: Get state implementation 58

  146. Trick #5.2: Get state implementation

  147. Trick #5.2: And a little bit magic :) 60

  148. Trick #5.2: And a little bit magic :) 60

  149. Trick #5: lisachenko/immutable-object 61 composer show lisachenko/immutable-object --all name :

    lisachenko/immutable-object descrip. : Immutable object library keywords : versions : * dev-master type : library license : MIT License (MIT)
  150. Trick #5: Usage example 62

  151. Trick #5: Usage example 63

  152. Trick #5: Try to change it… 64

  153. Trick #5: Try to change it… 64

  154. Trick #5: Try to change it… 65

  155. Trick #5: Try to change it… 65 Maybe you can

    hack it?
  156. Trick #6: It contains anti-XDebug code! 66

  157. Trick #7: Stream processing

  158. Trick #7: Stream processing

  159. Trick #7: Stream processing

  160. Trick #7: Stream processing

  161. Trick #7: Stream processing

  162. Trick #7: Stream processing

  163. Trick #8: Aspect-oriented programming

  164. Trick #8: Aspect-oriented programming

  165. Is this code good or bad? 72

  166. Is this code good or bad? 72

  167. Is this code good or bad? 72

  168. Is this code good or bad? 72

  169. Same code without secondary concerns 73

  170. Same code without secondary concerns 73

  171. Authorization control… 74

  172. Authorization control… 74

  173. Logging and audit… 75

  174. Logging and audit… 75

  175. Error handling… 76

  176. Error handling… 76

  177. 77

  178. 77

  179. Aspect glossary 78

  180. Aspect glossary 78

  181. Aspect glossary Pointcut - describes list of interesting events 78

  182. Aspect glossary Pointcut - describes list of interesting events 78

    Joinpoint - defines an event object
  183. Aspect glossary Pointcut - describes list of interesting events Advice

    - event handler 78 Joinpoint - defines an event object
  184. Aspect VS Event Listener 79

  185. Aspect VS Event Listener 79

  186. Aspect VS Event Listener 79

  187. Aspect VS Event Listener 79

  188. 80 All aspects (or advisors) are registered in the aspect

    kernel
  189. 80 All aspects (or advisors) are registered in the aspect

    kernel
  190. 81 The special php://filter stream filter is registered via stream_filter_register()

  191. 82 The composer class loader is replaced with a weaving

    proxy
  192. 83 Lexical analysis and parsing of source code into the

    AST is performed (nikic/PHP-Parser)
  193. 84 Static reflection is created from the AST (goaop/parser-reflection)

  194. 84 Static reflection is created from the AST (goaop/parser-reflection)

  195. 84 Static reflection is created from the AST (goaop/parser-reflection)

  196. 84 Static reflection is created from the AST (goaop/parser-reflection)

  197. 85 The original class is renamed and replaced with a

    new class with additional behavior; stored in the cache
  198. 85 The original class is renamed and replaced with a

    new class with additional behavior; stored in the cache
  199. 85 The original class is renamed and replaced with a

    new class with additional behavior; stored in the cache Same class name!
  200. 85 The original class is renamed and replaced with a

    new class with additional behavior; stored in the cache Original class renamed Same class name!
  201. 85 The original class is renamed and replaced with a

    new class with additional behavior; stored in the cache Original class renamed Overridden method Same class name!
  202. 86 What to expect in future:

  203. 86 What to expect in future: Opcache preloading for AOP

    core
  204. 86 What to expect in future: Opcache preloading for AOP

    core FFI integration to modify binary opcodes
  205. 86 What to expect in future: Opcache preloading for AOP

    core FFI integration to modify binary opcodes Modifying PHP engine internal callbacks
  206. 86 What to expect in future: Opcache preloading for AOP

    core FFI integration to modify binary opcodes Modifying PHP engine internal callbacks Some more magic?
  207. Trick #8: goaop/framework 87 composer show goaop/framework --all name :

    goaop/framework descrip. : Framework for aspect-oriented programming in PHP. keywords : php, aop, library, aspect versions : dev-master, 3.0.x-dev, 2.x-dev, 2.3.1, … type : library license : MIT License
  208. If it is too magic for you, just use PhpStorm

    plugin for that! 88
  209. If it is too magic for you, just use PhpStorm

    plugin for that! 88
  210. Pointcut syntax highlighting, completion and analysis 89

  211. Pointcut syntax highlighting, completion and analysis 89

  212. Navigate to advice/advised elements 90

  213. Navigate to advice/advised elements 90

  214. Текст Trick #9: Deferred methods

  215. 92 Trick: prevent execution of methods wrapping them into promises

    and run after the fastcgi_finish_request.
  216. Trick 9.1. Define an annotation 93

  217. Trick 9.2. Define an aspect 94

  218. Trick 9.2. Define an aspect 94

  219. Trick 9.2. Define an aspect 94 All methods with «Async»

    annotation
  220. Trick 9.2. Define an aspect 94 Record each call with

    arguments
  221. Trick 9.2. Define an aspect 94 Prevent execution of original

    method
  222. Trick 9.2. Define an aspect 94 Return «our» value

  223. Trick 9.2. Define an aspect 95

  224. Trick 9.2. Define an aspect 95

  225. Trick 9.2. Define an aspect 95

  226. Trick 9.2. Define an aspect 95

  227. Trick 9.2. Define an aspect 95 Finish FASTCGI Request

  228. Trick 9.2. Define an aspect 95 Execute delayed methods

  229. Trick 9.3. Let’s use services 96

  230. Trick 9.3. Let’s use services 96 Some long service call

  231. Trick 9.3. Let’s use services 96

  232. Trick 9.4. Declare deferred 97

  233. Trick 9.4. Declare deferred 97 Now it will be deferred

  234. Trick 9.4. Declare deferred 97

  235. 98 The End

  236. 98 The End

  237. Thank you! Please, leave your feedback! 99 https://joind.in/event/php-russia-2019/school-of-php-magic---php