Skip to content

9. PHP-Netzwerkfunktionen

Wir werden nun die Netzwerkfunktionen von PHP behandeln, die es uns ermöglichen, TCP/IP-Programmierung (Transmission Control Protocol/Internet Protocol) durchzuführen.

9.1. Abrufen des Namens oder der IP-Adresse eines Rechners im Internet (inet_01)


<?php
 
// functions machine name <--> address IP machine
ini_set("display_errors", "off");
// constants
$HOTES = array("istia.univ-angers.fr", "www.univ-angers.fr", "www.ibm.com", "localhost", "", "xx");
// IP addresses of $HOTES machines
for ($i = 0; $i < count($HOTES); $i++) {
  getIPandName($HOTES[$i]);
}
// end
exit;
 
//------------------------------------------------
function getIPandName($nomMachine) {
//$nomMachine: name of the machine whose address is required IP: name of the machine whose address is required IP: name of the machine whose address is required
// nomMachine-->adresse IP
  $ip = gethostbyname($nomMachine);
  if ($ip != $nomMachine) {
    print "ip[$nomMachine]=$ip\n";
// address IP --> nomMachine
    $name = gethostbyaddr($ip);
    if ($name != $ip) {
      print "name[$ip]=$name\n";
    } else {
      print "Erreur, machine[$ip] non trouvée\n";
    }
  } else {
    print "Erreur, machine[$nomMachine] non trouvée\n";
  }
}

Ergebnisse:

ip[istia.univ-angers.fr]=193.49.146.171
name[193.49.146.171]=istia.istia.univ-angers.fr
ip[www.univ-angers.fr]=193.49.144.40
name[193.49.144.40]=ametys-fo.univ-angers.fr
ip[www.ibm.com]=129.42.56.216
Erreur, machine[129.42.56.216] non trouvée
ip[localhost]=127.0.0.1
name[127.0.0.1]=localhost127.0.0.1
ip[]=192.168.1.11
name[192.168.1.11]=st-PC.home
Erreur, machine[xx] non trouvée

Kommentare

  • Zeile 4: Wir weisen das System an, keine Laufzeitfehler anzuzeigen.

In der Funktion getIpandName in Zeile 15 werden die Netzwerkfunktionen von PHP verwendet.

  • Zeile 18: Die Funktion gethostbyname($name) ruft die IP-Adresse „ip3.ip2.ip1.ip0“ des Rechners mit dem Namen $name ab. Wenn der Rechner $name nicht existiert, gibt die Funktion $name als Ergebnis zurück.
  • Zeile 22: Die Funktion `gethostbyaddr($ip)` ermittelt den Hostnamen des Rechners mit der IP-Adresse `$ip` im Format „ip3.ip2.ip1.ip0“. Falls der Rechner `$ip` nicht existiert, gibt die Funktion `$ip` als Ergebnis zurück.

9.2. Ein Web-Client ( inet_02)

Ein Skript zum Abrufen des Inhalts der Indexseite einer Website.


<?php
 
// error management
ini_set("display_errors","off");
// otain the text HTML from URL
// list of websites
$SITES = array("istia.univ-angers.fr", "www.univ-angers.fr", "www.ibm.com", "xx");
// reading the index pages of the sites in the $SITES table
for ($i = 0; $i < count($SITES); $i++) {
// read site index page $SITES[$i]
  $résultat = getIndex($SITES[$i]);
// result display
  print "$résultat\n";
}//for
// end
exit;
 
//-----------------------------------------------------------------------
function getIndex($site) {
// reads the URL $site/ and stores it in the $site.html file
// create file $site.html
  $html = fopen("$site.html", "w");
  if (!$html)
    return "Erreur lors de la création du fichier $site.html";
 
// open a connection on port 80 of $site
  $connexion = fsockopen($site, 80);
// return if error
  if (!$connexion)
    return "Echec de la connexion au site ($site,80) : $erreur";
// $connexion represents a bidirectional communication flow
// between the client (this program) and the contacted web server
// this channel is used for the exchange of orders and information
// the dialog protocol is HTTP
// the customer sends the get command to request URL /
// syntaxe get URL HTTP/1.0
// protocol HTTP headers must end with an empty line
  fputs($connexion, "GET / HTTP/1.0\n\n");
// the server will now respond on channel $connexion. It will send all
// then close the channel. The client therefore reads everything that arrives from $connexion
// until the channel closes
  while ($ligne = fgets($connexion, 1000))
    fputs($html, $ligne);
// the customer in turn closes the connection
  fclose($connexion);
// close file $html
  fclose($html);
// return
  return "Transfert réussi de la page index du site $site";
}

