如何从 WordPress 数据库中获取高级自定义字段字段键?
Posted
技术标签:
【中文标题】如何从 WordPress 数据库中获取高级自定义字段字段键?【英文标题】:How to get Advanced Custom Fields field key from WordPress database? 【发布时间】:2014-02-06 16:08:04 【问题描述】:我正在使用具有后期类型的高级自定义字段。我有一些选择的自定义字段,我想显示每个字段的所有标签选项。
我试过这种方法。
$field = get_field_object('hair_color');
$hair = $field["choices"];
foreach($hair as $value)
做一个
var_dump($field)
它看起来是空的:
array(18)
["key"] => string(16) "field_hair_color"
["label"] => string(0) ""
["name"] => string(10) "hair_color"
["_name"] => string(10) "hair_color"
["type"]=> string(4) "text"
["order_no"]=> int(1)
["instructions"]=> string(0) ""
["required"]=> int(0)
["id"] => string(20) "acf-field-hair_color"
["class"] => string(4) "text"
["conditional_logic"] => array(3)
["status"] => int(0)
["allorany"]=> string(3) "all"
["rules"]=> int(0)
["default_value"] => string(0) ""
["formatting"] => string(4) "html"
["maxlength"] => string(0) ""
["placeholder"] => string(0) ""
["prepend"] => string(0) ""
["append"] => string(0) ""
["value"] => bool(false)
获得完整的唯一方法是:
get_field_object('field_51ac9d333d704');
array(17)
["key"] => string(19) "field_51ac9d333d704"
["label"] => string(13) "Color de pelo"
["name"] => string(10) "hair_color"
["_name"] => string(10) "hair_color"
["type"] => string(6) "select"
["order_no"] => int(9)
["instructions"] => string(27) "Selecciona el color de pelo"
["required"] => int(0)
["id"] => string(20) "acf-field-hair_color"
["class"] => string(6) "select"
["conditional_logic"] => array(3)
["status"] => int(0)
["rules"] => array(1)
[0] => array(3)
["field"] => string(19) "field_5195ef9879361"
["operator"] => string(2) "=="
["value"] => string(5) "small"
["allorany"] => string(3) "all"
["choices"] => array(5)
["bald"] => string(5) "Calvo"
["brown"] => string(8) "Castaño"
["brunette"] => string(6) "Moreno"
["red"] => string(9) "Pelirrojo"
["blonde"] => string(5) "Rubio"
["default_value"] => string(0) ""
["allow_null"] => int(1)
["multiple"] => int(0)
["field_group"] => int(90679)
["value"]=> bool(false)
但我有 3 个环境,我不想硬编码字段键。
有什么解决办法吗? 提前致谢。
【问题讨论】:
我已经这样做了:$pageme = get_page_by_title('post_title', OBJECT, 'post_type' ); $field = get_field_object('hair_color', $pageme->ID); $pais = $field["choices"];
它工作正常。
【参考方案1】:
我只是想自己做这件事,所以我做了一些调查。似乎 ACF 的每个字段和字段组都作为自定义帖子类型存储在数据库的 wp_posts 表中。字段是“acf-field”,组是“acf-field-group”。
我能够使用此函数获取字段键,然后在还没有该字段的帖子上使用 update_field($field_key, $value)。
function get_acf_key($field_name)
global $wpdb;
return $wpdb->get_var("
SELECT post_name
FROM $wpdb->posts
WHERE post_type='acf-field' AND post_excerpt='$field_name';
");
然后我就可以使用了:
update_field(get_acf_key('my_field_name'), 'some value', $post_id);
要更新已拥有该字段的帖子的字段,或添加该字段并将其作为对尚未拥有该字段的帖子的关键引用。
【讨论】:
我认为您必须使用旧版本的高级自定义字段 - 字段不再保留在帖子表中,所以很遗憾这不起作用。 我使用的是最新版本。用于描述字段的数据在帖子表中作为自定义帖子类型。具有相关数据的字段存储在 postmeta 表中。最初的问题是如何获取命名字段的密钥。 这些字段绝对不在帖子中。只有字段组保留在帖子中。 版本 5.3.7(2016 年 4 月)(专业版)在 wp_posts 中包含 acf-field 作为 post_type。 这有点跑题了,但是如果您想验证/错误检测 ACF update_field 是否有效(它不提供开箱即用的功能),您可以执行以下操作:$field_key = get_acf_key('my_field_name') update_field($field_key, 'some value', $post_id); $verified_value = get_field($field_key, $post_id); if ($value !== $verified_value) : $errors[] = 'Error updating field'; endif;
【参考方案2】:
这是@BFDatabaseAdmin 提供的答案的修改版本,与“LIKE”中的确切元值匹配
function get_acf_key($field_name)
global $wpdb;
$length = strlen($field_name);
$sql = "
SELECT `meta_key`
FROM $wpdb->postmeta
WHERE `meta_key` LIKE 'field_%' AND `meta_value` LIKE '%\"name\";s:$length:\"$field_name\";%';
";
return $wpdb->get_var($sql);
【讨论】:
【参考方案3】:我将另一种选择加入其中。我认为现有的答案很好,但是除非您查看父组,否则您将永远无法获得可靠的字段键,因为字段名称可以跨多个组存在。
例如,假设您有两个自定义组 - 一个用于帖子类型 books,另一个用于自定义帖子类型 movies。两个组都添加了一个名为标题的字段。
在数据库中,两者都以post_except = 'title'
和post_type = 'acf-field'
存储。两个具有相同post_except
的条目,因此任何依赖于post_except
的only 查询都是错误的,无论是否为通配符。
任何依赖帖子 id 的查询也不是很好,因为帖子可能并不总是存在以传递。
所以你需要传入字段和组的组合来从名称中获取字段键。这个 sn-p 对我很有效:
if (! function_exists('acf_field_from_name'))
function acf_field_from_name($field, $group)
global $wpdb;
return $wpdb->get_var($wpdb->prepare("
SELECT post.post_name as field_name
FROM $wpdb->posts AS post
LEFT JOIN $wpdb->posts AS parent
ON post.post_parent = parent.id
WHERE post.post_excerpt = %s
AND post.post_type = 'acf-field'
AND parent.post_excerpt = %s
AND parent.post_type = 'acf-field-group'
", $field, $group));
将从名称和组返回字段键,如果不存在则返回 null。
用法:
acf_field_from_name('title', 'movie-fields'); // returns field_3333333333333
acf_field_from_name('title', 'book-fields'); // returns field_4444444444444
acf_field_from_name('plumbus', 'movie'); // returns null
【讨论】:
【参考方案4】:ACF 提供了一些简单的方法来帮助保持多个环境同步 - 您可以使用 php 或本地 JSON 文件注册您的字段。这样做可以让您在多个环境中继续使用带有单个字段键的 get_field_object()。见:
http://www.advancedcustomfields.com/resources/register-fields-via-php/
http://www.advancedcustomfields.com/resources/local-json/
我通常使用用户界面进行 ACF 开发,然后将我的所有字段组导出为 PHP 以跨多个环境进行部署。
更新一个简单的例子: 您可以将此添加到 functions.php 或自定义插件中,以编程方式将您的字段添加到多个环境中......然后您使用所有环境中的通用 field_key 调用 get_field_object()
add_action('acf/init', 'wp123_add_local_acf_fields');
function wp123_add_local_acf_fields()
acf_add_local_field_group(array(
'key' => 'group_1',
'title' => 'My Group',
'fields' => array (
array (
'key' => 'field_51ac9d333d704',
'label' => 'Color de pelo',
'name' => 'hair_color',
'type' => 'select',
'instructions' => 'Selecciona el color de pelo'
'required' => 0,
'choices' => array (
'bald' => 'Calvo',
'brown' => 'Castaño',
'brunette' => 'Moreno',
'red' => 'Pelirrojo',
'blonde' => 'Rubio',
),
'default_value' => array (
),
'allow_null' => 1,
'multiple' => 0,
)
),
'location' => array (
array (
array (
'param' => 'post_type',
'operator' => '==',
'value' => 'post',
),
),
),
));
【讨论】:
主要由链接组成的答案可能会被删除;我会使用这些链接中的特定代码示例来改进您的答案。 当然 - 我添加了一个如何使用 php 注册字段的示例【参考方案5】:ACF 的工作方式你真的应该使用密钥。
来自 (http://www.advancedcustomfields.com/resources/get_field_object/)
“您可以而且应该在 100% 的时间内使用 $field_key。
使用 $field_name 的问题是,如果引用不存在,ACF 将无法找到字段对象,也无法保存该值。如果您使用代码插入帖子,就会出现这种情况。
此外,使用 field_key 作为 update_field 函数中的第一个参数更有效,因为它绕过了参考查找。”
【讨论】:
肯定有办法从field_name中找出field_key。我不使用 field_keys,因为它们在我的不同数据库中是不同的。 没有可靠的方法,因为插件从键中获取名称,而不是相反;我发布了一个适用于一些(大量)警告的解决方案。 @Phil_1984_ 我们使用 WP Sync DB 来同步我们单独的环境以保持密钥相同,仅供参考。【参考方案6】:正确的方法是使用acf_maybe_get_field
函数,就像这样:
acf_maybe_get_field( 'field_name', false, false );
参数是:field name
、post id
(默认为当前帖子)和最重要的strict
,默认为true
,但我们在这里将其设置为false
获取字段对象,即使它尚不存在于帖子中。
指Get ACF field key programmatically by field name
【讨论】:
是的,这行得通。请记住,尽管您的目标字段名称可以与各种自定义字段相同(例如电影和书籍自定义帖子类型的“评分”字段 - 可以将十分之一的选择字段分配给“评分”字段名称,而另一个可以有“好/坏”复选框),所以这有点风险。我所做的是硬编码字段键,然后如果没有结果,我使用acf_maybe_get_field
。
请参阅我对相同主题的评论。【参考方案7】:
没有办法可靠地使用名称检索密钥,因为名称是元数据,因此可以更改,而密钥(至少无需手动编辑数据库)不是。
但是,此功能适用于最新版本的 ACF,但有几点需要注意。 ACF 在帖子中创建字段组作为 ACF 的自定义帖子类型,但有关字段本身的所有数据都保存在 post_meta 表中。
function get_acf_key($field_name)
global $wpdb;
return $wpdb->get_var("
SELECT `meta_key`
FROM $wpdb->postmeta
WHERE `meta_key` LIKE 'field_%' AND `meta_value` LIKE '%$field_name%';
");
警告:因为字段名称存储为数组的一部分,当通过 SQL 查找它时,您必须依赖通配符搜索,它对错误。只要您的所有字段的名称完全不同,就可以了,但如果您有一个字段名为“farm”,另一个字段名为“farmer”,则会出错,因为它会同时找到这两个字段。
更新字段的唯一可靠方法是手动对密钥进行编码,尽管这无疑很笨拙,这也是我开始的原因。
【讨论】:
谢谢你 - 有关于如何做到这一点的任何更新吗? 据我所知,没有。 ACF 的官方说法(也是最安全的方法)是使用密钥而不是名称。 请注意,如果您在 PHP 中使用导出函数(而不是使用 DB 字段定义)对 ACF 字段进行硬编码,那么此方法将不起作用。但是,如果该字段是硬编码的,那么密钥可能不会改变,并且在多个环境中保持不变。【参考方案8】:遇到同样的问题,最后也使用了 key 导致我进入另一个死胡同,没有正常的方法来获取 key 值,但幸运的是遇到了这个。
取自 - https://wordpress.stackexchange.com/questions/248006/acf-add-fields-values-to-newly-inserted-post
function acf_getValue($fieldname, $post_id)
if(($value = get_field($fieldname, $post_id)))
return $value;
$value = get_post_meta($post_id, $fieldname);
return $value[0];
function acf_updateValue($fieldname, $value, $post_id)
$field_key = 'field_' . uniqid();
update_post_meta($post_id, $fieldname, $value);
update_post_meta($post_id, '_'.$fieldname, $field_key);
update_field($field_key, $value, $post_id);
acf_updateValue 模拟手动保存时 ACF 自身如何完成。因为对于 ACF 列,只有 update_field 是不够的
【讨论】:
您好,获取或更新。 500 可能意味着错字,您在哪一行有确切的日志消息吗?以上是关于如何从 WordPress 数据库中获取高级自定义字段字段键?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ACF 和 Wordpress 从页面获取字段组 ID?
Wordpress - 我如何从其他自定义帖子中获取_categories?
如何检查 Wordpress 高级自定义字段插件中的字段组?