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. Excel数据导入数据库的SQL快速生成

    =CONCATENATE("insert into table_name(id, code, name, remark) values (uuid(),'",B2,"', ...

  2. Redis 的性能幻想与残酷现实

    2011 年,当初选择 Redis 作为主要的内存数据存储,主要吸引我的是它提供多样的基础数据结构可以很方便的实现业务需求.另一方面又比较担心它的性能是否足以支撑,毕竟当时 Redis 还属于比较新的 ...

  3. 谈谈对Spring IOC的理解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  4. 跟vczh看实例学编译原理——一:Tinymoe的设计哲学

    自从<序>胡扯了快一个月之后,终于迎来了正片.之所以系列文章叫<看实例学编译原理>,是因为整个系列会通过带大家一步一步实现Tinymoe的过程,来介绍编译原理的一些知识点. 但 ...

  5. Windows Azure Storage (6) Windows Azure Storage之Table

    <Windows Azure Platform 系列文章目录> 最近想了想,还是有必要把Windows Azure Table Storage 给说清楚. 1.概念 Windows Azu ...

  6. Module-Zero之租户管理

    返回<Module Zero学习目录> 开启多租户 租户实体 租户管理者 默认租户 开启多租户 ABP和Module-Zero可以运行多租户或单租户模式.多租户默认是禁用的.我们可以在mo ...

  7. Java学习笔记(06)

    继承 super关键字 重写 final关键字 抽象类/abstract关键字 接口 一.继承 继承是类与类之间的继承,是一种is a 的关系(继承的满足条件) 继承的类叫子类 / 派生类,被继承的叫 ...

  8. Java集合类的组织结构和继承、实现关系

    Collection继承.实现关系如下(说明(I)表示接口,(C)表示Java类,<--表示继承,<<--表示实现): (I)Iterable |<--(I)Collectio ...

  9. EditText中imeOptions属性使用及设置无效解决

    虽然通常输入法软键盘右下角会是回车按键 但我们经常会看到点击不同的编辑框,输入法软键盘右下角会有不同的图标 点击浏览器网址栏的时候,输入法软键盘右下角会变成“GO”或“前往” 而我们点击Google搜 ...

  10. 解读sencha touch移动框架的核心架构(二)

    本来这行要详解Ext.extend的,但是发现网站有很详细的,那么就跳过去吧 为保持一个系列的分析,还是先搬过来吧,下章开始分析Ext4.0的新架构 在Java中,我们在实现继承的时候存在下面几个事实 ...