【问题标题】:Remove "%" from strings in serialized arrays in MySQL database从 MySQL 数据库中序列化数组中的字符串中删除“%”
【发布时间】:2011-03-28 01:48:02
【问题描述】:

在将博客从 Blogger 转换为 WP 并运行脚本以获取热链接图像以进行托管的过程中,我最终得到了一些时髦的图像名称,例如

act%252Bapandas-210x290.png

这些图像名称会阻止图像显示在网页上,因为 url 编码以文件名本身结尾(不要问!)。我在文件服务器上重命名了它们,没有问题,但名称也在每个帖子的附件元数据中。

如何从wp_postmeta 表中的所有图像引用中删除“%”?它们中的大多数出现在meta_values 中的序列化数组中,用于meta_keys 的_wp_attachment_metadata。我没有找到一个插件,并且不确定如何建立一个纯 SQL 解决方案。

编辑:

正如评论员所说,问题是更改或删除“%”字符并更新数组以报告正确的字符数(即 s:13 表示 yoursite.com is 13 char[]) 我也愿意使用 php 解决方案!有什么能帮我解决这个烂摊子。

后记和解决方案

我并没有真正根据 WordPress 问题来构建这个问题,而是将其构建为 SQL 问题。我相应地给予了我的答案。但我能够在本地解决问题(在Rarst@的帮助下。这是我解决问题的方法,在循环中使用原生 WordPress 函数:

$posts = get_posts(array(
    'post_type' => 'attachment',
    'numberposts' => -1, ));

foreach( $posts as $post ) {

    // retrieve data, unserialized automatically
    $meta = get_post_meta($post->ID,'_wp_attachment_metadata', true);

    // loop through array to do any search and replaces

    // write it back
    update_post_meta($post->ID, '_wp_attachment_metadata', $meta); }

这些函数将自动确定您正在检索或写入的数据类型,并在必要时对其进行(取消)序列化。这是通过内部使用 maybe_serialize() 和 maybe_unserialize() 函数来处理的。

【问题讨论】:

  • 请参阅@zerkms 的 cmets 了解更改序列化数组数据的陷阱。
  • 这就是为什么不建议将数据存储在序列化数组中的原因。

标签: php mysql regex wordpress serialization


【解决方案1】:

由于序列化数组结构的复杂性,我确信纯 SQL 是不可能的。

【讨论】:

  • 对不起,应该提出这个问题,说我真的愿意接受任何解决方案。
  • @two7s_clash:完全正确。这是不可能的;-)
  • 难道不能使用这样的解决方案,在 $old 和 $new 的一些正则表达式中工作吗?如果我有误会,我很乐意为您解答。
  • @two7s_clash: 改变序列化数组的唯一可能方法:1) 反序列化 2) 修改它 3) 序列化回来。
【解决方案2】:

要消除列中的 % 符号,您应该能够执行以下操作:

UPDATE table_name
SET field_name = replace(field_name, '[%]', '')

【讨论】:

  • 你知道序列化数组是什么吗?
【解决方案3】:

如果你只是想去掉 %'s,这很简单——只需用 REPLACE 函数替换 '%' 即可。

但是,我怀疑你不想要这个。您的问题尚不清楚,但我怀疑您也想解码 %xxx 回正确的字符。在这种情况下,您可以先提取字符串的“xxx”部分(应为十六进制),在其前面附加“0x”并将其转换回一个数字,然后将该数字转换为字符串。然后,您使用 SUBSTRING 缝合文本数据,删除“%”并就地替换新字符串。

编辑:不要这样做:这可能会破坏序列化数组(请参阅下面的评论)

我保留这个(不正确的)答案只是为了让人们知道它的陷阱。

【讨论】:

  • @zerkms,我认为你说得有道理。但是,您提出观点的方式有待改进。您应该在您的 cmets 中添加更多信息,以便人们可以学到一些东西。
  • @Stephen Chung:好的。序列化数组是一种特殊的复杂格式,强烈依赖于数据大小。如果您只是从字符串中删除某些内容而不重新计算大小 - 您的数据将被破坏。这是一个示例:ideone.com/2kFdy。在第二种情况下,我们简单地删除了% char 并保持字符串 size = 2 不变。
  • @zerkms,我假设在 PHP 序列化数组中,'%' 字符被单独留下(尽管我没有测试过)。如果您认为 PHP 的序列化使用了某些 '%' 字符,请不吝赐教。如果您认为我们应该先将 %-escaped 字符转换为 PHP 序列化格式,那么也请不吝赐教。
  • @zerkms,好的。知道了。奇怪,但真实。每天学些新东西!为您的评论 +1。
  • @Stephen Chung:修改序列化数组中数据的唯一正确方法是:1)将字符串反序列化回数组 2)对数组项执行更改 3)将数组序列化回字符串
【解决方案4】:

试试这个查询:(将 FIELD_NAMES 替换为您作为单独查询输入的字段名称)

update wp_postmeta set FIELD_NAME = replace(FIELD_NAME, '%', '');

注意:您可以更改 '' 并将其设置为空格或您想要的任何内容(保留它,因为它替换 %,没有空格,没有其他内容)。

编辑:没关系,阅读 Stephen Chung 的大评论。

【讨论】:

  • 你知道序列化数组是什么吗?
  • @zerkms - 我在我的问题中添加了一个数组示例。
【解决方案5】:

这是我解决问题的方法,在循环中使用原生 WordPress 函数:

$posts = get_posts(array(
    'post_type' => 'attachment',
    'numberposts' => -1, ));

foreach( $posts as $post ) {

    // retrieve data, unserialized automatically
    $meta = get_post_meta($post->ID,'_wp_attachment_metadata', true);

    // loop through array to do any search and replaces

    // write it back
    update_post_meta($post->ID, '_wp_attachment_metadata', $meta); }

【讨论】:

    猜你喜欢
    • 2021-12-09
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    相关资源
    最近更新 更多