ショートコードでWarning: Illegal string offsetエラーが出る時の解決策【ワードプレス】
先日、ショートコード関連の記事を書いていて、Warning: Illegal string offset なんちゃらかんちゃらとエラーが出現。。。恥ずかしながら、見た事ありませんでした。
気持ち悪いし、今まで書いたショートコードも不安になるので、詳しく原因を探って解決してみました。
~ 目次 ~
エラーが出たコード
余計な部分は省いていますが、エラーが出たショートコードは、下のような感じです。引数に名前を付けて連想配列のキー名を指定して取り出すコードですね。
1 2 3 4 |
function test_func($atts){ return $atts['id']; } add_shortcode('test','test_func'); |
引数ありなら問題なし
このショートコードに、id=110などと引数を渡してあげれば問題はない。
1 |
[test id=110] |
引数無しで使うとWarning: Illegal string offset エラー
しかし、引数無しで下の様に実行すると、「Warning: Illegal string offset ~」とエラー。「こっ、これだけでエラー!?returnしとるだけやろ!」と思いましたが、やはりエラーです。
1 |
[test] |
たしか前はこのようなコードでエラーは出なかったはず…。むむむ…。
それに、取り出す時に連想配列ではなく、$atts[1]のような添字配列を使用すれば、引数無しで使用してもこのエラーは出ません。
Warning: Illegal string offsetエラーの意味
Google翻訳的な内容で申し訳ありませんが、文字列オフセットが不正だとおっしゃっています…。PHP5.4以降で出るようになったようです。実際にPHP5.3で調べてみましたが、今回のショートコードを引数無しで使用してもエラーは出ませんでした。
オフセットは位置というような解釈でいいかと。
つまり、キーで指定した文字列内の位置が不正だというエラーですね。
ショートコードの引数は値が無いと空文字列
Warning: Illegal string offsetエラーの意味がわかったところで、あれショートコードの引数って配列じゃないの?という疑問が。
関数内でショートコードの引数から値を取り出す時は、$atts[2]とか$atts[‘id’]のように配列のキーを指定して取り出しますよね。たとえ引数が1つでも取り出すときは$atts[0]です。
勘違いしてました!
私は勘違いしていました。引数は配列だと。
しかし、実際は何も値が渡されなかった場合、引数は配列ではなく空文字列になります。何らかの値を受け取った時だけ配列になるんですね。
連想配列の時だけエラーになる原因
原因は、引数無しでショートコードを実行した時、関数内で受け取る引数は配列ではなく文字列である事です。
PHPで文字列に対して[1]のように指定すると、1文字ずつ格納された配列のように扱えます。[1]はゼロから数えますので2文字目(2バイト目)の文字となります。これは不正ではありません。
1 2 3 |
$text='xyz'; echo $text[1]; 実行結果:y |
逆に連想配列を使用していた場合、文字列に対して[‘id’]のようなオフセット指定をしてしまうので、不正となってしまいます。したがって、内容的には同じショートコードでも、関数内で取り出す時に連想配列を使用すると、引数無しで使用した時にエラーを出してしまうんですね。
PHP5.4以降でショートコードを書く時の対応策
使う人の事を考えると「引数は1つだけ。でも、名前があった方がわかりやすいな♪」なんて思って、気軽に下のようなコードを書いてしまう事があるかもしれません。PHP5.3以前は特に問題ありませんでしたが、少なくとも今現在こういうショートコードは、引数無しで使用されるとエラーを出してしまいます。
1 2 3 4 |
function test_func($atts){ return 'ID:'.$atts['id']; } add_shortcode('test','test_func'); |
PHP5.4以降の場合、引数に名前を付けてショートコードを作成する時は、たとえ引数が1つでもちゃんとshortcode_attsを使ってデフォルトの定義をする。。。事にします。私は!
たとえデフォルト値なんか要らなかろうが、引数が1つだろうが引数に名前を付けてショートコードを作る時はshortcode_atts()をちゃんと使います。
1 2 3 4 5 |
function test_func($atts){ $atts=shortcode_atts(array('id'=>''),$atts); return 'ID:'.$atts['id']; } add_shortcode('test','test_func'); |
これで引数が無い場合でも必ず配列として扱われるので、Warning: Illegal string offsetエラーは絶対に出ません。
本当に配列なのかを疑ってみる
今回はショートコードを作成していて、Warning: Illegal string offsetエラーを食らいました。
もし、普通にPHPを書いている時などにこのエラーに出くわしたら、連想配列のキーを指定している”配列”が、本当に配列なのか?文字列ではないのか?を疑ってみましょう。
最後に
存在しないキーにアクセスした時に出るNotice:なんちゃらエラーと原因を混同しそうになりましたが、原因は全く違うようでした。
PHP5.3系以前からPHP5.4以降にバージョン変更した時や、久々に新サイトを立ち上げた方などはハマりやすいかもしれませんね。こんなエラー要らないので、そのうち出なくなっているといいのですが。。。
[…] ショートコードでWarning: Illegal string offsetエラーが出る時の解決策【ワードプレス】 […]