何が都合いいかわからんけど、とりあえず手段を持つのだ。
何がしたいかとかの話
SCFでオプションページを作って、その中に繰り返しフィールドを作ってデータベースの代用とした。
データベースなのでソートを掛けて任意の値を取得したい。
1回の処理で複数回取得する可能性があり、毎度カスタムフィールドを取りに行くと処理が重くなるんじゃないのっていう危惧がある。
受け取ったカスタムフィールドの情報を配列にしてしまえば、そして配列からデータを引っ張れば、負荷の削減ができるんじゃないかって思った。
なのでそれをやってみる。
準備
SCFを使って、オプションページにカスタムフィールドを作ったとする。
オプションページ:sample-options
繰り返しフィールド:sample-cf
繰り返しフィールド内のフィールド:cf01、cf02
これでやっていくとする。
こんな感じ
普通にオプションページの繰り返しを取ってきて出力するならこう。
$sample = SCF::get_option_meta('sample-options','sample-cf');
foreach($sample as $field){
echo $field['cf01'];
echo $field['cf02'];
}
多次元連想配列にする。
//配列を用意
$sampleAry = array();
//配列に格納
$sample = SCF::get_option_meta('sample-options','sample-cf');
foreach($sample as $field){
array_push($sampleAry, array('cf01'=>$field['cf01'], 'cf02'=>$field['cf02']));
}
//出力
echo('<pre>');
var_dump($sampleAry);
echo('</pre>');
ニーズがめっちゃ限られそうだけど。
ソートしましょう
上記で作った配列はこんな感じになる。
$sampleAry[
['cf01' => '****', 'cf02' => '****'],
['cf01' => '****', 'cf02' => '****'],
['cf01' => '****', 'cf02' => '****'],
['cf01' => '****', 'cf02' => '****'],
⋮
]
ここから任意のデータを引っ張ろうという話。
どういう条件で引っ張るかで方法が変わる。
ユニークな値を指定して引っ張りたい場合
$sampleAry[
['cf01' => '001', 'cf02' => '****'],
['cf01' => '002', 'cf02' => '****'],
['cf01' => '003', 'cf02' => '****'],
['cf01' => '004', 'cf02' => '****'],
['cf01' => '005', 'cf02' => '****'],
['cf01' => '006', 'cf02' => '****'],
⋮
]
こんな感じで一つをIDなり連番なりで扱っていて、それを指定して引っ張る。
例えばこんな感じ。
$keyIndex = array_search('001',array_column($sampleAry, 'cf01'));
$result = $sampleAry[$keyIndex];
var_dump($result);
で、こんな感じになる。
$result[
'cf01' => '001', 'cf02' => '****'
];
再三になるけどここで注意しないといけないのは、これは「該当の値のやつを引っ張る」内容であって「該当する値を持つもの全部を引っ張る」わけじゃない。
例えばユーザーデータを溜めてたとして。
「性別が男性のデータを全部取得する」はできない。
「特定個人のユーザーデータを取得する」はできる。
つまり、「該当するキーを持つデータを全部拾ってくれるものじゃない」ということ。
重複がある場合、先頭の1件だけ拾って終わり。
連番とかIDとかの、ユニークなところを引っ張ってください。
だからそもそもユニークな値を持つ形で配列を登録してください。
指定した値を持つデータを引っ張りたい場合
例えばユーザーデータを溜めてたとして「性別が男性のデータを全部取得する」をやりたい場合とかのやつ。
前項でできなかったやつ。
こんな。
$sampleAry[
['cf01' => 'aaaa', 'cf02' => '****'],
['cf01' => 'aaaa', 'cf02' => '****'],
['cf01' => 'aaaa', 'cf02' => '****'],
['cf01' => 'bbbb', 'cf02' => '****'],
['cf01' => 'bbbb', 'cf02' => '****'],
['cf01' => 'cccc', 'cf02' => '****'],
['cf01' => 'cccc', 'cf02' => '****'],
]
cf01がaaaaのやつをすべて取得、配列にまとめる。
$col = array_column($sampleAry,'cf01');
$keys = array_keys($col,'aaaa');
$sampleAry02 = array();
for($n = 0; $n < count($keys); $n++){
$index = $keys[$n];
array_push($sampleAry02, $sampleAry[$index]);
}
echo('<pre>');
var_dump($sampleAry02);
echo('</pre>');
こんな中身になる。
$sampleAry02[
['cf01' => 'aaaa', 'cf02' => '****'],
['cf01' => 'aaaa', 'cf02' => '****'],
['cf01' => 'aaaa', 'cf02' => '****'],
];
該当する値を持つデータの在処をarray_column、array_keysで拾って、forで回して大元の配列から引っこ抜いて、該当のものだけをまとめた配列($sampleAry)に格納したという流れ。
変数が多いので、実際に組み込むときには他と混ざらないように注意すること。
絶対に間違いなくユニークなkeyから引っ張ってきたい場合
array_push()の使い方なんだけども。
前項の話から、こうすると
$sample = SCF::get_option_meta('example-options','example-cf');
$sampleAry = array();
foreach($sample as $field){
array_push($sampleAry, array('cf01'=>$field['cf01'], 'cf02'=>$field['cf02']));
}
こうなる。
$sampleAry[
['cf01' => 'aaaa', 'cf02' => '****'],
];
ここからこうやって出力することになる。
echo($sampleAry[0]['cf01']);
echo($sampleAry[0]['cf02']);
通常はこれでいい。
今回のようなケースでは仕様としてのユニーク枠がないので、被る可能性はどうやっても出てくる。
だからこれでもいいんだけど、とはいえ無駄な階層を減らしたいよねってなった場合。
[0]があることから階層が1個ムダに多いということが分かる。
なので、格納方法を変える。
こうすると
$sample = SCF::get_option_meta('sample-options','sample-cf');
$sampleAry = array();
foreach($sample as $field){
array_push($sampleAry, , 'cf01', $field['cf01']);
array_push($sampleAry, , 'cf02', $field['cf02']);
}
こうなって
$sampleAry[
'cf01' => 'aaaa',
'cf02' => '****',
];
こうなる。
echo($sampleAry['cf01']);
echo($sampleAry['cf02']);
これでまた怖いのが、連想配列のkeyは重複しても壊れないということ。
だから、該当データが複数あった場合は全部格納されちゃって、えらいことになる。
階層分けされてればまだ、複数データがあっても指定できる余地があるから最低限のリスクヘッジというか保険がかけられるわけで、だからあんまりこの格納方法はやらない方がいい気がする。
自分で組み立てたときはいいんだけど、格納元がカスタムフィールドなわけだから、手離れした後に下手にいじられてぶっ壊れて、泣きつかれたときにこっちも覚えてないんですけど、ってなるとめっちゃ時間がもったいない。
いやまあ、そもそもがカスタムフィールドによるユニークありきの構築はかなりピーキーだから、そもそもの話としてやらないほうがいいんだけどね。
画像を扱う場合
ちょっとややこしい。
$sample = SCF::get_option_meta('example-options','example-cf');
$sampleAry = array();
foreach($sample as $field){
array_push($sampleAry, array('cf01'=>$field['cf01'], 'cf02'=>$field['cf02'],'img'=> wp_get_attachment_image_src($field['image'],'full')[0])));
}
echo '<img src="'.$sampleAry[0]['img'].'" alt="">';
SCFの画像はURLが出力できるんだけど、出力時に画像サイズの指定もする。
それに、単体じゃなくて配列で出てくる。
なので、他のフィールドと違ってちょっと長ったらしい記述になる。
使わないけど使う内容
WPをDBもどきにする方法、正直あんまりやりたくないんだけどね。
登録内容を編集したいって希望があるならDBを直接触らせるよりも使い勝手がいいかなとか、そういうね。
WPは置いておいて、とりあえずアプローチ自体は知っておいたほうがいい内容ではある。
コメント