No, it is not possible, and could even be dangerous.
序列化数据是一种攻击向量,也是一个主要的性能问题。
我强烈建议您取消序列化数据并修改保存例程。类似于此的内容应将数据转换为新格式:
$args = array(
\'post_type\' => \'my-post-type\',
\'meta_key\' => \'_coordinates\',
\'posts_per_page\' => -1
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
// get the data
$c = get_post_meta( $post->ID, \'_coordinates\', true );
// save it in the new format, separate post meta, taxonomy term etc
add_post_meta( $post->ID, \'_longitude\', $c[\'longitude\'] );
add_post_meta( $post->ID, \'_latitude\', $c[\'latitude\'] );
// clean up the old post meta
delete_post_meta( $post->ID, \'_coordinates\', $c );
}
}
然后,您可以根据需要使用各个键进行查询
如果需要存储多个经度和多个纬度,可以使用相同的名称存储多个post meta。只需使用的第三个参数get_post_meta
, 它将以数组的形式返回它们
为什么不能查询内部序列化数据
MySQL将其视为一个字符串,无法将其分解为结构化数据。将其分解为结构化数据正是上面的代码所做的
您可能能够查询部分数据块,但这将是非常不可靠、昂贵、缓慢且非常脆弱的,并且有很多边缘情况。序列化数据不适用于SQL查询,也不是以常规和恒定的方式格式化的。
除了部分字符串搜索的成本外,post meta查询速度很慢,序列化数据可能会根据内容的长度等因素发生变化,这使得搜索非常昂贵,如果不是不可能的话,这取决于您正在搜索的值
那怎么办LIKE
?
您可能会看到一些善意的问题,建议使用
LIKE
为了实现这一点。这不能解决问题吗?
This is not the solution, it is fools gold.有几个主要问题:
- false matches, 正在搜索
test
具有LIKE
也将匹配test
, testing
, untested
, 和其他值对于具有键或对象的数组,无法将其压缩为子键,无法进行排序,速度非常慢,成本非常高LIKE
将只适用于不现实的特定有限情况,并且会带来严重的性能损失。关于将记录/实体/对象作为序列化对象存储在Meta中的注意事项您可能希望在post-Meta中存储事务记录,或者在user-Meta中存储其他类型的数据结构,然后遇到上述问题。
这里的解决方案不是将其分解为单独的post meta,而是要意识到它本来就不应该是meta,而是一种自定义的post类型。例如,日志或记录可以是自定义的日志类型,原始日志可以作为父日志,也可以通过分类术语连接
安全和序列化对象
Storing serialized PHP objects via the serialize
function can be dangerous, 不幸的是,将对象传递给WordPress将意味着它将被序列化。这是因为当对象反序列化时,将创建一个对象,并执行其所有唤醒方法和构造函数。这似乎不是什么大不了的事,除非用户设法潜入精心编制的输入,从而在从数据库读取数据并由WordPress反序列化时执行远程代码。这可以通过使用JSON来避免,这也使得查询更容易,但只正确存储数据和避免结构化序列化数据一开始就更容易/更快。
如果我有一个ID列表怎么办
您可能想给WP一个数组,或者将其转换为逗号分隔的列表,但您不必这样做!Post元密钥不是唯一的,您可以多次存储同一密钥,例如:
$id = ...;
add_post_meta( $id, \'mylist\', 1 );
add_post_meta( $id, \'mylist\', 2 );
add_post_meta( $id, \'mylist\', 3 );
add_post_meta( $id, \'mylist\', 4 );
add_post_meta( $id, \'mylist\', 5 );
add_post_meta( $id, \'mylist\', 6 );
但是我怎样才能把数据拿回来呢?你有没有注意到get_post_meta
是否有始终设置为true的第三个参数?将其设置为false
:$mylist = get_post_meta( $id, \'mylist\', false );
foreach ( $mylist as $number ) {
echo \'<p>\' . $number . \'</p>;
}
如果我有一个命名项数组怎么办
如果我想以允许我查询字段的方式存储此数据结构,该怎么办?{
"foo": "bar",
"fizz": "buzz"
"parent": {
"child": "value"
}
}
很简单,用前缀将其拆分:add_post_meta( $id, "tomsdata_foo", "bar" );
add_post_meta( $id, "tomsdata_fizz", "buzz" );
add_post_meta( $id, "tomsdata_parent_child", "value" );
如果需要循环这些值,请使用get_post_meta( $id );
要获取所有post meta并循环键,例如:$all_meta = get_post_meta( $id );
$look_for = \'tomsdata_parent\';
foreach ( $all_meta as $key => $value ) {
if ( substr($string, 0, strlen($look_for)) !== $look_for ) {
continue; // doesn\'t match, skip!
}
echo \'<p>\' . $key . \' = \' . $value . \'</p>\';
}
将输出:<p>tomsdata_parent_child = value</p>
<记住,当WP获取一篇文章时,它会同时获取所有的文章元,所以get_post_meta
调用非常便宜,不会触发额外的数据库查询如果您知道需要搜索/查询/筛选子值,那么为什么不使用该值存储一个额外的post meta以便您可以搜索它呢?
结论
So you don\'t need to store structured data as a string in the database, and you shouldn\'t if you plan to search/query/filter on those values.
可以使用正则表达式和LIKE
, 但这是extremely unreliable, 对大多数类型的数据都不起作用,而且速度非常慢,数据库负担也很重。如果结果是单独的值,你也不能像对结果进行数学运算那样