<?php
// Fonction permettant d'invoquer un service distant.
function sendRequest($url, $auth, $serviceName, $arguments = array())
{
   // On accepte des URL en http ou https
   assert('preg_match(\'`^https?://`i\', $url)');
   // La clef d'authentification doit être une chaîne
   assert('is_string($auth)');
   // Le nom du service ne doit pas contenir autre chose que des lettres,
   // chiffres, ":" et "_"
   assert('preg_match("`^[\w:]+$`", $serviceName)');
   // Les arguments doivent être placés dans un tableau.
   assert('is_array($arguments)');
   // On construit une chaîne contenant les paramêtres d'appel.
   $data = 'auth=' . $auth;
   $data .= '&serviceName=' . $serviceName;
   // Après la linéarisation, il faut encoder le résultat pour placer ça en
   // paramètres d'une URL
   $data .= '&args=' . urlencode(serialize($arguments));
   // On appelle le service distant en masquant les erreurs de chargement
   $content = @file_get_contents($url . '?' . $data);

   if (false === $content) {
      // Si le contenu retourné contient "false" cela indique un problème de
      // connexion au serveur
      throw new Exception('Problème d\'accès au serveur distant');
   } else {
      // On délinéarise le contenu retourné
      $result = unserialize($content);
      if (false === $result) {
         // Problème de délinéarisation du résultat (ou résultat contenant
         // "false"). Cela arrive quand le script distant affiche une erreur.
         throw new Exception('Problème de délinéarisation du résultat');
      } elseif (! is_array($result) or
            !(
               array_key_exists('exception', $result) or
               array_key_exists('return', $result)
               )) {
         // Si le contenu n'est pas un tableau, ou qu'il n'y a ni exception ni
         // résultat, cela indique que le résultat linéarisé n'est pas
         // conforme aux attentes (tableau contenant "exception" et "return")
         throw new Exception('Résultat retourné non conforme');
      }
   }

   if (! empty($result['exception'])) {
      // Il y a une exception, alors on la lève
      throw new Exception($result['exception']);
   } else {
      // On retourne le résultat s'il n'y a pas d'exception.
      return $result['return'];
   }
}

?>
