Skip to content

9. Le funzioni di rete di PHP

Passiamo ora alle funzioni di rete di PHP che ci consentono di effettuare la programmazione TCP / IP (Transfer Control Protocol / Internet Protocol).

9.1. Ottenere il nome o l’indirizzo IP di un computer su Internet (inet_01)


<?php

// funzioni nome macchina <--> indirizzo IP macchina
ini_set("display_errors", "off");
// costanti
$HOTES = array("istia.univ-angers.fr", "www.univ-angers.fr", "www.ibm.com", "localhost", "", "xx");
// indirizzi IP delle macchine di $HOTES
for ($i = 0; $i < count($HOTES); $i++) {
  getIPandName($HOTES[$i]);
}
// fine
exit;

//------------------------------------------------
function getIPandName($nomMachine) {
//$nomMachine: nome della macchina di cui si desidera l'indirizzo IP
// nomMachine-->indirizzo IP
  $ip = gethostbyname($nomMachine);
  if ($ip != $nomMachine) {
    print "ip[$nomMachine]=$ip\n";
// indirizzo 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";
  }
}

Risultati:

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

Commenti

  • riga 4: si richiede che gli errori di esecuzione non vengano visualizzati.

Le funzioni di rete di PHP vengono utilizzate nella funzione getIpandName alla riga 15.

  • riga 18: la funzione gethostbyname($nom) consente di ottenere l'indirizzo IP "ip3.ip2.ip1.ip0" del computer denominato $nom. Se la macchina $nom non esiste, la funzione restituisce $nom come risultato.
  • riga 22: la funzione gethostbyaddr($ip) consente di ottenere il nome del computer con indirizzo $ip nella forma "ip3.ip2.ip1.ip0". Se il computer $ip non esiste, la funzione restituisce $ip come risultato.

9.2. Un client web ( inet_02)

Uno script che consente di ottenere il contenuto della pagina indice di un sito web.


<?php

// gestione degli errori
ini_set("display_errors","off");
// ottenere il testo HTML da URL
// elenco dei siti web
$SITES = array("istia.univ-angers.fr", "www.univ-angers.fr", "www.ibm.com", "xx");
// lettura delle pagine indice dei siti della tabella $SITES
for ($i = 0; $i < count($SITES); $i++) {
// lettura della pagina indice del sito $SITES[$i]
  $résultat = getIndex($SITES[$i]);
// visualizzazione del risultato
  print "$résultat\n";
}//per
// fine
exit;

//-----------------------------------------------------------------------
function getIndex($site) {
// legge il file URL $site/ e lo salva nel file $site.html
// creazione del file $site.html
  $html = fopen("$site.html", "w");
  if (!$html)
    return "Erreur lors de la création du fichier $site.html";

// apertura di una connessione sulla porta 80 di $site
  $connexion = fsockopen($site, 80);
// ritorno in caso di errore
  if (!$connexion)
    return "Echec de la connexion au site ($site,80) : $erreur";
// $connexion rappresenta un flusso di comunicazione bidirezionale
// tra il client (questo programma) e il server web contattato
// questo canale viene utilizzato per lo scambio di comandi e informazioni
// il protocollo di comunicazione è HTTP
// il client invia il comando GET per richiedere l'URL /
// sintassi GET URL HTTP/1.0
// le intestazioni (header) del protocollo HTTP devono terminare con una riga vuota
  fputs($connexion, "GET / HTTP/1.0\n\n");
// il server risponderà ora sul canale $connexion. Invierà tutti
// questi dati e poi chiuderà il canale. Il client legge quindi tutto ciò che arriva da $connexion
// fino alla chiusura del canale
  while ($ligne = fgets($connexion, 1000))
    fputs($html, $ligne);
// il client chiude a sua volta la connessione
  fclose($connexion);
// chiusura del file $html
  fclose($html);
// ritorno
  return "Transfert réussi de la page index du site $site";
}

Risultati: ad esempio, il file ricevuto per il sito [www.ibm.com]:

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>
  • le righe da 1 a 11 sono le intestazioni HTTP della risposta del server
  • riga 1: il server chiede al client di reindirizzarsi all’indirizzo indicato alla riga 8
  • riga 2: data e ora della risposta
  • riga 3: identità del server web
  • riga 4: contenuto inviato dal server. In questo caso una pagina HTML che inizia alla riga 13
  • riga 12: la riga vuota che conclude le intestazioni HTTP
  • righe 13-19: la pagina HTML inviata dal server web.

Commenti al codice:

  • riga 7: l’elenco degli URL dei siti web di cui si desidera la pagina iniziale. Questa verrà salvata nel file di testo [nomsite.html].
  • riga 11: la funzione getIndex esegue l'operazione
  • riga 19: la funzione getIndex($site) scarica la pagina radice (o pagina iniziale) del sito web $site e la salva nel file di testo $site.html.
  • riga 27: la funzione fsockopen($site,$port) consente di creare una connessione con un servizio TCP / IP operante sulla porta $port del computer $site. Una volta aperta la connessione client/server, numerosi servizi TCP / IP scambiano righe di testo. È il caso, in questo contesto, del protocollo HTTP (HyperText Transfer Protocol). Il flusso proveniente dal server e in arrivo al client può quindi essere trattato come un file di testo. Lo stesso vale per il flusso in uscita dal client verso il server.
  • riga 38: la funzione fputs consente al client di inviare dati al server. In questo caso, la riga di testo inviata ha il seguente significato: «Voglio (GET) la pagina radice (/) del sito web a cui sono connesso. Sto utilizzando il protocollo HTTP versione 1.0". La versione attuale di questo protocollo è la 1.1.
  • riga 42: le righe di testo della risposta del server possono essere lette riga per riga con un ciclo while e salvate nel file di testo [$site.html]. Quando il server web ha inviato la pagina richiesta, chiude la connessione con il client. Dal lato client, ciò verrà rilevato come fine del file.

9.3. Un client SMTP (inet_03)

Tra i protocolli TCP / IP, SMTP (SendMail Transfer Protocol) è il protocollo di comunicazione del servizio di invio dei messaggi.

