HOME>WEBプログラム覚書>[PHP]ウェブデザイナーはどんな関数をつくればよいか。

[PHP]ウェブデザイナーはどんな関数をつくればよいか。

PHPを学び始めて関数の作り方はわかったけど、どういう関数作ればいいのかよくわからんって人に。 HTMLを記述する人(クライアント)向けにどんな関数を作ればよいのか考えていきます。

WordPressのプラグインとかテンプレートタグ作る場合も役立つと思います。

ダメ絶対ダメ。

まずは後々死にたくなる関数とその利用パターン。

my_function.php

  1. <?php
  2. display_books()
  3. {
  4.     $books = array(
  5.         'php' => array(
  6.             'title' => 'PHPでサイト制作',
  7.             'price' => '2000',
  8.         ),
  9.         'javascript' => array(
  10.             'title' => 'サーバーサイドJavascript',
  11.             'price' => '4000',
  12.         ),
  13.         'actionscript' => array(
  14.             'title' => 'Actionscript3.0 Tips',
  15.             'price' => '2500',
  16.         ),
  17.     );
  18.  
  19.     echo '<table>';
  20.     foreach ($books as $key => $value) {
  21.         echo '<tr>';
  22.         echo '<th>' . $value['title'] . '</th>';
  23.         echo '<td>' . $value['price'] . '</td>';
  24.         echo '</tr>';
  25.     }
  26.     echo '<table>';
  27. }
  28. ?>

index.php

  1. <div class="myBooks">
  2.     <?php display_books(); ?>
  3. </div>
  4.  

こういう関数を利用してサイト作っちゃうと高確率で死ねます。

で、何が問題なのか?

display_books()が「データの保持」と「出力」の両方をやってしまっている点です。 これでは本のデータを他で利用したいと思ったとき、利用することが出来ません。

なので「データの保持」と「出力」を分離します。

my_function.php

  1. <?php
  2. get_books()
  3. {
  4.     $data = array(
  5.         'php' => array(
  6.             'title' => 'PHPでサイト制作',
  7.             'price' => '2000',
  8.         ),
  9.         'javascript' => array(
  10.             'title' => 'サーバーサイドJavascript',
  11.             'price' => '4000',
  12.         ),
  13.         'actionscript' => array(
  14.             'title' => 'Actionscript3.0 Tips',
  15.             'price' => '2500',
  16.         ),
  17.     );
  18.     return $data;
  19. }
  20.  
  21. display_books()
  22. {
  23.     $books = getBooks();
  24.  
  25.     echo '<table>';
  26.     foreach ($books as $key => $value) {
  27.         echo '<tr>';
  28.         echo '<th>' . $value['title'] . '</th>';
  29.         echo '<td>' . $value['price'] . '</td>';
  30.         echo '</tr>';
  31.     }
  32.     echo '<table>';
  33. }
  34. ?>

とりあえずこれで本のデータを何処からでも取得できるようになりました。

では、次なる問題点はなんでしょう?

そのHTMLが最終形態だと思ってはいけない

そうです。フリーザ様同様にマークアップも変身していくのです。

にも関わらず、display_books()は関数内でHTMLを出力しちゃってます。これでは次の処理につなげられません。 どういうことかというと、こんなことができなくなります。

PHP

  1. <?php
  2. div_wrap($html) {
  3.     return '<div class="styleX">' . $html . '</div>';
  4. }
  5. echo div_wrap(display_books());
  6. ?>

HTMLのマークアップは多様です。関数が返したものをさらに加工したい場合も多々あるのです。 なので「いつ出力するか」は最終形態を知るクライアントが決めればよいのです。

バッファリングという手もありますが、そんなの毎回するのは非効率的です。 なので関数内で生成したHTMLは出力ではなく、必ず返すようにしたほうがよいでしょう。

では、display_books()から出力の機能を取り外してみましょう。


