I just spent the last 45 minutes banging my head against my keyboard because when using libcurl for a lighttpd server I would get a 400 Bad Request Error.
It turns out, that despite what has been mentioned in other comments, when using the CURLOPT_HTTPHEADER option, you must use \r\n as newline separators for each header NOT \n. For some reason lighttpd will not accept them. Other webservers will however.
Example:
<?php
$str = "Accept-Language: en-us,en;q=0.5\r\n";
$str .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
$str .= "Keep-Alive: 300\r\n";
$str .= "Connection: keep-alive\r\n";
curl_setopt($this->curl_handle, CURLOPT_HTTPHEADER, array($str));
?>
curl_setopt
(PHP 4 >= 4.0.2, PHP 5)
curl_setopt — Définit une option de transmission cURL
Description
Définit une option de transfert cURL.
Liste de paramètres
- ch
-
Un gestionnaire cURL retourné par la fonction curl_init().
- option
-
L'option CURLOPT_XXX à définir.
- value
-
La valeur à définir pour option .
value doit être un booléen pour les valeurs suivantes du paramètres option :
Option Définissez le paramètre value à Notes CURLOPT_AUTOREFERER TRUE pour spécifier automatiquement le champ Referer: dans les requêtes où une redirection Location: suit. Disponible depuis PHP 5.1.0. CURLOPT_BINARYTRANSFER TRUE pour retourner la ligne affichée lorsque CURLOPT_RETURNTRANSFER est utilisé. CURLOPT_COOKIESESSION TRUE pour marquer ceci comme un nouveau cookie "session". Cela forcera libcurl à ignorer tous les cookies qui sont prêts à être chargés qui sont des "cookies de session" provenant des sessions antérieures. Par défaut, libcurl enregistre et charge toujours tous les cookies, indépendamment s'ils sont des cookies de session ou pas. Les cookies de session sont des cookies sans date d'expiration et existeront que pour cette "session" seulement. Disponible depuis PHP 5.1.0. CURLOPT_CRLF TRUE pour convertir les nouvelles lignes Unix en nouvelles lignes CRLF pendant le transfert. CURLOPT_DNS_USE_GLOBAL_CACHE TRUE pour utiliser un cache DNS global. Cette option n'est pas thread-safe et est activée par défaut. CURLOPT_FAILONERROR TRUE pour que PHP traite silencieusement les codes HTTP supérieurs ou égaux à 400. Le comportement par défaut est de retourner la page normalement, en ignorant ce code. CURLOPT_FILETIME TRUE pour tenter de récupérer la date de modification du document distant. Vous pouvez également retrouver cette valeur en utilisant l'option CURLINFO_FILETIME avec curl_getinfo(). CURLOPT_FOLLOWLOCATION TRUE pour suivre toutes les en-têtes "Location: " que le serveur envoie dans les en-têtes HTTP (notez que cette fonction est récursive et que PHP suivra toutes les en-têtes "Location: " qu'il trouvera à moins que CURLOPT_MAXREDIRS ne soit définie). CURLOPT_FORBID_REUSE TRUE pour forcer la connexion à se fermer explicitement lorsque le processus est terminé et ne sera pas mise en cache pour être réutilisée. CURLOPT_FRESH_CONNECT TRUE pour forcer à utiliser une nouvelle connexion au lieu de celle en cache. CURLOPT_FTP_USE_EPRT TRUE pour utiliser EPRT (et LPRT) lors de l'activation des téléchargements FTP. Utilisez FALSE pour désactiver EPRT et LPRT et ainsi, n'utiliser que PORT. Ajouté en PHP 5.0.0. CURLOPT_FTP_USE_EPSV TRUE pour tenter tout d'abord une commande EPSV pour les transferts FTP avant de revenir à une commande PASV. Définissez cette option à FALSE pour désactiver EPSV. CURLOPT_FTPAPPEND TRUE pour que PHP concatène le fichier distant, plutôt que de l'écraser. CURLOPT_FTPASCII Un alias de CURLOPT_TRANSFERTEXT. Utilisez celui-là à la place. CURLOPT_FTPLISTONLY TRUE pour ne lister que les noms d'un dossier FTP. CURLOPT_HEADER TRUE pour inclure l'en-tête dans la valeur de retour. CURLOPT_HTTPGET TRUE pour réinitialiser la méthode de requête HTTP à POST. Sachant que GET est la valeur par défaut, cela n'est uniquement nécessaire que si la méthode de requête a été changée. CURLOPT_HTTPPROXYTUNNEL TRUE pour effectuer un tunnel à travers un proxy HTTP. CURLOPT_MUTE TRUE pour que PHP soit totalement silencieux concernant toutes les fonctions cURL. CURLOPT_NETRC TRUE pour que PHP analyse votre fichier ~./netrc et utilise votre nom de compte et mot de passe sur le site distant que vous souhaitez contacter. CURLOPT_NOBODY TRUE pour que le corps du transfert ne soit pas inclus dans la valeur de retour. CURLOPT_NOPROGRESS TRUE pour désactiver la barre de progression des transferts cURL.
Note: PHP choisit automatiquement une valeur non nulle. Ne changez cette valeur que le temps du débogage.
CURLOPT_NOSIGNAL TRUE pour ignorer toutes les fonctions cURL qui cause l'envoi d'un signal au processus PHP. Activé par défaut dans les SAPIs multi-threadés, les options d'expiration peut toujours être utilisées. Ajouté dans cURL 7.10 et PHP 5.0.0. CURLOPT_POST TRUE pour que PHP fasse un HTTP POST. Un POST est un encodage normal application/x-www-from-urlencoded, utilisé couramment par les formulaires HTML. CURLOPT_PUT TRUE pour que le chargement se fasse par HTTP PUT. Le fichier à charger doit être fixé avec les options CURLOPT_INFILE et CURLOPT_INFILESIZE. CURLOPT_RETURNTRANSFER TRUE retourne directement le transfert sous forme de chaîne de la valeur retournée par curl_exec() au lieu de l'afficher directement. CURLOPT_SSL_VERIFYPEER FALSE pour arrêter CURL de vérifier le certificat. Les certificats alternatifs peuvent être spécifiés avec l'option CURLOPT_CAINFO (ajouté dans CURL 7.9.8) ou un répertoire de certificat peut être spécifié avec l'option CURLOPT_CAPATH . Tout comme CURL 7.10, CURL installe un paquet par défaut. CURLOPT_SSL_VERIFYHOST doit aussi être positionnée à 1 ou 0 si CURLOPT_SSL_VERIFYPEER est désactivée (par défaut à 2). TRUE par défaut depuis cURL 7.10. Paquet installé par défaut depuis cURL 7.10. CURLOPT_TRANSFERTEXT TRUE pour utiliser le mode ASCII pour les transferts FTP. Pour LDAP, il récupère les données en texte plein au lieu d'Html. Sur les systèmes WIndows, STDOUT ne sera pas définie en mode binaire. CURLOPT_UNRESTRICTED_AUTH TRUE pour garder l'envoi du nom de l'utilisateur ainsi que le mot de passe lorsque l'on suit les chemins (en utilisant CURLOPT_FOLLOWLOCATION ), même si le nom d'hôte change. Ajouté en PHP 5.0.0. CURLOPT_UPLOAD TRUE pour que PHP prépare un chargement. CURLOPT_VERBOSE TRUE pour afficher tous les événements. Écrit la sortie sur stderr ou dans le fichier spécifié en utilisant CURLOPT_STDERR . value doit être un entier pour les valeurs suivantes du paramètres option :
Option Définissez le paramètre value à Notes CURLOPT_BUFFERSIZE La taille du buffer à utiliser pour chaque lecture. Cependant, il n'y a aucune garantie que cette requête soit accomplie. Ajouté en cURL 7.10 et PHP 5.0.0. CURLOPT_CLOSEPOLICY Soit CURLCLOSEPOLICY_LEAST_RECENTLY_USED , soit CURLCLOSEPOLICY_OLDEST . Il y a trois autres constantes CURLCLOSEPOLICY_ mais CURL ne les supporte pas encore. CURLOPT_CONNECTTIMEOUT Le nombre de secondes à attendre durant la tentative de connexion. Utilisez une valeur de 0 pour attendre indéfiniment. CURLOPT_DNS_CACHE_TIMEOUT Le temps en seconde que CURL doit conserver les entrées DNS en mémoire. Cette option est définie à 120 (2minutes) par défaut. CURLOPT_FTPSSLAUTH La méthode d'identification FTP, lorsqu'elle est activée : CURLFTPAUTH_SSL (tente SSL en premier), CURLFTPAUTH_TLS (tente TLS en premier) ou CURLFTPAUTH_DEFAULT (laisse cURL décider). Ajouté en cURL 7.12.2 et PHP 5.1.0. CURLOPT_HTTP_VERSION CURL_HTTP_VERSION_NONE (défaut, laisse cURL décider la version à utiliser), CURL_HTTP_VERSION_1_0 (force HTTP/1.0), ou CURL_HTTP_VERSION_1_1 (force HTTP/1.1). CURLOPT_HTTPAUTH La méthode d'identification HTTP à utiliser. Ces options sont : CURLAUTH_BASIC , CURLAUTH_DIGEST , CURLAUTH_GSSNEGOTIATE , CURLAUTH_NTLM , CURLAUTH_ANY et CURLAUTH_ANYSAFE .
Vous pouvez utiliser le séparateur | ou un opérateur pour combiner plus d'une méthode. Si vous faites cela, CURL interrogera le serveur pour voir quelles sont les méthodes supportées et prendra la meilleur.
CURLAUTH_ANY est un alias pour CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM.
CURLAUTH_ANYSAFE est un alias pour CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM.
Ajouté en PHP 5.0.0. CURLOPT_INFILESIZE La taille attendue, en octets, du fichier lors du téléchargement d'un fichier depuis un site distant. CURLOPT_LOW_SPEED_LIMIT La vitesse de transfert minimale en octets par secondes en dessous de laquelle, et pendant CURLOPT_LOW_SPEED_TIME secondes, PHP considérera qu'elle est trop lente, et annulera le transfert. CURLOPT_LOW_SPEED_TIME Le temps en secondes, qui, si la vitesse de transfert reste en dessous de CURLOPT_LOW_SPEED_LIMIT, PHP considérera que la connexion est trop lente, et l'annulera. CURLOPT_MAXCONNECTS Le nombre maximal de connexions persistantes autorisées. Lorsque la limite est atteinte, l'option CURLOPT_CLOSEPOLICY est utilisé pour afficher les connexions fermées. CURLOPT_MAXREDIRS Le nombre maximal de redirections HTTP à suivre. Utilisez cette option avec l'option CURLOPT_FOLLOWLOCATION . CURLOPT_PORT Le numéro du port de connexion, à la place de la valeur par défaut utilisée par le protocole. CURLOPT_PROXYAUTH La méthode d'identification HTTP à utiliser pour la connexion à un proxy. Utilisez la même méthode que celle décrite dans CURLOPT_HTTPAUTH. Pour une identification avec un proxy, seuls CURLAUTH_BASIC et CURLAUTH_NTLM sont actuellement supportés. Ajouté en CURL 7.10.7 et PHP 5.1.0. CURLOPT_PROXYPORT Le numéro du port du proxy à utiliser pour la connexion. Ce numéro de port peut également être défini dans l'option CURLOPT_PROXY . Ajouté en PHP 5.0.0. CURLOPT_PROXYTYPE Soit CURLPROXY_HTTP (par défaut), soit CURLPROXY_SOCKS5 . Ajouté en cURL 7.10 et PHP 5.0.0. CURLOPT_RESUME_FROM L'offset, en octets, à partir duquel vous voulez commencer le transfert. CURLOPT_SSL_VERIFYHOST 1 pour vérifier l'existence d'un nom commun dans le certificat SSL. 2 pour vérifier l'existence d'un nom commun et vérifier qu'il correspond avec le nom d'hôte fourni. CURLOPT_SSLVERSION La version de SSL (2 ou 3) à utiliser. Par défaut, PHP essayera de le déterminer lui-même, bien que dans certains cas, il vous faudra le faire manuellement. CURLOPT_TIMECONDITION Comment CURLOPT_TIMEVALUE est traité. Utilisez CURL_TIMECOND_IFMODSINCE pour retourner la page uniquement si elle a été modifiée depuis le temps spécifié par CURLOPT_TIMEVALUE. Si elle n'a pas été modifiée, un en-tête HTTP "304 Not Modified" sera retourné en supposant que CURLOPT_HEADER vaut TRUE. Utilisez CURL_TIMECOND_ISUNMODSINCE pour faire l'inverse. CURL_TIMECOND_IFMODSINCE est par défaut. Ajouté en PHP 5.1.0. CURLOPT_TIMEOUT Le temps maximum d'exécution de la fonction cURL. CURLOPT_TIMEVALUE Le temps en secondes depuis le 1er janvier 1970. Cette valeur sera utilisée comme spécifié dans l'option CURLOPT_TIMECONDITION. Par défaut, CURL_TIMECOND_IFMODSINCE sera utilisée. value doit être une chaîne pour les valeurs suivantes du paramètres option :
Option Définissez le paramètre value à Notes CURLOPT_CAINFO Le nom d'un fichier contenant un ou plusieurs certificats pour vérifier la concordance. Cela n'a de sens que si vous l'utilisez en combinaison de l'option CURLOPT_SSL_VERIFYPEER . CURLOPT_CAPATH Un dossier qui contient les certificats CA. Utilisez cette option avec l'option CURLOPT_SSL_VERIFYPEER . CURLOPT_COOKIE Le contenu de l'en-tête "Set-Cookie: ", à transmettre dans l'en-tête HTTP. CURLOPT_COOKIEFILE Le nom du fichier contenant les données de cookie. Le fichier de cookie peut être au format Netscape, ou simplement des en-têtes HTTP écrits dans un fichier. CURLOPT_COOKIEJAR Le nom de fichier pour y sauvegarder tous les cookies internes lorsque la connexion se ferme. CURLOPT_CUSTOMREQUEST Une méthode de requête qui sera utilisée à la place de "GET" ou "HEAD" lors des requêtes HTTP. Cette commande est pratique pour effectuer un "DELETE" ou une autre commande HTTP exotique. Les valeurs valides sont "GET", "POST", "CONNECT" et plus ; i.e. n'entrez pas une requête HTTP ici. Pour le moment, entrez "GET /index.html HTTP/1.0\r\n\r\n" serait incorrect.
Note: N'utilisez pas cette commande sans vous assurer que le serveur l'accepte.
CURLOPT_EGDSOCKET Comme CURLOPT_RANDOM_FILE excepté que vous passez une chaîne qui contient un nom de fichier vers le socket Entropy Gathering Daemon. CURLOPT_ENCODING Le contenu des en-têtes "Accept-Encoding: " et active le décodage de la réponse. Les encodages supportés sont "identity", "deflate" et "gzip". Si une chaîne vide "" est utilisé, un en-tête contenant tous les types d'encodage supportés est envoyé. Ajouté en cURL 7.10. CURLOPT_FTPPORT La valeur qui sera utilisée pour récupérer l'adresse IP utilisée pour l'instruction FTP "PORT". L'instruction POST indique au serveur distant de se connecter à cette adresse IP. La chaîne peut être une adresse IP, un nom d'hôte, un nom d'interface réseau (sous UNIX), ou juste '-', pour utiliser les IP par défaut du système. CURLOPT_INTERFACE Le nom de l'interface à utiliser. Cela peut être le nom d'une interface, une adresse IP ou encore le nom de l'hôte. CURLOPT_KRB4LEVEL Le degré de sécurité KRB4 (Kerberos 4). Chacune des valeurs (dans l'ordre du plus petit au plus grand) suivantes sont valides : "clear", "safe", "confidential", "private".. Si la chaîne passée ne correspond pas à une de ces valeurs, la valeur "private" sera définie. Positionner cette valeur à NULL revient à désactiver la sécurité KRB4. Actuellement, la sécurité KRB4 fonctionne uniquement avec les transaction FTP. CURLOPT_POSTFIELDS Toutes les données à passer lors d'une opération de HTTP POST. Pour envoyer un fichier, préfixez le nom du fichier avec un @ et utilisez le chemin complet. CURLOPT_PROXY Le nom du proxy HTTP au tunnel qui le demande. CURLOPT_PROXYUSERPWD Un nom d'utilisateur et un mot de passe formatés sous la forme "[username]:[password]" à utiliser pour la connexion avec le proxy. CURLOPT_RANDOM_FILE Un nom de fichier à utiliser pour interroger le générateur de nombre aléatoire pour SSL. CURLOPT_RANGE La plage de valeurs à récupérer sous la forme "X-Y", où les valeurs de X ou Y peuvent être omises. Le transfert HTTP supporte aussi plusieurs intervalles, séparés par des virgules : "X-Y,N-M". CURLOPT_REFERER Le contenu de l'en-tête "Referer: " à utiliser dans une requête HTTP. CURLOPT_SSL_CIPHER_LIST Une liste de chiffrements à utiliser avec SSL. Par exemple, RC4-SHA et TLSv1 sont des listes valides de chiffrements. CURLOPT_SSLCERT Le nom de fichier du certificat, au format PEM. CURLOPT_SSLCERTPASSWD Le mot de passe nécessaire pour utiliser le certificat CURLOPT_SSLCERT. CURLOPT_SSLCERTTYPE Le format de votre certificat. Les formats supportés sont "PEM" (par défaut), "DER", et "ENG". Ajouté en cURL 7.9.3 et PHP 5.0.0. CURLOPT_SSLENGINE L'identifiant pour le moteur de chiffrement de votre clé privée spécifié dans CURLOPT_SSLKEY. CURLOPT_SSLENGINE_DEFAULT L'identifiant pour le moteur de chiffrement utilisé pour les opérations de chiffrement asymétrique. CURLOPT_SSLKEY Un nom de fichier contenant votre clé privée SSL. CURLOPT_SSLKEYPASSWD Le mot de passe secret utilisé par votre clé SSL privée spécifié dans CURLOPT_SSLKEY. Note: Du fait que cette option contient un mot de passe sensible, souvenez-vous de conserver le script PHP qui le contient en toute sécurité.
CURLOPT_SSLKEYTYPE Le type de votre clé SSL privée spécifié dans CURLOPT_SSLKEY. Les types de clés supportés sont "PEM" (défaut), "DER", et "ENG". CURLOPT_URL L'URL à récupérer. Vous pouvez aussi choisir cette valeur lors de l'appel à curl_init(). CURLOPT_USERAGENT Le contenu de l'en-tête "User-Agent: " à utiliser dans une requête HTTP. CURLOPT_USERPWD Un nom d'utilisateur et un mot de passe formatés sous la forme "[username]:[password]" à utiliser pour la connexion. value doit être un tableau pour les valeurs suivantes du paramètres option :
Option Définissez le paramètre value à Notes CURLOPT_HTTP200ALIASES Un tableau de réponses HTTP 200 qui sera traité comme réponses valides et non comme des erreurs. Ajouté en CURL 7.10.3 et PHP 5.0.0. CURLOPT_HTTPHEADER Un tableau de champs d'en-têtes HTTP à définir. CURLOPT_POSTQUOTE Un tableau de commandes FTP à exécuter sur le serveur après que la requête FTP se soit exécutée. CURLOPT_QUOTE Un tableau de commande FTP à exécuter sur le serveur avant la requête FTP. value doit être une ressource (utilisant fopen(), par exemple) pour les valeurs suivantes du paramètre option :
Option Définissez le paramètre value à Notes CURLOPT_FILE Le fichier où sera écrit le transfert. Par défaut, STDOUT (la fenêtre du navigateur). CURLOPT_INFILE Le fichier lu par le transfert lors du chargement. CURLOPT_STDERR Un chemin alternatif à utiliser pour afficher les erreurs au lieu de STDERR. CURLOPT_WRITEHEADER Le fichier où sera écrit les parties d'en-tête du transfert. value doit être une chaîne de caractères qui sera un nom valide de fonction de rappel pour les valeurs suivantes du paramètre option :
Option Définissez le paramètre value à Notes CURLOPT_HEADERFUNCTION Le nom d'une fonction de rappel qui prend deux paramètres. Le premier est la ressource CURL, le second, une chaîne contenant les données de l'en-tête à écrire. En utilisant cette fonction de rappel, il est de votre responsabilité de l'écriture des données de l'en-tête. Retourne le nombre d'octets écrits. CURLOPT_PASSWDFUNCTION Le nom d'une fonction de rappel qui prend trois paramètres. Le premier est la ressource CURL, le second, une chaîne contenant un mot de passe de prompt et le troisième, est la longueur maximale du mot de passe. Retourne une chaîne contenant le mot de passe. CURLOPT_READFUNCTION Le nom d'une fonction de rappel où la fonction de rappel prend deux paramètres. Le premier est la ressource CURL et le second, une chaîne contenant les données à lire. En utilisant cette fonction de rappel, il devient de votre responsabilité de lire les données. Retourne le nombre d'octets lus. Retourne 0 à un signal EOF. CURLOPT_WRITEFUNCTION Le nom d'une fonction de rappel où la fonction de rappel prend deux paramètres. Le premier est la ressource CURL et le second, une chaîne contenant les données à écrire. En utilisant cette fonction de rappel, il devient de votre responsabilité d'écrire les données. Doit retourner le nombre exact d'octets écrits ou il échouera.
Valeurs de retour
Cette fonction retourne TRUE en cas de succès, FALSE en cas d'échec.
Exemples
Exemple #1 Initialisation d'une nouvelle session CURL et recherche d'une page Web
<?php
// Création d'une ressource cURL
$ch = curl_init();
// Définition de l'URL et autres options appropriées
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_HEADER, false);
// Récupération de l'URL et passage au navigateur
curl_exec($ch);
// Fermeture de la ressource cURL et libération des ressources systèmes
curl_close($ch);
?>
Exemple #2 Uploader un fichier
<?php
/* http://localhost/upload.php:
print_r($_POST);
print_r($_FILES);
*/
$ch = curl_init();
$data = array('name' => 'Foo', 'file' => '@/home/user/test.png');
curl_setopt($ch, CURLOPT_URL, 'http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);
?>
L'exemple ci-dessus va afficher :
Array ( [name] => Foo ) Array ( [file] => Array ( [name] => test.png [type] => image/png [tmp_name] => /tmp/phpcpjNeQ [error] => 0 [size] => 279 ) )
curl_setopt
07-May-2008 03:26
30-Apr-2008 11:31
OMG! I've joust found kinda bug:
YES, you can set an IP for curl to use by using this statement: curl_setopt($curl, CURLOPT_INTERFACE, $ip);
NO, you CAN NOT set another IP for the same curl object. I mean if u do curl_setopt($curl, CURLOPT_INTERFACE, $ip2); - it wont work!
So to change an IP you need to re-create curl object (curl_close, then curl_init).
10-Apr-2008 02:55
If you are doing a POST, and the content length is 1,025 or greater, then curl exploits a feature of http 1.1: 100 (Continue) Status.
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3
* it adds a header, "Expect: 100-continue".
* it then sends the request head, waits for a 100 response code, then sends the content
Not all web servers support this though. Various errors are returned depending on the server. If this happens to you, suppress the "Expect" header with this command:
<?php
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
?>
See http://www.gnegg.ch/2007/02/the-return-of-except-100-continue/
04-Apr-2008 06:22
Clarification for the CURLOPT_NOBODY option: by excluding the body from your request, you're effectively making a HEAD request. Use the CURLOPT_NOBODY option to return only the headers in the remote response.
Example:
function check_url($url) {
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_HEADER, 1); // get the header
curl_setopt($c, CURLOPT_NOBODY, 1); // and *only* get the header
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); // get the response as a string from curl_exec(), rather than echoing it
curl_setopt($c, CURLOPT_FRESH_CONNECT, 1); // don't use a cached version of the url
if (!curl_exec($c)) { return false; }
$httpcode = curl_getinfo($c, CURLINFO_HTTP_CODE);
return ($httpcode < 400);
}
16-Feb-2008 07:26
If you try to upload file to a server, you need do CURLOPT_POST first and then fill CURLOPT_POSTFIELDS.
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
^^ This will post multipart/form-data
Next example don't work:
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
curl_setopt($ch, CURLOPT_POST, 1);
Sets to content-lenght:0 if $postvars an array.
29-Dec-2007 06:13
Despite the documentation for CURLOPT_HTTPHEADER, all header fields MUST be in one string, with a eol indicator, inside a single element array, in my experience.
For example, this will fail.
<?php
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Range: Bytes=0-50"));
?>
This will work.
<?php
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Range: Bytes=0-50\n"));
?>
This will only set the first header
<?php
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Range: Bytes=0-50\n","Otherheader: stuff\n"));
?>
This however, will set both headers as we want.
<?php
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Range: Bytes=0-50\nOtherheader: stuff\n"));
?>
12-Dec-2007 09:34
hey hey hey!
the problem: curl_setopt($ch,FOLLOW_LOCATION,1);
the error: trouble with open_basedir and safe_mode
the solution: a function already developed by someone
the solution n 2: the same function, modifed, works great for me..
function curl_redir_exec($ch,$debug="")
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops++ >= $curl_max_loops)
{
$curl_loops = 0;
return FALSE;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$debbbb = $data;
list($header, $data) = explode("\n\n", $data, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302) {
$matches = array();
preg_match('/Location:(.*?)\n/', $header, $matches);
$url = @parse_url(trim(array_pop($matches)));
//print_r($url);
if (!$url)
{
//couldn't process the url to redirect to
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
/* if (!$url['scheme'])
$url['scheme'] = $last_url['scheme'];
if (!$url['host'])
$url['host'] = $last_url['host'];
if (!$url['path'])
$url['path'] = $last_url['path'];*/
$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query']?'?'.$url['query']:'');
curl_setopt($ch, CURLOPT_URL, $new_url);
// debug('Redirecting to', $new_url);
return curl_redir_exec($ch);
} else {
$curl_loops=0;
return $debbbb;
}
}
just use this function without de FOLLOW_LOCATION and should work. the problem was that when you get to the line where you return the data if http_code was different than 301 oe 302, $data has obsolete information or none. so $debbbb does the job.
hope this helps someone out there
thanks from argentina
20-Aug-2007 11:03
This is very clear in hindsight, but it still cost me several hours:
curl_setopt($session, CURLOPT_HTTPPROXYTUNNEL, 1);
means that you will tunnel THROUGH the proxy, as in "your communications will go as if the proxy is NOT THERE".
Why do you care? - Well, if you are trying to use, say, Paros, to debug HTTP between your cURL and the server, with CURLOPT_HTTPPROXYTUNNEL set to TRUE Paros will not see or log your traffic thus defeating the purpose and driving you nuts.
There are other cases, of course, where this option is extremely useful...
20-Jul-2007 06:07
The explanation of CURLOPT_NOBODY ("TRUE to exclude the body from the output.") seems unclear to me -- I originally read "output" to mean the return value, i.e. the response. In fact it means to exclude the body from your *request*. Not sure whether "output" means the same thing for CURLOPT_HEADER though.
06-Jul-2007 12:09
if you are trying to connect to 'https://...' and after that want to work with POST data - that's the way:
$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_COOKIEFILE, "cookiefile");
curl_setopt($curl, CURLOPT_COOKIEJAR, "cookiefile"); # SAME cookiefile
curl_setopt($curl, CURLOPT_URL, "url1"); # this is where you first time connect - GET method authorization in my case, if you have POST - need to edit code a bit
$xxx = curl_exec($curl);
curl_setopt($curl, CURLOPT_URL, "url2"); # this is where you are requesting POST-method form results (working with secure connection using cookies after auth)
curl_setopt($curl, CURLOPT_POSTFIELDS, "var1=value&var2=value&var3=value&"); # form params that'll be used to get form results
$xxx = curl_exec($curl);
curl_close ($curl);
echo $xxx;
27-Jun-2007 08:18
Two things that I noted, one of which has been mentioned earlier, if you are connecting to an SSL site (https) and don't have the appropriate certificate, don't forget to set CURLOPT_SSL_VERIFYPEER as "false"... it's set to "true" by default. Scratched my head over 2 hours to figure this one out as I had a machine with an older version installed and everything worked fine without using this option on that one - but failed on other machines with newer versions.
Second very important thing, I've never had my scripts work (tried on various machines, multiple platforms) with a Relative path to a COOKIEJAR or COOKIEFILE. In my experience I HAVE to specify the absolute path and not the relative path.
Small script I wrote to connect to a page, gather all cookies into a jar, connect to another page to login, taking the cookiejar with you for authentication:
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, "/Library/WebServer/Documents/tmp/cookieFileName");
curl_setopt($ch, CURLOPT_URL,"https://www.example.com/myaccount/start.asp");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
ob_start(); // Prevent output
curl_exec ($ch);
ob_end_clean(); // End preventing output
curl_close ($ch);
unset($ch);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "field1=".$f1."&field2=".$f2."&SomeFlag=True");
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_COOKIEFILE, "/Library/WebServer/Documents/tmp/cookieFileName");
curl_setopt($ch, CURLOPT_URL,"https://www.example.com/myaccount/Login.asp");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec ($ch);
curl_close ($ch);
12-Jun-2007 11:35
If you are getting the following error:
SSL: certificate subject name 'domain-or-ip-1.com' does not match target host name 'domain-or-ip-2.com'
Then you can set the following option to get around it:
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
12-Jun-2007 10:55
Please note that the CURLOPT_INTERFACE setting only accepts IP addresses and hostnames of the local machine. It is not meant to send a URL to a specific IP address.
12-May-2007 06:52
curl will sometimes return an "Empty reply from server" error if you don't send a User-Agent string. Use the CURLOPT_USERAGENT option.
24-Apr-2007 06:01
Options not included in the above, but that work (Taken from the libcurl.a C documentation)
CURLOPT_FTP_SSL
Pass a long using one of the values from below, to make libcurl use your desired level of SSL for the ftp transfer. (Added in 7.11.0)
CURLFTPSSL_NONE
Don't attempt to use SSL.
CURLFTPSSL_TRY
Try using SSL, proceed as normal otherwise.
CURLFTPSSL_CONTROL
Require SSL for the control connection or fail with CURLE_FTP_SSL_FAILED.
CURLFTPSSL_ALL
Require SSL for all communication or fail with CURLE_FTP_SSL_FAILED.
14-Mar-2007 01:26
Seems that CURLOPT_RETURNTRANSFER Option set to TRUE, returns a "1" when the transaction returns a blank page.
I think is for eliminate the FALSE to can be with a blank page as return
08-Mar-2007 03:50
How to get rid of response after POST: just add callback function for returned data (CURLOPT_WRITEFUNCTION) and make this function empty.
function curlHeaderCallback($ch, $strHeader) {
}
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'curlHeaderCallback')
03-Mar-2007 03:36
In response to "brett at brettbrewer dot com" and Jamolkhon, the fact you don't take into account is when a redirection (Location: ...) occurs, all the headers are given so the \r\n\r\n can also separate twp consecutive headers.
An even better trick to get the header is to use CURLINFO_HEADER_SIZE :
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($output, 0, $header_size - 4);
$body = substr($output, $header_size);
Then $headers contains all the headers.
15-Dec-2006 08:11
in response to "brett at brettbrewer dot com":
another useful way of getting headers without using regular expression
<?php
class CCurl {
var $m_handle;
var $m_header;
var $m_body;
function CCurl($sUrl) {
$this->m_handle = curl_init();
curl_setopt($this->m_handle, CURLOPT_URL, $sUrl);
curl_setopt($this->m_handle, CURLOPT_HEADER, 1);
curl_setopt($this->m_handle, CURLOPT_RETURNTRANSFER, 1);
return;
}
function getHeader() {
return $this->m_header;
}
function execute() {
$sResponse = curl_exec($this->m_handle);
$this->m_body = substr($sResponse, strpos($sResponse, "\r\n\r\n") + 4);
$this->m_header = substr($sResponse, 0, -strlen($this->m_body));
return $this->m_body;
}
function close() {
curl_close($this->m_handle);
return;
}
}
?>
(you can add something or make some changes to suit your needs)
22-Nov-2006 05:40
If you are trying to use CURLOPT_FOLLOWLOCATION and you get this warning:
Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set...
then you will want to read http://www.php.net/ChangeLog-4.php which says "Disabled CURLOPT_FOLLOWLOCATION in curl when open_basedir or safe_mode are enabled." as of PHP 4.4.4/5.1.5. This is due to the fact that curl is not part of PHP and doesn't know the values of open_basedir or safe_mode, so you could comprimise your webserver operating in safe_mode by redirecting (using header('Location: ...')) to "file://" urls, which curl would have gladly retrieved.
Until the curl extension is changed in PHP or curl (if it ever will) to deal with "Location:" headers, here is a far from perfect remake of the curl_exec function that I am using.
Since there's no curl_getopt function equivalent, you'll have to tweak the function to make it work for your specific use. As it is here, it returns the body of the response and not the header. It also doesn't deal with redirection urls with username and passwords in them.
<?php
function curl_redir_exec($ch)
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops++ >= $curl_max_loops)
{
$curl_loops = 0;
return FALSE;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
list($header, $data) = explode("\n\n", $data, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302)
{
$matches = array();
preg_match('/Location:(.*?)\n/', $header, $matches);
$url = @parse_url(trim(array_pop($matches)));
if (!$url)
{
//couldn't process the url to redirect to
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
if (!$url['scheme'])
$url['scheme'] = $last_url['scheme'];
if (!$url['host'])
$url['host'] = $last_url['host'];
if (!$url['path'])
$url['path'] = $last_url['path'];
$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query']?'?'.$url['query']:'');
curl_setopt($ch, CURLOPT_URL, $new_url);
debug('Redirecting to', $new_url);
return curl_redir_exec($ch);
} else {
$curl_loops=0;
return $data;
}
}
?>
09-Nov-2006 08:27
I have seen two posts complaining the "CURLOPT_POSTFIELDS" option is not working well.
This was the solution given below:
$o="";
foreach ($post_data as $k=>$v)
{
$o.= "$k=".utf8_encode($v)."&";
}
$post_data=substr($o,0,-1);
The assumption that this is an error is not true, as stated on http://curl.rtin.bz/docs/httpscripting.html:
" The data you send to the server MUST already be properly encoded, curl will
not do that for you. For example, if you want the data to contain a space,
you need to replace that space with %20 etc. Failing to comply with this
will most likely cause your data to be received wrongly and messed up."
This means you do really have to encode the data yourself the right way.
01-Oct-2006 01:51
As Yevgen mentioned earlier sometimes we can't use CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE. Below is a header callback function I wrote back in January that lets you maintain cookies between cURL requests. Cookies are added to $ch during all requests even during redirection, so you can use it together with CURLOPT_FOLLOWLOCATION.
Here is the code:
function read_header($ch, $string)
{
global $location; #keep track of location/redirects
global $cookiearr; #store cookies here
global $ch;
# ^overrides the function param $ch
# this is okay because we need to
# update the global $ch with
# new cookies
$length = strlen($string);
if(!strncmp($string, "Location:", 9))
{ #keep track of last redirect
$location = trim(substr($string, 9, -1));
}
if(!strncmp($string, "Set-Cookie:", 11))
{ #get the cookie
$cookiestr = trim(substr($string, 11, -1));
$cookie = explode(';', $cookiestr);
$cookie = explode('=', $cookie[0]);
$cookiename = trim(array_shift($cookie));
$cookiearr[$cookiename] = trim(implode('=', $cookie));
}
$cookie = "";
if(trim($string) == "")
{ #execute only at end of header
foreach ($cookiearr as $key=>$value)
{
$cookie .= "$key=$value; ";
}
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
return $length;
}
Using the header function with curl (add this before curl_exec):
#don't forget globals, especially if you are using this in function
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
This code assumes that you will reuse $ch without initializing it every time (call curl_init only once, in the beginning). If you need to initialize $ch again at any point in your code you can access the currently stored cookies in $cookiearr and include them in the new $ch.
I wrote this function before I had enough experience with regular expressions so you won't find any preg_match calls here. I have used this code for quite a while and without any problems accessing gmail, yahoo, hotmail, aol etc. where I had to go through login and a few pages before getting to what I was looking for.
Svetlozar Petrov (http://svetlozar.net)
23-Aug-2006 07:35
Note that if you want to use a proxy and use it as a _cache_, you'll have to do:
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Pragma: "));
else by default Curl puts a "Pragma: no-cache" header in and thus force cache misses for all requests.
14-Jul-2006 12:58
You can use CURLOPT_HEADERFUNCTION with a callback inside an object. This makes is it easy to capture the headers for later use. For example:
<?
class Test
{
public $headers;
//...
public function exec($opts)
{
$this->headers = array();
$opts[CURLOPT_HEADERFUNCTION] = array($this, '_setHeader');
$ch = curl_init();
curl_setopt_array($ch, $opts);
return curl_exec($ch);
}
private function _setHeader($ch, $header)
{
$this->headers[] = $header;
return strlen($header);
}
}
$test = new Test();
$opts = array(
//... your curl opts here
);
$data = $test->exec($opts);
print_r($test->headers);
?>
...something like that
(This works in php v. 5.1.4)
30-May-2006 08:31
Clarification on the callback methods:
- CURLOPT_HEADERFUNCTION is for handling header lines received *in the response*,
- CURLOPT_WRITEFUNCTION is for handling data received *from the response*,
- CURLOPT_READFUNCTION is for handling data passed along *in the request*.
The callback "string" can be any callable function, that includes the array(&$obj, 'someMethodName') format.
-Philippe
14-Apr-2006 04:22
Sometimes you can't use CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE becoz of the server php-settings(They say u may grab any files from server using these options). Here is the solution
1)Don't use CURLOPT_FOLLOWLOCATION
2)Use curl_setopt($ch, CURLOPT_HEADER, 1)
3)Grab from the header cookies like this:
preg_match_all('|Set-Cookie: (.*);|U', $content, $results);
$cookies = implode(';', $results[1]);
4)Set them using curl_setopt($ch, CURLOPT_COOKIE, $cookies);
Good Luck, Yevgen
27-Mar-2006 12:59
- CURLOPT-HTTPAUTH is defined in php 4.4.2 9and maybe lower), even tough the manual says php 5.0 only...
- it is not clear from the manual what kind of http auth is carried out by default if user specifies username/pwd: it is BASIC auth
ps: note to manual writers: the version info on this page always looks a bit inaccurate, especially regarding the php version where a given option first appeared...
27-Dec-2005 11:24
To further expand upon use of CURLOPT_CAPATH and CURLOPT_CAINFO...
In my case I wanted to prevent curl from talking to any HTTPS server except my own using a self signed certificate. To do this, you'll need openssl installed and access to the HTTPS Server Certificate (server.crt by default on apache)
You can then use a command simiar to this to translate your apache certificate into one that curl likes.
$ openssl x509 -in server.crt -out outcert.pem -text
Then set CURLOPT_CAINFO equal to the the full path to outcert.pem and turn on CURLOPT_SSL_VERIFYPEER.
If you want to use the CURLOPT_CAPATH option, you should create a directory for all the valid certificates you have created, then use the c_rehash script that is included with openssl to "prepare" the directory.
If you dont use the c_rehash utility, curl will ignore any file in the directory you set.
22-Dec-2005 11:13
There is really a problem of transmitting $_POST data with curl in php 4+ at least.
I improved the encoding function by Alejandro Moreno to work properly with mulltidimensional arrays.
<?php
function data_encode($data, $keyprefix = "", $keypostfix = "") {
assert( is_array($data) );
$vars=null;
foreach($data as $key=>$value) {
if(is_array($value)) $vars .= data_encode($value, $keyprefix.$key.$keypostfix.urlencode("["), urlencode("]"));
else $vars .= $keyprefix.$key.$keypostfix."=".urlencode($value)."&";
}
return $vars;
}
curl_setopt($ch, CURLOPT_POSTFIELDS, substr(data_encode($_POST), 0, -1) );
?>
23-Oct-2005 03:34
Resetting CURLOPT_FILE to STDOUT won't work by calling curl_setopt() with the STDOUT constant or a php://output stream handle (at least I get error messages when trying the code from phpnet at andywaite dot com). Instead, one can simply reset it as a side effect of CURLOPT_RETURNTRANSFER. Just say
curl_setopt($this->curl,CURLOPT_RETURNTRANSFER,0);
and following calls to curl_exec() will output to STDOUT again.
20-Oct-2005 10:42
A little mistake, that took a half-day to fix it:
When specifing CURLOPT_COOKIEFILE or CURLOPT_COOKIEJAR options, don't forget to "chmod 777" that directory where cookie-file must be created.
23-Aug-2005 05:10
when specifing the file for either CURLOPT_COOKIEFILE or CURLOPT_COOKIEJAR you may need to use the full file path instead of just the relative path.
07-Jun-2005 11:08
After setting CURLOPT_FILE, you may want want to revert back to the normal behaviour of displaying the results. This can be achieved using:
$fp = fopen ("php://output", "w") or die("Unable to open stdout for writing.\n");
curl_setopt($ch, CURLOPT_FILE, $fp);
09-May-2005 06:26
Using cURL, I needed to call a third-party script which was returning binary data as attachment to pass on retrieved data again as attachment.
Problem was that the third-party script occassionally returned HTTP errors and I wanted to avoid passing on zero-length attachment in such case.
Combination of using CURLOPT_FAILONERROR and CURLOPT_HEADERFUNCTION callback helped to process the third-party script HTTP errors neatly:
<?
function curlHeaderCallback($resURL, $strHeader) {
if (preg_match('/^HTTP/i', $strHeader)) {
header($strHeader);
header('Content-Disposition: attachment; filename="file-name.zip"');
}
return strlen($strHeader);
}
$strURL = 'http://www.somesite.com/script-whichs-dumps-binary-attachment.php';
$resURL = curl_init();
curl_setopt($resURL, CURLOPT_URL, $strURL);
curl_setopt($resURL, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($resURL, CURLOPT_HEADERFUNCTION, 'curlHeaderCallback');
curl_setopt($resURL, CURLOPT_FAILONERROR, 1);
curl_exec ($resURL);
$intReturnCode = curl_getinfo($resURL, CURLINFO_HTTP_CODE);
curl_close ($resURL);
if ($intReturnCode != 200) {
print 'was error: ' . $intReturnCode;
}
?>
05-May-2005 02:00
I don't know if in PHP 5+ this problem is solved, but, when I send via POST using CURLOPT_POSTFIELDS some times it doesnt work an associative array as parameter... and, if I need to send non-ascii characters (like á,é,ñ,ü,etc..) this problem appears too.
The solution is to encode in a unique string all the post key=>values
Possibly this code doesnt work:
<?php
$post_data = array();
$post_data['var1'] = "Diseño web uruguay";
$post_data['var2'] = "Other string";
$url = "http://www.someurl.com/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, );
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$result = curl_exec($ch);
?>
But this works:
<?php
$post_data = array();
$post_data['var1'] = "Diseño web uruguay";
$post_data