3. Februar 2011

DHL Tracking with PHP v0.1

The german post (packet service: DHL) provides a XML webservice which gives information about the delivery state. It just returns the current state and not the whole history, so I've written a short PHP script which is pulling the state from the webservice and enters the data to a MySQL database.
It compares the current state and the last inserted state and sends an email when the status is saved.
It allows me to stay informed.

Online-Shop like Amazon refreshes their state not live so newer information could be available before Amazon ist displaying it.

From time to time I will extend the script with Google Maps support (the webservice cotains localization data) and hopefully some other delivery services like UPS etc.

Tell me if you have any suggestions for future versions.

Create the tables in a MySQL Database:


CREATE TABLE `delivery_type` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `identifier` varchar(255) DEFAULT NULL,
  `function_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `delivery_type` (`id`,`identifier`,`function_name`)
VALUES
(1, 'dhl', 'dhl_tracking');


CREATE TABLE `packet_tracking` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `id_delivery_type` bigint(20) NOT NULL,
  `identifier` varchar(255) NOT NULL,
  `id_status` bigint(20) DEFAULT NULL,
  `creation_date` bigint(20) DEFAULT NULL,
  `last_action` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `tracking_event` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `id_packet` bigint(20) DEFAULT NULL,
  `city` varchar(255) DEFAULT NULL,
  `country` varchar(255) DEFAULT NULL,
  `recipient` varchar(255) DEFAULT NULL,
  `event_timestamp` bigint(20) DEFAULT NULL,
  `status_text` varchar(255) DEFAULT NULL,
  `next_status_text` varchar(255) DEFAULT NULL,
  `standard_event_code` varchar(2) DEFAULT NULL,
  `product_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


And the PHP scripts:

connect.php

$vHost = 'hostname';
$vPort = 'port';
$vUser = 'username';
$vPassword = 'password';
$vDatabase = 'database-name';

$vConn = mysql_pconnect($vHost . ':' . $vPort,
        $vUser,
        $vPassword);
mysql_select_db($vDatabase, $vConn);


tracking.php
<?php

include('connect.php');

function dhl_tracking(
   $aTrackingNumber, 
   $aPacketId = 1, 
   $aLastAction = null){
   
   
 global $vConn;
 
 $vRootMail = "mail@mail.de";
 
 $vData  = '<?xml version="1.0" encoding="ISO-8859-1" ?>';
 $vData .= '<data appname="nol-public" password="anfang" 
   request="get-status-for-public-user" 
   language-code="de">';
 $vData .= '  <data 
   piece-code="'.$aTrackingNumber.'"></data>';
 $vData .= '</data>';

 // URL bauen und File hohlen
 $vXml = simplexml_load_file(sprintf(
  'http://nolp.dhl.de/nextt-online-public/direct/nexttjlibpublicservlet?xml=%s', 
  $vData));
 
 // FALSE, if Syntax or HTTP Error
 if ($vXml === false) return false;

 $vReturn = array();
 
 // coverts xml to array
 foreach ($vXml->data->data->attributes() 
    as $vKey => $vValue) {
  $vReturn[$vKey] = (string) $vValue;
 }

 $vActionTime = strptime(
  $vReturn['last-event-timestamp'], 
  '%d.%m.%y %H:%M');

 $vActionTime = mktime(
  $vActionTime['tm_hour'], 
  $vActionTime['tm_min'], 
  0, 
  $vActionTime['tm_mon']+1, 
  $vActionTime['tm_mday'], 
  1900+$vActionTime['tm_year']);

 if($aLastAction === null || $vActionTime 
   > $aLastAction){
  
  mysql_query("INSERT INTO tracking_event values (
   null, 
   $aPacketId, 
   '" . mysql_real_escape_string(
     $vReturn['event-location']) . "', 
   '" . mysql_real_escape_string(
     $vReturn['event-country']) . "', 
   '" . mysql_real_escape_string(
     $vReturn['recipient-name']) . "', 
   " . $vActionTime . ", 
   '" . mysql_real_escape_string(
     $vReturn['status']) . "', 
   '" . mysql_real_escape_string(
     $vReturn['status-next']) . "', 
   '" . mysql_real_escape_string(
     $vReturn['standard-event-code']) . "', 
   '" . mysql_real_escape_string(
     $vReturn['product-name']) . "')", 
   $vConn);

   $vStatus = (int)(
    $vReturn['delivery-event-flag'] == '1'
    );
   mysql_query("UPDATE packet_tracking set 
    last_action = $vActionTime, 
    id_status = $vStatus 
    where id = $aPacketId", $vConn);
   
   $vMessage = var_export($vReturn,true);
   mail($vRootMail, 
    "TRACKING-TOOL: New Event Found", 
    $vMessage);
 }
 
 return $vReturn;
}

function processAllOpenTrackings(){
 global $vConn;
 
 $vResult = mysql_query("SELECT pt.*, dt.function_name 
  FROM packet_tracking pt, delivery_type dt 
  where pt.id_delivery_type = dt.id and pt.id_status = 0", 
  $vConn);

 while ($vRow = mysql_fetch_array($vResult, MYSQL_ASSOC)) {
  call_user_func(
   $vRow['function_name'], 
   $vRow['identifier'], 
   $vRow['id'], 
   $vRow['last_action']);
 }
}

processAllOpenTrackings();
?>


Just create a new set in the 'packet_tracking' table and call the script. I have entered a Cron Entry and call the script via wget. Files are attached...

Tracking v0.1

1 Kommentar:

  1. Nice script, but it does not work anymore because of changes DHL made.

    AntwortenLöschen