Skip to content

9. Las funciones de red de PHP

Ahora abordamos las funciones de red de PHP que nos permiten realizar programación TCP / IP (Protocolo de control de transferencia / Protocolo de Internet).

9.1. Obtener el nombre o la dirección IP de un equipo de Internet (inet_01)


<?php

// funciones nombre de máquina <--> dirección IP máquina
ini_set("display_errors", "off");
// constantes
$HOTES = array("istia.univ-angers.fr", "www.univ-angers.fr", "www.ibm.com", "localhost", "", "xx");
// direcciones IP de las máquinas de $HOTES
for ($i = 0; $i < count($HOTES); $i++) {
  getIPandName($HOTES[$i]);
}
// fin
exit;

//------------------------------------------------
function getIPandName($nomMachine) {
//$nomMachine: nombre de la máquina cuya dirección se desea obtener IP
// nomMachine-->dirección IP
  $ip = gethostbyname($nomMachine);
  if ($ip != $nomMachine) {
    print "ip[$nomMachine]=$ip\n";
// dirección 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";
  }
}

Resultados:

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

Comentarios

  • línea 4: se solicita que no se muestren los errores de ejecución.

Las funciones de red de PHP se utilizan en la función getIpandName de la línea 15.

  • línea 18: la función gethostbyname($nom) permite obtener la dirección IP «ip3.ip2.ip1.ip0» de la máquina denominada $nom. Si la máquina $nom no existe, la función devuelve $nom como resultado.
  • línea 22: la función gethostbyaddr($ip) permite obtener el nombre de la máquina de la dirección $ip con el formato «ip3.ip2.ip1.ip0». Si el equipo $ip no existe, la función devuelve $ip como resultado.

9.2. Un cliente web ( inet_02)

Un script que permite obtener el contenido de la página de inicio de un sitio web.


<?php

// gestión de errores
ini_set("display_errors","off");
// obtener el texto HTML de URL
// lista de sitios web
$SITES = array("istia.univ-angers.fr", "www.univ-angers.fr", "www.ibm.com", "xx");
// lectura de las páginas de índice de los sitios de la tabla $SITES
for ($i = 0; $i < count($SITES); $i++) {
// lectura de la página de índice del sitio $SITES[$i]
  $résultat = getIndex($SITES[$i]);
// visualización del resultado
  print "$résultat\n";
}//para
// fin
exit;

//-----------------------------------------------------------------------
function getIndex($site) {
// lee el archivo URL $site/ y lo guarda en el archivo $site.html
// creación del archivo $site.html
  $html = fopen("$site.html", "w");
  if (!$html)
    return "Erreur lors de la création du fichier $site.html";

// apertura de una conexión en el puerto 80 de $site
  $connexion = fsockopen($site, 80);
// retorno en caso de error
  if (!$connexion)
    return "Echec de la connexion au site ($site,80) : $erreur";
// $connexion representa un flujo de comunicación bidireccional
// entre el cliente (este programa) y el servidor web contactado
// este canal se utiliza para el intercambio de comandos e información
// el protocolo de diálogo es HTTP
// el cliente envía el comando get para solicitar el URL /
// sintaxis get URL HTTP/1.0
// los encabezados (headers) del protocolo HTTP deben terminar con una línea en blanco
  fputs($connexion, "GET / HTTP/1.0\n\n");
// el servidor responderá ahora en el canal $connexion. Enviará todos
// estos datos y luego cerrará el canal. Por lo tanto, el cliente lee todo lo que llega desde $connexion
// hasta que se cierre el canal
  while ($ligne = fgets($connexion, 1000))
    fputs($html, $ligne);
// el cliente cierra la conexión a su vez
  fclose($connexion);
// cierre del archivo $html
  fclose($html);
// retorno
  return "Transfert réussi de la page index du site $site";
}