Note:

  • su un computer Windows dotato di antivirus, quest’ultimo probabilmente impedirà allo script PHP di connettersi alla porta 25 di un server SMTP. È quindi necessario disattivare l’antivirus. Per McAfee, ad esempio, è possibile procedere come segue:
  • in [1], si attiva la console VirusScan
  • in [2], si arresta il servizio [Protection lors de l'accès]
  • in [3], il servizio è arrestato

Lo script:


<?php

// client SMTP (protocollo di trasferimento SendMail) che consente di inviare un messaggio
// le informazioni vengono prelevate da un file $INFOS contenente le seguenti righe
// riga 1: smtp, mittente, destinatario
// righe successive: il testo del messaggio
// mittente: email del mittente
// destinatario: email del destinatario
// smtp: nome del server smtp da utilizzare
// protocollo di comunicazione client-server SMTP
// -> il client si connette alla porta 25 del server SMTP
// <- il server gli invia un messaggio di benvenuto
// -> il client invia il comando EHLO: nome del proprio computer
// <- il server risponde con OK oppure no
// -> il client invia il comando mail from: <mittente>
// <- il server risponde con OK oppure no
// -> il client invia il comando rcpt a: <destinatario>
// <- il server risponde con OK oppure no
// -> il client invia il comando data
// <- il server risponde con OK oppure no
// -> il client invia tutte le righe del proprio messaggio e termina con una riga contenente il
// unico carattere.
// <- il server risponde con OK oppure no
// -> il client invia il comando quit
// <- il server risponde con OK oppure no
// le risposte del server hanno il formato xxx testo, dove xxx è un numero a 3 cifre. Qualsiasi numero xxx >=500
// segnala un errore. La risposta può comprendere più righe, tutte inizianti con xxx tranne l'ultima
// del formato xxx(spazio)
// le righe di testo scambiate devono terminare con i caratteri RC(#13) e LF(#10)

// dati
$INFOS = "mail.txt"; // i parametri di invio dell'e-mail
// si recuperano i parametri della posta
list($erreur, $smtpServer, $expéditeur, $destinataire, $message) = getInfos($INFOS);
// errore?
if ($erreur) {
  print "$erreur\n";
  exit;
}
print "Envoi du message [$smtpServer,$expéditeur,$destinataire]\n";
// invio dell'e-mail in modalità verbosa
$résultat = sendmail($smtpServer, $expéditeur, $destinataire, $message, 1);
print "Résultat de l'envoi : $résultat\n";
// fine
exit;

//-----------------------------------------------------------------------
function getInfos($fichier) {
// restituisce le informazioni ($smtp,$expéditeur,$destinataire,$message) dal file di testo $fichier
// riga 1: smtp, mittente, destinatario
// righe successive: il testo del messaggio

// apertura di $fichier
  $infos = fopen($fichier, "r");
// il file $fichier esiste
  if (!$infos)
    return array("Le fichier $fichier n'a pu être ouvert en lecture");
// lettura della prima riga
  $ligne = fgets($infos, 1000);
// rimozione del carattere di fine riga
  $ligne = cutNewLineChar($ligne);
// recupero dei campi smtp, mittente, destinatario
  $champs = explode(",", $ligne);
// il numero di campi è corretto?
  if (count($champs) != 3)
    return "La ligne 1 du fichier $fichier (serveur smtp, expéditeur, destinataire) a un
nombre de champs incorrect";
// "elaborazione" delle informazioni recuperate
  for ($i = 0; $i < count($champs); $i++)
    $champs[$i] = trim($champs[$i]);
// recupero dei campi
  list($smtpServer, $expéditeur, $destinataire) = $champs;
// lettura del messaggio
  $message = "";
  while ($ligne = fgets($infos, 1000))
    $message.=$ligne;
  fclose($infos);
// ritorno
  return array("", $smtpServer, $expéditeur, $destinataire, $message);
}

//-----------------------------------------------------------------------

function sendmail($smtpServer, $expéditeur, $destinataire, $message, $verbose) {
// invia $message al server SMTP $smtpserver a nome di $expéditeur
// per $destinataire. Se $verbose=1, esegue il monitoraggio degli scambi client-server
// si recupera il nome del client
  $client = gethostbyaddr(gethostbyname(""));
// apertura di una connessione sulla porta 25 di $smtpServer
  $connexion = fsockopen($smtpServer, 25);
// ritorno in caso di errore
  if (!$connexion)
    return "Echec de la connexion au site ($smtpServer,25)";
// $connexion rappresenta un flusso di comunicazione bidirezionale
// tra il client (questo programma) e il server SMTP contattato
// questo canale viene utilizzato per lo scambio di comandi e informazioni

// dopo la connessione, il server invia un messaggio di benvenuto che viene letto
  $erreur = sendCommand($connexion, "", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }

// comando EHLO:
  $erreur = sendCommand($connexion, "EHLO $client", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }

// comando mail from:
  $erreur = sendCommand($connexion, "MAIL FROM: <$expéditeur>", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }

// comando rcpt to:
  $erreur = sendCommand($connexion, "RCPT TO: <$destinataire>", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }

// comando data
  $erreur = sendCommand($connexion, "DATA", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }

// preparazione del messaggio da inviare
  // deve contenere le righe
  // Da: mittente
  // A: destinatario
  // riga vuota
  // Messaggio
  // .
  $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;
  }

// comando quit
  $erreur = sendCommand($connexion, "QUIT", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }

// fine
  fclose($connexion);
  return "Message envoyé";
}

// --------------------------------------------------------------------------

function sendCommand($connexion, $commande, $verbose, $withRCLF) {
// invia $commande nel canale $connexion
// modalità verbosa se $verbose=1
// se $withRCLF=1, aggiunge la sequenza RCLF allo scambio

// dati
  if ($withRCLF)
    $RCLF = "\r\n"; else
    $RCLF="";

// invio comando se $commande non è vuoto
  if ($commande) {
    fputs($connexion, "$commande$RCLF");

// eventuale eco
    if ($verbose)
      affiche($commande, 1);
  }//se

// lettura della risposta
  $réponse = fgets($connexion, 1000);

// eventuale eco
  if ($verbose)
    affiche($réponse, 2);

// recupero codice di errore
  $codeErreur = substr($réponse, 0, 3);

// ultima riga della risposta?
  while (substr($réponse, 3, 1) == "-") {

     // lettura risposta
    $réponse = fgets($connexion, 1000);

     // eventuale eco
    if ($verbose)
      affiche($réponse, 2);
  }//while
// risposta terminata

// errore restituito dal server?
  if ($codeErreur >= 500)
    return substr($réponse, 4);

// ritorno senza errori
  return "";
}

// --------------------------------------------------------------------------

