wordpress是用php语言开发的博客平台,它扩展性强,容易扩展,很适合拿来做二次开发。

1,问题由来

本周五,我在浏览公司的网站(基于wordpress开发)时发现,网站首页上有两篇文章的缩略图重复了,于是我进入网站后台检查,想看下是不是某位员工在撰写文章时不小心这两篇文章选择了相同的图片作为封面图片。

结果发现这两篇文章选用的封面图片的文件名还真是相同,但我转念又想到,员工再糊涂也不至于犯这样的错误。于是,我检查了下这几篇文章的封面图片url地址,这些地址是相同的。

我想到,有可能是这两张图片的文件名相同(至于为什么会出现这种情况,恐怕只有鬼知道),然后文件被上传后,后上传的图片将前面上传的图片覆盖,最后只有一张图片留在了云存储的服务器上。

注:我写了个插件,在上传图片时,可以将图片上传至百度云的BOS上。

2,问题该如何解决

其实,一开始我是很纠结这个问题的:是让编辑文章的员工下次注意,每次上传图片时都要按年月日时间、加序号和图片其它信息将图片重名后再上传呢,还是自己默默的在自己写的插件里加上一些代码把图片重命名呢?

好吧,写到这里,你肯定能猜到我做了什么样的选择?写代码吧。

3,曲折的过程

我的插件原来只负责把图片上传到百度云的BOS上,然后把本地图片删除,主要用到了wordpress的wp_update_attachment_metadata钩子。我在这个钩子里调用了一个自己定义的函数upload_attachement_to_bos,

这个函数就负责把图片上传到BOS并删除本地图片。一开始,我一直在想如何在这个函数里做文章:把原图重命名,把缩略图重命名,额,试了半天都没有效果。我检查了下BOS上的图片,上传成功、文件名也是修改后的。

可是为什么网站的图片url地址还是没变?

不能着急,先去媒体库下面看下图片,结果发现媒体库的图片文件名、标题、url中的名称都还是原来的文件名。

我虽然把服务器上的文件名都改了,但数据库中与图片有关的字段的值都没有改。于是,我尝试更改wordpress的数据表,来看媒体库和文章缩略图中的图片文件名是否有变化。

期间,我试着修改post表中的postname、post_title、guid字段,然而并没有用。postname:文章的别名,显示在url地址中,一般可用来美化url地址,post_title:与媒体库中,附件详情表单页面中的图片标题对应,就相当于文章标题,

guid:这个,说实话,我也不知道它有什么用,好像是文章的唯一标识。

我最后定位到postmeta表中的meta_key: _wp_attached_file对应的meta_value。这个_wp_attached_file的值会影响文章附件的相关信息,如媒体库中的附件详情页中的图片url、文件名都是取的meta_value值

另外就是wordpress主题(据我测试的有限的几个主题)下首页文章缩略图、文章单页中的头图url中的文件名都是取的这个值。

好,总算找到病根了,剩下的问题就是如何把这个值给修改掉。

4,问题暂时解决,但还有一些遗留问题

前面说到了,我用到了wp_update_attachment_metadata钩子,于是我在对应的钩子函数里做文件名修改、更新_wp_attached_file的工作。钩子函数代码大致如下:

 // 钩子函数: 重命名文件,更新文件meta信息,调用上传函数,并将上传的原图在bucket下的路径信息保存到数据库
function update_attachment_metadata($data, $post_id) {
/* 重命名文件防止冲突 */
date_default_timezone_set('PRC');
$wp_upload_dir = wp_upload_dir();
$old_path = $wp_upload_dir['basedir'] . '/' . $data['file'];
$ext = pathinfo($old_path, PATHINFO_EXTENSION);
$old_namestr = str_replace('.' . $ext, '', basename($data['file']));
$new_namestr = date('YmdHis-') . dechex(mt_rand(100000, 999999));
$new_path = $wp_upload_dir['path'] . '/' . $new_namestr. '.' . $ext; rename($old_path, $new_path); if (isset($data['sizes']) && count($data['sizes']) > 0) {
$thumb_data = &$data['sizes'];
foreach ($thumb_data as $key => $thumb) {
$old_thumbpath = $wp_upload_dir['basedir'] . '/' . substr($data['file'], 0, 8)
. $thumb['file'];
$new_thumbpath = str_replace($old_namestr, $new_namestr, $old_thumbpath);
if (file_exists($old_thumbpath)) {
rename($old_thumbpath, $new_thumbpath);
}
}
}
/* 更新data中的文件名 */
$old_jsdata = json_encode($data, JSON_UNESCAPED_UNICODE);
$new_data = json_decode(str_replace($old_namestr, $new_namestr, $old_jsdata), true); unset($data, $old_jsdata); $ori_object_key = upload_attachement_to_bos($new_data, $post_id);
// 将原始图片在BOS bucket下的路径信息(object信息)添加到数据库
add_post_meta($post_id, 'bos_info', $ori_object_key); /* 更新数据库中postmeta表中_wp_attached_fies的值 */
$old_meta = get_post_meta($post_id, '_wp_attached_file', true);
update_post_meta($post_id, '_wp_attached_file', str_replace($old_namestr, $new_namestr, $old_meta)); return $new_data;
}

关键是36、37行修改postmeta表中的_wp_attached_file值,然后需要注意的是,我这里对函数的返回值进行了处理,返回的$new_data数组是替换文件名后的数组,我暂时还不知道这么做会不会产生什么副作用。

然后,我把插件代码更新了下。嗯,插件起作用了,重命名功能实现,原有功能没被破坏。

5,其他啰哩啰嗦的问题