Ergebnisse: Beispielsweise die für die Website [www.ibm.com] empfangene Datei:

HTTP/1.1 302 Found
Date: Wed, 08 Jun 2011 15:43:56 GMT
Server: IBM_HTTP_Server
Content-Type: text/html
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Pragma: no-cache
Cache-Control: no-cache, must-revalidate
Location: http://www.ibm.com/us/en/
Content-Length: 209
Kp-eeAlive: timeout=10, max=14
Connection: Keep-Alive

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://www.ibm.com/us/en/">here</a>.</p>
</body></html>
  • Die Zeilen 1–11 sind die HTTP-Header der Serverantwort
  • Zeile 1: Der Server weist den Client an, zur in Zeile 8 angegebenen URL umzuleiten
  • Zeile 2: Datum und Uhrzeit der Antwort
  • Zeile 3: Identität des Webservers
  • Zeile 4: Vom Server gesendeter Inhalt. Hier eine HTML-Seite, die in Zeile 13 beginnt
  • Zeile 12: Die Leerzeile, die die HTTP-Header abschließt
  • Zeilen 13–19: Die vom Webserver gesendete HTML-Seite.

Code-Kommentare:

  • Zeile 7: Die Liste der URLs für die Websites, deren Startseiten wir benötigen. Diese werden in der Textdatei [sitename.html] gespeichert.
  • Zeile 11: Die Funktion getIndex erledigt die Arbeit
  • Zeile 19: Die Funktion getIndex($site) lädt die Startseite (oder Indexseite) der Website $site herunter und speichert sie in der Textdatei $site.html.
  • Zeile 27: Die Funktion fsockopen($site,$port) stellt eine Verbindung zu einem TCP/IP-Dienst her, der auf Port $port des Rechners $site läuft. Sobald die Client-Server-Verbindung besteht, tauschen viele TCP/IP-Dienste Textzeilen aus. Dies ist hier beim HTTP (HyperText Transfer Protocol) der Fall. Der Datenstrom vom Server zum Client kann dann wie eine Textdatei behandelt werden. Dasselbe gilt für den Datenstrom vom Client zum Server.
  • Zeile 38: Die Funktion fputs ermöglicht es dem Client, Daten an den Server zu senden. Hier hat die gesendete Textzeile folgende Bedeutung: „Ich möchte (GET) die Startseite (/) der Website, mit der ich verbunden bin. Ich verwende HTTP Version 1.0.“ Die aktuelle Version dieses Protokolls ist 1.1.
  • Zeile 42: Die Textzeilen der Antwort des Servers können mit einer while-Schleife zeilenweise gelesen und in der Textdatei [$site.html] gespeichert werden. Sobald der Webserver die angeforderte Seite gesendet hat, schließt er seine Verbindung zum Client. Auf der Client-Seite wird dies als Dateiende erkannt.

9.3. Ein SMTP-Client (inet_03)

Unter den TCP/IP-Protokollen ist SMTP (Simple Mail Transfer Protocol) das Kommunikationsprotokoll für den E-Mail-Versanddienst.

Hinweise:

  • Auf einem Windows-Rechner mit Antivirensoftware verhindert das Antivirenprogramm wahrscheinlich, dass das PHP-Skript eine Verbindung zu Port 25 eines SMTP-Servers herstellt. Sie müssen daher das Antivirenprogramm deaktivieren. Bei McAfee können Sie dies beispielsweise wie folgt tun:
  • Öffnen Sie in [1] die VirusScan-Konsole
  • Beenden Sie in [2] den Dienst [On-Access Protection]
  • in [3] ist er angehalten

Das Skript:


<?php
 
// client SMTP (SendMail Transfer Protocol) for sending a message
// information is taken from a $INFOS file containing the following lines
// line 1: smtp, sender, recipient
// next lines: message text
// sender: email sender
// recipient: email recipient
// smtp: name of smtp server to use
// communication protocol SMTP client-server
// -> client connects to smtp server port 25
// <- server sends him a welcome message
// -> customer sends command EHLO: machine name
// <- server responds OK or not
// -> customer sends mail order from: <sender>
// <- server responds OK or not
// -> client sends the rcpt to command: <recipient>
// <- server responds OK or not
// -> customer sends data order
// <- server responds OK or not
// -> client sends all the lines of its message and ends with a line containing the
// single character .
// <- server responds OK or not
// -> customer sends quit order
// <- server responds OK or not
// server responses have the form xxx text where xxx is a 3-digit number. Any number xxx >=500
// indicates an error. The answer may consist of several lines all beginning with xxx except the last one
// of the form xxx(space)
// exchanged text lines must end with the characters RC(#13) and LF(#10)
 
// data
$INFOS = "mail.txt"; // mail settings
// retrieve mail parameters
list($erreur, $smtpServer, $expéditeur, $destinataire, $message) = getInfos($INFOS);
// mistake?
if ($erreur) {
  print "$erreur\n";
  exit;
}
print "Envoi du message [$smtpServer,$expéditeur,$destinataire]\n";
// sending mail in verbose mode
$résultat = sendmail($smtpServer, $expéditeur, $destinataire, $message, 1);
print "Résultat de l'envoi : $résultat\n";
// end
exit;
 
//-----------------------------------------------------------------------
function getInfos($fichier) {
// returns information ($smtp,$expéditeur,$destinataire,$message) taken from text file $fichier
// line 1: smtp, sender, recipient
// next lines: message text
 
// opening of $fichier
  $infos = fopen($fichier, "r");
// does the $fichier file exist?
  if (!$infos)
    return array("Le fichier $fichier n'a pu être ouvert en lecture");
// read the 1st line
  $ligne = fgets($infos, 1000);
// delete end-of-line mark
  $ligne = cutNewLineChar($ligne);
// retrieving smtp, sender and recipient fields
  $champs = explode(",", $ligne);
// do we have the right number of fields?
  if (count($champs) != 3)
    return "La ligne 1 du fichier $fichier (serveur smtp, expéditeur, destinataire) a un
nombre de champs incorrect";
// "processing" the recovered information
  for ($i = 0; $i < count($champs); $i++)
    $champs[$i] = trim($champs[$i]);
// field recovery
  list($smtpServer, $expéditeur, $destinataire) = $champs;
// read message
  $message = "";
  while ($ligne = fgets($infos, 1000))
    $message.=$ligne;
  fclose($infos);
// return
  return array("", $smtpServer, $expéditeur, $destinataire, $message);
}
 
//-----------------------------------------------------------------------
 
function sendmail($smtpServer, $expéditeur, $destinataire, $message, $verbose) {
// sends $message to smtp server $smtpserver from $expéditeur
// for $destinataire. If $verbose=1, tracks client-server exchanges
// retrieve the customer's name
  $client = gethostbyaddr(gethostbyname(""));
// open a connection on port 25 of $smtpServer
  $connexion = fsockopen($smtpServer, 25);
// return if error
  if (!$connexion)
    return "Echec de la connexion au site ($smtpServer,25)";
// $connexion represents a bidirectional communication flow
// between the client (this program) and the smtp server contacted
// this channel is used for the exchange of orders and information
 
// after connection, the server sends a welcome message which is read as follows
  $erreur = sendCommand($connexion, "", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }
 
// cmde ehlo:
  $erreur = sendCommand($connexion, "EHLO $client", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }
 
// cmde mail from:
  $erreur = sendCommand($connexion, "MAIL FROM: <$expéditeur>", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }
 
// cmde rcpt to:
  $erreur = sendCommand($connexion, "RCPT TO: <$destinataire>", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }
 
// cmde data
  $erreur = sendCommand($connexion, "DATA", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }
 
// prepare message to send
  // it must contain the lines
  // From: expéditeur
  // To: recipient
  // blank line
  // Message
  // .
  $data = "From: $expéditeur\r\nTo: $destinataire\r\n$message\r\n.\r\n";
  $erreur = sendCommand($connexion, $data, $verbose, 0);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }
 
// cmde quit
  $erreur = sendCommand($connexion, "QUIT", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }
 
// end
  fclose($connexion);
  return "Message envoyé";
}
 
// --------------------------------------------------------------------------
 
function sendCommand($connexion, $commande, $verbose, $withRCLF) {
// sends $commande to the $connexion channel
// verbose mode if $verbose=1
// if $withRCLF=1, adds sequence RCLF to exchange
 
// data
  if ($withRCLF)
    $RCLF = "\r\n"; else
    $RCLF="";
 
// send cmde if $commande not empty
  if ($commande) {
    fputs($connexion, "$commande$RCLF");
 
// possible echo
    if ($verbose)
      affiche($commande, 1);
  }////if
 
// reading response
  $réponse = fgets($connexion, 1000);
 
// possible echo
  if ($verbose)
    affiche($réponse, 2);
 
// error code recovery
  $codeErreur = substr($réponse, 0, 3);

// last line of the answer?
  while (substr($réponse, 3, 1) == "-") {
 
     // reading response
    $réponse = fgets($connexion, 1000);
 
     // possible echo
    if ($verbose)
      affiche($réponse, 2);
  }////while
// answer completed
 
// error returned by the server?
  if ($codeErreur >= 500)
    return substr($réponse, 4);
 
// error-free return
  return "";
}
 
// --------------------------------------------------------------------------
 
function affiche($échange, $sens) {
// displays $échange on screen
// if $sens=1 displays -->$echange
// if $sens=2 displays <-- $échange without the last 2 characters RCLF
  switch ($sens) {
    case 1:
      print "--> [$échange]\n";
      return;
    case 2:
      $L = strlen($échange);
      print "<-- [" . substr($échange, 0, $L - 2) . "]\n";
      return;
  }////switch
}
 
// --------------------------------------------------------------------------
 
function cutNewLinechar($ligne) {
// delete the end-of-line mark from $ligne if it exists
  ...
}

Die Datei infos.txt:

1
2
3
4
5
6
7
smtp.orange.fr, serge.tahe@univ-angers.fr , serge.tahe@istia.univ-angers.fr
Subject: test

ligne1
ligne2

ligne3
  • Zeile 1: [smtp.orange.fr] der zum Versenden der E-Mail verwendete Server, [serge.tahe@univ-angers.fr] die Absenderadresse, [serge.tahe@istia.univ-angers.fr] die Empfängeradresse
  • Zeile 2: Nachrichten-Header. Hier gibt es nur einen, den Betreff der Nachricht.
  • Zeile 3: Die Leerzeile beendet die Nachrichten-Header
  • Zeilen 4–7: der Nachrichtentext

Anzeigeergebnisse:

Envoi du message [smtp.orange.fr,serge.tahe@univ-angers.fr,serge.tahe@univ-angers.fr]
<-- [220 mwinf5d05 ME ESMTP server ready]
--> [EHLO st-PC.home]
<-- [250-mwinf5d05 hello [2.1.22.82], pleased to meet you]
<-- [250-HELP]
<-- [250-AUTH LOGIN PLAIN]
<-- [250-SIZE 44000000]
<-- [250-ENHANCEDSTATUSCODES]
<-- [250-8BITMIME]
<-- [250 OK]
--> [MAIL FROM: <serge.tahe@univ-angers.fr>]
<-- [250 2.1.0 <serge.tahe@univ-angers.fr> sender ok]
--> [RCPT TO: <serge.tahe@univ-angers.fr>]
<-- [250 2.1.5 <serge.tahe@univ-angers.fr> recipient ok]
--> [DATA]
<-- [354 enter mail, end with "." on a line by itself]
--> [From: serge.tahe@univ-angers.fr
To: serge.tahe@univ-angers.fr
Subject: test

ligne1
ligne2
ligne3
.
]
<-- [250 2.0.0 Ag3i1h0051mFoG203g3ip1 mail accepted for delivery]
--> [QUIT]
<-- [221 2.0.0 mwinf5d05 ME closing connection]
Résultat de l'envoi : Message envoyé
  • Zeile 1: Meldung zur Verfolgung der Skriptausführung
  • Zeile 2: Erste Antwort vom SMTP-Server. Dies folgt auf die Verbindung des Clients mit Port 25 des SMTP-Servers. Serverantworten sind Zeilen in der Form [xxx Nachricht] oder [xxx-Nachricht]. Die erste Syntax zeigt an, dass die Antwort vollständig ist. xxx ist ein Statuscode. Ein Wert größer oder gleich 500 weist auf einen Fehler hin. Die zweite Syntax zeigt an, dass die Antwort nicht vollständig ist und eine weitere Zeile folgt.
  • Zeile 2: Der SMTP-Server zeigt an, dass er bereit ist, Befehle zu empfangen
  • Zeile 3: Der Client sendet den Befehl [EHLO machineName], wobei machineName der Hostname des Rechners ist, auf dem der Client läuft
  • Zeilen 4–10: Antwort vom SMTP-Server
  • Zeile 11: Der Client sendet den Befehl [MAIL FROM: <Absender>], der die E-Mail-Adresse des Absenders angibt.
  • Zeile 12: Der SMTP-Server zeigt an, dass er diese Adresse akzeptiert. Er hätte sie ablehnen können, wenn die Syntax falsch gewesen wäre. Allerdings überprüft er nicht, ob die E-Mail-Adresse tatsächlich existiert.
  • Zeile 13: Der Client sendet den Befehl [RCPT TO: <Empfänger>], der die E-Mail-Adresse des Empfängers der Nachricht angibt.
  • Zeile 14: Der SMTP-Server antwortet, dass er diese Adresse akzeptiert. Auch hier wird eine Syntaxprüfung durchgeführt.
  • Zeile 15: Der Client sendet den Befehl [DATA], der dem Benutzer anzeigt, dass die folgenden Zeilen den Textkörper der Nachricht bilden.
  • Zeile 16: Der Server antwortet, dass die Nachricht gesendet werden kann. Die Nachricht besteht aus einer Folge von Textzeilen, die mit einer einstelligen Zeile enden muss: einem Punkt.
  • Zeilen 17–25: Die vom Client gesendete Nachricht
  • Zeilen 17–19: Die Nachrichtenkopfzeilen [From:, To:, Subject:] geben jeweils den Absender, den Empfänger und den Betreff der Nachricht an.
  • Zeile 20: Eine Leerzeile, die das Ende der Kopfzeilen anzeigt
  • Zeilen 21–23: Der Hauptteil der Nachricht
  • Zeile 24: Die Zeile, die aus einem einzelnen Punkt besteht und das Ende der Nachricht signalisiert.
  • Zeile 26: Der SMTP-Server antwortet, dass er die Nachricht annimmt
  • Zeile 27: Der Client sendet den Befehl [QUIT], um anzuzeigen, dass er fertig ist
  • Zeile 28: Der SMTP-Server antwortet, dass er die Verbindung zum Client schließen wird

Code-Kommentare

Wir werden nicht näher auf den Skriptcode eingehen, da er ausführlich kommentiert ist.

  • Zeilen 48–80: Die Funktion, die die Datei [infos.txt] verarbeitet, die die zu versendende Nachricht sowie die für den Versand erforderlichen Informationen enthält. Sie gibt ein Array ($error, $smtpServer, $sender, $recipient, $message) zurück, wobei:
    • $error: eine mögliche Fehlermeldung; andernfalls leer.
    • $smtpServer: der Name des SMTP-Servers, mit dem eine Verbindung hergestellt werden soll
    • $sender: die E-Mail-Adresse des Absenders
    • $recipient: die E-Mail-Adresse des Empfängers
    • $message: die zu versendende Nachricht. Zusätzlich zum Nachrichtentext können Kopfzeilen vorhanden sein.
  • Zeilen 84–157: Die Funktion sendMail ist für den Versand der Nachricht zuständig. Ihre Parameter lauten wie folgt:
    • $smtpServer: der Name des SMTP-Servers, mit dem eine Verbindung hergestellt werden soll
    • $sender: die E-Mail-Adresse des Absenders
    • $recipient: die E-Mail-Adresse des Empfängers
    • $message: die zu versendende Nachricht.
    • $verbose: Der Wert 1 gibt an, dass die Kommunikation mit dem SMTP-Server in der Konsole protokolliert werden soll.

Die Funktion sendMail gibt eine Fehlermeldung zurück; wenn keine Fehler aufgetreten sind, gibt sie eine leere Zeichenfolge zurück.

  • Zeile 88: Ruft den Windows-Namen eines Computers ab, auf dem das Windows-Betriebssystem läuft.
  • Zeile 99: Wir haben gesehen, dass der Client-Server-Dialog diesem Muster folgt:
    • Der Client sendet einen Befehl in einer einzigen Zeile
    • Serverantwort in einer oder mehreren Zeilen
  • Zeilen 161–208: Die Funktion `sendCommand` akzeptiert die folgenden Parameter:
    • $connection: der TCP/IP-Kanal, der den Client mit dem Server verbindet
    • $command: der Befehl, der über diesen Kanal gesendet werden soll. Die Antwort des Servers auf diesen Befehl wird gelesen.
    • $verbose: Der Wert 1 gibt an, dass der Austausch mit dem SMTP-Server auf der Konsole angezeigt werden soll.
    • $withRCLF: Der Wert 1 gibt an, dass die Zeilenende-Markierung „\r\n“ am Ende des Befehls hinzugefügt werden muss
  • Zeile 173: Der Client sendet den Befehl
  • Zeile 181: Lesen der ersten Zeile der Antwort des SMTP-Servers in der Form xxx-Text oder xxx-Text. Im letzteren Fall gibt der Server an, dass noch eine weitere Zeile gesendet wird. xxx ist der vom Server gesendete Fehlercode.
  • Zeile 188 – Abrufen des Fehlercodes aus der Antwort
  • Zeilen 191–199: Lesen der übrigen Zeilen der Antwort
  • Zeilen 203–204: Wenn der Fehlercode >=500 ist, meldet der SMTP-Server einen Fehler.

9.4. Ein zweites Programm zum Versenden von E-Mails (inet_04)

