Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: Matkahuollon XML-rajapinta

Metabolix [29.06.2012 23:08:46]

#

Tässä on esimerkki Matkahuollon XML-rajapinnan käyttämisestä. Koodi on kirjoitettu Matkahuollon oman esimerkkikoodin pohjalta mutta huomattavasti lyhyemmin, selvemmin ja paremmin.

pdf.php:

<?php
require_once "Matkahuolto.php";

$mh = new Matkahuolto();

$mh->MessageType = "N";
$mh->Weight = "3.25";
$mh->Packages = "2";
$mh->SenderId = "09430023";
$mh->ReceiverName1 = "Metabolix";
$mh->ReceiverPostal = "00280";
$mh->ReceiverCity = "HELSINKI";
$mh->ProductCode = "30";

try {
	$mh->sendRequest("09430023", "456", "https://mhhkiweb1.matkahuolto.fi/scripts101c/mhshipmentxmltesti.wsc/ovtinxml");
	$mh->outputPDF();
} catch (MatkahuoltoException $e) {
	header("Content-Type: text/plain");
	echo $e->getMessage();
}

Matkahuolto.php:

<?php

class MatkahuoltoException extends Exception {
}

class Matkahuolto {
	// Pyynnössä tarvittavat kentät
	private static $shipment_vars = array('MessageType', 'ShipmentNumber', 'ShipmentDate', 'Weight', 'Volume', 'Packages', 'SenderId', 'SenderName1', 'SenderName2', 'SenderAddress', 'SenderPostal', 'SenderCity', 'SenderContactName', 'SenderContactNumber', 'SenderEmail', 'SenderReference', 'DeparturePlaceCode', 'DeparturePlaceName', 'ReceiverId', 'ReceiverName1', 'ReceiverName2', 'ReceiverAddress', 'ReceiverPostal', 'ReceiverCity', 'ReceiverContactName', 'ReceiverContactNumber', 'ReceiverEmail', 'ReceiverReference', 'DestinationPlaceCode', 'DestinationPlaceName', 'PayerCode', 'Remarks', 'ProductCode', 'ProductName', 'Pickup', 'PickupPayer', 'PickupRemarks', 'Delivery', 'DeliveryPayer', 'DeliveryRemarks', 'CODSum', 'CODCurrency', 'CODAccount', 'CODReference', 'Goods', 'VAKCode', 'VAKDescription', 'DocumentType');

	// Vastauksen kentät
	private static $response_vars = array('ShipmentNumber', 'SenderReference', 'ShipmentPdf', 'ErrorNbr', 'ErrorMsg');

	// Puuttuvien muuttujien hakeminen
	public function __get($x) {
		if (in_array($x, self::$shipment_vars) || in_array($x, self::$response_vars)) {
			return null;
		}
		throw new MatkahuoltoException("Unknown variable: $x");
	}

	// Puuttuvien muuttujien asettaminen
	public function __set($x, $value) {
		if (in_array($x, self::$shipment_vars) || in_array($x, self::$response_vars)) {
			return $this->$x = $value;
		}
		throw new MatkahuoltoException("Unknown variable: $x");
	}

	// Pyynnön lähetys
	public function sendRequest($user, $password, $url) {
		if (!class_exists("XMLWriter")) {
			throw new MatkahuoltoException("XMLWriter missing");
		}
		if (!class_exists("XMLReader")) {
			throw new MatkahuoltoException("XMLReader missing");
		}

		// Luodaan pyyntö.
		$xml = new XMLWriter();
		$xml->openMemory();
		$xml->startDocument('1.0');
		$xml->startElement('MHShipmentRequest');
		$xml->writeElement("Version", "1.0");
		$xml->writeElement("pUserId", $user);
		$xml->writeElement("Password", $password);
		$xml->startElement('Shipment');
		foreach (self::$shipment_vars as $x) if ($this->$x !== null) {
			$xml->writeElement($x, $this->$x);
		}
		$xml->endElement();
		$xml->endElement();
		$xml->endDocument();
		$xml = $xml->flush();

		if (function_exists("curl_init")) {
			// Lähetetään pyyntö.
			$ch = curl_init();
			if (!($ch = curl_init())) {
				throw new MatkahuoltoException("cURL: curl_init failed");
			}
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($ch, CURLOPT_TIMEOUT, 1000);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
			curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
			$data = curl_exec($ch);
			if (curl_errno($ch)) {
				throw new MatkahuoltoException("cURL: ". curl_errno($ch). ": ". curl_error($ch));
			}
			curl_close($ch);
		} else {
			// Lähetetään pyyntö.
			$ctx = stream_context_create(array("http" => array(
				"method" => "POST",
				"content" => $xml,
				"header" => "Content-Type: text/xml",
				"timeout" => 10,
			)));
			$data = @file_get_contents($url, null, $ctx);
			if ($data === false) {
				$tmp = error_get_last();
				throw new MatkahuoltoException($tmp["message"]);
			}
		}

		// Tulkitaan vastaus.
		$xml = new XMLReader();
		$xml->XML($data);
		foreach (array_diff(self::$response_vars, self::$shipment_vars) as $x) {
			$this->$x = null;
		}
		while ($xml->read()) {
			if ($xml->nodeType == 1) {
				if (in_array($name = $xml->name, self::$response_vars)) {
					$xml->read();
					$this->$name = $xml->value;
				}
			}
		}
		if ($this->ErrorNbr) {
			throw new MatkahuoltoException("{$this->ErrorNbr}: {$this->ErrorMsg}");
		}

		// Puretaan PDF.
		$this->ShipmentPdf = base64_decode($this->ShipmentPdf);
	}

	// PDF:n näyttäminen
	public function outputPDF() {
		if (headers_sent()) {
			throw new MatkahuoltoException("Headers already sent");
		}
		header("Content-Type: application/pdf");
		header("Content-Length: ".strlen($this->ShipmentPdf));
		header("Content-Disposition: attachment; filename=\"{$this->ShipmentNumber}.pdf\"");
		echo $this->ShipmentPdf;
	}
}

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta