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

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

新規登録して質問してみよう
ただいま回答率
85.48%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

1556閲覧

WordPressの「update_post_meta」が、複数チェックボックスに対して機能しないケース

waru

総合スコア16

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/02/26 06:13

編集2019/02/27 02:13

###実現したいこと・問題点

WordPressでカスタムフィールドにチェックをしたいです。

下記のようにupdate_post_metaに配列を使っても1つもチェックされないという問題が発生しました。

PHPエラーはありません。

###該当のソースコード
こちらが問題のコードです。

php

1$check_get = esc_html( $_POST['check_get'] ); // check1,check2 が入ります 2$check_arr = explode(",", $check_get); // それを配列にします 3update_post_meta($id, 'checkbox', $check_arr); // チェックできません

$check_get には間違いなく check1,check2 が入っていますが、下記のようにチェックがされません。

イメージ説明

尚、$check_arr$のように配列で渡すという方法はこちらを参考にしたのですが、間違っていますでしょうか?(https://stackoverflow.com/questions/22660822/how-to-save-multiple-checkbox-on-update-post-meta-in-wordpress

###foreachだと1つだけチェックできる
ちなみに下記のようにforeachを使うと、check2 だけにチェックが入ります

php

1$check_get = esc_html( $_POST['check_get'] ); // check1,check2 が入ります 2$check_arr = explode(",", $check_get); // それを配列にします 3foreach ($check_arr as $check) { 4 update_post_meta($id, 'checkbox', $check); // check2 だけにチェックが入ります 5}

下図のようになります。
イメージ説明

###ラジオボタンはできる
あとラジオボタンだとできます。

php

1$radio_get = esc_html( $_POST['radio_get'] ); 2$radio_add = $radio_get == '' ? 'radio1' : $radio_get; 3update_post_meta($id, 'radiobox', $radio_add); // チェックできます

1つもチェックしなければ下記のようにradio1にチェックがきちんと入りますし、もしradio2にチェックすれば同様に機能します。
イメージ説明

###まとめ
どうすればチェックできるようになるか、原因や対策などを知りたいと思い質問させて頂きました。
どうぞ宜しくお願い致します。

###追記(m6u様へ)
m6u様からの追記依頼の件です。
チェックボックスを表示している箇所(上記の画像1枚目の箇所)の、webブラウザ上でのhtmlソースになります。

html

1<div id="checkbox" class="postbox "> 2 <button type="button" class="handlediv" aria-expanded="true"> 3 <span class="screen-reader-text">パネルを閉じる: checkbox</span> 4 <span class="toggle-indicator" aria-hidden="true"></span> 5 </button> 6 <h2 class="hndle ui-sortable-handle"><span>checkbox</span></h2> 7 <div class="inside"> 8 <input type="hidden" id="nonce-checkbox" name="nonce-checkbox" value="1859407a37"> 9 <input type="hidden" name="_wp_http_referer" value="/wp-admin/post.php?post=47&amp;action=edit"> 10 <label><input style="" type="checkbox" name="checkbox" value="check1">check1</label> 11 <label><input style="" type="checkbox" name="checkbox" value="check2">check2</label> 12 </div> 13</div>

###追記(CHERRY様へ)
CHERRY様からの追記依頼の件です。
カスタムフィールドを定義している部分のコードになります。

php

1add_action( 'admin_menu', 'add_meta_field' ); 2function add_meta_field() { 3 add_meta_box( 'checkbox', 'checkbox', 'create_checkbox', 'custom', 'side' ); 4} 5 6function create_checkbox() { 7 $keyname = 'checkbox'; 8 global $post; 9 $get_value = get_post_meta( $post->ID, $keyname, true ); 10 $data = ['check1', 'check2']; 11 wp_nonce_field( 'action-' . $keyname, 'nonce-' . $keyname ); 12 foreach( $data as $d ) { 13 $checked = ''; 14 if( $d === $get_value ) $checked = ' checked'; 15 echo '<label><input style="" type="checkbox" name="' . $keyname . '" value="' . $d . '"' . $checked . '>' . $d . '</label>'; 16 } 17} 18 19add_action( 'save_post', 'save_meta_field' ); 20function save_meta_field( $post_id ) { 21 $custom_fields = [ 22 'checkxox', 23 ]; 24 foreach( $custom_fields as $d ) { 25 if ( isset( $_POST['nonce-' . $d] ) && $_POST['nonce-' . $d] ) { 26 if( check_admin_referer( 'action-' . $d, 'nonce-' . $d ) ) { 27 if( isset( $_POST[$d] ) && $_POST[$d] ) { 28 update_post_meta( $post_id, $d, $_POST[$d] ); 29 }else{ 30 update_post_meta( $post_id, $d, '' ); 31 } 32 } 33 } 34 } 35}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/26 06:40

チェックボックスを表示している箇所の、webブラウザ上でのhtmlソースがどうなっているか見せてください。
CHERRY

2019/02/26 06:59

カスタムフィールドは、どのように作成されましたか?  なにかプラグインをお使いですか? functions.php にコードを記載したのであれば、カスタムフィールドを定義している部分のコードを質問に追記していただけないでしょうか?
guest

回答1

0

ベストアンサー

まず、最初に

下記のようにupdate_post_metaに配列を使っても1つもチェックされないという問題が発生しました。 

update_post_meta($id, 'checkbox', $check_arr); // チェックできません

と書かれているのが気になるのですが、update_post_meta は、データベースに保存されているカスタムフィールドのデータを更新するだけで、チェックボックスにチェックを入れる機能はありません。

update_post_meta 参照。


追記いただいたコードを拝見すると、 create_checkbox の中で、チェックを入れていますね。

create_checkbox の中で、

if( $d === $get_value ) $checked = ' checked';

と比較しているので、 カスタムフィールドの値が1つの時はうまくいきますが、複数の場合は一致しないと思います。

1個でも複数でも動くようにするとすれば、

if( $d === $get_value ) $checked = ' checked';

の部分を

if ( in_array($d, $get_value) ) $checked = " checked"; (カスタムフィールドがない場合に、エラーが発生するので回答を修正。)

if ( ! empty( $get_value ) && in_array($d, $get_value) ) $checked = " checked";

のような感じで、配列に値を含んでいるか調べる感じでしょうか。

投稿2019/02/27 01:39

編集2019/02/27 02:58
CHERRY

総合スコア25171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

waru

2019/02/27 02:11 編集

>チェックボックスにチェックを入れる機能はありません ありがとうございます。価は入っているのに、ダッシュボードにはその値のチェックは入らないということでしょうか。知りませんでした…。 ということは、たとえばその値でWP_queryなどから検索する場合はきちんと値が入ったものとして検索されるのですか?
waru

2019/02/27 02:23 編集

>のような感じで、配列に値を含んでいるか調べる感じでしょうか。 そのようにしたところ「in_array() expects parameter 2 to be array」のエラーが出ましたので、 $get_value = get_post_meta( $post->ID, $keyname, true ); を $get_value = get_post_meta( $post->ID, $keyname ); としました。 しかし依然問題は解決されず、チェックは入らないようです。 ただし「get_post_meta」してみると、「a:2:{i:0;s:6:"check1";i:1;s:6:"check2";}」のようになっており、値は入っているようでした。 たびたびお手数おかけして申し訳ございませんが、引き続き宜しくお願い致します。
CHERRY

2019/02/27 02:55 編集

あぁ.... 失礼しました。 カスタムフィールドがない場合、つまり、未チェックの場合に $get_value が、 '' になるので、コメントに記載されている「in_array() expects parameter 2 to be array」のエラーが出ますね。 回答に記載した > if ( in_array($d, $get_value) ) $checked = " checked"; を if ( ! empty( $get_value ) && in_array($d, $get_value) ) $checked = " checked"; のように書き換えて、$get_value が、空でない場合という条件を加える必要がありますね。 別の方法としては、 > $get_value = get_post_meta( $post->ID, $keyname, true ); > $data = ['check1', 'check2']; の間に $get_value = $get_value ? $get_value : array(); を入れて、$get_value が、'' の場合、空の array() を代入する方法でもエラーは出なくなると思います。
waru

2019/02/27 03:02

できました!本っ当にありがとうございます。かれこれ5時間くらいハマってました。笑 すみません、ご回答と少しずれるのですが、私の間違いについてよくわからない部分があります。 私がtrueを取った理由は「第三引数にtrueを設定すると文字列として取得されてしまうから、trueを取って配列として取得すればいいのかも?」というものでした。 しかし実際にtrueの有無では次の違いでした。 $get_value = get_post_meta( $post->ID, 'checkbox' ); // array ( 0 => array ( 0 => 'check1', 1 => 'check2', ), ) $get_value = get_post_meta( $post->ID, 'checkbox', true ); // array ( 0 => 'check1', 1 => 'check2', ) え??一体なぜ、trueがないとarrayが1つ増えるんですか?? 第三引数にtrueがないと文字列として取得されるという話は私の勘違いでしょうか?
CHERRY

2019/02/27 03:42

カスタムフィールドに保存された値が、「シリアライズ」されている場合(コメントに書かれている `a:2:{i:0;s:6:"check1";i:1;s:6:"check2";}` のような形で保存されている場合)は、true をセットすると maybe_unserialize 関数 ( https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/maybe_unserialize ) でアンシリアライズ処理された結果が、配列で取得できます。 false の場合は、カスタムフィールドに入っているシリアライズされてたままの文字列が、そのまま配列で取得されます。 コメントに書かれている例だと シリアライズされた値の場合は、 true では、 array( 0 => 'check1', 1 => 'check2' ) ですが、false の場合、 array( 0 => ’a:2:{i:0;s:6:"check1";i:1;s:6:"check2";}’ ) が、帰ってくると思うのですが... コメントに書かれている内容だと 「’a:2:{i:0;s:6:"check1";i:1;s:6:"check2";}’」の部分もアンシリアライズされているようなので、あとで、動作確認してみます。
CHERRY

2019/02/27 03:46 編集

ドキュメント https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/get_post_meta にも > <?php $meta_values = get_post_meta($post_id, $key, $single); ?> > $single >(真偽値) (オプション) true をセットした場合、文字列として単一の結果を返します。false または値をセットしなかった場合、関数はカスタムフィールドの配列を返します。 > これは、配列がシリアル化された文字列として格納されている場合、あまり直感的ではありません。例えば、この関数でシリアル化された配列を取得した場合、$single を true にセットすると非シリアル化された配列が返されます。false または 値をセットしなかった場合、一つの要素からなる配列が返ってきて、インデックス 0 の値はシリアル化された文字列となります。 > 初期値: false と シリアル化(シリアライズ)された文字列での動作の違いについて、書かれていますね。(わかりにくいですが...)
waru

2019/02/28 06:10

コメントに書かれている例だと シリアライズされた値の場合は、 true では、 array( 0 => 'check1', 1 => 'check2' ) ですが、false の場合、 array( 0 => ’a:2:{i:0;s:6:"check1";i:1;s:6:"check2";}’ ) が、帰ってくると思うのですが... -- ↑についてご報告です。 どうやら、「チェックボックスの値をそのままテキストボックスにコピーした場合」はそれが帰ってくるみたいです。 「チェックボックスの場合」に還ってくるのは私が書いたような違い(2019/02/27 12:02)でした。 ほんとヤヤコシイですね。笑
waru

2019/02/28 06:10

まとめるとこのような感じです。 $get_all_val = get_post_meta( $post->ID ) ; var_export($get_all_val) ; では下記➀➁の出力になり、チェックボックスとテキストボックスで結果が違う。 ---------------- ➀チェックボックスにチェックがされている場合の出力 ---------------- array ( 'meta_checkbox' => array ( 0 => 'a:2:{i:0;s:6:"check1";i:1;s:6:"check2";}', ), ) ---------------- ➁の値 a:2:{i:0;s:6:"check1";i:1;s:6:"check2";} をテキストボックスに書いた場合の出力 ---------------- array ( 'meta_input' => array ( 0 => 's:40:"a:2:{i:0;s:6:"check1";i:1;s:6:"check2";}";', ), )
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問