Upload souborů pomocí cURL v PHP

(publikováno 27.07.2016) 2 PHP, Windows, Tipy & triky

cURL je velmi mocný nástroj jak pro příkazovou řádku, tak pro mnohé programovací jazyky, včetně PHP. Při změnách v PHP se ale trochu komplikovalo odesílání souborů v rámci požadavku.

Upload souborů pomocí cURL v PHP

Pomocí knihovny cURL můžete programově vytvářet požadavky na server pomocí mnoha protokolů. Nás ale bude dnes zajímat pouze HTTP nebo HTTPS a konkrétně odeslání jednoho nebo více souborů.

Oprava 9.8.2017: Nemožnost použít @ pro upload souboru není záležitostí Windows, ale nekompatibilní změna mezi PHP 5.5 a 5.6, viz dokumentace.

cURL a POST se soubory

V následujícím kódu je ukázka, jak odeslat POST požadavek, který obsahuje soubory. Samozřejmě kromě souborů můžeme přidávat i další pole. Ukázka obsahuje odeslání cookies, ignorování nevalidních SSL certifikátů a ukládání celé komunikace do logu.

$post = array(
    'jmeno' => "...",
    'prijmeni' => "...",
    'profilova_fotka' => new CURLFile("/home/pavel/fotka.jpg"),
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/createAccount.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Cookie: nazev_cookie=hodnota; nazev_dalsi_cookie=hodnota"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// Lze vypnout kontrolu certifikátu, nebo odkazem níže nastavit PHP tak,
// Aby kontrolu prováděl na základě známých certifikačních autorit
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

// Ukládá log požadavku, lze zakomentovat
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen(dirname(__FILE__)."/log/curl.log", 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);

// Provedeme požadavek a skončíme
$result=curl_exec ($ch);
fclose($verbose);
curl_close ($ch);

Pro správné ověřování certifikačních autorit je nutné stáhnout do PHP balík CA a nastavit. Jak na to je popsáno v článku cURL chyba 60 - SSL certificate problem.

PHP 5.5 a níže

V PHP pod verzí 5.5 včetně, funguje postup se syntaxí @cesta_k_souboru a je také nutné vypnout SAFE_UPLOAD. Adresa k souboru musí být vždy absolutní a začínat znakem @. Následuje na Linuxu  / nebo pod Windows C: apod. 

// Vypnutí SAFE_UPLOAD
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);

// Za @ musí být absolutní cesta
$post = array(
    ...
    'profilova_fotka' => "@/home/pavel/fotka.jpg",
);

Za jakoukoli zpětnou vazbu budu rád, stačí pouze napsat komentář.

K tomuto článku již není možné přidávat další komentáře

Komentáře

Dobrý den,
sháním info užití cURL knihovny v aplikacích .Net.
Její použití a zasílání souborů (příkazů) do banky.
Nevím zda jste se s tímto setkal v prostředí .Net .
Děkuji za případné info.
BrLu

S cURL pro .NET žádné zkušenosti nemám. Můj odhad ale je, že tam budou jiné třídy a metody, protože cURL není nativně ve Windows, takže tam se to bude dělat nejspíše jinak.