(1)代码中的$data数组是一个多维数组,多维数组做字符串替换该怎么做呢?str_replace()函数好像只能替换一维数组。我在代码里用的是将数组转化为字符串再替换的方法,用到了json_encode()和json_decode(),不知道还有没有其他更好的方法。

(2)文件重名的的方法rename(),在对文件重命名之前要先判断文件是否存在和文件夹权限(或者权限不够时,修改文件夹权限),我这里没有做。

ps:我写的这个wp-bos插件(支持wordpress使用云存储作为图片的存储空间,目前支持BOS百度云存储)托管在gitoschinagithub上,

不过托管的代码暂时还没有将重命名的功能加入,等到插件在网站上运行一段时间没有问题后,我会及时将更改push上去,感兴趣的朋友可以关注下。

wordpress上传图片时重命名--修改插件时遇到的一些问题的更多相关文章

  1. 纯代码实现WordPress上传图片自动重命名的方法

    在我们使用 WordPress 发布文章时,经常都需要添加图片.多媒体什么的.然而,大家都知道 WordPress 是舶来物,对于中文用户来说,我们都会把图片命名为中文的,由于 WordPress 机 ...

  2. 在重命名SqlServer数据库时,报5030错误的解决办法

    数据库不能重名名5030的错误,其实很简单原因就是有应用程序正在占用这个连接,使用这样一行命令就可以查询出正在占用的连接 use master select spid from master.dbo. ...

  3. 通过restore database时重命名数据库rename database

    backup database testdb to disk='c:\testdb_ful.bak' with compression backup log testdb to disk='c:\te ...

  4. gson转换json到bean时重命名

    @Expose   @SerializedName("0001") public Map<String,ChannelBean> c0001 = new HashMap ...

  5. asp.net使用FileUpload控件上传图片且重命名

    我在根目录下创建了一个Images图片存放文件夹,上传的图片都在这 下面贴代码 if (FileUpload1.HasFile) { string filename = FileUpload1.Fil ...

  6. 织梦dedecms修改include和plus重命名提高安全性防漏洞注入挂马

    织梦dedecms是新手站长使用得比较多的一个建站开源程序,正因如此,也是被被入侵挂马比较多的程序.下面就来跟大家说一下怎么重新命名dedecms的include文件夹以及plus文件夹来提高网站的安 ...

  7. linux安装PyCharm,PyCharm常用快捷键及调试模式,pycharm里面对文件夹或者文件进行重命名

    PyCharm常用快捷键及调试模式 2017年10月18日 23:13:43 菜鸟之神 阅读数:5835    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn ...

  8. VS中C++ 项目重命名

    应该都有过这样的经历,在Visual studio中创建解决方案,添加几个项目进去,然后开始愉快的敲代码....写代码正欢的时候,却总是感觉那里有些不舒服,一细看,这项目名称取的真心挫,修改个吧.直接 ...

  9. Web 在线文件管理器学习笔记与总结(13)重命名文件夹(14)复制文件夹

    (13)重命名文件夹 ① 重命名文件夹通过 rename($oldname,$newname) 实现 ② 检测文件夹名是否符合规范 ③ 检测当前目录中是否存在同名文件夹名称,如果不存在则重命名成功 i ...

随机推荐

  1. Spring MVC的配置文件(XML)的几个经典案列

    1.既然是配置文件版的,那配置文件自然是必不可少,且应该会很复杂,那我们就以一个一个的来慢慢分析这些个经典案列吧! 01.实现Controller /* * 控制器 */ public class M ...

  2. cocos2d-x:Particle System(粒子系统)

    一.粒子系统简介: 粒子系统最早出现在80年代,主要用于解决由大量按一定规则运动(变化)的微小物质在计算机上的生成和显示问题.Particle System的应用非常广泛,大的可以模拟原子弹爆炸,星云 ...

  3. TP5验证规则使用

    定义验证器类: namespace app\index\validate; use think\Validate; class User extends Validate { protected $r ...

  4. SQLServer存储过程事务用法

    更多资源:http://denghejun.github.io IF object_id('InsertAntennaProcedure') IS NOT NULL DROP PROCEDURE In ...

  5. ASP.NET Core 十种方式扩展你的 Views

    原文地址:http://asp.net-hacker.rocks/2016/02/18/extending-razor-views.html 作者:Jürgen Gutsch 翻译:杨晓东(Savor ...

  6. ASP.NET Core中显示自定义错误页面-增强版

    之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...

  7. 剑指Offer面试题:16.合并两个排序的链表

    PS:这也是一道出镜率极高的面试题,我相信很多童鞋都会很眼熟,就像于千万人之中遇见不期而遇的人,没有别的话可说,唯有轻轻地问一声:“哦,原来你也在这里? ” 一.题目:合并两个排序的链表 题目:输入两 ...

  8. 借助 Lucene.Net 构建站内搜索引擎(上)

    前言:最近翻开了之前老杨(杨中科)的Lucene.Net站内搜索项目的教学视频,于是作为老杨脑残粉的我又跟着复习了一遍,学习途中做了一些笔记也就成了接下来您看到的这篇博文,仅仅是我的个人笔记,大神请呵 ...

  9. java.lang.IndexOutOfBoundsException at java.io.FileOutputStream.writeBytes(Native Method)

    ss available : /usr/linkapp/data/linkapp/ddn_1440639847758_temp java.lang.IndexOutOfBoundsException ...

  10. 生成lua的静态库.动态库.lua.exe和luac.exe

    前些日子准备学习下关于lua coroutine更为强大的功能,然而发现根据lua 5.1.4版本来运行一段代码的话也会导致 "lua: attempt to yield across me ...