「WordPressで学ぶPHP(3)関数編」を発売しました。
本書は「WordPressで学ぶPHP(1)変数・制御構造編」「WordPressで学ぶPHP(2)データ構造(配列・オブジェクト)編」の続編にあたり、PHP組み込みの関数や、独自の関数を作る方法などを解説します。
Kindle本で、定価400円です。
NabeAzzテンプレート問題パート2・解答例1
昨日NabeAzzテンプレート問題パート2を出題しましたが、テンプレートの組み方はいろいろ考えられます。
mixiのコミュニティで何人かの方がテンプレートを作られていましたが、それぞれやり方が違って、面白かったです。
私も何通りか解答例を作ってみました。
今日はその中で、比較的読みやすそうなものを紹介します。
1.テンプレート
テンプレートのうち、HTMLのヘッダー等を除いて、問題の部分を出力するところだけを抜き出すと、以下のようになります。
<MTIgnore>xは出力する数値</MTIgnore>
<MTSetVar name="x" value="1">
<table>
<MTIgnore>二重ループ</MTIgnore>
<MTFor var="r" from="1" to="20">
<tr>
<MTFor var="c" from="1" to="10">
<MTIgnore>市松模様の判断</MTIgnore>
<MTSetVar name="f" value="0">
<MTIf var="r" op="%" value="2" eq="0">
<MTIf var="c" op="%" value="2" eq="1">
<MTSetVar name="f" value="1">
</MTIf>
<MTElse>
<MTIf var="c" op="%" value="2" eq="0">
<MTSetVar name="f" value="1">
</MTIf>
</MTIf>
<td<MTIf name="f" value="1"> class="reverse"</MTIf>>
<MTIgnore>開始タグの出力</MTIgnore>
<MTIf name="x" op="%" value="3" eq="0">
<b>
</MTIf>
<MTIf name="x" like="3">
<u>
</MTIf>
<MTIf name="x" op="%" value="5" eq="0">
<i>
</MTIf>
<MTIf name="x" like="5">
<s>
</MTIf>
<MTIgnore>数値の出力</MTIgnore>
<MTGetVar name="x">
<MTIgnore>終了タグの出力</MTIgnore>
<MTIf name="x" like="5">
</s>
</MTIf>
<MTIf name="x" op="%" value="5" eq="0">
</i>
</MTIf>
<MTIf name="x" like="3">
</u>
</MTIf>
<MTIf name="x" op="%" value="3" eq="0">
</b>
</MTIf>
</td>
<MTIgnore>xを1増やす</MTIgnore>
<MTSetVar name="x" op="++">
</MTFor>
</tr>
</MTFor>
</table>
2.二重ループ
HTMLでは、表の各行をtr要素で表し、行内の個々のセルをtd要素で表します。
この問題では、1~200の数値を1行あたり10列の表で出力するので、以下のような二重の繰り返しを行うことになります。
- 表全体で、行(<tr>~</tr>)を20回出力
- 1つの行につき、セル(<td>~</td>)を10回出力
そこで、MTForタグの中にさらにMTForタグを入れて、二重ループの構造をとりました。
外側の<MTFor var="r" from="1" to="20">の繰り返しは、行を20回出力するための繰り返しです。
そして、内側の<MTFor var="c" from="1" to="10">の繰り返しは、各行にセルを10回ずつ出力するための繰り返しです。
また、出力する数値は、変数xで別途管理するようにし、セルを1個出力するごとにxを1つずつ増やすようにしました。
なお、「数値=(行番号ー1)×10+列番号)」で計算する方法も考えられますが、それだと処理が長くなりますので、この方法は取りませんでした。
3.市松模様の判断
表の個々のセルには、背景に色を付けて、市松模様にします。
表の行/列の番号と市松模様の関係は、以下のようになります。
| 列 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ||
| 行 | 1 | ||||||||||
| 2 | |||||||||||
| 3 | |||||||||||
| 4 | |||||||||||
| ... | ... | ||||||||||
この表を見ると、濃い色がついているセルは、行/列の番号が以下のどちらかの条件を満たしています。
- 行番号が偶数で、かつ列番号が奇数
- 行番号が奇数で、かつ列番号が偶数
また、奇数か偶数かの判断は、「2で割ったときの余りが1(0)かどうか」で行うことができます。
そこで、以下のような考え方で、濃い色を付けるセルとそうでないセルを分けます。
「色を付ける」ことを表すための変数を0に初期化
if (行番号を2で割った余りが0(=行番号が偶数))
}
else { /* 行番号が偶数でない場合にここにくるので、ここでは行番号は奇数 */
if (列番号を2で割った余りが0(=列番号が偶数) {
「色を付ける」の変数に1を代入
}
}
この流れを実際にMTタグに表すと、テンプレートの「市松模様の判断」の部分のようになります。
テンプレートでは、「『色を付ける』ことを表すための変数」として、「f」という変数を使っています。
また、行/列の番号は、MTForタグでそれぞれ変数r/cに代入していますので、これらの変数を2で割った余りを条件判断しています。
4.数値をタグで囲んで出力
最後に、以下の条件で、数値をタグで囲みつつ出力します。
- 3で割り切れる数(例:6)は、bタグで囲みます。
- 3を含む数(例:13)は、uタグで囲みます。
- 5で割り切れる数(例:10)は、iタグで囲みます。
- 5を含む数(例:52)は、sタグで囲みます。
「○○で割り切れる」という条件は、「○○で割ったときの余りが0」と言い換えることができます。
そこで、数値を出力する前と後で、出力する数を3や5で割ったときの余りが0かどうかを判断します。
そして、余りが0であれば、数値の前に<b>や<u>のタグを出力し、後に</b>や</u>のタグを出力します。
また、「○○を含む」は、MTIfタグでは「like="○○"」で表現することができます。
これを使って、数値の前後にタグを出力します。
なお、開始タグと終了タグは正しく対になっている必要があります。
そのため、「3で割り切れる」等の条件を判断する順番は、開始タグと終了タグとで逆になります。
5.課題点
今回の例では、開始タグと終了タグを出力する際に、同じ条件を2回ずつ判断していて、効率が良くありません。
そこで、条件判断を1回にまとめる例を、明日紹介します。
