require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
$image_id = media_sideload_image($image_url, 0, null, "id");
Second way for existing images in FTP :
<?php $file = $images_DIR . $sku . '.jpg';
$attachment = [
'post_mime_type' => 'image/jpeg',
'post_title' => $sku,
'post_content' => '',
'post_status' => 'inherit'
];
$attach_id = wp_insert_attachment($attachment, $file, $product_id);
$attach_data = wp_generate_attachment_metadata($attach_id, $file);
wp_update_attachment_metadata($attach_id, $attach_data);
set_post_thumbnail($product_id, $attach_id);