<html>
<! DynamicFunctionCall.php                                    >
<! Chapter 7, Oracle Database XE PHP Web Programming          >
<! by Michael McLaughlin                                      >
<!                                                            >
<! This demonstrates defining an anonymous function by        >
<! passing a name as an actual parameter to the user_sort()   >
<! local function. The string literal than maps at runtime    >
<! to a target function, either bubble_sort() or              >
<! cocktail_sort() functions.                                 >
<head>
<title>
  Chapter 7 : DynamicFunctionCall.php
</title>
</head>
<body>
<?php
  // Declare sample arrays.
  $array1 = array(7,3,2,1,6,5,4);
  $array2 = array(3,7,2,6,5,4,8);

  // Choose a bubble sort.
  user_sort('bubble_sort',$array1);

  // Choose a cocktail sort.
  user_sort('cocktail_sort',$array2);

  // Print the bubble sort results.
  print "[".print_r($array1,true)."]<br>";

  // Print the cocktail sort results.
  print "[".print_r($array2,true)."]<br>";

  // Performs a function by reference.
  function user_sort($function,&$array)
  {
    // Build function statement at runtime.
     $function($array);
  }

  // Performs a classic bubble sort passing array by reference.
  function bubble_sort(&$array)
  {
    // Read contents with one index.
    for ($i = 0;$i < count($array);$i++)
    {
      // Read contents with another index.
      for ($j = 0;$j < count($array);$j++)
      {
        // Check outer less than inner or switch by reference.
        if ($array[$i] < $array[$j])
          swap($array[$i],$array[$j]);
      }
    }
  }

  // Performs a classic cocktail sort passing array by reference.
  function cocktail_sort(&$array)
  {
    // Declare logical control variable.
    $done = false;

    // Declare boundary variables.
    $left = 0;
    $right = count($array);

    do
    {
      // Set exit criteria.
      $done = true;

      // Decrement right boundary to avoid index overrun.
      --$right;

      // Read from left to right boundary.
      for ($i = $left;$i < $right;$i++)
      {
        // Check current greater than next and switch by reference.
        if ($array[$i] > $array[$i+1])
          swap($array[$i],$array[$i+1]);
          $done = false;
      }

      // Read from right to left boundary.
      for ($i = $right;$i > $left;$i--)
      {
        // Check current less than next and switch by reference.
        if ($array[$i] < $array[$i-1])
          swap($array[$i],$array[$i-1]);
          $done = false;
      }

      // Increment left boundary.
      $left++;

    } while (!$done);
  }

  // Swap two variables by reference.
  function swap(&$a,&$b)
  {
    $c = $a;
    $a = $b;
    $b = $c;
  }
?>
</body>
</html>