Dieses Skript hat dieselbe Funktionalität wie das vorherige: das Versenden einer E-Mail. Dazu verwenden wir Module aus der PEAR-Bibliothek. Diese Bibliothek enthält Dutzende von Modulen, die verschiedene Bereiche abdecken. Wir werden folgende verwenden:

  • Net/SMTP: ein Modul für die Kommunikation mit einem SMTP-Server
  • Mail: ein Modul zur Verwaltung des E-Mail-Versands über verschiedene Protokolle.
  • Mail/Mime: ein Modul zum Erstellen einer Nachricht, die angehängte Dokumente enthalten kann.

Um diese Module nutzen zu können, müssen Sie sie zunächst auf dem Rechner installieren, auf dem das PHP-Skript ausgeführt wird. Durch die Installation des WampServer-Softwarepakets wurde ein PHP-Interpreter installiert. Innerhalb dessen Verzeichnisstruktur können Sie PEAR-Module installieren.

  • in [1], dem Installationsverzeichnis des PHP-Interpreters
  • in [2] der PEAR-Ordner, der die zu installierenden PEAR-Module enthalten wird
  • [3] ist die Batch-Datei [go-pear.bat], die die PEAR-Bibliothek initialisiert

Um die PEAR-Bibliothek zu initialisieren, öffnen Sie ein DOS-Fenster und führen Sie die Datei [go-pear.bat] aus. Dieses Skript stellt eine Verbindung zur Website der PEAR-Bibliothek her. Daher ist eine Internetverbindung erforderlich.

C:\serveursSGBD\wamp21\bin\PHP\php5.3.5>go-pear.bat

Sobald die Verbindung zur PEAR-Bibliothekswebsite hergestellt ist, lädt das Skript eine Reihe von Dateien herunter. Darunter befindet sich ein neues Skript [pear.bat]. Wir werden dieses Skript verwenden, um die verschiedenen PEAR-Module zu installieren, die wir benötigen. Dieses Skript wird mit Argumenten aufgerufen. Unter diesen liefert das Argument [help] eine Liste der vom Skript akzeptierten Befehle:

C:\serveursSGBD\wamp21\bin\PHP\php5.3.5>pear help
Commands:
build                  Build an Extension From C Source
bundle                 Unpacks a Pecl Package
channel-add            Add a Channel
channel-alias          Specify an alias to a channel name
channel-delete         Remove a Channel From the List
channel-discover       Initialize a Channel from its server
channel-info           Retrieve Information on a Channel
channel-login          Connects and authenticates to remote channel server
channel-logout         Logs out from the remote channel server
channel-update         Update an Existing Channel
clear-cache            Clear Web Services Cache
config-create          Create a Default configuration file
config-get             Show One Setting
config-help            Show Information About Setting
config-set             Change Setting
config-show            Show All Settings
convert                Convert a package.xml 1.0 to package.xml 2.0 format
cvsdiff                Run a "cvs diff" for all files in a package
cvstag                 Set CVS Release Tag
download               Download Package
download-all           Downloads each available package from the default channel

info                   Display information about a package
install                Install Package
list                   List Installed Packages In The Default Channel
list-all               List All Packages
list-channels          List Available Channels
list-files             List Files In Installed Package
list-upgrades          List Available Upgrades
login                  Connects and authenticates to remote server [Deprecated i
n favor of channel-login]
logout                 Logs out from the remote server [Deprecated in favor of c
hannel-logout]
makerpm                Builds an RPM spec file from a PEAR package
package                Build Package
package-dependencies   Show package dependencies
package-validate       Validate Package Consistency
pickle                 Build PECL Package
remote-info            Information About Remote Packages
remote-list            List Remote Packages
run-scripts            Run Post-Install Scripts bundled with a package
run-tests              Run Regression Tests
search                 Search remote package database
shell-test             Shell Script Test
sign                   Sign a package distribution file
svntag                 Set SVN Release Tag
uninstall              Un-install Package
update-channels        Update the Channel List
upgrade                Upgrade Package
upgrade-all            Upgrade All Packages [Deprecated in favor of calling upgr
ade with no parameters]
Usage: pear [options] command [command-options] <parameters>
Type "pear help options" to list all options.
Type "pear help shortcuts" to list all command shortcuts.
Type "pear help <command>" to get the help for the specified command.

Der Befehl [install] dient zur Installation von PEAR-Modulen. Sie können Hilfe zum Befehl [install] abrufen:

C:\serveursSGBD\wamp21\bin\PHP\php5.3.5>pear help install
pear install [options] [channel/]<package> ...
Installs one or more PEAR packages.  You can specify a package to install in four ways:

"Package-1.0.tgz" : installs from a local file

"http://example.com/Package-1.0.tgz" : installs from anywhere on the net.

