SMS mit PHP versenden - Tutorial

Die meisten SMS werden nach wie vor von Handy zu Handy versandt. Aber es ist auch möglich, SMS über PHP und das HTTP-Protokoll von einer Webseite oder über eine Software zu versenden.

Die Vorteile davon sind vielfältig. Man kann z.B. Gratis-SMS auf seiner Webseite anbieten, um mehr Traffic dorthin zu lenken.

Es ist auch möglich, SMS als E-mail zu versenden. In diesem Tutorial soll aber ausschließlich der Versand über GET und POST HTTP in PHP behandelt werden.

Dieses Tutorial kann auf jedes SMS-Gateway angewandt werden, welches eine HTTP-Schnittstelle anbietet. Es wurde jedoch speziell für das smstrade.de SMS Gateway erstellt, da sie zum einen eine Simulationsoption bieten, mit der man seine Skripts optimieren kann. Weiterhin verlangen sie keine Setup-Gebühren, bieten generell niedrige Preise und sind sehr zuverlässig.

SMS über HTTP versenden - die Anforderungen an den Gateway

Auf SMS API findet man alle benötigten Angaben, um SMSTRADE benutzen zu können. Grundsätzlich benötigt man 6 Datensätze:

key: persönliche Identifikationskey
message: Inhalt der Nachricht
to: Empfänger
from: Absender
route: Versandroute

Wir fügen noch ein "debug" als 6. Datensatz hinzu, das bedeutet "Testmodus", d.h. es wird kein Geld für diese SMS von unserem Konto abgezogen und sie werden auch nicht abgesandt.

SMS über HTTP versenden - Erstellen des HTTP-Requests

Nun wird der eigentliche Auslieferungsprozess über den Gateway abgewickelt. Dazu muss der Inhalt der SMS noch in eine HTTP-Vorlage umgewandelt werden, wie z.B. diese hier:

http://gateway.smstrade.de/?key=123&to=4917212345&message=Hello+World&route=gold&from=SMSTRADE

Dieses auf GET basierende Beispiel kann man auch testen, indem man es in die Addresszeile seines Browsers einfügt. Man erhält den Wert 50 zurück. Das bedeutet, dass der Userkey invalid ist und ist normal, da es ja nur ein Beispiel zur Demonstration ist.

Als erstes muss man nun die Datensätze als Variable speichern und sie dann in eine URL-Form umwandeln. Dafür gibt es verschiedene Möglichkeiten, die folgende:

01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
<?php

// +--------------------------------------------+
// | Copyright (c) 2007-2009 by SMSTRADE.DE     |
// +--------------------------------------------+

$url "http://gateway.smstrade.de"// URL des Gateways
$request ""// Request Variable initialisieren
$param["key"] = "123"// Gateway Key
$param["to"] = "4917212345"// Empfänger der SMS
$param["message"] = "Hello World"// Inhalt der Nachricht
$param["route"] = "gold";// Nutzung der Goldroute
$param["from"] = "SMSTRADE";// Absender der SMS 
$param["debug"] = "1";// SMS wird nicht versendet - Testmodus

foreach($param as $key=>$val// Alle Parameter durchlaufen

  
$request.= $key."=".urlencode($val); // Werte müssen url-encoded sein
  
$request.= "&"// Trennung der Parameter mit &
}

// SMS kann jetzt versendet werden
...

Die Datensätze werden in das $param-Array eingegeben. Jeder Parameter muss dann URL-verschlüsselt werden und die Parameter werden durch & getrennt.

Dieses Skript erzeugt folgenden Request, der an das SMS-Gateway gesandt werden kann:

http://gateway.smstrade.de/?key=123&message=Hello+World&to=4917212345&from=Absender&route=gold&debug=1

SMS über HTTP versenden - den Request über file() versenden

Wie eben gesehen, könnte man nun den generierten Request ausgegeben und direkt in den Internetbrowser eingegeben um die Nachricht zu versenden. Die unkomplizierteste Möglichkeit den Request aus dem Script heraus abzusetzen, bietet die Funktion file().

Nachteil: Es stehen keine weiteren Optionen wie bestimmter timeout zur Verfügung.

01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
<?
...

$response = @file($url."?".$request); // Request absetzen

