咱们的 WordPress 网站在运用了图床,或复制粘贴了别人网站内容的状况下,文案中会显现有些外边照片(位置)。倘若运用的图床停止服务(尤其是白嫖的免费图床),或别人的网站挂了,就会引起咱们网站文案中的外链照片亦随之失效,没法表示。
此时,倘若提前备份了照片还好,重新上传或批量替换位置什么的就能够了,无非便是麻烦有些。但倘若照片无备份,那就糟糕了,重新给所有文案配图可不是一件容易的事。
那样, 怎样避免这个问题呢?最保险的做法自然是将文案中的外边照片,下载并保留到 WordPress 媒介库,并将文案中的照片链接替换为本地服务器的照片链接。实现亦很简单,无需安装插件,直接将下方代码加入到主题 functions.php 文件中,之后更新发布文案就会看到效果了。 function ecp_save_post($post_id, $post
) { global $wpdb
; if ($post->post_status == publish
) { $p = /<img.*[\s]src=[\"|\](.*)[\"|\].*>/iU
; $num = preg_match_all($p, $post->post_content, $matches
); if ($num
) { $wp_upload_dir
= wp_upload_dir();
set_time_limit(0); $ch
= curl_init(); curl_setopt($ch, CURLOPT_HEADER, false
); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true
); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false
); curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true
); curl_setopt($ch
, CURLOPT_MAXREDIRS, 20); curl_setopt($ch
, CURLOPT_CONNECTTIMEOUT, 30); $ecp_options = $_SERVER[HTTP_HOST
]; foreach ($matches[1] as $src
) { if (isset($src) && strpos($src, $ecp_options) === false
) { $file_info = wp_check_filetype(basename($src
), null); if ($file_info[ext] == false
) { date_default_timezone_set(PRC
); $file_name = date(YmdHis-) . dechex(mt_rand(100000, 999999)) . .tmp
; } else
{ $file_name= dechex(mt_rand(100000, 999999)) .- . basename($src
);
} curl_setopt($ch, CURLOPT_URL, $src
); $file_path = $wp_upload_dir[path] . / . $file_name
; $img = fopen($file_path, wb
); curl_setopt($ch, CURLOPT_FILE,$img
); $img_data = curl_exec($ch
); fclose($img
); if (file_exists($file_path) && filesize($file_path
) > 0) { $t = curl_getinfo($ch
, CURLINFO_CONTENT_TYPE); $arr = explode(/, $t
); if (pathinfo($file_path, ATHINFO_EXTENSION) == tmp
) { $file_path = ecp_handle_ext($file_path, $arr[1], $wp_upload_dir[path], $file_name, tmp
);
} $post->post_content = str_replace($src, $wp_upload_dir[url] . / . basename($file_path), $post
->post_content); $attachment= ecp_get_attachment_post(basename($file_path), $wp_upload_dir[url] . / . basename($file_path
)); $attach_id = wp_insert_attachment($attachment, ltrim($wp_upload_dir[subdir] . / . basename($file_path), /
), 0); $attach_data = wp_generate_attachment_metadata($attach_id, $file_path
); $ss = wp_update_attachment_metadata($attach_id, $attach_data
);
}
}
} curl_close($ch
); $wpdb->update($wpdb->posts, array(post_content => $post->post_content), array(ID => $post
->ID));
}
}
} function ecp_handle_ext($file, $type, $file_dir, $file_name, $ext
) { if ($ext === tmp
) { if (rename($file, str_replace(tmp, $type, $file
))) { return $file_dir . / . str_replace(tmp, $type, $file_name
);
}
} return $file
;
} function ecp_get_attachment_post($filename, $url
) { $file_info = wp_check_filetype($filename
, null); return
array( guid => $url
, post_type => attachement
, post_mime_type => $file_info[type
], post_title => preg_replace(/\.[^.]+$/, , $filename
), post_content
=> , post_status => inherit
);
} add_action(save_post, ecp_save_post
, 120, 2);
不外,亦有这种状况和需要:网站运用了国外服务器,但把照片放在国内服务器上(如利用国内大厂的某些服务当作免费图床)以提高加载速度。因此呢期盼能够暂时运用国内的照片外链,只是先将外链照片提前备份到媒介库。当某天万一外链照片挂了,再替换成内链照片。
怎样实现呢?下面供给两段代码,任选其一就可。代码 1 是在以上代码基本上修改而来。 保持原外链照片文件名和格式,再也不自动重命名上传的照片仅上传外链照片至媒介库,再也不自动替换文案中的照片链接位置
代码 1 function ecp_save_post($post_id, $post
) { global $wpdb
; if($post->post_status == publish
) { $p = /<img.*[\s]src=[\"|\](.*)[\"|\].*>/iU
; $num = preg_match_all($p, $post->post_content, $matches
); if ($num
) { $wp_upload_dir
= wp_upload_dir();
set_time_limit(0); $ch
= curl_init(); curl_setopt($ch, CURLOPT_HEADER, false
); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true
); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false
); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true
); curl_setopt($ch
, CURLOPT_MAXREDIRS, 20); curl_setopt($ch
, CURLOPT_CONNECTTIMEOUT, 30); $ecp_options = $_SERVER[HTTP_HOST
]; foreach ($matches[1] as $src
) { if (isset($src) && strpos($src, $ecp_options) === false
) { $attachment_id= attachment_url_to_postid($src
); if ($attachment_id
) { continue
;
} $file_name = basename($src
); $file_path = $wp_upload_dir[path] . / . $file_name
; if (file_exists($file_path
)) { continue
;
} curl_setopt($ch, CURLOPT_URL, $src
); $img = fopen($file_path, wb
); curl_setopt($ch, CURLOPT_FILE, $img
); $img_data = curl_exec($ch
); fclose($img
); if (file_exists($file_path) && filesize($file_path
) > 0) { $attachment = ecp_get_attachment_post($file_name, $wp_upload_dir[url] . / . $file_name
); $attach_id = wp_insert_attachment($attachment, $file_path
, 0); $attach_data = wp_generate_attachment_metadata($attach_id, $file_path
); wp_update_attachment_metadata($attach_id, $attach_data
);
}
}
} curl_close($ch
);
}
}
} function ecp_get_attachment_post($filename, $url
) { $file_info = wp_check_filetype($filename
, null); return
array( guid => $url
, post_type => attachment
, post_mime_type => $file_info[type
], post_title => preg_replace(/\.[^.]+$/, , $filename
), post_content
=> , post_status => inherit
);
} add_action(save_post, ecp_save_post
, 120, 2);
代码 2 function backup_external_images_to_media_library( $post_id
) { $post = get_post( $post_id
); $content = $post
->post_content; preg_match_all( /<img[^>]+src="([^">]+)"/i, $content, $matches
); if ( isset( $matches[1] ) && !empty( $matches
[1] ) ) { foreach ($matches[1] as $image_url
) { if ( strpos( $image_url, home_url() ) === false
) { $attachment_id = attachment_url_to_postid( $image_url
); if ( !$attachment_id
) { $upload = upload_image_to_media_library_without_replacement( $image_url
); if ( $upload && !is_wp_error( $upload
) ) {
}
}
}
}
}
} functionupload_image_to_media_library_without_replacement($image_url
) { $image_data = file_get_contents( $image_url
); if ( !$image_data
) { return new WP_Error( image_download_failed, __( Failed to download image., text-domain
) );
} $filename = basename( parse_url( $image_url
, HP_URL_PATH ) ); $upload_dir
= wp_upload_dir(); $upload_path = $upload_dir[path] . / . $filename
; if ( file_exists( $upload_path
) ) { return false
;
} if ( !file_put_contents( $upload_path, $image_data
) ) { return new WP_Error( image_save_failed, __( Failed to save image., text-domain
) );
} $file_type = wp_check_filetype( $filename
, null ); $attachment
= array( guid => $upload_dir[url] . / . basename( $filename
), post_mime_type => $file_type[type
], post_title => sanitize_file_name( $filename
), post_content
=> , post_status => inherit
,
); $attachment_id= wp_insert_attachment($attachment, $upload_path
); if ( !is_wp_error( $attachment_id
) ) { require_once( ABSPATH . wp-admin/includes/image.php
); $attachment_data= wp_generate_attachment_metadata($attachment_id, $upload_path
); wp_update_attachment_metadata( $attachment_id, $attachment_data
); return
array( id => $attachment_id
, url => wp_get_attachment_url( $attachment_id
),
);
} return false
;
} add_action( save_post, backup_external_images_to_media_library
);
哪段代码更好?
代码 1的优良在于它运用了 cURL,能够更好地处理繁杂的网络请求,如大照片下载、重定向等场景。倘若需要处理更加多不确定性原因(如外边服务器响应时间较长、繁杂的重定向状况),第1段代码可能更适合,但亦需要更繁杂的守护和优化。
代码 2更加简洁、易读、模块化,且错误处理更清晰,适合大都数平常场景。它的实现更符合现代编程习惯,代码守护性较好。倘若无特殊的超时或重定向处理需要,它的实现方式较优。
因此呢,倘若目的是简单的下载和备份外边照片,举荐运用 代码 2,由于它更加简洁,且易于扩展和守护。倘若需要处理更加多繁杂的网络请求,如跨站点的大文件下载或重定向,代码 1 的 cURL 方式可能更适合。
最后,倘若仅仅先备份照片到媒介库,小白意见不要在内链照片位置中包括年份和月份(日期),以方便以后替换链接。只需要在 WordPress 网站后台 - 设置 - 媒介 - 文件上传,取消勾选”以年—月目录形式组织上传内容“就能够了。
|