my_function.php

  1. <?php
  2. get_books()
  3. {
  4.     $data = array(
  5.         'php' => array(
  6.             'title' => 'PHPでサイト制作',
  7.             'price' => '2000',
  8.         ),
  9.         'javascript' => array(
  10.             'title' => 'サーバーサイドJavascript',
  11.             'price' => '4000',
  12.         ),
  13.         'actionscript' => array(
  14.             'title' => 'Actionscript3.0 Tips',
  15.             'price' => '2500',
  16.         ),
  17.     );
  18.     return $data;
  19. }
  20.  
  21. get_books_table()
  22. {
  23.     $books = getBooks();
  24.     $html = '';
  25.     $html .= '<table>';
  26.     foreach ($books as $key => $value) {
  27.         $html .= '<tr>';
  28.         $html .= '<th>' . $value['title'] . '</th>';
  29.         $html .= '<td>' . $value['price'] . '</td>';
  30.         $html .= '</tr>';
  31.     }
  32.     $html .= '<table>';
  33.     return $html;
  34. }
  35.  
  36. div_wrap($html) {
  37.     return '<div class="styleX">' . $html . '</div>';
  38. }
  39. ?>

index.php

  1. echo div_wrap(get_books_table());
  2.  

で次なる問題点。

WordPressの関数を全て覚えてますか?

get_books_table()が、「本のリストをテーブルマークアップする」という用途にしか使えません。 まぁそれはそれで間違いではないのですが、難癖つけていきましょう。

get_books_table()のような関数はなぜ問題なのか?

繰り返し書いているようにHTMLのマークアップが多様だからです。 tableではなく、ulやdlでマークアップしたい場合、このままではget_books_ul()やget_books_dl()を作ることになるでしょう。

またデータの種類も大抵増えていくものです。 例えばゲームソフトを扱う場合、get_games_table()、get_games_ul()とget_games_dl()を作らなくてはなりません。

このように要求が増えるたびに、関数も増えていってしまうのです。 当然関数が増えると同じ関数名は使えませんから、長くなってしまったり、似たような名前になってしまったり、 宇宙の法則がみだれてget_books_dl()であるべきところをget_dl_books()としてしまったり。

WordPressの関数を全て覚えてますか? はい。と答えれるような頭脳をもった人に、僕から言えることなんて何もありません。自分の好きなようにやっても問題は起こらないでしょう。自分の道を邁進していただきたい。

それ以外の人は、自分でも何のために作ったのか、使ってるのか使ってないのか分からない関数を生み出す可能性大です。 関数作成のスキルを身につけた人が大抵通る道ですから。

なぜ、get_books_table()の用途が限られているのか

ではなぜ、get_books_table()の用途が限られているのでしょうか? それは「何を(本を)」と「どのような形式で(テーブル形式で)」の2つのを処理してしまっているからです。

そもそも「何を」と「どういう形式で」使うのかはクライアントの頭の中です。 なので「何を」と「どういう形式で」をクライアントが使用するときに選択するというのが自然です。

全てのパターン満たす関数を用意したって、クライアントも自分の要求を満たす関数を膨大な関数の中から探すのは大変なのです。

ということでそこら辺を分けていきます。

html.php

  1. <?php
  2. function table(Array $data)
  3. {
  4.     $html = '';
  5.     $html .= '<table>';
  6.     foreach ($data as $key => $value) {
  7.         $html .= '<tr>';
  8.         $html .= '<th>' . $value['title'] . '</th>';
  9.         $html .= '<td>' . $value['price'] . '</td>';
  10.         $html .= '</tr>';
  11.     }
  12.     $html .= '<table>';
  13.     return $html;
  14. }
  15.  
  16. function ul(Array $data)
  17. {
  18.     $html = '';
  19.     $html .= '<ul>';
  20.     foreach ($data as $key => $value) {
  21.         $html .= '<th>' . $value['title'] . $value['price'] . '</th>';
  22.     }
  23.     $html .= '<ul>';
  24.     return $html;
  25. }
  26.  
  27. function dl(Array $data)
  28. {
  29.     $html = '';
  30.     $html .= '<dl>';
  31.     foreach ($data as $key => $value) {
  32.         $html .= '<dt>' . $value['title'] . '</dt>';
  33.         $html .= '<dd>' . $value['price'] . '</dd>';
  34.     }
  35.     $html .= '<dl>';
  36.     return $html;
  37. }
  38. ?>

