ObserverTutorial/WebService

Version 4 (modified by jean-gui, 3 years ago)

--

The calculator Web Service

An observer of unicorn is simply a web service outputting results in a Unicorn-compatible format. In this first part of the tutorial, we're going to create a calculator web service following the specifications described in the introduction.

The service will be implemented in PHP as this language is fairly easy to read.

caculator.php

<?php 
if(array_key_exists('uri', $_GET)) {
    // File containing expressions to evaluate
    $resource = fopen($_GET['uri'], 'r');
    
    if($resource) {
        // Line count to track error lines
        $line = 0;
        
        // List of errors found in $resource
        $errors = array();
        // Results 
        $results = array();
        
        // for each line
        while(!feof($resource)) {
            $op = trim(fgets($resource));
            $line++;
            if($op !== '') {
                // Quick sanity-check to only allow integers, operators and parentheses
                if(preg_match('/^[0-9*-+()\/]+$/', $op)) {
                    ob_start();
                    // evaluate the expression, using eval is not nice and can be dangerous
                    // but earlier sanity-check should prevent misuses
                    $result = eval('return ' . $op . ';');
                    // get the error message if something went wrong
                    $out = trim(ob_get_contents());
                    ob_end_clean();
                    if($out !== '') {
                        // an error occurred
                        $errors[$line] = array($op, $out);
                    }
                    else {
                        if($_GET['x2']) {
                            // Multiply by two
                            $result *= 2;
                        }
                        $results[$line] = array($op, $result);
                    }
                }
                else {
                    $errors[$line] = array($op, 'Forbidden characters');
                }
            }
        }
    }
    else {
        $errors['N/A'] = array($_GET['uri'], 'Couldn\'t load URI');
    }
}
else {
    $errors['N/A'] = array('N/A', 'No URI provided');
}

/*
 * Output results using separate templates
 */
$valid_formats[] = 'html';

// Output format
$format = $_GET['output'];

if(!$format || !in_array($format, $valid_formats)) {
    $format = 'html';
}
include('calculator_' . $format . '.tpl');

?>

calculator_html.tpl

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Calculator Results for <?php echo $_GET['uri']; ?></title>
  </head>
  <body>
    <h1>Calculator Results for <?php echo $_GET['uri']; ?></h1>

    <h2>Errors</h2>
    <?php if(count($errors) > 0): ?>
      <dl>
      <?php foreach($errors as $line => $val): ?>
        <dt>Line: <?php echo $line; ?>, context: <?php echo $val[0]; ?></dt>
        <dd><?php echo $val[1]; ?>
      <?php endforeach ?>
      </dl>
    <?php endif ?>

    <h2>Results</h2>
    <?php if(count($results) > 0): ?>
      <dl>
      <?php foreach($results as $line => $val): ?>
        <dt>Line <?php echo $line; ?></dt>
        <dd><?php echo $val[0]; ?> = <?php echo $val[1]; ?></dd>
      <?php endforeach; ?>
      </dl>
    <?php endif ?>
  </body>
</html>

Explanation

Attachments