on transfers where curl detected any errors, curl_errno($ch) should no longer return 0, so if(curl_errno($ch)!==0)
, something bad probably happened to your download.
another thing, as pointed out by @Pamela in a comment, if the response code is not 2XX (like HTTP 200 OK or HTTP 204 No Content), that's another sign something probably went wrong, which can be detected by doing if(((string)curl_getinfo($ch,CURLINFO_RESPONSE_CODE))[0]!=='2')
so..
if(curl_errno($ch)!==0 || ((string)curl_getinfo($ch,CURLINFO_RESPONSE_CODE))[0]!=='2'){
// the download probably failed.
}
generally speaking, this may be impossible to detect on servers that doesn't implement "Content-Length" headers, if you're downloading from a server that doesn't support Content-Length, then there may be no standardized way to detect the broken download at all.. (you may have to inspect what you've downloaded to make sure it's what you expect or something, idk)
for example, on transfers where the body length doesn't match the "Content-Length" header, curl_errno($ch) returns int(56) (instead of the usual int(0)), and curl_exec($ch) returns bool(false) (PS! if you used CURLOPT_RETURNTRANSFER, then it may contain a string instead of bool)
here's a little HTTP server sending "Content-Length: 3", then cutting the connection after just sending 2 (of allegedly 3) bytes of the body:
<?php
$port=1234;
$srv=socket_create_listen($port);
while(($conn=socket_accept($srv))){
$headers=implode("\r\n",array(
"HTTP/1.1 200 OK",
"Content-Type: text/plain",
"Content-Length: 3",
"Connection: close",
"","",
));
// i lied! i said 3 bytes body, but only send 2 bytes body
$body="ab";
$response=$headers.$body;
var_dump(strlen($response),socket_write($conn,$response));
socket_close($conn);
}
and an accompanying test script:
<?php
$ch=curl_init("http://127.0.0.1:1234");
var_dump(curl_exec($ch));
var_dump(curl_errno($ch),curl_error($ch));
printing:
abbool(false)
int(56)
string(38) "Recv failure: Connection reset by peer"