Técnicas para dominar cURL
Spanish (Español) translation by Valeria Angulo (you can also view the original English article)
cURL es una herramienta para transferir archivos y datos con sintaxis de URL, soportando muchos protocolos incluyendo HTTP, FTP, TELNET y más. Inicialmente, cURL fue diseñado para ser una herramienta de línea de comandos. Por suerte para nosotros, la biblioteca cURL también está soportada por PHP. En este artículo, veremos algunas de las características avanzadas de cURL, y cómo podemos usarlas en nuestros scripts de PHP.
¿Por qué cURL?
Es cierto que hay otras formas de obtener el contenido de una página web. Muchas veces, sobre todo por pereza, me he limitado a utilizar simples funciones de PHP en lugar de cURL:
1 |
$content = file_get_contents("http://www.nettuts.com"); |
2 |
|
3 |
// or
|
4 |
|
5 |
$lines = file("http://www.nettuts.com"); |
6 |
|
7 |
// or
|
8 |
|
9 |
readfile("http://www.nettuts.com"); |
Sin embargo, no tienen prácticamente ninguna flexibilidad y carecen de una gestión suficiente de errores. Además, hay ciertas tareas que simplemente no puedes hacer, como tratar con cookies, autenticación, envíos de formularios, subidas de archivos, etc.
cURL es una potente librería que soporta muchos protocolos y opciones diferentes, y proporciona información detallada sobre las peticiones de URL.
Estructura básica
Antes de pasar a ejemplos más complicados, revisemos la estructura básica de una petición cURL en PHP. Hay cuatro pasos principales:
- Inicializar
- Establecer opciones
- Ejecutar y obtener el resultado
- Liberar el manejador de cURL
1 |
// 1. initialize
|
2 |
$ch = curl_init(); |
3 |
|
4 |
// 2. set the options, including the url
|
5 |
curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); |
6 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
7 |
curl_setopt($ch, CURLOPT_HEADER, 0); |
8 |
|
9 |
// 3. execute and fetch the resulting HTML output
|
10 |
$output = curl_exec($ch); |
11 |
|
12 |
// 4. free up the curl handle
|
13 |
curl_close($ch); |
El paso #2 (es decir, las llamadas a curl_setopt()) va a ser una gran parte de este artículo, porque es donde ocurre toda la magia. Hay una larga lista de opciones de cURL que se pueden establecer, que pueden configurar la solicitud de la URL en detalle. Puede ser difícil revisar toda la lista y digerirla de una vez. Así que hoy, solo vamos a utilizar algunas de las opciones más comunes y útiles en varios ejemplos de código.
Comprobación de errores
Opcionalmente, puedes añadir la comprobación de errores:
1 |
// ...
|
2 |
|
3 |
$output = curl_exec($ch); |
4 |
|
5 |
if ($output === FALSE) { |
6 |
|
7 |
echo "cURL Error: " . curl_error($ch); |
8 |
|
9 |
}
|
10 |
|
11 |
// ...
|
Ten en cuenta que tenemos que utilizar "=== FALSE" para la comparación en lugar de "== FALSE". Porque necesitamos distinguir entre una salida vacía y el valor booleano FALSE, que indica un error.
Obtención de información
Otro paso opcional es obtener información sobre la petición cURL, después de que se haya ejecutado.
1 |
// ...
|
2 |
|
3 |
curl_exec($ch); |
4 |
|
5 |
$info = curl_getinfo($ch); |
6 |
|
7 |
echo 'Took ' . $info['total_time'] . ' seconds for url ' . $info['url']; |
8 |
|
9 |
// ...
|
La siguiente información se incluye en la matriz devuelta:
- "url"
- "content_type"
- "http_code"
- "header_size"
- "request_size"
- "filetime"
- "ssl_verify_result"
- "redirect_count"
- "total_time"
- "namelookup_time"
- "connect_time"
- "pretransfer_time"
- "size_upload"
- "size_download"
- "speed_download"
- "speed_upload"
- "download_content_length"
- "upload_content_length"
- "starttransfer_time"
- "redirect_time"
Detectar la redirección en función del navegador
En este primer ejemplo, escribiremos un script que pueda detectar las redirecciones de URL en función de la configuración del navegador. Por ejemplo, algunos sitios web redirigen a los navegadores de teléfonos móviles, o incluso a los navegantes de diferentes países.
Vamos a utilizar la opción CURLOPT_HTTPHEADER para establecer nuestras cabeceras HTTP salientes, incluyendo la cadena del agente de usuario y los idiomas aceptados. Finalmente comprobaremos si estos sitios web están intentando redirigirnos a diferentes URL.
1 |
// test URLs
|
2 |
$urls = array( |
3 |
"http://www.cnn.com", |
4 |
"http://www.mozilla.com", |
5 |
"http://www.facebook.com"
|
6 |
);
|
7 |
// test browsers
|
8 |
$browsers = array( |
9 |
|
10 |
"standard" => array ( |
11 |
"user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)", |
12 |
"language" => "en-us,en;q=0.5" |
13 |
),
|
14 |
|
15 |
"iphone" => array ( |
16 |
"user_agent" => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A537a Safari/419.3", |
17 |
"language" => "en" |
18 |
),
|
19 |
|
20 |
"french" => array ( |
21 |
"user_agent" => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", |
22 |
"language" => "fr,fr-FR;q=0.5" |
23 |
)
|
24 |
|
25 |
);
|
26 |
|
27 |
foreach ($urls as $url) { |
28 |
|
29 |
echo "URL: $url\n"; |
30 |
|
31 |
foreach ($browsers as $test_name => $browser) { |
32 |
|
33 |
$ch = curl_init(); |
34 |
|
35 |
// set url
|
36 |
curl_setopt($ch, CURLOPT_URL, $url); |
37 |
|
38 |
// set browser specific headers
|
39 |
curl_setopt($ch, CURLOPT_HTTPHEADER, array( |
40 |
"User-Agent: {$browser['user_agent']}", |
41 |
"Accept-Language: {$browser['language']}" |
42 |
));
|
43 |
|
44 |
// we don't want the page contents
|
45 |
curl_setopt($ch, CURLOPT_NOBODY, 1); |
46 |
|
47 |
// we need the HTTP Header returned
|
48 |
curl_setopt($ch, CURLOPT_HEADER, 1); |
49 |
|
50 |
// return the results instead of outputting it
|
51 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
52 |
|
53 |
$output = curl_exec($ch); |
54 |
|
55 |
curl_close($ch); |
56 |
|
57 |
// was there a redirection HTTP header?
|
58 |
if (preg_match("!Location: (.*)!", $output, $matches)) { |
59 |
|
60 |
echo "$test_name: redirects to $matches[1]\n"; |
61 |
|
62 |
} else { |
63 |
|
64 |
echo "$test_name: no redirection\n"; |
65 |
|
66 |
}
|
67 |
|
68 |
}
|
69 |
echo "\n\n"; |
70 |
}
|
Primero tenemos un conjunto de URL para probar, seguido de un conjunto de configuraciones del navegador para probar cada una de estas URL. A continuación, hacemos un bucle a través de estos casos de prueba y hacemos una solicitud cURL para cada uno.
Debido a la configuración de las opciones de cURL, la salida devuelta solo contendrá las cabeceras HTTP (guardadas en $output). Con una simple regex, podemos ver si había una cabecera "Location:" incluida.
Cuando ejecutes este script, deberías obtener una salida como esta:


POSTeando a una URL
En una solicitud GET, los datos pueden ser enviados a una URL a través de la "cadena de consulta". Por ejemplo, cuando se realiza una búsqueda en Google, el término de búsqueda se encuentra en la parte de la cadena de consulta de la URL:
1 |
http://www.google.com/search?q=nettuts |
Puede que no necesites cURL para simular esto en un script web. Puedes simplemente ser perezoso y usar esa url con "file_get_contents()" para recibir los resultados.
Pero algunos formularios HTML están configurados con el método POST. Cuando estos formularios se envían a través del navegador, los datos se envían a través del cuerpo de la solicitud HTTP, en lugar de la cadena de consulta. Por ejemplo, si haces una búsqueda en los foros de CodeIgniter, estarás POSTeando tu consulta de búsqueda a:
1 |
http://codeigniter.com/forums/do_search/ |
Podemos escribir un script PHP para simular este tipo de solicitud de URL. Primero vamos a crear un archivo simple para aceptar y mostrar los datos POST. Llamémoslo post_output.php:
1 |
print_r($_POST); |
A continuación creamos un script PHP para realizar una petición cURL:
1 |
$url = "http://localhost/post_output.php"; |
2 |
|
3 |
$post_data = array ( |
4 |
"foo" => "bar", |
5 |
"query" => "Nettuts", |
6 |
"action" => "Submit" |
7 |
);
|
8 |
|
9 |
$ch = curl_init(); |
10 |
|
11 |
curl_setopt($ch, CURLOPT_URL, $url); |
12 |
|
13 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
14 |
// we are doing a POST request
|
15 |
curl_setopt($ch, CURLOPT_POST, 1); |
16 |
// adding the post variables to the request
|
17 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); |
18 |
|
19 |
$output = curl_exec($ch); |
20 |
|
21 |
curl_close($ch); |
22 |
|
23 |
echo $output; |
Cuando ejecutes este script, deberías obtener una salida como esta:

Este envió un POST al script post_output.php, que volcó la variable $_POST, y capturamos esa salida vía cURL.
Carga de archivos
La subida de archivos funciona de forma muy similar al ejemplo anterior de POST, ya que todos los formularios de subida de archivos tienen el método POST.
Primero vamos a crear un archivo para recibir la petición y llamarlo upload_output.php:
1 |
print_r($_FILES); |
Y aquí está el script real que realiza la subida de archivos:
1 |
$url = "http://localhost/upload_output.php"; |
2 |
|
3 |
$post_data = array ( |
4 |
"foo" => "bar", |
5 |
// file to be uploaded
|
6 |
"upload" => "@C:/wamp/www/test.zip" |
7 |
);
|
8 |
|
9 |
$ch = curl_init(); |
10 |
|
11 |
curl_setopt($ch, CURLOPT_URL, $url); |
12 |
|
13 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
14 |
|
15 |
curl_setopt($ch, CURLOPT_POST, 1); |
16 |
|
17 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); |
18 |
|
19 |
$output = curl_exec($ch); |
20 |
|
21 |
curl_close($ch); |
22 |
|
23 |
echo $output; |
Cuando quieras subir un archivo, todo lo que tienes que hacer es pasar tu ruta de archivo como una variable post, y poner el símbolo @ delante de esta. Ahora cuando ejecutes este script deberías obtener una salida como esta:


Multi cURL
Una de las características más avanzadas de cURL es la capacidad de crear un "multi" manejador de cURL. Esto te permite abrir conexiones a múltiples URL simultáneamente y de forma asíncrona.
En una petición cURL normal, la ejecución del script se detiene y espera a que termine la petición de la URL para poder continuar. Si se pretende acceder a múltiples URL, esto puede llevar mucho tiempo, ya que solo se puede solicitar una URL a la vez. Podemos superar esta limitación utilizando el multimanejador.
Veamos este código de ejemplo de php.net:
1 |
// create both cURL resources
|
2 |
$ch1 = curl_init(); |
3 |
$ch2 = curl_init(); |
4 |
|
5 |
// set URL and other appropriate options
|
6 |
curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); |
7 |
curl_setopt($ch1, CURLOPT_HEADER, 0); |
8 |
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); |
9 |
curl_setopt($ch2, CURLOPT_HEADER, 0); |
10 |
|
11 |
//create the multiple cURL handle
|
12 |
$mh = curl_multi_init(); |
13 |
|
14 |
//add the two handles
|
15 |
curl_multi_add_handle($mh,$ch1); |
16 |
curl_multi_add_handle($mh,$ch2); |
17 |
|
18 |
$active = null; |
19 |
//execute the handles
|
20 |
do { |
21 |
$mrc = curl_multi_exec($mh, $active); |
22 |
} while ($mrc == CURLM_CALL_MULTI_PERFORM); |
23 |
|
24 |
while ($active && $mrc == CURLM_OK) { |
25 |
if (curl_multi_select($mh) != -1) { |
26 |
do { |
27 |
$mrc = curl_multi_exec($mh, $active); |
28 |
} while ($mrc == CURLM_CALL_MULTI_PERFORM); |
29 |
}
|
30 |
}
|
31 |
|
32 |
//close the handles
|
33 |
curl_multi_remove_handle($mh, $ch1); |
34 |
curl_multi_remove_handle($mh, $ch2); |
35 |
curl_multi_close($mh); |
La idea es que puedas abrir múltiples manejadores cURL y asignarlos a un único multimanejador. Entonces puedes esperar a que terminen de ejecutarse mientras estás en un bucle.
Hay dos bucles principales en este ejemplo. El primer bucle do-while llama repetidamente a curl_multi_exec(). Esta función es non-blocking. Se ejecuta lo menos posible y devuelve un valor de estado. Mientras el valor devuelto sea la constante 'CURLM_CALL_MULTI_PERFORM', significa que todavía hay trabajo más inmediato que hacer (por ejemplo, enviar cabeceras http a las URL.) Por eso seguimos llamándola hasta que el valor de retorno sea otro.
En el siguiente bucle while, continuamos mientras la variable $active sea 'true'. Esta fue pasada como el segundo argumento a la llamada de curl_multi_exec(). Se pone a 'true' mientras haya conexiones activas dentro del multimanejador. Lo siguiente que hacemos es llamar a curl_multi_select(). Esta función está 'bloqueando' hasta que haya alguna actividad de conexión, como recibir una respuesta. Cuando esto ocurre, entramos en otro bucle do-while para continuar la ejecución.
Veamos si podemos crear un ejemplo que funcione, que tenga un propósito práctico.
Verificador de enlaces en Wordpress
Imagina un blog con muchas entradas que contienen enlaces a sitios web externos. Algunos de estos enlaces pueden terminar muertos después de un tiempo por varias razones. Tal vez la página ya no existe, o el sitio web completo ha desaparecido.
Vamos a construir un script que analice todos los enlaces y encuentre los sitios web que no cargan y las páginas 404 y nos devuelva un informe.
Ten en cuenta que esto no va a ser un plugin de Wordpress real. Es solo un script de utilidad independiente, y es solo para fines de demostración.
Así que vamos a empezar. Primero necesitamos obtener los enlaces de la base de datos:
1 |
// CONFIG
|
2 |
$db_host = 'localhost'; |
3 |
$db_user = 'root'; |
4 |
$db_pass = ''; |
5 |
$db_name = 'wordpress'; |
6 |
$excluded_domains = array( |
7 |
'localhost', 'www.mydomain.com'); |
8 |
$max_connections = 10; |
9 |
// initialize some variables
|
10 |
$url_list = array(); |
11 |
$working_urls = array(); |
12 |
$dead_urls = array(); |
13 |
$not_found_urls = array(); |
14 |
$active = null; |
15 |
|
16 |
// connect to MySQL
|
17 |
if (!mysql_connect($db_host, $db_user, $db_pass)) { |
18 |
die('Could not connect: ' . mysql_error()); |
19 |
}
|
20 |
if (!mysql_select_db($db_name)) { |
21 |
die('Could not select db: ' . mysql_error()); |
22 |
}
|
23 |
|
24 |
|
25 |
// get all published posts that have links
|
26 |
$q = "SELECT post_content FROM wp_posts |
27 |
WHERE post_content LIKE '%href=%'
|
28 |
AND post_status = 'publish'
|
29 |
AND post_type = 'post'"; |
30 |
$r = mysql_query($q) or die(mysql_error()); |
31 |
while ($d = mysql_fetch_assoc($r)) { |
32 |
|
33 |
// get all links via regex
|
34 |
if (preg_match_all("!href=\"(.*?)\"!", $d['post_content'], $matches)) { |
35 |
|
36 |
foreach ($matches[1] as $url) { |
37 |
|
38 |
// exclude some domains
|
39 |
$tmp = parse_url($url); |
40 |
if (in_array($tmp['host'], $excluded_domains)) { |
41 |
continue; |
42 |
}
|
43 |
|
44 |
// store the url
|
45 |
$url_list []= $url; |
46 |
}
|
47 |
}
|
48 |
}
|
49 |
|
50 |
// remove duplicates
|
51 |
$url_list = array_values(array_unique($url_list)); |
52 |
|
53 |
if (!$url_list) { |
54 |
die('No URL to check'); |
55 |
}
|
Primero tenemos alguna configuración de la base de datos, seguida de una matriz de nombres de dominio que ignoraremos ($dominios_excluidos). También establecemos un número para el máximo de conexiones simultáneas que usaremos más tarde ($max_connections). Luego nos conectamos a la base de datos, obtenemos las publicaciones que contienen enlaces, y las recogemos en una matriz ($url_list).
El siguiente código puede ser un poco complejo, así que intentaré explicarlo en pequeños pasos.
1 |
// 1. multi handle
|
2 |
$mh = curl_multi_init(); |
3 |
|
4 |
// 2. add multiple URLs to the multi handle
|
5 |
for ($i = 0; $i < $max_connections; $i++) { |
6 |
add_url_to_multi_handle($mh, $url_list); |
7 |
}
|
8 |
|
9 |
// 3. initial execution
|
10 |
do { |
11 |
$mrc = curl_multi_exec($mh, $active); |
12 |
} while ($mrc == CURLM_CALL_MULTI_PERFORM); |
13 |
|
14 |
// 4. main loop
|
15 |
while ($active && $mrc == CURLM_OK) { |
16 |
|
17 |
// 5. there is activity
|
18 |
if (curl_multi_select($mh) != -1) { |
19 |
|
20 |
// 6. do work
|
21 |
do { |
22 |
$mrc = curl_multi_exec($mh, $active); |
23 |
} while ($mrc == CURLM_CALL_MULTI_PERFORM); |
24 |
|
25 |
// 7. is there info?
|
26 |
if ($mhinfo = curl_multi_info_read($mh)) { |
27 |
// this means one of the requests were finished
|
28 |
|
29 |
// 8. get the info on the curl handle
|
30 |
$chinfo = curl_getinfo($mhinfo['handle']); |
31 |
|
32 |
// 9. dead link?
|
33 |
if (!$chinfo['http_code']) { |
34 |
$dead_urls []= $chinfo['url']; |
35 |
|
36 |
// 10. 404?
|
37 |
} else if ($chinfo['http_code'] == 404) { |
38 |
$not_found_urls []= $chinfo['url']; |
39 |
|
40 |
// 11. working
|
41 |
} else { |
42 |
$working_urls []= $chinfo['url']; |
43 |
}
|
44 |
|
45 |
// 12. remove the handle
|
46 |
curl_multi_remove_handle($mh, $mhinfo['handle']); |
47 |
curl_close($mhinfo['handle']); |
48 |
|
49 |
// 13. add a new url and do work
|
50 |
if (add_url_to_multi_handle($mh, $url_list)) { |
51 |
|
52 |
do { |
53 |
$mrc = curl_multi_exec($mh, $active); |
54 |
} while ($mrc == CURLM_CALL_MULTI_PERFORM); |
55 |
}
|
56 |
}
|
57 |
}
|
58 |
}
|
59 |
|
60 |
// 14. finished
|
61 |
curl_multi_close($mh); |
62 |
|
63 |
echo "==Dead URLs==\n"; |
64 |
echo implode("\n",$dead_urls) . "\n\n"; |
65 |
|
66 |
echo "==404 URLs==\n"; |
67 |
echo implode("\n",$not_found_urls) . "\n\n"; |
68 |
|
69 |
echo "==Working URLs==\n"; |
70 |
echo implode("\n",$working_urls); |
71 |
|
72 |
// 15. adds a url to the multi handle
|
73 |
function add_url_to_multi_handle($mh, $url_list) { |
74 |
static $index = 0; |
75 |
|
76 |
// if we have another url to get
|
77 |
if ($url_list[$index]) { |
78 |
|
79 |
// new curl handle
|
80 |
$ch = curl_init(); |
81 |
|
82 |
// set the url
|
83 |
curl_setopt($ch, CURLOPT_URL, $url_list[$index]); |
84 |
// to prevent the response from being outputted
|
85 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
86 |
// follow redirections
|
87 |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); |
88 |
// do not need the body. this saves bandwidth and time
|
89 |
curl_setopt($ch, CURLOPT_NOBODY, 1); |
90 |
|
91 |
// add it to the multi handle
|
92 |
curl_multi_add_handle($mh, $ch); |
93 |
|
94 |
|
95 |
// increment so next url is used next time
|
96 |
$index++; |
97 |
|
98 |
return true; |
99 |
} else { |
100 |
|
101 |
// we are done adding new URLs
|
102 |
return false; |
103 |
}
|
104 |
}
|
Y aquí está la explicación del código anterior. Los números en la lista corresponden a los números en los comentarios del código.
- Creamos un multimanejador.
- Más adelante crearemos la función add_url_to_multi_handle(). Cada vez que se llame, se añadirá una url al multimanejador. Inicialmente, agregamos 10 (basado en $max_connections) URL al multimanejador.
- Debemos ejecutar curl_multi_exec() para el trabajo inicial. Mientras devuelva CURLM_CALL_MULTI_PERFORM, hay trabajo que hacer. Esto es principalmente para crear las conexiones. No espera la respuesta completa de la URL.
- Este bucle principal se ejecuta mientras haya alguna actividad en el multimanejador.
- curl_multi_select() espera el script hasta que ocurra una actividad con cualquiera de las búsquedas de la URL.
- De nuevo debemos dejar que cURL haga algo de trabajo, principalmente para obtener los datos de la respuesta.
- Comprobamos la información. Hay una matriz devuelta si una petición de URL fue terminada.
- Hay un manejador de cURL en la matriz devuelta. Lo usamos para obtener información sobre la solicitud cURL individual.
- Si el enlace estaba muerto o se agotó el tiempo, no habrá código http.
- Si el enlace era una página 404, el código http será 404.
- En caso contrario, asumimos que el enlace funciona. (Puedes añadir comprobaciones adicionales para códigos de error 500, etc...)
- Quitamos el manejador cURL del multimanejador ya que no es necesario, y lo cerramos.
- Ahora podemos añadir otra url al multimanejador, y de nuevo hacer el trabajo inicial antes de seguir adelante.
- Todo está terminado. Podemos cerrar el multimanejador e imprimir un informe.
- Esta es la función que añade una nueva url al multimanejador. La variable estática $index se incrementa cada vez que se llama a esta función, de modo que podemos llevar la cuenta de dónde lo dejamos.
He ejecutado el script en mi blog (con algunos enlaces rotos añadidos a propósito, para probar), y así es como se veía:


Solo tardó menos de 2 segundos en recorrer unas 40 URL. Las ganancias de rendimiento son significativas cuando se trata de conjuntos de URL aún más grandes. Si abres diez conexiones al mismo tiempo, puede funcionar hasta diez veces más rápido. También puedes utilizar la naturaleza no bloqueante del multimanejador de curl para hacer solicitudes de URL sin detener tu script web.
Otras opciones útiles de cURL
Autenticación HTTP
Si hay autenticación basada en HTTP en una URL, puedes usar esto:
1 |
$url = "http://www.somesite.com/members/"; |
2 |
|
3 |
$ch = curl_init(); |
4 |
|
5 |
curl_setopt($ch, CURLOPT_URL, $url); |
6 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
7 |
|
8 |
// send the username and password
|
9 |
curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword"); |
10 |
|
11 |
// if you allow redirections
|
12 |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); |
13 |
// this lets cURL keep sending the username and password
|
14 |
// after being redirected
|
15 |
curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); |
16 |
|
17 |
$output = curl_exec($ch); |
18 |
|
19 |
curl_close($ch); |
Carga FTP
PHP tiene una biblioteca FTP, pero también puedes usar cURL:
1 |
// open a file pointer
|
2 |
$file = fopen("/path/to/file", "r"); |
3 |
|
4 |
// the url contains most of the info needed
|
5 |
$url = "ftp://username:password@mydomain.com:21/path/to/new/file"; |
6 |
|
7 |
$ch = curl_init(); |
8 |
|
9 |
curl_setopt($ch, CURLOPT_URL, $url); |
10 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
11 |
|
12 |
// upload related options
|
13 |
curl_setopt($ch, CURLOPT_UPLOAD, 1); |
14 |
curl_setopt($ch, CURLOPT_INFILE, $fp); |
15 |
curl_setopt($ch, CURLOPT_INFILESIZE, filesize("/path/to/file")); |
16 |
|
17 |
// set for ASCII mode (e.g. text files)
|
18 |
curl_setopt($ch, CURLOPT_FTPASCII, 1); |
19 |
|
20 |
$output = curl_exec($ch); |
21 |
curl_close($ch); |
Uso de un proxy
Puedes realizar tu petición de URL a través de un proxy:
1 |
$ch = curl_init(); |
2 |
|
3 |
curl_setopt($ch, CURLOPT_URL,'http://www.example.com'); |
4 |
|
5 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
6 |
|
7 |
// set the proxy address to use
|
8 |
curl_setopt($ch, CURLOPT_PROXY, '11.11.11.11:8080'); |
9 |
|
10 |
// if the proxy requires a username and password
|
11 |
curl_setopt($ch, CURLOPT_PROXYUSERPWD,'user:pass'); |
12 |
|
13 |
$output = curl_exec($ch); |
14 |
|
15 |
curl_close ($ch); |
Funciones de devolución de llamada
Es posible hacer que cURL llame a determinadas funciones de retrollamada durante la petición de la URL, antes de que esta termine. Por ejemplo, mientras se descarga el contenido de la respuesta, se puede empezar a utilizar los datos, sin esperar a que se complete toda la descarga.
1 |
$ch = curl_init(); |
2 |
|
3 |
curl_setopt($ch, CURLOPT_URL,'http://net.tutsplus.com'); |
4 |
|
5 |
curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function"); |
6 |
|
7 |
curl_exec($ch); |
8 |
|
9 |
curl_close ($ch); |
10 |
|
11 |
|
12 |
function progress_function($ch,$str) { |
13 |
|
14 |
echo $str; |
15 |
return strlen($str); |
16 |
|
17 |
}
|
La función de devolución de llamada DEBE devolver la longitud de la cadena, que es un requisito para que esto funcione correctamente.
Mientras se obtiene la respuesta de la URL, cada vez que se recibe un paquete de datos, se llama a la función de devolución de llamada.
Conclusión
Hoy hemos explorado el poder y la flexibilidad de la biblioteca cURL. Espero que hayas disfrutado y aprendido de este artículo. La próxima vez que necesites hacer una petición de URL en tu aplicación web, considera usar cURL.
¡Gracias y que tengas un buen día!
Escribe un Tutorial Plus
¿Sabías que puedes ganar hasta 600 dólares por escribir un tutorial PLUS y/o un screencast para nosotros? Estamos buscando tutoriales profundos y bien escritos sobre HTML, CSS, PHP y JavaScript. Si eres capaz de hacerlo, ponte en contacto con Jeffrey en nettuts@tutsplus.com.
Por favor, ten en cuenta que la compensación real dependerá de la calidad del tutorial final y del screencast.

- Síguenos en Twitter, o suscríbete al feed RSS de Nettuts+ para obtener los mejores tutoriales de desarrollo web en la web.



