如何从 WordPress 数据库中获取高级自定义字段字段键?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21184015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:27:19  来源:igfitidea点击:

How to get Advanced Custom Fields field key from WordPress database?

wordpresscustom-fieldsadvanced-custom-fields

提问by user1432966

I'm using Advanced Custom Fields with post-type. I have some select custom fields, and I want to show all the label choices from each field.

我正在使用带有后期类型的高级自定义字段。我有一些选择的自定义字段,我想显示每个字段的所有标签选择。

I've tried this way.

我试过这种方法。

$field = get_field_object('hair_color');
$hair = $field["choices"];
    foreach($hair as $value){

Doing a

做一个

var_dump($field)

var_dump($field)

it appears empty:

它看起来是空的:

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) 
}

The only way to get it full is that:

让它充满的唯一方法是:

get_field_object('field_51ac9d333d704');

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) 
}

But I have 3 environment, and I don't want to hardcode the field key.

但是我有 3 个环境,我不想对字段键进行硬编码。

Is there any solution? Thanks in advance.

有什么解决办法吗?提前致谢。

回答by Hivenfour

Here is a modified version of answer provided by @BFDatabaseAdmin matching the exact meta_value in "LIKE"

这是@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);
}

回答by aaron.cimolini

Just trying to do this myself so I did some investigation. Seems each field and field group for ACF are stored in the wp_posts table in the database as custom post types. fields are 'acf-field' and groups are 'acf-field-group'.

只是想自己做,所以我做了一些调查。似乎 ACF 的每个字段和字段组都作为自定义帖子类型存储在数据库的 wp_posts 表中。字段是“acf-field”,组是“acf-field-group”。

I was able to use this function to get the field key to then use update_field($field_key, $value) on posts that didn't have the field already.

我能够使用这个函数来获取字段键,然后在没有该字段的帖子上使用 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';
    ");
}

Then I was able to use:

然后我就可以使用:

update_field(get_acf_key('my_field_name'), 'some value', $post_id);

To either update the field for posts that had it already or add the field and it's key reference to posts that did not already have the field.

要么更新已经拥有它的帖子的字段,要么添加该字段,它是对尚未拥有该字段的帖子的关键引用。

回答by Chris

I'm throwing another option into the mix. I think the existing answers are good, but unless you look at the parent group, you will never get a reliable field key because the field name can exist across multiple groups.

我正在考虑另一种选择。我认为现有的答案很好,但是除非您查看父组,否则您永远不会获得可靠的字段键,因为字段名称可以存在于多个组中。

For example, lets say you have two custom groups - one for post type books, and one for custom post type movies. Both groups have added a field called title.

例如,假设您有两个自定义组 - 一个用于帖子类型的书籍,另一个用于自定义帖子类型的电影。两个组都添加了一个名为 title 的字段。

In the database, both are stored with post_except = 'title'and post_type = 'acf-field'. Two entries with the same post_except, so any query relying onlyon post_exceptwill be wrong, wildcard or not.

在数据库中,两者都以post_except = 'title'和存储post_type = 'acf-field'。两个条目相同post_except,因此任何依赖于的查询post_except都将是错误的,无论是否通配符。

Any query relying on post id is not great either, as a post might not always exist to pass in.

任何依赖于帖子 ID 的查询也不是很好,因为帖子可能并不总是存在以传递。

So you need to pass in a combination of field and group to get the field key from the name. This snippet works well for me:

所以需要传入 field 和 group 的组合,才能从 name 中获取 field key。这个片段很适合我:

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));
    }
}

Will return the field key from name and group, or null if none exists.

将从名称和组返回字段键,如果不存在则返回 null。

Usage:

用法:

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

回答by locomo

ACF provides some easy ways to help keep multiple environments in sync - you can register your fields with PHP or a local JSON file. Doing this would allow you to keep using get_field_object() with a single field key across multiple environments. See:

ACF 提供了一些简单的方法来帮助保持多个环境同步 - 您可以使用 PHP 或本地 JSON 文件注册您的字段。这样做将允许您在多个环境中继续使用带有单个字段键的 get_field_object() 。看:

http://www.advancedcustomfields.com/resources/register-fields-via-php/

http://www.advancedcustomfields.com/resources/register-fields-via-php/