function affiche($échange, $sens) {
// visualizza $échange sullo schermo
// se $sens=1 visualizza -->$echange
// se $sens=2 visualizza <-- $échange senza gli ultimi 2 caratteri 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) {
// si rimuove il carattere di fine riga da $ligne se presente
  ...
}

Il file 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
  • riga 1: [smtp.orange.fr] il server utilizzato per l'invio della posta, [serge.tahe@univ-angers.fr] l'indirizzo del mittente, [serge.tahe@istia.univ-angers.fr] l'indirizzo del destinatario
  • riga 2: intestazioni del messaggio. In questo caso ce n’è solo una, quella dell’oggetto del messaggio.
  • riga 3: la riga vuota conclude le intestazioni del messaggio
  • righe 4-7: il testo del messaggio

Risultati sullo schermo:

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é
  • riga 1: messaggio di monitoraggio dell’esecuzione dello script
  • riga 2: prima risposta del server SMTP. Segue la connessione del client alla porta 25 del server SMTP. Le risposte del server sono righe del tipo [xxx message] o [xxx-message]. La prima sintassi indica che la risposta è terminata. xxx è un codice di risultato. Un valore pari o superiore a 500 segnala un errore. La seconda sintassi indica che la risposta non è terminata e che seguirà un'altra riga.
  • riga 2: il server SMTP indica di essere pronto a ricevere comandi
  • riga 3: il client invia il comando [EHLO nomDeMachine], dove nomDeMachine è il nome Internet del computer su cui è in esecuzione il client
  • righe 4-10: risposta del server SMTP
  • riga 11: il client invia il comando [MAIL FROM: <expéditeur>] che indica l'indirizzo e-mail del mittente.
  • riga 12: il server SMTP indica di accettare tale indirizzo. Avrebbe potuto rifiutarlo se la sintassi fosse stata errata. Detto questo, non verifica se l’indirizzo e-mail esista realmente.
  • riga 13: il client invia il comando [RCPT TO: <destinataire>] che indica l'indirizzo e-mail del destinatario del messaggio.
  • riga 14: il server SMTP risponde che accetta tale indirizzo. Anche in questo caso viene effettuata una verifica sintattica.
  • riga 15: il client invia il comando [DATA], che indica all’utente che le righe che seguiranno costituiscono il testo del messaggio.
  • riga 16: il server risponde che il messaggio può essere inviato. Si tratta di una sequenza di righe di testo che deve terminare con una riga composta da un solo carattere, un punto.
  • righe 17-25: il messaggio inviato dal client
  • righe 17-19: le intestazioni del messaggio [From:, To:, Subject:] servono a indicare rispettivamente il mittente, il destinatario e l’oggetto del messaggio.
  • riga 20: riga vuota che segnala la fine delle intestazioni
  • righe 21-23: il corpo del messaggio
  • riga 24: la riga composta da un unico punto che segnala la fine del messaggio.
  • riga 26: il server SMTP risponde che accetta il messaggio
  • riga 27: il client invia il comando [QUIT] per indicare che ha terminato
  • riga 28: il server SMTP risponde che chiuderà la connessione che lo collega al client

Commenti sul codice

Non approfondiremo molto il codice dello script poiché è stato ampiamente commentato.

  • righe 48-80: la funzione che elabora il file [infos.txt], contenente il messaggio da inviare e le informazioni necessarie per l’invio. Restituisce un array ($erreur, $smtpServer, $expéditeur, $destinataire, $messge) contenente:
    • $erreur: un eventuale messaggio di errore, altrimenti vuoto.
    • $smtpServer: il nome del server SMTP a cui connettersi
    • $expéditeur: l'indirizzo e-mail del mittente
    • $destinataire: l'indirizzo e-mail del destinatario
    • $message: il messaggio da inviare. Oltre al corpo del messaggio, possono essere presenti delle intestazioni.
  • righe 84-157: la funzione sendMail si occupa di inviare il messaggio. I suoi parametri sono i seguenti:
    • $smtpServer: il nome del server SMTP a cui è necessario connettersi
    • $expéditeur: l'indirizzo e-mail del mittente
    • $destinataire: l'indirizzo e-mail del destinatario
    • $message: il messaggio da inviare.
    • $verbose: se pari a 1, indica che gli scambi con il server SMTP devono essere visualizzati sulla console.