"package.xml" : installs the package described in package.xml.  Useful for testing, or for wrapping a PEAR package in another package manager such as RPM.

"Package[-version/state][.tar]" : queries your default channel's server(pear.php.net) and downloads the newest package with the preferred quality/state (stable).

To retrieve Package version 1.1, use "Package-1.1," to retrieve Package state beta, use "Package-beta."  To retrieve an uncompressed file, append .tar (make sure there is no file by the same name first)

To download a package from another channel, prefix with the channel name like "channel/Package"

More than one package may be specified at once.  It is ok to mix these four ways of specifying packages.

Options:
  -f, --force
        will overwrite newer installed packages
  -l, --loose
        do not check for recommended dependency version
  -n, --nodeps
        ignore dependencies, install anyway
  -r, --register-only
        do not install files, only register the package as installed
  -s, --soft
        soft install, fail silently, or upgrade if already installed
  -B, --nobuild
        don't build C extensions
  -Z, --nocompress
        request uncompressed files when downloading
  -R DIR, --installroot=DIR
        root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM
  -P DIR, --packagingroot=DIR
        root directory used when packaging files, like RPM packaging
  --ignore-errors
        force install even if there were errors
  -a, --alldeps
        install all required and optional dependencies
  -o, --onlyreqdeps
        install all required dependencies
  -O, --offline
        do not attempt to download any urls or contact channels
  -p, --pretend
        Only list the packages that would be downloaded

Die zu installierenden PEAR-Module sind: [Mail], [Mail_Mime], [Net_SMTP]. Geben Sie im Eingabeaufforderungsfenster nacheinander die folgenden Befehle ein:

<PHP_installDir>pear install Mail
...
<PHP_installDir>pear install Mail_Mime
<PHP_installDir>pear install Net_SMTP

wobei <PHP_installDir> das Installationsverzeichnis des PHP-Interpreters ist (in diesem Beispiel C:\serveursSGBD\wamp21\bin\PHP\php5.3.5)

Sie können die installierten Module anzeigen:

C:\serveursSGBD\wamp21\bin\PHP\php5.3.5>pear list
INSTALLED PACKAGES, CHANNEL PEAR.php.NET:
=========================================
PACKAGE          VERSION STATE
Archive_Tar      1.3.7   stable
Console_Getopt   1.3.1   stable
Mail             1.2.0   stable
Mail_Mime        1.8.1   stable
Net_SMTP         1.6.0   stable
Net_Socket       1.0.10  stable
PEAR             1.9.4   stable
PHPUnit          1.3.2   stable
Structures_Graph 1.0.4   stable
XML_Util         1.2.1   stable

Die Module werden im Ordner <PHP_installDir>/PEAR installiert:

Nachdem die PEAR-Module installiert sind, sieht das PHP-Skript zum Versenden von E-Mails wie folgt aus:


<?php
 
// error management
ini_set("display_errors", "off");
// modules
ini_set("include_path", ".;C:\serveursSGBD\wamp21\bin\PHP\php5.3.5\PEAR");
require_once "Mail.php";
require_once "Mail/Mime.php";
require_once "Net/SMTP.php";
 
 
// client SMTP (SendMail Transfer Protocol) for sending a message
// information is taken from a $INFOS file containing the following lines
// line 1: smtp, sender, recipient, attachment
// next lines: message text
// sender:email sender
// recipient: email recipient
// smtp: name of smtp server to use
// attachment: name of the document to be attached
// 
// data
$INFOS = "mail2.txt"; // mail settings
// retrieve mail parameters
list($erreur, $smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement) = getInfos($INFOS);
// mistake?
if ($erreur) {
  print "$erreur\n";
  exit;
}
print "Envoi du message [$smtpServer,$expéditeur,$destinataire,$sujet, $attachement]\n";
// sending mail in verbose mode
$résultat = sendmail($smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement);
print "Résultat de l'envoi : $résultat\n";
// end
exit;
 
//-----------------------------------------------------------------------
function getInfos($fichier) {
// returns information ($smtp,$expéditeur,$destinataire,$message, $sujet, $attachement) taken from text file $fichier
// line 1: smtp, sender, recipient, subject, attachment
// next lines: message text
...
// return
  return array("", $smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement);
}
 
//getInfos
//-----------------------------------------------------------------------
 
function sendmail($smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement) {
// sends $message to smtp server $smtpserver from $expéditeur
// for $destinataire. Document $attachement is attached to the message
// message has subject $sujet
// 
  // message
  $msg = new Mail_Mime();
  $msg->setTXTBody($message);
  $msg->addAttachment($attachement);
  $headers = $msg->headers(array("From" => $expéditeur, "To" => $destinataire, "Subject" => $sujet));
  // shipping
  $mailer = &Mail::factory("smtp", array("host" => $smtpServer, "port" => 25));
  $envoi = $mailer->send($expéditeur, $headers, $msg->get());
  if ($envoi === TRUE) {
    return "Message envoyé";
  } else {
    return $envoi;
  }
}
 