resource.php

  1. <?php
  2. get_books()
  3. {
  4.     $data = array(
  5.         'php' => array(
  6.             'title' => 'PHPでサイト制作',
  7.             'price' => '2000',
  8.         ),
  9.         'javascript' => array(
  10.             'title' => 'サーバーサイドJavascript',
  11.             'price' => '4000',
  12.         ),
  13.         'actionscript' => array(
  14.             'title' => 'Actionscript3.0 Tips',
  15.             'price' => '2500',
  16.         ),
  17.     );
  18.     return $data;
  19. }
  20. ?>

my_function.php

  1. <?php
  2. div_wrap($html) {
  3.     return '<div class="styleX">' . $html . '</div>';
  4. }
  5. ?>

index.php

  1. <?php
  2. echo div_wrap(table(get_books()));
  3. echo div_wrap(ul(get_books()));
  4. ?>

クライアントが多少見にくくなったかもしれませんが、ゲームというデータが増えた場合も下記のようにデータを取得する関数を追加するだけで済むようになりました。

resource.phpに追加

  1. <?php
  2. get_games()
  3. {
  4.     $data = array(
  5.         'wii' => array(
  6.             'title' => 'うぃ',
  7.             'price' => '2000',
  8.         ),
  9.         'nintendo 3ds' => array(
  10.             'title' => 'ニンテンドー3DS',
  11.             'price' => '25000',
  12.         ),
  13.         'wii U' => array(
  14.             'title' => 'うぃー U',
  15.             'price' => '30000',
  16.         ),
  17.     );
  18.     return $data;
  19. }
  20. ?>

index.php

  1. <?php
  2. echo div_wrap(table(get_books()));
  3. echo div_wrap(ul(get_books()));
  4.  
  5. echo div_wrap(table(get_games()));
  6. echo div_wrap(ul(get_games()));
  7. ?>

ここでdiv_wrap(table(get_books()))を頻繁に使うようであれば、 my_function.phpも寂しくなったことだしbook用の関数を作りましょう。

my_function.php

  1. <?php
  2. books_for_html()
  3. {
  4.         return div_wrap(table(get_books()));
  5. }
  6. ?>

で、あまり使わなそうなものは直接コーディングしてしまいましょう。

index.php

  1. <div class="myFavaritGames">
  2.     <table class="styleX">
  3.     <?php
  4.    $html = "";
  5.    foreach (get_games() as $key => $value) {
  6.         $html .= sprintf('
  7.         <tr class="%s">
  8.             <th class="styleY">%s</th>
  9.             <td><img src="icon.gif">%s</td>
  10.         </tr>
  11.         ',
  12.         $key,
  13.         $value['title'],
  14.         $value['price']
  15.         );
  16.     }
  17.     echo $html;
  18.     ?>
  19.     </table>
  20. </div>
  21.  

ここら辺のコーディングの話と直接コーディングした場合の問題については、 レッドブル プラシーボ効果も切れたのでまた今度書きたいと思います。

とりあえず現在のイメージ。

関数の名前

触れ忘れてましたが、関数の名前も重要です。最初に登場したdisplay_books()は良くない名前です。 これを記述するindex.phpでは、プレビューするか関数の中を覗かないと何が出力されるかわからないからです。

特にDreamweaver(最近どうなんだろ?)などのエディタでは、IDEのように関数にジャンプすることができません。 なので、どのようなHTMLが出力されるのか「つかみ」ができるような関数名が望ましいです。

何気にbooks_for_html()もよくないですねwいやー命名ってムズイですね。

まとめ

とりあえず、

  • 関数内で出力しない
  • なんでもかんでも関数をつくろうとしない

に気をつけておくと、使い勝手のよい関数になるんじゃないのかなと思います。

投稿日 2011年6月10日 03:34
カテゴリ PHP
タグ WordPress | 関数
トラックバック URL http://www.kantenna.com/cgi-bin/mt504/mt-tb.cgi/1225

コメント

コメントする
Name
Email Address
URL