Steve Frécinaux

Synchronisation avec PHP

NTP Time est sans doute le protocole le plus simple de l’internet. Il se résume à ceci : vous vous connectez sur le port n°13 d’un serveur, et en retour il vous donne une chaine de caractère représentant l’heure courante de ce serveur à un format donné. Rien d’autre, pas de données à envoyer, pas d’autres données à recevoir. Une simplicité extrême, surtout par rapport à HTTP, par exemple.

Quelle utilité, me direz-vous ? Sur votre machine personnelle, ça peut servir à synchroniser l’horloge interne. Mais sur un serveur web ? La réponse est que j’en avais besoin bêtement pour synchroniser deux sites, dont un sur un serveur dont l’horloge… ahem… laissait à désirer. Le concept est donc de calculer un offset entre le temps du serveur et le “vrai” temps (récupéré sur le serveur NTP), de le stocker dans un fichier de configuration, et de l’additionner systématiquement lors de chaque appel de time(). Le fichier est tout simple, de par la simplicité même du protocole :

function ntp_time($server, $port=13, $timeout=10)
{
    $time = time();
    $fp = @fsockopen($server, $port, $errno, $errstr, $timeout);
    if (!$fp) {
        $GLOBALS['err'] = $errno . ': ' . $errstr;
        return false;
    }
  
    $str = '';
    while (!feof($fp) && time() < $time + $timeout)
    {
        $str .= fgets($fp, 1024);
    }
    fclose($fp);

    if ($str != '') {
        return strtotime($str);
    } else {
        $GLOBALS['err'] = 'Socket timeout';
        return false;
    }
}

Je crois que le code se passe de commentaires. On se contente de se connecter au serveur, de récupérer ce qu’il nous retourne, et de le transformer en timestamp. Pour l’usage, très simple également :

if (($time_ntp = ntp_time($server, 13, 15)) == false) {
    echo $err;
    exit();
} else {
    $offset = time() - $time_ntp;
}