本文目录导读:

我来详细介绍PHP项目中实现物流跟踪的几种方案:
集成第三方物流API(推荐)
主流物流API服务商
// 1. 快递100 API
$apiKey = 'your_api_key';
$customer = 'your_customer_id';
$trackingNumber = 'SF1234567890';
$company = 'shunfeng'; // 快递公司编码
$url = "https://api.kuaidi100.com/api?id={$apiKey}&com={$company}&nu={$trackingNumber}&show=0&muti=1&order=desc";
$response = file_get_contents($url);
$data = json_decode($response, true);
// 2. 菜鸟物流API
// 需要注册成为菜鸟开发者,获取appKey和appSecret
封装物流查询类
<?php
class LogisticsTracker {
private $apiKey;
private $apiSecret;
public function __construct($apiKey, $apiSecret) {
$this->apiKey = $apiKey;
$this->apiSecret = $apiSecret;
}
// 快递100查询示例
public function trackByExpress100($companyCode, $trackingNumber) {
$url = "https://api.kuaidi100.com/api";
$postData = [
'customer' => $this->apiKey,
'sign' => md5($postData['param'] . $this->apiSecret . $this->apiKey),
'param' => json_encode([
'com' => $companyCode,
'num' => $trackingNumber
])
];
return $this->curlPost($url, $postData);
}
private function curlPost($url, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
数据库设计方案
-- 物流信息表
CREATE TABLE logistics_tracking (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT NOT NULL,
tracking_number VARCHAR(50) UNIQUE,
company_code VARCHAR(20), -- 快递公司编码
company_name VARCHAR(50), -- 快递公司名称
status ENUM('pending','shipped','in_transit','delivered','failed') DEFAULT 'pending',
current_location VARCHAR(200),
estimated_delivery DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_order (order_id),
INDEX idx_tracking (tracking_number)
);
-- 物流轨迹明细表
CREATE TABLE logistics_tracks (
id INT PRIMARY KEY AUTO_INCREMENT,
tracking_id INT,
status VARCHAR(50),
location VARCHAR(200),
description TEXT,
operator VARCHAR(50),
track_time DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (tracking_id) REFERENCES logistics_tracking(id)
);
物流跟踪功能实现
查询物流信息
<?php
class LogisticsService {
private $db;
private $tracker;
public function __construct($db, $tracker) {
$this->db = $db;
$this->tracker = $tracker;
}
// 创建物流记录
public function createTracking($orderId, $trackingNumber, $companyCode) {
$sql = "INSERT INTO logistics_tracking (order_id, tracking_number, company_code, company_name)
VALUES (?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
$companyName = $this->getCompanyName($companyCode);
$stmt->execute([$orderId, $trackingNumber, $companyCode, $companyName]);
return $this->db->lastInsertId();
}
// 查询物流信息
public function getTrackingInfo($trackingId) {
// 先从数据库获取缓存
$sql = "SELECT * FROM logistics_tracking WHERE id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([$trackingId]);
$tracking = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$tracking) {
return null;
}
// 检查是否需要更新(缓存策略:30分钟更新一次)
if ($this->needUpdate($tracking)) {
$this->updateTrackingInfo($tracking);
}
// 获取轨迹详情
$tracks = $this->getTracks($trackingId);
$tracking['tracks'] = $tracks;
return $tracking;
}
// 更新物流信息
private function updateTrackingInfo(&$tracking) {
$result = $this->tracker->trackByExpress100(
$tracking['company_code'],
$tracking['tracking_number']
);
if (isset($result['data']) && !empty($result['data'])) {
// 更新主表
$latest = $result['data'][0];
$sql = "UPDATE logistics_tracking SET
current_location = ?,
status = ?,
updated_at = NOW()
WHERE id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([
$latest['context'],
$this->mapStatus($result['state']),
$tracking['id']
]);
// 更新轨迹明细
$this->updateTracks($tracking['id'], $result['data']);
}
}
// 更新轨迹明细
private function updateTracks($trackingId, $tracks) {
foreach ($tracks as $track) {
$sql = "INSERT IGNORE INTO logistics_tracks
(tracking_id, status, location, description, track_time)
VALUES (?, ?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute([
$trackingId,
$track['status'] ?? '',
$track['context'],
$track['desc'] ?? '',
$track['time']
]);
}
}
}
前端展示示例
<!-- 物流跟踪页面 -->
<div class="logistics-tracking">
<h3>物流跟踪</h3>
<div class="tracking-header">
<span class="company">快递公司:<?php echo htmlspecialchars($tracking['company_name']); ?></span>
<span class="number">运单号:<?php echo htmlspecialchars($tracking['tracking_number']); ?></span>
<span class="status">状态:<?php echo $this->getStatusText($tracking['status']); ?></span>
</div>
<div class="tracking-timeline">
<?php foreach ($tracking['tracks'] as $track): ?>
<div class="track-item">
<div class="track-time"><?php echo date('Y-m-d H:i:s', strtotime($track['track_time'])); ?></div>
<div class="track-content">
<p class="location"><?php echo htmlspecialchars($track['location']); ?></p>
<p class="desc"><?php echo htmlspecialchars($track['description']); ?></p>
<p class="operator">操作人:<?php echo htmlspecialchars($track['operator']); ?></p>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<style>
.tracking-timeline {
position: relative;
padding: 20px 0;
}
.track-item {
position: relative;
padding-left: 30px;
margin-bottom: 20px;
border-left: 2px solid #e0e0e0;
}
.track-item:last-child {
border-left-color: #4CAF50;
}
.track-time {
color: #666;
font-size: 14px;
margin-bottom: 5px;
}
.track-content {
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
}
.track-content .location {
font-weight: bold;
color: #333;
}
</style>
定时任务自动更新
// cron.php - 定时更新物流信息
<?php
// 每30分钟执行一次
require_once 'config.php';
$db = new PDO("mysql:host=localhost;dbname=your_db", "user", "password");
$tracker = new LogisticsTracker($apiKey, $apiSecret);
$service = new LogisticsService($db, $tracker);
// 获取需要更新的物流记录
$sql = "SELECT * FROM logistics_tracking
WHERE status NOT IN ('delivered', 'failed')
AND updated_at < DATE_SUB(NOW(), INTERVAL 30 MINUTE)";
$stmt = $db->query($sql);
while ($tracking = $stmt->fetch(PDO::FETCH_ASSOC)) {
$service->updateTrackingInfo($tracking);
// 防止API限制,每次请求间隔1秒
sleep(1);
}
注意事项
- API选择:根据业务量选择合适的API服务商,注意API调用次数限制
- 缓存策略:避免频繁调用API,设置合理的缓存时间
- 错误处理:处理API调用失败、快递单号错误等情况
- 数据安全:保护API密钥,不要在客户端暴露
建议先用免费API(如快递100免费版)测试,业务量大了再考虑付费方案。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播