37.2. Working with Zend_TimeSync

Zend_TimeSync can return the actual time from any given NTP or SNTP timeserver. It can automatically handle multiple servers and provides a simple interface.

[Замечание] Замечание

In all examples within this chapter we are using one of the available public generic timeservers. In our case 0.europe.pool.ntp.org. For your environment it is recommended that you are using a public generic timeserver which is nearly to the location of your server. See http://www.pool.ntp.org for details.

37.2.1. Generic timeserver request

Requesting the time from a timeserver is quite simple. All you have to give is the timeserver from which you want to have the time.

<?php
require_once 'Zend/TimeSync.php';

$server = new Zend_TimeSync('0.pool.ntp.org');

print $server->getDate()->getIso();
        

So what is happening in the background of Zend_TimeSync? First the syntax of the given server is checked. So in our example '0.pool.ntp.org' is checked and recognised as possible correct adress for a timeserver. Then when calling getDate() the actual set timeserver is requested and it will return it's own time. Zend_TimeSync then calculates the difference to the actual time of the server running the script and returns a Zend_Date objekt with the actual, corrected time.

For details about Zend_Date and it's methods you can refer to Zend_Date.

37.2.2. Multiple timeservers

Not all timeservers are always available and will return their time. Servers will have a time where they can not be reached, for example when having a maintenance. In such cases, when the time can not be requested from the timeserver, you would get an exception.

As simple solution Zend_TimeSync can handle multiple timeservers and supports a automatic fallback machanism. There are two supported ways. You can either give an array of timeservers when creating the instance. Or you can add additionally timeservers afterwards with the addServer() method.

<?php
require_once 'Zend/TimeSync.php';

$server = new Zend_TimeSync(array('0.pool.ntp.org',
                                  '1.pool.ntp.org',
                                  '2.pool.ntp.org'));
$server->addServer('3.pool.ntp.org');

print $server->getDate()->getIso();
        

There is no limitation in the ammount of timeservers you can add. When a timeserver is can not be reached Zend_TimeSync will fallback and try to connect to the next given timeserver.

When you give more than one timeserver, which should be your default behaviour, you should name your servers. You can either name your servers with the array key, but also with the second parameter at initiation or addition of an other timeserver.

<?php
require_once 'Zend/TimeSync.php';

$server = new Zend_TimeSync(array('generic'  => '0.pool.ntp.org',
                                  'fallback' => '1.pool.ntp.org',
                                  'reserve'  => '2.pool.ntp.org'));
$server->addServer('3.pool.ntp.org', 'additional');

print $server->getDate()->getIso();
        

Naming the timeservers gives you the ability to request a specific timeserver as we will see later in this chapter.

37.2.3. Protocols of timeservers

There are different types of timeservers. The most public timeservers are using NTP as protocol. But there are different other protocols available.

You can set the proper protocol within the address of the timeserver. Actual there are two protocols which are supported by Zend_TimeSync. The default protocol ist NTP. If you are only using NTP you can ommit the protocol within the address as show in the previous examples.

<?php
require_once 'Zend/TimeSync.php';

$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org',
                                  'reserve'  => 'ntp:\\2.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

print $server->getDate()->getIso();
        

Zend_TimeSync is able to handle mixed timeservers. So you are not restricted to only one protocol, but you can add any server independently from it's protocol.

37.2.4. Using ports for timeservers

As every protocol within the world wide web, the NTP and NTP protocols are using standard ports. For both protocols this is the port 123.

But sometimes the used port differ from the standard one. You can define the port which has to be used for each server within the address. Just add the number of the port behind the address. If no port is defined, then Zend_TimeSync will use the standard port.

<?php
require_once 'Zend/TimeSync.php';

$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org:200',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com:399', 'additional');

print $server->getDate()->getIso();
        

37.2.5. Options for timeservers

Actually there is only one option within Zend_TimeSync which will be used internally. But you can set any self defined option you are in need for and request it.

The option timeout defines the number of seconds after which a connection is detected as broken when there was no response. The default value is 1, which means that Zend_TimeSync will fallback to the next timeserver is the actual requested timeserver does not respond in one second.

With the setOptions() method, you can set any option. If accepts an array where the key is the option to set and the value is the value of that option. Any previous set option will be overwritten by the new value. If you want to know which options are set, use the getOptions() method. It accepts either a key which returns the given option if set or, if no key is set, it will return all set options.

<?php
require_once 'Zend/TimeSync.php';

Zend_TimeSync::setOptions(array('timeout' => 3, 'myoption' => 'timesync'));
$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

print $server->getDate()->getIso();
print_r(Zend_TimeSync::getOptions();
print "Timeout = " . Zend_TimeSync::getOptions('timeout');
        

As you can see the options for Zend_TimeSync are static, which means that each instance of Zend_TimeSync will act with the same options.

37.2.6. Using different timeservers

The default behaviour for requesting a time is to request it from the first given server. But sometimes it is useful to set a different timeserver from which to request the time. This can be done with the setServer() method. To define the used timeserver just set the alias as parameter within the method. And to get the actual used timeserver just call the getServer() method. It accepts an alias as parameter which defined the timeserver to be returned. If no parameter is given, the current timeserver will be returned.

<?php
require_once 'Zend/TimeSync.php';

$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

$actual = $server->getServer();
$server = $server->setServer('additional');
        

37.2.7. Informations from timeservers

Timeservers offer not only the time itself but also additionally informations. You can get these informations with the getInfo() method.

<?php
require_once 'Zend/TimeSync.php';

$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));

print_r ($server->getInfo());
        

The returned informations differ with the used protocols and they can also differ with the used servers.

37.2.8. Taking care of exceptions

Exceptions are collected for all timeserver and will be returned as array. So you are able to iterate through all throwed exceptions like shown in the following example:

<?php
$serverlist = array(
        // invalid servers
        'invalid_a'  => 'ntp://a.foo.bar.org',
        'invalid_b'  => 'sntp://b.foo.bar.org',
);

$server = new Zend_TimeSync($serverlist);

try {
    $result = $server->getDate();
    echo $result->getIso();
} catch (Zend_TimeSync_Exception $e) {

    $exceptions = $e->get();

    foreach ($exceptions as $key => $myException) {
        echo $myException->getMessage();
        echo '<br />';
    }
}
        
    Поддержать сайт на родительском проекте КГБ