かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

PHP 配列からいい感じに CSS のクラス名を作りたい

3億年ぶりに古の WordPress 製のサイトを更新する必要があり、PHP のテンプレートで CSS のクラス名を動的に作成する必要があった JavaScript で言うところの classnames のような挙動をさせたい

CSS のクラス

class="foo bar mofu" のような形

  • スペース区切りの文字列
  • クラス名が重複していても特に問題はない

配列から Falsey な値を取り除いて スペースで結合すれば良い

TypeScript での例

export const classnames = (
 ...args: (string | undefined | null | false)[]
): string => {
  if (!args.length) {
    return '';
  }
  return args.filter((value) => 
    value !== null && value !== undefined && value !== false && value !== ""
  ).join(' ').trim();
};

細かいことを抜きにしらこんな感じで実現できる
これに近いことを PHP で実装できれば OK

array_filter + implode で実現する

  1. array_filter で配列から Falsey な値を取り除く
  2. implode で配列をスペース区切りで文字列結合する
<?php declare(strict_types=1);
function classnames(array $arr): string {
  return implode(' ', array_filter($arr));
}

echo classnames(['ichigo', false, 'aoi', 0, 'ran', '', null, 'akari']);
// -> "ichigo aoi ran akari"

このコードには下記の問題があるが、ライブラリとして公開しているわけでもないのでヨシ!とした

  • 0"0" も Falsey な値として除去されてしまうが、そんな class 名を付けることはほぼ無い想定とした
  • 関数に型を設定しているが、PHP の形は array に含まれる要素の型を指定する方法がイマイチわからなかったので、文字列変換できないものが渡されるとクラッシュする可能性がある

array_filter Example #2 array_filter() without callback

<?php
$entry = [
    0 => 'foo',
    1 => false,
    2 => -1,
    3 => null,
    4 => '',
    5 => '0',
    6 => 0,
];
print_r(array_filter($entry));
// Array
// (
//     [0] => foo
//     [2] => -1
// )

cf. PHP: array_filter - Manual

うごいてるからヨシ!

おわり ฅ^•ω•^ฅ


[参考]