Недавно я обновился до PHP 7.2 (с 5.x), и один из моих плагинов Opencart начал вести себя странно. Я думаю, что это происходит, когда curl пытается подключиться к ссылке 404. В журнале я вижу:
curl_multi_exec(): supplied resource is not a valid cURL handle resource in
Я думаю, что он находится в бесконечном цикле, потому что он не останавливается сам по себе.
Код следующий:
public function uploadMultipleImages($images, $importer, &$parent) {
set_error_handler('error_handler_for_export',E_ALL);
register_shutdown_function('fatal_error_shutdown_handler_for_export');
if(count($images) == 0)
return true;
//ini_set('memory_limit', '512M');
ini_set('memory_limit', '-1');
try {
$img = array();
$directory = rtrim(DIR_IMAGE . 'data/' . str_replace('../', '', $importer), '/');
if(!is_dir($directory))
if (!mkdir($directory, 0777, true))
die('Failed to create folders...');
$pack = 30;
$chs = array();
$cmh = curl_multi_init();
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP xml Image: Images to download: ' . count($images));
}
for ($t = 0; $t < $pack && $t < count($images) ; $t++)
{
$chs[$t] = curl_init();
curl_setopt($chs[$t], CURLOPT_URL, $images[$t]['image']);
curl_setopt($chs[$t], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($chs[$t], CURLOPT_CONNECTTIMEOUT, 100);
curl_setopt($chs[$t], CURLOPT_TIMEOUT, 100);
curl_multi_add_handle($cmh, $chs[$t]);
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: Added to queue image 51: ' . $images[$t]['image'] . ' CNT: '. count($chs));
}
}
do {
while(($execrun = curl_multi_exec($cmh, $running)) == CURLM_CALL_MULTI_PERFORM);
if($execrun != CURLM_OK)
break;
//usleep(200000);
// Block for data in / output; error handling is done by curl_multi_exec
curl_multi_select($cmh);
// a request was just completed -- find out which one
while($done = curl_multi_info_read($cmh)) {
$info = curl_getinfo($done['handle']);
if ($info['http_code'] > 199 && $info['http_code'] < 300 ) {
$file = curl_multi_getcontent($done['handle']);
// handle the done request
if($file != null && $file != '' && !empty($file) && $file != 'null' )
{
$parts = parse_url($info['url']);
$filename = basename($parts['path']);
$path_to_file = $directory . '/' . $filename;
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: Image extension: ' . $ext);
}
$ok = TRUE;
if( $ext == 'jpg' || $ext == 'jpeg' || $ext == 'png' || $ext == 'gif' ) {
$path_to_file = $directory . '/' . $this->clean_filename($filename);
$theFileName = $this->clean_filename($filename);
}
else
{
$path_to_file = $directory . '/' . $this->clean_filename($filename .$parts['query']);
$theFileName = $this->clean_filename($filename .$parts['query']) . ".jpg";
switch ($info['content_type']) {
case 'image/jpeg':
$path_to_file = $path_to_file.'.jpg';
$theFileName = $theFileName.'.jpg';
$ok = TRUE;
break;
case 'image/gif':
$path_to_file = $path_to_file.'.gif';
$theFileName = $theFileName.'.gif';
$ok = TRUE;
break;
case 'image/png':
$path_to_file = $path_to_file.'.png';
$theFileName = $theFileName.'.png';
$ok = TRUE;
break;
default:
$ok = FALSE;
break;
}
}
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: Image type: ' . $info['content_type']);
}
if($ok === TRUE)
if(file_put_contents($path_to_file, $file) > 0)
{
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: Image saved image: ' . $info['url']);
}
$parent->nr_images_imported++;
}
}
unset($file);
} else {
// request failed. add error handling.
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: Failed downloading image: ' . $info['url']);
}
}
// start a new request (it's important to do this before removing the old one)
if($t+1 < count($images)) {
$t++;
$chs[$t] = curl_init();
curl_setopt($chs[$t], CURLOPT_URL, $images[$t]['image']);
curl_setopt($chs[$t], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($chs[$t], CURLOPT_CONNECTTIMEOUT, 100);
curl_setopt($chs[$t], CURLOPT_TIMEOUT, 100);
curl_multi_add_handle($cmh, $chs[$t]);
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: Added to queue image: 147' . $images[$t]['image'] . ' CNT: '. count($chs));
}
}
// remove the curl handle that just completed
curl_close($done['handle']);
curl_multi_remove_handle($cmh, $done['handle']);
if(($key = array_search($done['handle'], $chs)) !== false) {
unset($chs[$key]);
}
unset($done);
clearstatcache();
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: Removed from queue image 160: ' . $info['url'] . ' CNT: '. count($chs));
}
if($t % 50 == 0) {
$parent->db->query("SELECT 1");
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: PING - MYSQL! 165 ');
}
}
}
} while ($running);
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP Importer Images: Before images m_CURL_CLOSE !');
}
curl_multi_close($cmh);
//PING
$parent->db->query("SELECT 1");
return TRUE;
} catch(Exception $e) {
$errstr = $e->getMessage();
$errline = $e->getLine();
$errfile = $e->getFile();
$errno = $e->getCode();
$parent->session->data['export_error'] = array( 'errstr'=>$errstr, 'errno'=>$errno, 'errfile'=>$errfile, 'errline'=>$errline );
if ($parent->config->get('config_error_log')) {
$parent->log->write('PHP ' . get_class($e) . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline);
}
return false;
}
}