Préambule
Je fais cette note technique car je me suis plus d’une fois confronté à différentes configurations pour accéder à une page Web à partir de PHP. Normalement un serveur Web dispose d’une connection directe à internet et n’a pas besoin d’un proxy pour y acceder. Mais si on fait des script PHP en CLI (non liès à un serveur Web) on peut se trouver confronter à différents problèmes…
Cas 1 : la simplicité même
Voici le cas le plus simple pour récupérer un page à partir de son URL. Dnas le cas où PHP dispose d’un accès direct à internet.
HTTP
$content = file_get_contents("http://www.google.com/"); |
$content = file_get_contents("http://www.google.com/");
HTTPS
$content = file_get_contents("https://www.google.com/"); |
$content = file_get_contents("https://www.google.com/");
Si il vous manque l’extension open_ssl vous aurez une erreur dans ce genre :
Notice: file_get_contents(): Unable to find the wrapper "https" - did you forget to enable it when you configured PHP? in ...\test_001.php on line 3
Warning: file_get_contents(https://www.google.com/): failed to open stream: Invalid argument in ...\test_001.php on line 3
C’est aussi valable pour les cas suivants.
Cas 2 : Authentification HTML
Si la page est protégée par un mot de passe, PHP peut transformer une URL avec utilisateur et mot de passe pour envoyer la requête avec les bons headers.
HTTP
$content = file_get_contents("http://user:pass@www.example.com/"); |
$content = file_get_contents("http://user:pass@www.example.com/");
HTTPS
$content = file_get_contents("https://user:pass@www.example.com/"); |
$content = file_get_contents("https://user:pass@www.example.com/");
Méthode alternative
Vous pouvez aussi envoyer vous même les headers contenant mots de passe et utilisateur. C’est plus compliqué mais ça marche aussi.
// URL des données à récupérer
$url = 'http://protectedstuff.com';
// Encodage de l'autentification
$auth = base64_encode('user:password');
// Création des options de la requête
$opts = array(
'http' => array (
'method'=>'GET',
'header'=>"Authorization: Basic $auth"
),
'https' => array (
'method'=>'GET',
'header'=>"Authorization: Basic $auth"
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
file_get_contents($url,false,$ctx); |
// URL des données à récupérer
$url = 'http://protectedstuff.com';
// Encodage de l'autentification
$auth = base64_encode('user:password');
// Création des options de la requête
$opts = array(
'http' => array (
'method'=>'GET',
'header'=>"Authorization: Basic $auth"
),
'https' => array (
'method'=>'GET',
'header'=>"Authorization: Basic $auth"
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
file_get_contents($url,false,$ctx);
Source : http://fr.php.net/manual/fr/function.stream-context-create.php#74431
Cas 3 : En passant par un proxy
Il m’est arrivé d’écrire des script en PHP-CLI qui se retrouvaient bloqués par un proxy.
HTTP ou HTTPS
// URL des données à récupérer
$url = 'https://www.google.com/';
// Création des options de la requête
$opts = array(
'http' => array (
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true
),
'https' => array (
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
$content = file_get_contents($url,false,$ctx); |
// URL des données à récupérer
$url = 'https://www.google.com/';
// Création des options de la requête
$opts = array(
'http' => array (
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true
),
'https' => array (
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
$content = file_get_contents($url,false,$ctx);
Cas 4 : Proxy et page avec authentification HTML
Si en plus la page que vous souhaitez télécharger requière une authentification, cela reste simple.
HTTP ou HTTPS
// URL des données à récupérer
$url = 'https://user:pass@www.example.com/';
// Création des options de la requête
$opts = array(
'http' => array (
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true
),
'https' => array (
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
$content = file_get_contents($url,false,$ctx); |
// URL des données à récupérer
$url = 'https://user:pass@www.example.com/';
// Création des options de la requête
$opts = array(
'http' => array (
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true
),
'https' => array (
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
$content = file_get_contents($url,false,$ctx);
Cas 5 : Proxy avec authentification
Dans certaines entreprises ou administration on peut se trouver derrière un proxy qui filtre les utilisateurs. Voici comment faire passer son script.
HTTP ou HTTPS
// URL des données à récupérer
$url = 'http://www.example.com/';
// Encodage de l'autentification
$authProxy = base64_encode('user:pass');
// Création des options de la requête
$opts = array(
'http' => array (
'method'=>'GET',
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true,
'header'=>"Proxy-Authorization: Basic $authProxy"
),
'https' => array (
'method'=>'GET',
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true,
'header'=>"Proxy-Authorization: Basic $authProxy"
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
$content = file_get_contents($url,false,$ctx); |
// URL des données à récupérer
$url = 'http://www.example.com/';
// Encodage de l'autentification
$authProxy = base64_encode('user:pass');
// Création des options de la requête
$opts = array(
'http' => array (
'method'=>'GET',
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true,
'header'=>"Proxy-Authorization: Basic $authProxy"
),
'https' => array (
'method'=>'GET',
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true,
'header'=>"Proxy-Authorization: Basic $authProxy"
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
$content = file_get_contents($url,false,$ctx);
Cas 6 : Proxy avec authentification et page avec authentification
Voici un des cas les plus complexes lorqu’il est question de récupérer des données. J’ai rencontré ce problème lorsque j’ai fait un script pour récupérer mes logs chez OVH.
HTTP ou HTTPS
// URL des données à récupérer
$url = 'https://user:pass@www.example.com/';
// Encodage de l'autentification
$authProxy = base64_encode('user:pass');
// Création des options de la requête
$opts = array(
'http' => array (
'method'=>'GET',
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true,
'header'=>"Proxy-Authorization: Basic $authProxy"
),
'https' => array (
'method'=>'GET',
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true,
'header'=>"Proxy-Authorization: Basic $authProxy"
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
$content = file_get_contents($url,false,$ctx); |
// URL des données à récupérer
$url = 'https://user:pass@www.example.com/';
// Encodage de l'autentification
$authProxy = base64_encode('user:pass');
// Création des options de la requête
$opts = array(
'http' => array (
'method'=>'GET',
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true,
'header'=>"Proxy-Authorization: Basic $authProxy"
),
'https' => array (
'method'=>'GET',
'proxy'=>'tcp://192.168.0.99:3128',
'request_fulluri' => true,
'header'=>"Proxy-Authorization: Basic $authProxy"
)
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
// Récupération des données
$content = file_get_contents($url,false,$ctx);
Conclusion
Les exemples présentés ne se limitent aux cas typique de récupération de pages distantes. Ces cas seront satisfaisant dans la plupart des cas. Si vous rencontrez un cas non décrit dans cet article vous trouverez peut être de l’aide ici. Et si vous avez toujours des problèmes vous pouvez me demander de l’aide dans les commentaires. 😉