http://www.advancedcustomfields.com/resources/local-json/

http://www.advancedcustomfields.com/resources/local-json/

I usually do my ACF development with the user interface and then export all of my fields groups as PHP to deploy across multiple environments.

我通常使用用户界面进行 ACF 开发,然后将所有字段组导出为 PHP,以便在多个环境中进行部署。

UPDATE with a simple example:You could add this to functions.php or a custom plugin to add your field to multiple environments programmatically .. then you call get_field_object() with a common field_key across all environments

用一个简单的例子更新:您可以将其添加到 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',
                ),
            ),
        ),
    ));

}

回答by Nigel Fish

The way ACF works you really should use the key.

ACF 的工作方式您确实应该使用密钥。

from (http://www.advancedcustomfields.com/resources/get_field_object/)

来自(http://www.advancedcustomfields.com/resources/get_field_object/

"You can and should use the $field_key 100% of the time.

“您可以而且应该 100% 地使用 $field_key。

The problem with using $field_name is that if the reference does not already exist, ACF will not be able to find the field object and will not be able to save the value. This situation would occur if you had used code to insert a post.

使用 $field_name 的问题在于,如果引用不存在,ACF 将无法找到字段对象,也无法保存该值。如果您使用代码插入帖子,就会发生这种情况。

Also, it is more efficient to use the field_key as the first parameter in the update_field function as it bypasses the reference look up."

此外,将 field_key 用作 update_field 函数中的第一个参数会更有效,因为它绕过了参考查找。”

回答by Sinister Beard

There's no way to reliablyretrieve the key using the name, because the name is metadata, and hence open to change, whereas the key (at least without editing the database manually) isn't.

没有办法使用名称可靠地检索密钥,因为名称是元数据,因此可以更改,而密钥(至少无需手动编辑数据库)不是。

However, this function will work with the most recent version of ACF, with a couple of caveats. ACF creates field groups within posts as a custom post type of ACF, but all the data about the fields themselves is held within the post_meta table.

但是,此功能将适用于最新版本的 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%';
    ");

}

A warning:because the field name is stored as part of an array, when finding it via SQL you have to rely on a wildcard search, which is open to errors. As long as all your fields have entirely different names, you're fine, but if for example you have one field called "farm" and another called "farmer", this will error because it will find both fields.

警告:因为字段名称存储为数组的一部分,当通过 SQL 查找它时,您必须依赖通配符搜索,这很容易出错。只要您的所有字段的名称完全不同,就可以了,但是例如,如果您有一个名为“farm”的字段和另一个名为“farmer”的字段,则会出错,因为它会找到这两个字段。

The only reliable way to update fields is to manually code the key, though this is admittedly clunky, which is what led me here to begin with.

更新字段的唯一可靠方法是手动编码密钥,尽管这确实很笨拙,这也是我在这里开始的原因。

回答by Mindaugas Jakubauskas

The right way is to use acf_maybe_get_fieldfunction, just like that:

正确的方法是使用acf_maybe_get_field函数,就像这样:

acf_maybe_get_field( 'field_name', false, false );

acf_maybe_get_field( 'field_name', false, false );

The arguments are: field name, post id(defaults to current post) and the most important strictwhich defaults to true, but we set it to falsehere to get field object even when it does not yet exist for the post.

参数是:field name, post id(默认为当前帖子)和最重要的strict默认为true,但我们将其设置为此false处以获取字段对象,即使该帖子尚不存在。

Refers to Get ACF field key programmatically by field name

通过字段名称以编程方式获取 ACF 字段键

回答by Jiro Matchonson

Had same problem, also ended up using key which lead me just to another dead end with no normal way to get key value, but luckily encountered this.

有同样的问题,也最终使用了 key 这导致我进入另一个死胡同,没有正常的方法来获取 key 值,但幸运的是遇到了这个。

Taken from - https://wordpress.stackexchange.com/questions/248006/acf-add-fields-values-to-newly-inserted-post

取自 - 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);
}

Where acf_updateValue simulates how its done by ACF itself when you manually save. Since only update_field is not enough for ACF columns

其中 acf_updateValue 模拟手动保存时 ACF 本身如何完成。因为对于 ACF 列,只有 update_field 是不够的