La funzione sendMail restituisce un messaggio di errore, vuoto se non si sono verificati errori.

  • riga 88: consente di ottenere il nome Windows di un computer che utilizza OS Windows.
  • riga 99: abbiamo visto che il dialogo client/server si presenta come una sequenza del tipo:
    • invio da parte del client di un comando su una riga
    • risposta del server su una o più righe
  • righe 161-208: la funzione sendCommand accetta i seguenti parametri:
    • $connexion: il canale TCP / IP che collega il client al server
    • $commande: il comando da inviare su questo canale. Verrà letta la risposta del server a tale comando.
    • $verbose: se impostato a 1, indica che gli scambi con il server SMTP devono essere visualizzati sulla console.
    • $withRCLF: se impostato a 1, indica che è necessario aggiungere il carattere di fine riga "\r\n" alla fine del comando
  • riga 173: invio del comando da parte del client
  • riga 181: lettura della prima riga della risposta del server SMTP nella forma xxx testo o xxx-testo. Quest'ultimo caso indica che il server ha un'altra riga da inviare. xxx è il codice di errore inviato dal server.
  • riga 188 – recupero del codice di errore dalla risposta
  • righe 191-199: lettura delle altre righe della risposta
  • righe 203-204: se il codice di errore è >=500, significa che il server SMTP segnala un errore.

9.4. Un secondo programma per l’invio di e-mail (inet_04)

Questo script ha la stessa funzionalità del precedente: inviare un’e-mail. A tal fine utilizziamo i moduli della libreria PEAR. Questa libreria comprende decine di moduli che coprono diversi ambiti. Utilizzeremo i seguenti:

  • Net/SMTP: un modulo che consente di interagire con un server SMTP
  • Mail: un modulo che consente di gestire l’invio di un’e-mail secondo diversi protocolli.
  • Mail/Mime: un modulo che consente di creare un messaggio che può includere documenti allegati.

Per poter utilizzare questi moduli, è necessario prima installarli sul computer su cui viene eseguito lo script PHP. L’installazione del pacchetto software WampServer ha installato un interprete PHP. Nella struttura di quest’ultimo è possibile installare i moduli PEAR.

  • in [1], la cartella di installazione dell'interprete PHP
  • in [2], la cartella PEAR che conterrà i moduli PEAR che verranno installati
  • in [3], il file di comandi [go-pear.bat] che inizializza la libreria PEAR

Per inizializzare la libreria PEAR, si apre una finestra DOS e si esegue il file [go-pear.bat]. Questo script si collegherà al sito web della libreria PEAR. È quindi necessaria una connessione a Internet.

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

Una volta connesso al sito web della biblioteca PEAR, lo script scaricherà una serie di elementi. Tra questi, un nuovo script [pear.bat]. È con questo script che installeremo i vari moduli PEAR di cui abbiamo bisogno. Questo script viene richiamato con degli argomenti. Tra questi, l’argomento [help] consente di ottenere un elenco dei comandi accettati dallo script:

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.

Il comando [install] consente di installare i moduli PEAR. È possibile richiedere assistenza sul comando [install]:

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

I moduli PEAR da installare sono i seguenti: [Mail], [Mail_Mime], [Net_SMTP]. Nella finestra DOS, digitare in successione i seguenti comandi:

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

dove <PHP_installDir> è la cartella di installazione dell'interprete PHP (C:\serveursSGBD\wamp21\bin\PHP\php5.3.5 in questo esempio)

È possibile visualizzare i moduli installati:

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

I moduli sono installati nella cartella <PHP_installDir>/PEAR:

Una volta installati i moduli PEAR, lo script PHP per l'invio delle e-mail diventa il seguente:


<?php

// gestione degli errori
ini_set("display_errors", "off");
// moduli
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 (protocollo di trasferimento SendMail) che consente di inviare un messaggio
// le informazioni sono tratte da un file $INFOS contenente le seguenti righe
// riga 1: smtp, mittente, destinatario, allegato
// righe successive: il testo del messaggio
// mittente: email del mittente
// destinatario: email del destinatario
// smtp: nome del server smtp da utilizzare
// allegato: nome del documento da allegare
// 
// dati
$INFOS = "mail2.txt"; // i parametri di invio dell'e-mail
// si recuperano i parametri dell'e-mail
list($erreur, $smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement) = getInfos($INFOS);
// errore?
if ($erreur) {
  print "$erreur\n";
  exit;
}
print "Envoi du message [$smtpServer,$expéditeur,$destinataire,$sujet, $attachement]\n";
// invio dell'e-mail in modalità verbosa
$résultat = sendmail($smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement);
print "Résultat de l'envoi : $résultat\n";
// fine
exit;