$response_code intval($response[0]); // Responsecode auslesen

$response_code_arr[0] = "Keine Verbindung zum Gateway";
$response_code_arr[10] = "Empfänger fehlerhaft";
$response_code_arr[20] = "Absenderkennung zu lang";
$response_code_arr[30] = "Nachrichtentext zu lang";
$response_code_arr[31] = "Messagetyp nicht korrekt";
$response_code_arr[40] = "Falscher SMS-Typ";
$response_code_arr[50] = "Fehler bei Login";
$response_code_arr[60] = "Guthaben zu gering";
$response_code_arr[70] = "Netz wird von Route nicht unterstützt";
$response_code_arr[71] = "Feature nicht über diese Route möglich";
$response_code_arr[80] = "SMS konnte nicht versendet werden";
$response_code_arr[90] = "Versand nicht möglich";
$response_code_arr[100] = "SMS wurde erfolgreich versendet.";

echo 
$response_code_arr[$response_code]; // Ausgabe Fehler oder Erfolg

?>

Zunächst wird der Request via file() abgesetzt. Das @ sollte unbedingt angewendet werden um die Fehlerausgabe zu unterdrücken. Ansonsten wird Ihr Gateway Key unverschlüsselt in der Fehlermeldung angezeigt wenn es mal zu keiner Verbindung zum Gateway kommen sollte.

Gleichzeitig wird die Rückgabe im $response Array gespeichert. Jetzt kann man über die Fehlercodes auslesen ob die SMS erfolgreich versendet wurde oder nicht.

SMS über HTTP versenden - den Request über CURL versenden

CURL bietet eine andere, elegantere Methode, welche im Hintergrund abläuft.

CURL ist eine sehr beeindruckende Library, mit der man über verschiedene Protokolle mit verschieden Servern kommunizieren kann. Weiter Informationen im PHP Manual

Dieser Code öffnet die Verbindung zum Gateway, schickt die SMS und gibt die Rückmeldung aus:

01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
<?
...

$ch curl_init(); //initialize curl handle 
curl_setopt($chCURLOPT_URL$url); //set the url
curl_setopt($chCURLOPT_RETURNTRANSFER,1); //return as a variable 
curl_setopt($chCURLOPT_POST1); //set POST method 
curl_setopt($chCURLOPT_POSTFIELDS$request); //set the POST variables
$response curl_exec($ch); //run the whole process and return the response
curl_close($ch); //close the curl handle

$response_code intval($response);

?>

Zunächst wird eine neue CURL-Session eröffnet und die gewünschten Sendeoptionen eingegeben. Dann führen wir den Call aus und schließen das Handle.
Der Response Code kann dann natürlich auch wie bei der file()-Methode ausgewertet werden.

SMS über HTTP versenden - den Request über Sockets versenden

CURL funktioniert nur mit einer externen Library. Um CURL nutzen zu können, muss PHP das "with-curl"-Symbol besitzen. Ansonsten kann der Request auch über Sockets verschickt warden.

01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
<?
...

// Connection vorbereiten
$host "gateway.smstrade.de";
$script "/";
$request_length strlen($request);
$method "POST";

// HTTP Header generieren
$header "$method $script HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: $request_length\r\n";
$header .= "Connection: close\r\n\r\n";
$header .= "$request\r\n";

// Connection öffnen
$socket = @fsockopen($host80$errno$errstr); 
if (
$socket// wenn geöffnet, dann...

  
fputs($socket$header); // Header senden
  
while(!feof($socket))
  {
    
$output[] = fgets($socket); // Response empfangen
  
}
  
fclose($socket); 


$response_code intval($output[8]);

?>

Zunächst gibt man die Sendeoptionen an und erstellt damit den HTTP-Header. Die Verbindung zum Gateway über das Socket wird mit fsockopen hergestellt. Das Senden/Empfangen geschieht nach demselben Prinzip wie bei CURL. Nach dem erfolgreichen Transfer schließt man das Socket mit fclose.

SMS über HTTP versenden - Zusammenfassung

Wenn man PHP mit CURL einsetzen kann, dann ist CURL wohl die beste, sauberste und schnelleste Option für den Versand. Die file()-Methode ist mit Abstand am Einfachsten, bietet allerdings nicht alle Funktionen wie bei CURL.