// --------------------------------------------------------------------------
 
function cutNewLinechar($ligne) {
// delete the end-of-line mark from $ligne if it exists
  
}

Die Datei [mail2.txt]:

1
2
3
4
smtp.orange.fr, serge.tahe@univ-angers.fr , serge.tahe@univ-angers.fr, test, document.pdf
ligne1
ligne2
ligne3
  • Zeile 1: in dieser Reihenfolge der SMTP-Server, die Absenderadresse, die Empfängeradresse, der Betreff der Nachricht, das anzuhängende Dokument.
  • Zeilen 2–4: der Nachrichtentext

Anzeige der Ergebnisse

Envoi du message [smtp.orange.fr,serge.tahe@univ-angers.fr,serge.tahe@univ-angers.fr,test, document.pdf]
Résultat de l'envoi : Message envoyé

Kommentare

Dieses Skript unterscheidet sich vom vorherigen lediglich durch die Verwendung der sendmail-Funktion. Wir beschreiben diese Funktion im Folgenden:

  • Zeile 6: Die PHP-Skripte für die PEAR-Module wurden in einem Verzeichnis installiert, das der PHP-Interpreter standardmäßig nicht durchsucht. Um sicherzustellen, dass der Interpreter die PEAR-Module finden kann, geben wir manuell die Verzeichnisse an, die er durchsuchen soll. Es ist möglich, bestimmte Konfigurationsparameter des PHP-Interpreters zur Laufzeit zu ändern. Diese Änderung ist nur für das Skript sichtbar, das sie vornimmt, und nur für die Dauer seiner Ausführung. Die Standardkonfiguration des PHP-Interpreters befindet sich in der Datei <PHP_installdir>/PHP.ini. Diese Datei enthält Zeilen der Form
clé=valeur

Der Wert des Schlüssels kann zur Laufzeit mit der Funktion ini_set(key, new_value) geändert werden. Der Schlüssel, der verwendet wird, um den Suchpfad für PHP-Funktionen und -Klassen anzugeben, auf die das Skript verweist, lautet „include_path“. Hier fügen wir sowohl das Skriptverzeichnis (.) als auch das PEAR-Verzeichnis innerhalb des Installationsverzeichnisses des PHP-Interpreters zum Suchpfad hinzu.

  • Zeilen 7–9: Die PHP-Skripte zum Versenden von E-Mails werden geladen.
  • Zeile 50: Die Funktion sendmail, die das Versenden der E-Mail übernimmt. Ihre Parameter lauten wie folgt:
    • $smtpServer: der Name des SMTP-Servers, mit dem eine Verbindung hergestellt werden soll
    • $sender: die E-Mail-Adresse des Absenders
    • $recipient: die E-Mail-Adresse des Empfängers
    • $message: die zu versendende Nachricht
    • $subject: der Betreff der Nachricht
    • $attachment: Der Name des Dokuments, das an die Nachricht angehängt werden soll

Die Funktion sendMail gibt eine Fehlermeldung zurück; sie ist leer, wenn kein Fehler aufgetreten ist.

  • Zeile 56: Erstellung einer Mail_Mime-Nachricht. Diese Nachricht besteht aus Kopfzeilen (From, To, Subject) und einem Textkörper (der Nachricht selbst)
  • Zeile 57: Der Textkörper der Mail_Mime-Nachricht wird festgelegt.
  • Zeile 58: Anhängen eines Dokuments an die Nachricht
  • Zeile 59: Festlegen der Kopfzeilen (From, To, Subject) der Mail_Mime-Nachricht
  • Zeile 61: Erstellung der Klasse, die für das Senden der Mail_Mime-Nachricht zuständig ist. Der erste Parameter der Methode ist der Name des zu verwendenden Protokolls, in diesem Fall das SMTP-Protokoll. Der zweite Parameter ist ein Array, das den Namen und den Port des zu verwendenden SMTP-Dienstes angibt
  • Zeile 62: Senden der Nachricht. Die send-Methode benötigt drei Parameter: die Absenderadresse, die Mail_Mime-Nachrichten-Header und den Mail_Mime-Nachrichten-Body. Die send-Funktion gibt den booleschen Wert TRUE zurück, wenn die Nachricht erfolgreich gesendet wurde, andernfalls eine Fehlermeldung.