Métodos para conectar a una página externa con PHP
Enviado por alegg | En PHP | El 10-08-2009
1
Este tutorial describe las distintas formas que pueden utilizarse conectar a
una pagina externa usando PHP o mostrar una pagina externa a través de
PHP.
Aqui hay una pequeña información de como lograrlo con diferentes
metodos. Si alguien desea añadir al tema, mostrando otro método es bienvenido. Lo estoy haciendo porque me vi en la necesidad de estudiar sobre el tema para unas aplicaciones en el trabajo y creo que será útil para muchos que deseamos aprender sobre el tema.
Hay varias maneras de mostrar un URL remoto en PHP. La elección de un
método sobre otro depende de las necesidades de su simplicidad, control y portabilidad.
Los tres métodos descritos en este post son los estándares file function, la extensión
cURL, y la clase de PEAR HTTP_Request.
Estos tres métodos pueden generalmente hacer todo lo que necesita y por lo menos uno de ellos deben estar disponibles, sea cual sea su configuración del servidor o capacidad de instalar las extensiones personalizadas.
Otras formas de recuperar las URL remotas incluye la extensión pecl_http (http://pecl.php.net/package/pecl_http),
que, aunque todavía en desarrollo, ofrece algunas características prometedoras,
y utilizando el fsockopen() para abrir un zócalo sobre el que envía una petición
HTTP que lo construye pieza por pieza.
El uso del estandar “file function” como la función file_get_contents() es
simple y conveniente.
Sigue automáticamente las redirecciones, así que si utiliza esta función para recuperar el directorio
http://www.example.com/persona/ y el servidor le redirecciona a
http://www.example.com/people/, obtendrá el contenido de la página de índice
de directorio, no un mensaje que le dice que la URL ha cambiado de dirección.
También las funciones de archivo estándar de trabajo tanto con HTTP y FTP.
El inconveniente de este método es que requiere la directiva de configuración
allow_url_fopen a estar activado.
La extensión CURL es una poderosa herramienta. Se basa en el popular libcurl (http://curl.haxx.se/)
para proporcionar un rápido, configurable mecanismo para el manejo de una amplia
variedad de peticiones de red. Si esta extensión está disponible en su servidor, le recomendamos que utilice.
Si se desactiva allow_url_fopen y cURL no está disponible, el módulo
PEAR HTTP_Request salva el día.
Al igual que todos los módulos de PEAR, es puro PHP, por lo que si puede guardar un archivo PHP en su servidor, puede utilizarlo. HTTP_Request soporta casi cualquier cosa que te gustaría hacer cuando se solicite una URL remota, incluyendo la modificación de cabeceras de
petición y el cuerpo, utilizando un método arbitrario, respuesta y recuperación
de los encabezados.
Para mas información sobre como instalar los modulo de PEAR puedes ir a
http://pear.php.net/manual/en/installation.getting.php
Para recibir información de URL seguras, solo escribe https en vez de http.
Siempre y cuando en PHP haya sido construido en una libreria SSL tal como OpenSSL, todas las funciones que pueden recibir información de URL regulares pueden recibir información de URL seguras.
Verifica la sección de “openssl” en la salida de phpinfo() para ver si tu configuración
de php tiene soporte de SSL.
Aquí hay varios ejemplos de lo que se puede hacer con los 3 métodos.
Obteniendo una URL con file_get_contents()
$page = file_get_contents('http://www.example.com/algo.txt');
echo $page;
Obteniendo una URL con cURL
$c = curl_init('http://www.example.com/algo.txt');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$page = curl_exec($c);
curl_close($c);
echo $page;
Obteniendo una URL con HTTP_Request
sendRequest();
$page = $r->getResponseBody();
echo $page;
Mostrar una pagina protegida con file_get_contents()
$url = 'http://FDW:PASS@www.example.com/proyecto.php';
$page = file_get_contents($url);
echo $page;
Mostrar una pagina protegida con cURL
$c = curl_init('http://www.example.com/proyecto.php');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_USERPWD, 'FDW:PASS');
$page = curl_exec($c);
curl_close($c);
echo $page;
Mostrar una pagina protegida con HTTP_Request
setBasicAuth('FDW','PASS');
$r->sendRequest();
$page = $r->getResponseBody();
echo $page;
Enviar por el método de POST requiere de manejo especial en cada argumento. Con el método de GET, estos argumentos están en la cadena de consulta, pero en un POST van en la solicitud cuerpo.
Además, la solicitud necesita una cabecera Content-Length que le dice al servidor el tamaño del contenido a esperar en la solicitud cuerpo.
Mostrar una dirección URL con el método de POST en vez del metdo de GET es bien útil cuando la cadena es muy larga, más de 200 caracteres aproximadamente.
La especificación de HTTP 1.1 en el RFC 2616 no impone una longitud máxima en las
URL, por lo que el comportamiento varía entre las diferentes web y servidores proxy.
Si al mostrar las URL con GET y recibes resultados inesperados o resultados con el código de estado 414 ( “Request-URI Too Long”), convierte la solicitud al método de POST.
Usar el metodo de POST con file_get_contents()
$url = 'http://www.example.com/submit.php';
$body = 'FDW=programacion&PHP=f18';
$options = array('method' => 'POST', 'content' => $body);
$context = stream_context_create(array('http' => $options));
$page = file_get_contents($url, false, $context);
echo $page;
Usar el metodo de POST con cURL
$url = 'http://www.example.com/submit.php'; $body = 'FDW=programacion&PHP=f18'; $c = curl_init($url); curl_setopt($c, CURLOPT_POST, true); curl_setopt($c, CURLOPT_POSTFIELDS, $body); curl_setopt($c, CURLOPT_RETURNTRANSFER, true); $page = curl_exec($c); curl_close($c); echo $page;
Usar el metodo de POST con HTTP_Request
setMethod(HTTP_REQUEST_METHOD_POST);
$r->addPostData('FDW','programacion');
$r->addPostData('PHP','f18');
$r->sendRequest();
$page = $r->getResponseBody();
echo $page;
Las cookies se envían al servidor en el encabezado de solicitud de cookies. La extensión cURL tiene una opción específica en cookies, pero con HTTP_Request, tienes que agregar el encabezado de cookies al igual que con otras cabeceras de petición.
Los valores de Cookie múltiples se envían en una lista delimitada por coma.
En los ejemplos vamos a enviar dos cookies: una con el nombre de user y con el valor FDW y otra con el nombre de actividad y con el valor de programacion.
Enviar cookies con file_get_contents()
$options = array('http' =>
array(
'method' => 'GET',
'header' => 'Content-type: text/plain;charset=UTF-8\r\n'.
'Referer: http://www.forosdelweb.com\r\n'.
'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6\r\n'.
'Cookie: user=FDW; actividad=programacion;\r\n'
)
);
$context = stream_context_create($options);
$page = file_get_contents('http://www.example.com/needs-cookies.php', false, $context);
echo $page;
Enviar cookies con cURL
$c = curl_init('http://www.example.com/needs-cookies.php');
curl_setopt($c, CURLOPT_COOKIE, 'user=FDW; actividad=programacion');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$page = curl_exec($c);
curl_close($c);
echo $page;
Enviar cookies con HTTP_Request
addHeader('Cookie','user=FDW; actividad=programacion');
$r->sendRequest();
$page = $r->getResponseBody();
echo $page;
Seguir redireccionamientos con file_get_contents()
Nota: El file_get_contents() sigue automáticamente las redirecciones (header(“Location: redireccion.php”)).
$url = 'http://www.example.com/redirector.php'; print file_get_contents($url);
Seguir redireccionamientos con cURL
$c = curl_init('http://www.example.com/redirector.php');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
$page = curl_exec($c);
curl_close($c);
Seguir redireccionamientos con HTTP_Client
Nota: HTTP_request no sigue las redirecciones, pero el módulo de PEAR HTTP_Client logra lo que queremos.
get($url);
$response = $client->currentResponse();
print $response['body'];
Como hemos indicado anteriormente el file_get_contents() sigue automáticamente las redirecciones (header(“Location: redireccion.php”)).
A partir de PHP 5.0.0, file_get_contents() y fopen() nos da unas opciones especificas acerca de como obtener el stream. En PHP 5.1.0 y posteriores, una de esas opciones es max_redirects el número máximo de redirecciones a seguir. Si indicamos el max_redirects a 0 o 1, solo hace una solicitud.
El max_redirects realmente no indica el número de redirecciones deben seguirse, pero el número máximo de solicitudes que deben efectuarse en el momento siguiente a la cadena de redireccionamiento. Es decir, un valor de 1 le dice a PHP que al menos una solicitud debe seguir, y no un redireccionamiento. Un valor de 2 le dice a PHP para que al menos de 2 solicitudes deben seguir y no más de 1 redireccionamiento. (Un valor de 0, sin embargo, se comporta como un valor de 1, PHP hace sólo 1 solicitud.)
No seguir redirecciones con file_get_contents()
$context = stream_context_create(array('http' => $options));
print file_get_contents($url, false, $context);
No seguir redirecciones con cURL
Nota: Para no seguir las redirecciones no uses CURLOPT_FOLLOWLOCATION
$c = curl_init('http://www.example.com/redirector.php');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$page = curl_exec($c);
curl_close($c);
No seguir redirecciones con HTTP_Request
Nota: HTTP_Request no sigue redirecciones
sendRequest(); print $r->getResponseBody();
Si quieres obtener una URL remota, pero no quieres esperar demasiado tiempo si el servidor remoto está ocupado o lento.
Configurar tiempo limite con file_get_contents()
Nota: Estableceremos el tiempo limite a 15 segundos
ini_set('default_socket_timeout', 15);
$page = file_get_contents('http://slow.example.com/');
Configurar tiempo limite con cURL
Nota: Estableceremos el tiempo limite a 15 segundos
$c = curl_init('http://slow.example.com/');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 15);
$page = curl_exec($c);
curl_close($c);
Configurar tiempo limite con HTTP_Request
Nota: Estableceremos el tiempo limite a 15 segundos
$req = new HTTP_Request('http://slow.example.com/', $opts);
$req->sendRequest();
Si dependes de un servicio remoto, puede estar funcionando y en marcha, pero no estará en condiciones de manejar sus pedidos debido a problemas de red entre tu servidor y el servidor remoto. Limitar la cantidad de tiempo que espera de
PHP para conectar a un servidor remoto es una buena idea, si se utilizan datos procedentes de fuentes remotas que sea parte del proceso de construcción de la página.
Todas las técnicas que describiremos limita la cantidad de tiempo de espera de PHP para conectar a un servidor remoto. Si estas realmente preocupado por las respuestas rápidas, adicionalmente configura el límite de cuánto tiempo
PHP espera recibir los datos de los zócalos conectados.
Para una conexión stream, utilice la función de stream_set_timeout(). Para esta función necesitas abrir un stream con fopen() y no con file_get_contents(). En los ejemplo limitaremos el tiempo de leer a 20 segundos.
Aunque el establecimiento de conexión y los tiempos de lectura puede mejorar el rendimiento, también puede dar lugar a respuestas ilegibles. La secuencia de comandos puede leer sólo una respuesta parcial ante un tiempo de expiración.
Si ha establecido los tiempos, asegúrese de validar toda la respuesta que ha recibido. Por otra parte, en situaciones en las que la generación de la página rápido es fundamental, puedes recuperar los datos externos en un proceso separado y escribir a una memoria caché local.
De esta forma, sus páginas pueden usar el caché, sin temor a límites de tiempo o respuestas parciales
Configurar el tiempo de leer con fopen()
$url = 'http://slow.example.com'; $stream = fopen($url, 'r'); stream_set_timeout($stream, 20); $response_body = stream_get_contents($stream);
Configurar el tiempo de leer con cURL
$c = curl_init('http://slow.example.com/');
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($c, CURLOPT_TIMEOUT, 20);
$page = curl_exec($c);
curl_close($c);
Configurar el tiempo de leer con HTTP_Request
require_once 'HTTP/Request.php';
$opts = array('readTimeout' => array(20,0));
$req = new HTTP_Request('http://slow.example.com/', $opts);
$req->sendRequest()
Para mostrar una página que incluye variables de cadena en la consulta, puedes hacer uso de
http_build_query() para crear la cadena de consulta. Se acepta una serie de clave/valor en pares y devuelve una única cadena con todo escapado correctamente. Usted es responsable del simbolo de ? en el URL que establecen la consulta.
Ejemplo con file_get_contents()
$vars = array('FDW' => 4, 'Programación' => 'PHP & f18');
$qs = http_build_query($vars);
$url = 'http://www.example.com/search.php?' . $qs;
$page = file_get_contents($url);
Ya hemos visto como obtener información de otros servidores. Si deseas manejar la informacion en vez de imprimirlo directamente en la pagina lo pasas a una variable y luego lo puedes manejar. Ejemplo de un codigo que desea mostrar en la pagina el resultado de las palabras que buscas pero que estén destacadas (“highlighted”).
$body = ' Me gusta mucho la programación de PHP. Deseas saber sobre programación de PHP. Yo deseo aprender sobre file_get_contents(), cURL y HTTP_Request.¡cURL no es una etiqueta de HTML! '; $words = array('PHP','cURL'); $replacements = array(); foreach ($words as $i => $word) { $replacements[] = "$word"; } $parts = preg_split("{(< (?:\"[^\"]*\"|'[^']*'|[^'\">])*>)}", $body, -1, PREG_SPLIT_DELIM_CAPTURE); foreach ($parts as $i => $part) { if (isset($part[0]) && ($part[0] == '< ')) { continue; } $parts[$i] = str_replace($words, $replacements, $part); } $body = implode('',$parts); print $body;
$body representa el resultado que hayamos obtenido usando uno de los métodos que hemos usado.
Para poder manipular los links de lo que hayamos obtenido usando cualquiera de los metodos mencionados podemos usar este codigo.
En este caso usare file_get_contents()
$html = file_get_contents('http://www.example.com/');
function extract_links($html) {
$links = array();
preg_match_all('/]*)[\"\']?[^>]*>(.*?)< \/a>/i', $html,$matches,PREG_SET_ORDER);
foreach($matches as $match) {
$links[] = array($match[1],$match[2]);
}
return $links."";
}
$links = extract_links($html);
foreach ($links as $link) {
echo $link[0] . "\n";
}
En este código usaremos cURL para ver los estatus de los links. Es una buena forma para ver si los links que hemos posteado en la pagina estan rotos o han sido movidos. Solo escribe el nombre en el navegador
http://localhost/nombre_de_este_arch…s_de_links.com No tiene que ser otra direccion puede ser hasta tus propios archivos.
Una vez que una página se haya cargado, el programa utiliza el XPath para obtener una lista de enlaces en la página. Entonces, después de un preprocesamiento busca cada uno de los vínculos, los enlace son recuperados.
Debido a que sólo necesita las cabeceras de estas respuestas, no necesitamos usar el método de GET, esto lo hacemos con la opción CURLOPT_NOBODY.
Al activar CURLOPT_HEADER le indica a curl_exec() que incluya en la respuesta la cabecera en la cadena que envia. Basado en la respuesta, el estatus del link es impreso a la misma vez con la nueva localidad si ha sido movido.
$url = $_GET['url'];
// Load the page
list($page,$pageInfo) = load_with_curl($url);
if (! strlen($page)) {
die("No page retrieved from $url");
}
// Convert to XML for easy parsing
$opts = array('output-xhtml' => true, 'numeric-entities' => true);
$xml = tidy_repair_string($page, $opts);
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('xhtml','http://www.w3.org/1999/xhtml');
// Compute the Base URL for relative links
$baseURL = '';
// Check if there is a in the page
$nodeList = $xpath->query('//xhtml:base/@href');
if ($nodeList->length == 1) {
$baseURL = $nodeList->item(0)->nodeValue;
}
// No , so build the Base URL from $url
else {
$URLParts = parse_url($pageInfo['url']);
if (! (isset($URLParts['path']) && strlen($URLParts['path']))) {
$basePath = '';
} else {
$basePath = preg_replace('#/[^/]*$#','',$URLParts['path']);
}
if (isset($URLParts['username']) || isset($URLParts['password'])) {
$auth = isset($URLParts['username']) ? $URLParts['username'] : '';
$auth .= ':';
$auth .= isset($URLParts['password']) ? $URLParts['password'] : '';
$auth .= '@';
} else {
$auth = '';
}
$baseURL = $URLParts['scheme'] . '://' .
$auth . $URLParts['host'] .
$basePath;
}
// Keep track of the links we visit so we don't visit each more than once
$seenLinks = array();
// Grab all links
$links = $xpath->query('//xhtml:a/@href');
foreach ($links as $node) {
$link = $node->nodeValue;
// resolve relative links
if (! preg_match('#^(http|https|mailto):#', $link)) {
if (((strlen($link) == 0)) || ($link[0] != '/')) {
$link = '/' . $link;
}
$link = $baseURL . $link;
}
// Skip this link if we've seen it already
if (isset($seenLinks[$link])) {
continue;
}
// Mark this link as seen
$seenLinks[$link] = true;
// Print the link we're visiting
echo $link.': ';
flush();
list($linkHeaders, $linkInfo) = load_with_curl($link, 'HEAD');
// Decide what to do based on the response code
// 2xx response codes mean the page is OK
if (($linkInfo['http_code'] >= 200) && ($linkInfo['http_code'] < 300)) {
$status = 'OK';
}
// 3xx response codes mean redirection
else if (($linkInfo['http_code'] >= 300) && ($linkInfo['http_code'] < 400)) {
$status = 'MOVED';
if (preg_match('/^Location: (.*)$/m',$linkHeaders,$match)) {
$status .= ': ' . trim($match[1]);
}
}
// Other response codes mean errors
else {
$status = "ERROR: {$linkInfo['http_code']}";
}
// Print what we know about the link
echo "$status\n";
}
function load_with_curl($url, $method = 'GET') {
$c = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
if ($method == 'GET') {
curl_setopt($c,CURLOPT_FOLLOWLOCATION, true);
}
else if ($method == 'HEAD') {
curl_setopt($c, CURLOPT_NOBODY, true);
curl_setopt($c, CURLOPT_HEADER, true);
}
$response = curl_exec($c);
return array($response, curl_getinfo($c));
}
Este tutorial se ha publicado gracias a la colaboracion de abimaelrc y se ira actualizando periódicamente




Información Bitacoras.com…
Valora en Bitacoras.com: Este tutorial describe las distintas formas que pueden utilizarse conectar a una pagina externa usando PHP o mostrar una pagina externa a través de PHP, etc. Aqui hay una pequeña información de como lograrlo con diferentes me…..