質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

WordPressでカスタムフィールドの入力値を配列格納したいです。

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,469

kinrinkaryu

score 35

資料皆無でWordPressの管理を引き継ぎました。
以前のデーターはPhpMyAdminで参照するとシリアライズされて格納されています。
a:10:{i:0;a:1:{s:6:"住所";s:9:"福岡市";}i:1;a:1:{s:6:"交通";s:9:"地下鉄";}}
新規投稿でこのカスタムフィールドに入力する値はどのようにすれば、配列として格納されますか?

限りある知識の中でCSVデーターのように入力したところ、
住所,福岡市交通,地下鉄
のようにタダの文字列になっており、配列出力でエラーになりました。
Invalid argument supplied for foreach() in 

どのようなフォーマットで入力すれば、正常に配列出力されますか?

補足:関連すると思われるソースコード

ワードプレス本来の/themes/name/single.phpにあたるファイル

<!--前提:(引き継ぐ以前に)カスタムフィールドに入力された値は配列としてで格納されている、入力ルールや処理方法は不明。-->
        <?php if (have_posts()) : ?> <?php while(have_posts()) : the_post(); ?>
        <?php
            $title = get_the_title();
            $title = $title === '' ? 'タイトルなし' : $title;

            $data = get_post_meta(get_the_ID(), 'data', true);//単一フィールド配列

            $sold_out = get_post_meta(get_the_ID(), 'sold_out', true);
            $content = get_the_content();
        ?>
        <h1><?php echo $title; ?><?php if ($sold_out === '1') echo '(ご成約)'; ?></h1>
        <div<?php if ($sold_out === '1') echo ' class="sold-out"'; ?>>
<!--出力ここから-->            
            <table class="">
                <?php foreach($data as $datum): ?><tr><?php foreach($datum as $key => $value): ?><th><?php echo $key; ?></th><td><?php echo $value; ?></td><?php endforeach; ?></tr><?php endforeach; ?>
            </table>
<!--出力ここまで-->            
    <!--中略-->            
    <?php endwhile; endif; ?>