//-----------------------------------------------------------------------
function getInfos($fichier) {
// restituisce le informazioni ($smtp,$expéditeur,$destinataire,$message, $sujet, $attachement) estratte dal file di testo $fichier
// riga 1: smtp, mittente, destinatario, oggetto, allegato
// righe successive: il testo del messaggio
...
// ritorno
  return array("", $smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement);
}

//getInfos
//-----------------------------------------------------------------------

function sendmail($smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement) {
// invia $message al server SMTP $smtpserver a nome di $expéditeur
// per $destinataire. Il documento $attachement è allegato al messaggio
//; l’oggetto del messaggio è $sujet
// 
  // messaggio
  $msg = new Mail_Mime();
  $msg->setTXTBody($message);
  $msg->addAttachment($attachement);
  $headers = $msg->headers(array("From" => $expéditeur, "To" => $destinataire, "Subject" => $sujet));
  // invio
  $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) {
// si elimina il carattere di fine riga da $ligne, se presente
  
}

Il file [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
  • riga 1: nell'ordine, il server SMTP, l'indirizzo del mittente, l'indirizzo del destinatario, l'oggetto del messaggio, il documento da allegare.
  • righe 2-4: il testo del messaggio

Risultati sullo schermo

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é

Commenti

Lo script differisce dal precedente solo per la funzione sendmail. Di seguito ne forniamo una descrizione:

  • riga 6: gli script PHP dei moduli PEAR sono stati installati in una directory che, per impostazione predefinita, non viene esplorata dall’interprete PHP. Affinché quest'ultimo possa individuare i moduli PEAR, definiamo noi stessi le cartelle che l'interprete PHP deve esplorare. È possibile modificare durante l'esecuzione alcuni parametri di configurazione dell'interprete PHP. Tale modifica è visibile solo allo script che la effettua e solo per la durata della sua esecuzione. La configurazione predefinita dell’interprete PHP si trova nel file <PHP_installdir>/PHP.ini. Questo file contiene righe della forma
clé=valeur

Il valore della chiave può essere modificato in fase di esecuzione tramite la funzione ini_set(chiave, nouvelle_valeur). La chiave per specificare il percorso di ricerca da parte dell’interprete delle funzioni e delle classi PHP a cui fa riferimento lo script è 'include_path'. In questo caso, inseriamo nel percorso di ricerca sia la cartella dello script (.) sia la cartella PEAR della cartella di installazione dell'interprete PHP.

  • righe 7-9: vengono caricati gli script PHP per l'invio delle e-mail.
  • riga 50: la funzione sendmail che si occupa di inviare l’e-mail. I suoi parametri sono i seguenti:
    • $smtpServer: il nome del server SMTP a cui connettersi
    • $expéditeur: l'indirizzo e-mail del mittente
    • $destinataire: l'indirizzo e-mail del destinatario
    • $message: il messaggio da inviare.
    • $sujet: l'oggetto del messaggio
    • $attachement: il nome del documento da allegare al messaggio

La funzione sendMail restituisce un messaggio di errore, vuoto se non si sono verificati errori.

  • riga 56: creazione di un messaggio di tipo Mail_Mime. Questo messaggio è composto da intestazioni (From, To, Subject) e da un corpo (il messaggio stesso)
  • riga 57: si imposta il corpo del messaggio Mail_Mime.
  • riga 58: si allega un documento al messaggio
  • riga 59: si impostano le intestazioni (From, To, Subject) del messaggio Mail_Mime
  • riga 61: si crea la classe incaricata di inviare il messaggio Mail_Mime. Il primo parametro del metodo è il nome del protocollo da utilizzare, in questo caso il protocollo SMTP. Il secondo parametro è un array che specifica il nome e la porta del servizio SMTP da utilizzare
  • riga 62: invio del messaggio. Il metodo send riceve tre parametri: l'indirizzo del mittente, le intestazioni del messaggio Mail_Mime e il corpo del messaggio Mail_Mime. La funzione send restituisce il valore booleano TRUE se l'invio è andato a buon fine, altrimenti restituisce un messaggio di errore.