Was recently brave (or foolhardy) enough to attempt to present how functional programming constructs could be used even in a language such as PHP. Now I am fully aware that one of the bigger reasons for functional programming ie. concurrency is simply not applicable as yet for a language like PHP, but I thought it might still be useful to reduce global variable proliferation, and improve both composability and testability.
The following sample PHP code was what I presented. The associated Twig template is not shown since it is not particularly relevant to the context. Note that the following is simply a sample code – any attempts to use it are at your own risk – I am simply not a good enough PHP programmer to even know if the code is good or has many smells that are entirely invisible (or unodorous) to me.
The code simply retrieves data from a table, filters it and shows it on screen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | <?php require_once 'Twig/Autoloader.php'; Twig_Autoloader::register(); ##### Global constants ##### $base='\/funcblog'; function initialise() { ##### Environment ##### $loader = new Twig_Loader_Filesystem('templates'); $twig = new Twig_Environment($loader, array( 'debug' => true, 'cache' => 'cache', )); #### Database initialisation ##### $link = mysql_connect('localhost', 'funcblog', 'funcblog') or die('Could not connect: ' . mysql_error()); mysql_select_db('funcblog',$link); return array('twig' => $twig, 'link' => $link); } ##### Application configuration ##### $routes = array( array(path=>'posts',handler=>'get_posts'), array(path=>'categories',handler => 'get_categories') ); // Initialise the route map based on the routes configuration $route_map = array_reduce( $routes, function ($x,$y) { $x[$y['path']] = $y['handler']; return $x;}, array()); ##### Functions ##### // Extract path and request components from URI function compose_request($request_uri,$base) { preg_match_all('/('. $base . ')(?P<path>(\/\w+)+)(\?(?P<query>(\w+=[^\&]+\&?)*))?/', $request_uri, $words, PREG_SET_ORDER); return array($words[0]['path'], $words[0]['query']); } // process the uri based on path and query options function process_uri($context, $route_map, $path,$query) { $handler_name = $route_map[ltrim($path,'/')]; return $handler_name($context, $query); } // Display the template with the associated data function display_template($context,$template,$data) { $context['twig']->loadTemplate($template)->display($data); } $context = initialise(); // Closure to extract rows from table $context['get_rows'] = function ($query) use($context) { $result = mysql_query($query,$context['link']); $rows = array(); while ($row = mysql_fetch_assoc($result)) { $rows[] = $row; } return $rows; }; // From the request URI, extract the path and the query parameters list($path, $query) = compose_request($_SERVER['REQUEST_URI'],$base); // Dispatch to the appropriate function based on the uri to routes mapping list($template, $data) = process_uri($context, $route_map,$path,$query); // Display the template display_template($context,$template,$data); ##### Custom Application Logic ##### function get_posts($context,$query) { # NOTE : An Array filter function, filters a collection using a # filter function. It returns a subset of that collection # for which the filter function (predicate) evaluates to true $posts = array_filter( $context['get_rows']('select * from posts'), function($row) { return ($row['author'] == 'dhananjay') ; } ); return array('posts.html', array('rows'=> $posts)); } ?> |