追記:wp_postmetaデーブルの一部
_wpcf-etcs-sort-order  a:1:{i:0;i:6233;} etcs  a:0:{} data  a:10:{i:0;a:1:{s:6:"住所";s:9:"福岡市";}i:1;a:1:{s:6:"交通";s:9:地下鉄"";...}
再追記:functions.phpの一部(コメントアウト状態なので無視していたが、念のために。)

// add_action('rest_api_init', function () {
//     register_rest_field(
//         'page',
//         'post_meta',
//         array(
//             'get_callback' => function($object, $field_name, $request) {
//                 $meta_fields = array(
//                     'wpcf-js',
//                     'wpcf-css',
//                 );
//                 $meta = array();
//                 foreach ($meta_fields as $field) {
//                     $meta[$field] = get_post_meta($object[ 'id' ], $field, true);
//                 }
//                 return $meta;
//             },
//             'update_callback' => function($value, $object, $field_name) {
//                 $js = $value['wpcf-js'];
//                 $css = $value['wpcf-css'];
//                 update_post_meta($object->ID, 'wpcf-js', $js);
//                 update_post_meta($object->ID, 'wpcf-css', $css);
//             }
// ,
//             'schema' => null,
//         )
//     );
// });

補足2:「WP自体」の記事&フィールドの投稿・更新動作

rest-api-init.phpからの抜き出し、

public function add_rest_field($posts, $fields) {
    global $posts_fields;
    foreach ($posts as $post) {
        foreach ($fields as $field) $posts_fields[$post][] = $field;
        register_rest_field(
            $post,
            'post_meta',
            [
                'get_callback' => function($object, $field_name, $request) use ($post) {
                    global $posts_fields;
                    $meta = [];
                    foreach($posts_fields[$post] as $field) {
                        $meta[$field] = get_post_meta($object['id'], $field, true);
                    }
                    return $meta;
                },
                'update_callback' => function($value, $object, $field_name) use ($post) {
                    global $posts_fields;
                    foreach($posts_fields[$post] as $field) {
                        if (!$this->validate($field, $value[$field])) break;
                        update_post_meta($object->ID, $field, $this->set($field, $value[$field]));
                    }
                },
                'schema' => null
            ]
        );
    }
}


ほとんど理解できていないが、おそらく肝心なところ↓
$meta[$field] = get_post_meta($object['id'], $field, true);
update_post_meta($object->ID, $field, $this->set($field, $value[$field]));

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

0

function customValue2Array2020( $A ){
    $supecialArray2020 = array("\r\n", "\r", "\n");
//    $supecialArray2020 = array("\\r\\n", "\\r", "\\n");// For Plugin : Post Snippets !!
    $A = str_replace( $supecialArray2020 , "|" , $A);
    $B = explode("|", $A);// Supecial Thank ! https://qiita.com/suin/items/835ac0f58e6d3bbb6280
    $B = array_map('trim', $B);
    $B = array_filter($B, 'strlen');
    $B = array_values($B);
    return $B ;
}


以上はWordPressのテーマ内、header.phpで利用した関数です。
例として、カスタムフィールド名:「  abcd_2020  」だとすると、

if( get_post_custom_values( 'abcd_2020' ) !== null ){};


でカスタムフィールド名が記事に存在するかを判定し、
データーが1つのカスタムフィールドに複数行に渡って登録されていたとしても、

$arr_abcd_2020 = customValue2Array2020( get_post_custom_values( 'abcd_2020' )[ 0 ] );


を実行すると配列として、$arr_abcd_2020 に、代入されます。

※ 初期値ではカスタムフィールドが表示されませんが、編集はWordPressの個別記事編集画面で、当該TEXTAREAで編集するのが簡単かと思います。それとも、phpMyAdminでエキスポートしたSQL構文を編集して、phpMyAdminで一気に置換したのですか?

上記のPHP関数の利用を実践し紹介した当方の愚ブログ記事「第二世代WordPressアイキャッチ静止画と動画

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/09 20:18

    古い質問にご回答いただき恐縮です、現在この件は無期限停止中なので、確認は後日になりますが、一番近いやり方だと思いましたので、ベストアンサーとしました。

    キャンセル

  • 2020/03/10 08:14

    「wordpress,array,function,php,customfields,カスタムフィールド,関数,配列」でGoogle検索すると今なら2ページ目に本ページが掲載されていますね。kinrinkaryu さんのタイトルこそが的を射ていると存じます。
    一記事に対してカスタムフィールド自体を多重に登録すれば、それ自体が配列ですけど、そんな使い方は行わないと思うんです。さすればカスタムフィールド内で例えば「行送り」を利用して複数の情報を入力する。それを配列変数として扱いたいニーズは高いと思います。「行送り」以外でも良いわけで、今回の関数の呼び出し変数の第二変数で区切り文字の指定を行えれば汎用性が高く、そして運用のヒントになるのかも知れません。

    キャンセル

0

WordPress 日本語Codexを見ると
関数リファレンス/add post meta

$$meta_value
(mixed) (必須) カスタムフィールドの値。配列を与えるとシリアライズされて文字列が格納されます。

関数リファレンス/update post meta

$meta_value
(mixed) (必須) カスタムフィールドの新しい値。配列を与えるとシリアル化されます。これは生の値でなければなりません(データベースクエリ時は無害化されます)。

と書いてある

何がしたいのか分からんが仕様なので諦めなはれ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/03 16:14

    ありがとうございます。
    現在の問題点は「新規入力した分がシリアライズされない」ことで、何か「特別な入力書式があるのでは?」と。
    それで「配列を与えるとシリアル化」の配列はどのような書き方がわからないです。

    キャンセル

0

現在の問題点は「新規入力した分がシリアライズされない」ことで、何か「特別な入力書式があるのでは?」と。

普通に配列を作って、

$array = array(
  '住所' => '福岡市',
  '交通' => '地下鉄'
);

add_post_meta で、$array をカスタムフィールドに保存するとどうなりますか?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/03 22:56

    なるほど、ありがとうございます。
    指定して格納したら配列になると言うことは分かりました。
    しかしWPの管理(記事編集)画面でカスタムフィールドに入力した値を
    どうやって区切って取得するのでしょうか?

    私の知識レベルでは「カンマやスペース」を区切りのルールとして、入力された文字列を取得分別し、配列に変換して格納するとしか思いつかないのですが、WPの処理にはその部分が見られないので、その区切りルールが不明です。
    この場合は「値取得、分別、配列変換」のコードを追記するのがいいでしょうか?

    キャンセル

0

情報が足りなさすぎるのでなんとも言えませんが、まずカスタムフィールドが何で作られているのかを調査した方がいいと思います。
functions.php等で定義されているのか、それともAdvancedCustomFieldsのようなプラグインで作られたフィールドなのか。
functions.phpで定義されているのであれば、そのコードを見ない限り正しい答えはわからないかと思います。

ちなみに、フィールドの右側に+ボタン等はないですか?
ACFなどで作成されたフィールドは、行や列を増やすことによって配列化し、それがDB上にシリアライズ化してデータが入ります。
DBを見れるのであれば、post_typeカラムを見ればプラグインかどうかの判別は付くかと。
ACFで作られたフィールドはacf-fieldのようになっているかと思います。
一度、ご確認なさってみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/07 11:53

    ありがとうございます、補足を追加しました。前任はプラグインを使っていません、私がACFを試してみましたが、目的と直結しなかったので、巻き戻し復元済みです。
    現在の問題点は前任が「どのようなルールで入力し、配列として格納したか」が全く不明です、そして新たに入力する値はそのままの文字として格納され、出力するときは当然格式に合わないので、エラーになります。
    アドバイスを頂けたら幸いです、よろしくお願い致します。

    キャンセル

  • 2019/06/07 21:15

    以前のデータは~と書かれていることから、既にCFが配列として格納されているpostがあるということですよね?
    DBを見て、該当のpost_idの記事でCFがどのように入力されているか見ればわかるのではないでしょうか?

    キャンセル

  • 2019/06/07 21:50

    ご返信ありがとうございます、以前のデーターはDBには存在するのですが、編集画面のCFは空白です、調べたらセキュリティの関連で通常は表示されないがのだそうです。それで新規にCFを入力すると新IDのものが追加されるだけでした。

    ちなみに、このテーブル形式で出力されるCFデータは、アーカイブ一覧にも使用されるので、手書きする選択肢はないのがネックです。rest-api-init.phpからヒントは得られる気がするのですが、都合よくCFを配列格納する記述がないのが残念なところです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る