如何用PHP项目实现时间戳服务?

wen java案例 2

本文目录导读:

如何用PHP项目实现时间戳服务?

  1. 基础时间戳生成
  2. RESTful API时间戳服务
  3. 带签名验证的安全时间戳服务
  4. 分布式时间戳服务
  5. 完整的时间戳服务示例
  6. 使用NTP同步时间
  7. 使用示例

我来介绍几种在PHP项目中实现时间戳服务的方法:

基础时间戳生成

<?php
class TimestampService {
    /**
     * 获取当前时间戳
     */
    public function getCurrentTimestamp(): int {
        return time();
    }
    /**
     * 获取微秒级时间戳
     */
    public function getMicrotime(): float {
        return microtime(true);
    }
    /**
     * 生成唯一时间戳
     */
    public function generateUniqueTimestamp(): string {
        $microtime = microtime(true);
        $milliseconds = floor(($microtime - floor($microtime)) * 1000);
        return date('YmdHis') . sprintf('%03d', $milliseconds) . mt_rand(100, 999);
    }
}

RESTful API时间戳服务

<?php
class TimestampAPI {
    private $config;
    public function __construct(array $config = []) {
        $this->config = $config;
    }
    /**
     * 提供时间戳API服务
     */
    public function handleRequest(): void {
        header('Content-Type: application/json');
        header('Access-Control-Allow-Origin: *');
        $action = $_GET['action'] ?? 'current';
        switch ($action) {
            case 'current':
                $this->getCurrentTimestamp();
                break;
            case 'convert':
                $this->convertTimestamp();
                break;
            case 'verify':
                $this->verifyTimestamp();
                break;
            default:
                http_response_code(400);
                echo json_encode(['error' => 'Invalid action']);
        }
    }
    private function getCurrentTimestamp(): void {
        $response = [
            'success' => true,
            'timestamp' => time(),
            'microtime' => microtime(true),
            'datetime' => date('Y-m-d H:i:s'),
            'timezone' => date_default_timezone_get()
        ];
        echo json_encode($response);
    }
    private function convertTimestamp(): void {
        $timestamp = $_GET['timestamp'] ?? null;
        if (!$timestamp || !is_numeric($timestamp)) {
            http_response_code(400);
            echo json_encode(['error' => 'Invalid timestamp']);
            return;
        }
        $format = $_GET['format'] ?? 'Y-m-d H:i:s';
        $response = [
            'success' => true,
            'original' => $timestamp,
            'converted' => date($format, $timestamp),
            'format' => $format
        ];
        echo json_encode($response);
    }
    private function verifyTimestamp(): void {
        $timestamp = $_GET['timestamp'] ?? null;
        $input = $_GET['input'] ?? null;
        if (!$timestamp || !$input) {
            http_response_code(400);
            echo json_encode(['error' => 'Missing parameters']);
            return;
        }
        // 验证时间戳是否在合理范围内
        $isValid = $this->isValidTimestamp((int)$timestamp);
        $response = [
            'success' => true,
            'timestamp' => $timestamp,
            'valid' => $isValid,
            'message' => $isValid ? 'Valid timestamp' : 'Invalid timestamp'
        ];
        echo json_encode($response);
    }
    private function isValidTimestamp(int $timestamp): bool {
        $minTime = strtotime('1970-01-01');
        $maxTime = strtotime('2038-01-19');
        return ($timestamp >= $minTime && $timestamp <= $maxTime);
    }
}

带签名验证的安全时间戳服务

<?php
class SecureTimestampService {
    private $secretKey;
    private $tokenExpiry = 300; // 5分钟
    public function __construct(string $secretKey) {
        $this->secretKey = $secretKey;
    }
    /**
     * 生成带签名的时间戳
     */
    public function generateSignedTimestamp(): array {
        $timestamp = time();
        $nonce = bin2hex(random_bytes(16));
        $signature = $this->generateSignature($timestamp, $nonce);
        return [
            'timestamp' => $timestamp,
            'nonce' => $nonce,
            'signature' => $signature,
            'expires_at' => $timestamp + $this->tokenExpiry
        ];
    }
    /**
     * 验证时间戳签名
     */
    public function verifySignedTimestamp(array $data): bool {
        // 检查是否过期
        if (($data['timestamp'] + $this->tokenExpiry) < time()) {
            return false;
        }
        // 重新计算签名
        $expectedSignature = $this->generateSignature(
            $data['timestamp'], 
            $data['nonce']
        );
        // 使用hash_equals防止时序攻击
        return hash_equals($expectedSignature, $data['signature']);
    }
    private function generateSignature(int $timestamp, string $nonce): string {
        return hash_hmac(
            'sha256',
            $timestamp . $nonce,
            $this->secretKey
        );
    }
}

分布式时间戳服务