Resultados: por ejemplo, el archivo recibido para el sitio [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>
  • las líneas 1-11 son los encabezados de la respuesta del servidor
  • línea 1: el servidor solicita al cliente que se redirija a la dirección indicada en la línea 8
  • línea 2: fecha y hora de la respuesta
  • línea 3: identidad del servidor web
  • línea 4: contenido enviado por el servidor. En este caso, una página HTML que comienza en la línea 13
  • línea 12: la línea vacía que termina los encabezados HTTP
  • líneas 13-19: la página HTML enviada por el servidor web.

Comentarios del código:

  • línea 7: la lista de Url de los sitios web de los que queremos la página de índice. Esta se almacenará en el archivo de texto [nomsite.html].
  • línea 11: la función getIndex realiza el trabajo
  • línea 19: la función getIndex($site) descarga la página raíz (o página de índice) del sitio web $site y la almacena en el archivo de texto $site.html.
  • línea 27: la función fsockopen($site,$port) permite crear una conexión con un servicio TCP / IP que opera en el puerto $port de la máquina $site. Una vez abierta la conexión cliente/servidor, numerosos servicios TCP / IP intercambian líneas de texto. Este es el caso del protocolo HTTP (HyperText Transfer Protocol). El flujo del servidor que llega al cliente puede tratarse entonces como un archivo de texto. Lo mismo ocurre con el flujo que va del cliente al servidor.
  • Línea 38: la función fputs permite al cliente enviar datos al servidor. En este caso, la línea de texto enviada tiene el siguiente significado: «Quiero (GET) la página raíz (/) del sitio web al que estoy conectado. Trabajo con el protocolo HTTP version 1.0». La versión actual de este protocolo es 1.1.
  • Línea 42: las líneas de texto de la respuesta del servidor se pueden leer línea por línea con un bucle while y guardar en el archivo de texto [$site.html]. Cuando el servidor web ha enviado la página solicitada, cierra su conexión con el cliente. Del lado del cliente, esto se detectará como un fin de archivo.

9.3. Un cliente SMTP (inet_03)

Entre los protocolos TCP / IP, SMTP (SendMail Transfer Protocol) es el protocolo de comunicación del servicio de envío de mensajes.

Notas:

  • en un equipo Windows que tenga un antivirus, es probable que este impida que el script PHP se conecte al puerto 25 de un servidor SMTP. En ese caso, hay que desactivar el antivirus. Para McAfee, por ejemplo, se puede proceder de la siguiente manera:
  • En [1], se activa la consola VirusScan
  • en [2], se detiene el servicio [Protection lors de l'accès]
  • en [3], está detenido

El script:


<?php

// cliente SMTP (protocolo de transferencia SendMail) que permite enviar un mensaje
// la información se toma de un archivo $INFOS que contiene las siguientes líneas
// línea 1: smtp, remitente, destinatario
// líneas siguientes: el texto del mensaje
// remitente: correo electrónico del remitente
// destinatario: correo electrónico del destinatario
// smtp: nombre del servidor smtp que se va a utilizar
// protocolo de comunicación SMTP cliente-servidor
// -> el cliente se conecta al puerto 25 del servidor SMTP
// <- el servidor le envía un mensaje de bienvenida
// -> el cliente envía el comando EHLO: nombre de su máquina
// <- el servidor responde OK o no
// -> el cliente envía el comando mail from: <remitente>
// <- el servidor responde OK o no
// -> el cliente envía el comando rcpt to: <destinatario>
// <- el servidor responde OK o no
// -> el cliente envía el comando data
// <- el servidor responde OK o no
// -> el cliente envía todas las líneas de su mensaje y termina con una línea que contiene el
// único carácter.
// <- el servidor responde OK o no
// -> el cliente envía el comando quit
// <- el servidor responde OK o no
// las respuestas del servidor tienen el formato xxx texto, donde xxx es un número de 3 dígitos. Cualquier número xxx >=500
// indica un error. La respuesta puede contener varias líneas que comienzan todas por xxx, excepto la última
// del formato xxx(espacio)
// las líneas de texto intercambiadas deben terminar con los caracteres RC(#13) y LF(#10)

// datos
$INFOS = "mail.txt"; // los parámetros de envío del correo
// se recuperan los parámetros del correo
list($erreur, $smtpServer, $expéditeur, $destinataire, $message) = getInfos($INFOS);
// ¿Error?
if ($erreur) {
  print "$erreur\n";
  exit;
}
print "Envoi du message [$smtpServer,$expéditeur,$destinataire]\n";
// envío del correo en modo detallado
$résultat = sendmail($smtpServer, $expéditeur, $destinataire, $message, 1);
print "Résultat de l'envoi : $résultat\n";
// fin
exit;

//-----------------------------------------------------------------------
function getInfos($fichier) {
// devuelve la información ($smtp,$expéditeur,$destinataire,$message) extraída del archivo de texto $fichier
// línea 1: smtp, remitente, destinatario
// líneas siguientes: el texto del mensaje

// apertura de $fichier
  $infos = fopen($fichier, "r");
// ¿existe el archivo $fichier?
  if (!$infos)
    return array("Le fichier $fichier n'a pu être ouvert en lecture");
// lectura de la primera línea
  $ligne = fgets($infos, 1000);
// eliminación del carácter de fin de línea
  $ligne = cutNewLineChar($ligne);
// recuperación de los campos smtp, remitente, destinatario
  $champs = explode(",", $ligne);
// ¿Tenemos el número correcto de campos?
  if (count($champs) != 3)
    return "La ligne 1 du fichier $fichier (serveur smtp, expéditeur, destinataire) a un
nombre de champs incorrect";
// «procesamiento» de la información recuperada
  for ($i = 0; $i < count($champs); $i++)
    $champs[$i] = trim($champs[$i]);
// recuperación de los campos
  list($smtpServer, $expéditeur, $destinataire) = $champs;
// lectura del mensaje
  $message = "";
  while ($ligne = fgets($infos, 1000))
    $message.=$ligne;
  fclose($infos);
// respuesta
  return array("", $smtpServer, $expéditeur, $destinataire, $message);
}

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

function sendmail($smtpServer, $expéditeur, $destinataire, $message, $verbose) {
// envía $message al servidor SMTP $smtpserver en nombre de $expéditeur
// para $destinataire. Si $verbose=1, realiza un seguimiento de los intercambios cliente-servidor
// se recupera el nombre del cliente
  $client = gethostbyaddr(gethostbyname(""));
// apertura de una conexión en el puerto 25 de $smtpServer
  $connexion = fsockopen($smtpServer, 25);
// retorno en caso de error
  if (!$connexion)
    return "Echec de la connexion au site ($smtpServer,25)";
// $connexion representa un flujo de comunicación bidireccional
// entre el cliente (este programa) y el servidor SMTP contactado
// este canal se utiliza para el intercambio de comandos e información

// tras la conexión, el servidor envía un mensaje de bienvenida que se lee
  $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;
  }

// preparación del mensaje para enviar
  // debe contener las líneas
  // De: remitente
  // Para: destinatario
  // línea en blanco
  // Mensaje
  // .
  $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 de salida
  $erreur = sendCommand($connexion, "QUIT", $verbose, 1);
  if ($erreur) {
    fclose($connexion);
    return $erreur;
  }

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

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

function sendCommand($connexion, $commande, $verbose, $withRCLF) {
// envía $commande al canal $connexion
// modo detallado si $verbose=1
// si $withRCLF=1, añade la secuencia RCLF al intercambio

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

// envío de comando si $commande no está vacío
  if ($commande) {
    fputs($connexion, "$commande$RCLF");

// posible eco
    if ($verbose)
      affiche($commande, 1);
  }//si

// lectura de respuesta
  $réponse = fgets($connexion, 1000);

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

// recuperación del código de error
  $codeErreur = substr($réponse, 0, 3);

// ¿Última línea de la respuesta?
  while (substr($réponse, 3, 1) == "-") {

     // lectura de respuesta
    $réponse = fgets($connexion, 1000);

     // posible eco
    if ($verbose)
      affiche($réponse, 2);
  }//while
// respuesta completada

// ¿error devuelto por el servidor?
  if ($codeErreur >= 500)
    return substr($réponse, 4);

// retorno sin error
  return "";
}

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

function affiche($échange, $sens) {
// muestra $échange en pantalla
// si $sens=1 muestra -->$echange
// si $sens=2 muestra <-- $échange sin los dos últimos caracteres 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) {
// se elimina el marcador de fin de línea de $ligne si existe
  ...
}

El archivo 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
  • línea 1: [smtp.orange.fr] el servidor utilizado para el envío del correo, [serge.tahe@univ-angers.fr] la dirección del remitente, [serge.tahe@istia.univ-angers.fr] la dirección del destinatario
  • línea 2: encabezados del mensaje. Aquí solo hay uno, el del asunto del mensaje.
  • línea 3: la línea en blanco cierra los encabezados del mensaje
  • líneas 4-7: el texto del mensaje

Resultados en pantalla:

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é
  • línea 1: mensaje de seguimiento de la ejecución del script
  • línea 2: primera respuesta del servidor SMTP. Se produce tras la conexión del cliente al puerto 25 del servidor SMTP. Las respuestas del servidor son líneas con el formato [xxx message] o [xxx-message]. La primera sintaxis indica que la respuesta ha finalizado. xxx es un código de resultado. Un valor superior o igual a 500 indica un error. La segunda sintaxis indica que la respuesta no ha finalizado y que seguirá otra línea.
  • línea 2: el servidor SMTP indica que está listo para recibir comandos
  • línea 3: el cliente envía el comando [EHLO nomDeMachine], donde nomDeMachine es el nombre de Internet del equipo en el que se ejecuta el cliente
  • líneas 4-10: respuesta del servidor SMTP
  • línea 11: el cliente envía el comando [MAIL FROM: <expéditeur>], que indica la dirección de correo electrónico del remitente.
  • línea 12: el servidor SMTP indica que acepta esta dirección. Podría haberla rechazado si su sintaxis hubiera sido incorrecta. Dicho esto, no comprueba si la dirección de correo electrónico existe realmente.
  • línea 13: el cliente envía el comando [RCPT TO: <destinataire>], que indica la dirección de correo electrónico del destinatario del mensaje.
  • línea 14: el servidor SMTP responde que acepta esta dirección. Una vez más, se realiza una comprobación sintáctica.
  • línea 15: el cliente envía el comando [DATA], que indica al usuario que las líneas siguientes son las del mensaje.
  • línea 16: el servidor responde que el mensaje puede enviarse. Este es una secuencia de líneas de texto que debe terminar con una línea formada por un solo carácter, un punto.
  • líneas 17-25: el mensaje enviado por el cliente
  • líneas 17-19: los encabezados del mensaje [From:, To:, Subject:] sirven para indicar, respectivamente, el remitente, el destinatario y el asunto del mensaje.
  • línea 20: línea vacía que señala el final de los encabezados
  • líneas 21-23: el cuerpo del mensaje
  • línea 24: la línea formada por un único punto que indica el final del mensaje.
  • línea 26: el servidor SMTP responde que acepta el mensaje
  • línea 27: el cliente envía el comando [QUIT] para indicar que ha terminado
  • línea 28: el servidor SMTP le responde que va a cerrar la conexión que lo une al cliente

Comentarios sobre el código

No entraremos en muchos detalles sobre el código del script, ya que está ampliamente comentado.

  • líneas 48-80: la función que procesa el archivo [infos.txt], que contiene el mensaje a enviar, así como la información necesaria para dicho envío. Devuelve una matriz ($erreur, $smtpServer, $expéditeur, $destinataire, $messge) con:
    • $erreur: un posible mensaje de error; en caso contrario, estará vacío.
    • $smtpServer: el nombre del servidor SMTP al que hay que conectarse
    • $expéditeur: la dirección de correo electrónico del remitente
    • $destinataire: la dirección de correo electrónico del destinatario
    • $message: el mensaje que se va a enviar. Además del cuerpo del mensaje, puede haber encabezados.
  • líneas 84-157: la función sendMail se encarga de enviar el mensaje. Sus parámetros son los siguientes:
    • $smtpServer: el nombre del servidor SMTP al que hay que conectarse
    • $expéditeur: la dirección de correo electrónico del remitente
    • $destinataire: la dirección de correo electrónico del destinatario
    • $message: el mensaje que se va a enviar.
    • $verbose: si es 1, indica que las comunicaciones con el servidor SMTP deben reproducirse en la consola.

La función sendMail devuelve un mensaje de error, vacío si no se ha producido ningún error.

  • línea 88: permite obtener el nombre de Windows de un ordenador que opera con OS Windows.
  • Línea 99: hemos visto que el diálogo cliente/servidor sigue el siguiente formato:
    • envío por parte del cliente de un comando en una línea
    • respuesta del servidor en una o varias líneas
  • líneas 161-208: la función sendCommand admite los siguientes parámetros:
    • $connexion: el canal TCP / IP que conecta al cliente con el servidor
    • $commande: el comando que se debe enviar a este canal. Se leerá la respuesta del servidor a este comando.
    • $verbose: si es 1, indica que los intercambios con el servidor SMTP deben reproducirse en la consola.
    • $withRCLF: si es 1, indica que hay que añadir el carácter de fin de línea «\r\n» al final del comando
  • línea 173: envío del comando por parte del cliente
  • línea 181: lectura de la primera línea de la respuesta del servidor SMTP con el formato xxx texto o xxx-texto. Este último caso indica que el servidor tiene otra línea que enviar. xxx es el código de error enviado por el servidor.
  • línea 188: recuperación del código de error de la respuesta
  • líneas 191-199: lectura de las demás líneas de la respuesta
  • líneas 203-204: si el código de error es >=500, significa que el servidor SMTP señala un error.

9.4. Un segundo programa de envío de correo electrónico (inet_04)

Este script tiene la misma funcionalidad que el anterior: enviar un correo electrónico. Para ello utilizamos módulos de la biblioteca PEAR. Esta biblioteca contiene decenas de módulos que abarcan diferentes ámbitos. Vamos a utilizar los siguientes:

  • Net/SMTP: un módulo que permite comunicarse con un servidor SMTP
  • Mail: un módulo que permite gestionar el envío de un correo electrónico según diferentes protocolos.
  • Mail/Mime: un módulo que permite crear un mensaje que puede incluir documentos adjuntos.

Para disponer de estos módulos, primero hay que instalarlos en el equipo que ejecuta el script PHP. La instalación del paquete de software WampServer ha instalado un intérprete PHP. En el árbol de directorios de este, es posible instalar módulos PEAR.

  • en [1], la carpeta de instalación del intérprete PHP
  • en [2], la carpeta PEAR que contendrá los módulos PEAR que se van a instalar
  • en [3], el archivo de comandos [go-pear.bat] que inicializa la biblioteca PEAR

Para inicializar la biblioteca PEAR, se abre una ventana DOS y se ejecuta el archivo [go-pear.bat]. Este script se conectará al sitio web de la biblioteca PEAR. Por lo tanto, se necesita una conexión a Internet.

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

Una vez conectado al sitio web de la biblioteca PEAR, el script descargará una serie de elementos. Entre ellos, un nuevo script [pear.bat]. Con este script instalaremos los diferentes módulos PEAR que necesitamos. Este script se ejecuta con argumentos. Entre ellos, el argumento [help] permite obtener una lista de los comandos aceptados por el 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.

El comando [install] permite instalar módulos PEAR. Se puede solicitar ayuda sobre el 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

Los módulos PEAR que hay que instalar son los siguientes: [Mail], [Mail_Mime], [Net_SMTP]. En la ventana de DOS, se escribirán sucesivamente los siguientes comandos:

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

donde <PHP_installDir> es la carpeta de instalación del intérprete PHP (C:\serveursSGBD\wamp21\bin\PHP\php5.3.5 en este ejemplo)

Se pueden ver los módulos instalados:

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

Los módulos se instalan en la carpeta <PHP_installDir>/PEAR:

Con los módulos PEAR instalados, el script PHP para el envío de correo electrónico queda así:


<?php

// gestión de errores
ini_set("display_errors", "off");
// módulos
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";


// cliente SMTP (protocolo de transferencia SendMail) que permite enviar un mensaje
// la información se toma de un archivo $INFOS que contiene las siguientes líneas
// línea 1: smtp, remitente, destinatario, archivo adjunto
// líneas siguientes: el texto del mensaje
// remitente: correo electrónico del remitente
// destinatario: correo electrónico del destinatario
// smtp: nombre del servidor smtp que se va a utilizar
// archivo adjunto: nombre del documento que se va a adjuntar
// 
// datos
$INFOS = "mail2.txt"; // parámetros de envío del correo
// se recuperan los parámetros del correo
list($erreur, $smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement) = getInfos($INFOS);
// ¿Error?
if ($erreur) {
  print "$erreur\n";
  exit;
}
print "Envoi du message [$smtpServer,$expéditeur,$destinataire,$sujet, $attachement]\n";
// envío del correo en modo detallado
$résultat = sendmail($smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement);
print "Résultat de l'envoi : $résultat\n";
// fin
exit;

//-----------------------------------------------------------------------
function getInfos($fichier) {
// devuelve la información ($smtp,$expéditeur,$destinataire,$message, $sujet, $attachement) extraídas del archivo de texto $fichier
// línea 1: smtp, remitente, destinatario, asunto, archivo adjunto
// líneas siguientes: el texto del mensaje
...
// volver
  return array("", $smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement);
}

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

function sendmail($smtpServer, $expéditeur, $destinataire, $message, $sujet, $attachement) {
// envía $message al servidor SMTP $smtpserver en nombre de $expéditeur
// para $destinataire. El documento $attachement se adjunta al mensaje
// el mensaje tiene como asunto $sujet
// 
  // mensaje
  $msg = new Mail_Mime();
  $msg->setTXTBody($message);
  $msg->addAttachment($attachement);
  $headers = $msg->headers(array("From" => $expéditeur, "To" => $destinataire, "Subject" => $sujet));
  // envío
  $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) {
// se elimina el marcador de fin de línea de $ligne si existe
  
}

El archivo [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
  • línea 1: en orden, el servidor SMTP, la dirección del remitente, la dirección del destinatario, el asunto del mensaje, el documento que se va a adjuntar.
  • líneas 2-4: el texto del mensaje

Resultados en pantalla

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é

Comentarios

El script solo se diferencia del anterior en su función sendmail. A continuación la describimos:

  • línea 6: los scripts PHP de los módulos PEAR se han instalado en un directorio que, por defecto, no es explorado por el intérprete PHP. Para que este encuentre los módulos PEAR, definimos nosotros mismos las carpetas que debe explorar el intérprete PHP. Es posible modificar durante la ejecución ciertos parámetros de configuración del intérprete PHP. Esta modificación solo es visible para el script que la realiza y únicamente mientras dura su ejecución. La configuración por defecto del intérprete PHP se encuentra en el archivo <PHP_installdir>/PHP.ini. Este archivo contiene líneas con el formato
clé=valeur

El valor de la clave se puede modificar en tiempo de ejecución mediante la función ini_set(clave, nouvelle_valeur). La clave para especificar la ruta de búsqueda por parte del intérprete de las funciones y clases PHP a las que hace referencia el script es «include_path». Aquí, incluimos en la ruta de búsqueda tanto la carpeta del script (.) como la carpeta PEAR de la carpeta de instalación del intérprete PHP.

  • líneas 7-9: se cargan los scripts PHP de envío de correo.
  • Línea 50: la función sendmail, que se encarga de enviar el correo. Sus parámetros son los siguientes:
    • $smtpServer: el nombre del servidor SMTP al que hay que conectarse
    • $expéditeur: la dirección de correo electrónico del remitente
    • $destinataire: la dirección de correo electrónico del destinatario
    • $message: el mensaje que se va a enviar.
    • $sujet: el asunto del mensaje
    • $attachement: el nombre del documento que se adjuntará al mensaje

La función sendMail devuelve un mensaje de error, vacío si no se ha producido ningún error.

  • línea 56: creación de un mensaje de tipo Mail_Mime. Este mensaje se compone de encabezados (From, To, Subject) y de un cuerpo (el mensaje en sí)
  • línea 57: se establece el cuerpo del mensaje Mail_Mime.
  • línea 58: se adjunta un documento al mensaje
  • línea 59: se fijan los encabezados (From, To, Subject) del mensaje Mail_Mime
  • línea 61: se crea la clase encargada de enviar el mensaje Mail_Mime. El primer parámetro del método es el nombre del protocolo que se va a utilizar, en este caso el protocolo SMTP. El segundo parámetro es una matriz que establece el nombre y el puerto del servicio SMTP que se va a utilizar
  • línea 62: envío del mensaje. El método send recibe tres parámetros: la dirección del remitente, los encabezados del mensaje Mail_Mime y el cuerpo del mensaje Mail_Mime. La función send devuelve el valor booleano TRUE si el envío se ha realizado correctamente; de lo contrario, devuelve un mensaje de error.