Serverless, ReactPHP, and Expanding Frontiers, May 2019

(singke) #1
38 \ May 2019 \ http://www.phparch.com

Memory Abstractions


Internal Apparatus


Call Stack
When we call one of our functions or methods in PHP,
we create a new stack frame. When programming in C, the
situation is similar—a function call causes the creation of a
new stack frame. The call stack^12 diagram—Figure 3—from
Wikipedia shows two stack frames on the stack.


The stack frame contains the parameters passed into the
function, the function’s local variables, and the return address
that gets us back to the calling function. To see why this is
important, consider the following recursive function to
calculate a triangular number^13.
The triangular number for n is the sum of the integers from
1 to n. Listing 1 shows this calculation in PHP.


The output is:


php Triangle.php
1
15



The triangular number for 1 is 1, and 1+2+3+4+5 is 15.
Our function sTriangle has no local variables other than
the passed in value of $n. If we were using the same value
every call, $n would overwrite itself every time, ultimately
producing the result 2 for every input larger than 1.
In this case, we have a recursive function calling itself. It
works the same with a larger chain where A calls B, B calls
C, and C calls A. Each call gets its stack frame, which means
each call has its separate copy of the local variables.
We’ve seen evidence of the call stack with PHP’s backtrace
functions and using Xdebug. We can modify our function as
in Listing 2 to show a backtrace.
The output is in Output 1.

12 call stack: https://en.wikipedia.org/wiki/Call_stack


13 triangular number: https://phpa.me/wikip-triangular-number


Listing 2


  1. <?php

  2. declare(strict_types=1);



  3. namespace App\Triangle;



  4. use Exception;



  5. class Backtrace

  6. {

  7. public static function sTriangle(int $n): int {

  8. if ($n <= 1) {

  9. throw new \Exception();

  10. }

  11. try {

  12. return self::sTriangle($n - 1) + $n;

  13. } catch (Exception $e) {

  14. echo $e->getTraceAsString(). PHP_EOL;

  15. return -1;

  16. }

  17. }

  18. }



  19. echo Backtrace::sTriangle( 5 ). PHP_EOL;


Figure 3. Upward-growing Stack Listing 1


  1. <?php

  2. declare(strict_types=1);



  3. namespace App\Triangle;



  4. class Triangle

  5. {

  6. public static function sTriangle(int $n): int {

  7. if ($n <= 1) {

  8. return 1 ;

  9. }

  10. return self::sTriangle($n - 1) + $n;

  11. }

  12. }



  13. echo Triangle::sTriangle( 1 ). PHP_EOL;

  14. echo Triangle::sTriangle( 5 ). PHP_EOL;


Output 1

$ php Backtrace.php
#0 Backtrace.php(14): App\Triangle\Backtrace::sTriangle(1)
#1 Backtrace.php(14): App\Triangle\Backtrace::sTriangle(2)
#2 Backtrace.php(14): App\Triangle\Backtrace::sTriangle(3)
#3 Backtrace.php(14): App\Triangle\Backtrace::sTriangle(4)
#4 Backtrace.php(22): App\Triangle\Backtrace::sTriangle(5)
#5 {main}
11
Free download pdf