<?php
class DistributedTimestampService {
    private $redis;
    private $lastTimestamp = 0;
    private $sequence = 0;
    private $datacenterId;
    private $workerId;
    public function __construct($redis, int $datacenterId = 1, int $workerId = 1) {
        $this->redis = $redis;
        $this->datacenterId = $datacenterId;
        $this->workerId = $workerId;
    }
    /**
     * 生成分布式唯一ID(类似雪花算法)
     */
    public function generateDistributedId(): int {
        $timestamp = $this->getMillisecond();
        // 生成序列号
        if ($timestamp === $this->lastTimestamp) {
            $this->sequence = ($this->sequence + 1) & 0xFFF;
            if ($this->sequence === 0) {
                // 等待下一毫秒
                while ($timestamp <= $this->lastTimestamp) {
                    $timestamp = $this->getMillisecond();
                }
            }
        } else {
            $this->sequence = 0;
        }
        $this->lastTimestamp = $timestamp;
        // 组装ID
        $id = (($timestamp - 1609459200000) << 22) // 自定义epoch
            | ($this->datacenterId << 17)
            | ($this->workerId << 12)
            | $this->sequence;
        return $id;
    }
    private function getMillisecond(): int {
        $microtime = microtime(true);
        return (int)($microtime * 1000);
    }
}

完整的时间戳服务示例

<?php
// index.php - 时间戳服务入口
require_once 'TimestampService.php';
class TimestampServer {
    private $timestampService;
    private $secureService;
    private $distributedService;
    public function __construct() {
        $this->timestampService = new TimestampService();
        $this->secureService = new SecureTimestampService('your-secret-key');
        // $this->distributedService = new DistributedTimestampService($redis);
    }
    public function run(): void {
        $method = $_SERVER['REQUEST_METHOD'];
        $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        switch ($path) {
            case '/api/timestamp':
                $this->handleTimestampRequest($method);
                break;
            case '/api/timestamp/secure':
                $this->handleSecureRequest($method);
                break;
            case '/api/timestamp/verify':
                $this->handleVerificationRequest($method);
                break;
            default:
                http_response_code(404);
                echo json_encode(['error' => 'Not found']);
        }
    }
    private function handleTimestampRequest(string $method): void {
        if ($method !== 'GET') {
            http_response_code(405);
            echo json_encode(['error' => 'Method not allowed']);
            return;
        }
        $response = [
            'timestamp' => $this->timestampService->getCurrentTimestamp(),
            'microtime' => $this->timestampService->getMicrotime(),
            'datetime' => date('Y-m-d H:i:s'),
            'timezone' => date_default_timezone_get()
        ];
        $this->sendResponse($response);
    }
    private function handleSecureRequest(string $method): void {
        if ($method !== 'POST') {
            http_response_code(405);
            return;
        }
        $token = $this->secureService->generateSignedTimestamp();
        $this->sendResponse([
            'success' => true,
            'token' => $token,
            'message' => 'Signed timestamp generated'
        ]);
    }
    private function handleVerificationRequest(string $method): void {
        if ($method !== 'POST') {
            http_response_code(405);
            return;
        }
        $input = json_decode(file_get_contents('php://input'), true);
        $isValid = $this->secureService->verifySignedTimestamp($input);
        $this->sendResponse([
            'valid' => $isValid,
            'message' => $isValid ? 'Timestamp verified' : 'Invalid timestamp'
        ]);
    }
    private function sendResponse(array $data, int $statusCode = 200): void {
        http_response_code($statusCode);
        header('Content-Type: application/json');
        echo json_encode($data, JSON_PRETTY_PRINT);
    }
}
// 启动服务
$server = new TimestampServer();
$server->run();

使用NTP同步时间

<?php
class NTPTimestampService {
    /**
     * 从NTP服务器获取精确时间
     */
    public function getNTPTime(string $server = 'pool.ntp.org'): ?int {
        $socket = @fsockopen("udp://$server", 123, $errno, $errstr, 5);
        if (!$socket) {
            // 回退到系统时间
            return time();
        }
        // 发送NTP请求
        $packet = chr(0x1B) . str_repeat(chr(0), 47);
        $sendTime = microtime(true);
        fwrite($socket, $packet);
        stream_set_timeout($socket, 5);
        $response = fread($socket, 48);
        if ($response === false) {
            fclose($socket);
            return time();
        }
        fclose($socket);
        // 解析NTP响应
        $data = unpack('N12', $response);
        $timestamp = sprintf('%u', $data[9]);
        // 修正延迟
        $receiveTime = microtime(true);
        $delay = ($receiveTime - $sendTime) / 2;
        return $timestamp - 2208988800 + (int)$delay;
    }
    /**
     * 校正本地时间
     */
    public function synchronizeTime(): bool {
        $ntpTime = $this->getNTPTime();
        if ($ntpTime === null) {
            return false;
        }
        $localTime = time();
        $diff = $ntpTime - $localTime;
        // 记录时间差
        file_put_contents('time_offset.txt', $diff);
        return true;
    }
}

使用示例

// 使用时间戳服务
$service = new TimestampService();
echo "当前时间戳: " . $service->getCurrentTimestamp();
echo "\n微秒时间戳: " . $service->getMicrotime();
echo "\n唯一时间戳: " . $service->generateUniqueTimestamp();
// 使用REST API
// http://your-server/api/timestamp?action=current
// 使用安全时间戳
$secureService = new SecureTimestampService('your-secret-key');
$token = $secureService->generateSignedTimestamp();
$verified = $secureService->verifySignedTimestamp($token);

这个实现提供了多种时间戳服务方案,从基础到高级,包括REST API、安全签名、分布式支持等,你可以根据具体需求选择合适的实现方式。

抱歉,评论功能暂时关闭!