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. Struts2使用demo

    创建一个web project: 导入Struts2的jar包放到lib目录下: WEB-INF下面创建login.jsp和welcome.jsp;index.jsp删掉: 说一下<%@ tag ...

  2. ecma6 yield

    function * generator(k){ console.log('begin'); var x = yield k; console.log('x:',x); var y = yield x ...

  3. C#3.0扩展方法学习篇

     什么是类的扩展方法 扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. MSDN Extension methods enable you to &q ...

  4. ENode框架Conference案例分析系列之 - 复杂情况的读库更新设计

    问题背景 Conference案例,是一个关于在线创建会议(类似QCon这种全球开发者大会).在线管理会议位置信息.在线预订某个会议的位置的,这样一个系统.具体可以看微软的这个项目的主页:http:/ ...

  5. 领域驱动设计(DDD)部分核心概念的个人理解

    领域驱动设计(DDD)是一种基于模型驱动的软件设计方式.它以领域为核心,分析领域中的问题,通过建立一个领域模型来有效的解决领域中的核心的复杂问题.Eric Ivans为领域驱动设计提出了大量的最佳实践 ...

  6. 日志系统实战(三)-分布式跟踪的Net实现

    介绍 在大型系统开发调试中,跨系统之间联调开始变得不好使了.莫名其妙一个错误爆出来了,日志虽然有记录,但到底是哪里出问题了呢? 是Ios端参数传的不对?还是A系统或B系统提供的接口导致?相信有不少人遇 ...

  7. Mycat 月分片方法

    概述 本篇文章主要介绍Mycat以月进行分片的方法,包括配置方法.注意事项等. mycat版本:1.4 数据节点:dn1,dn2,dn3 架构:主从 配置  创建测试表 CREATE TABLE `t ...

  8. Improve Your Study Habits

    1.Plan your time carefully. Make a list of your weekly tasks.Then make a schedule or chart of your t ...

  9. window系统JDK1.7的快速配置

    快速配置java环境变量 右键单击计算机--->属性 点击 "高级系统设置"--->"环境变量",出现环境变量设置窗口 系统变量--->新建 ...

  10. DOM访问元素样式和操作元素样式

    在HTML中定义样式的方式有三种:通过<link/>元素包含外部样式表文件(外部样式表).使用<style/>元素定义嵌入式样式(嵌入式样式表).使用style特性定义针对特定 ...