カテゴリ: 3,66

PHPのプログラムデザインを考えてみる

PHPで書くコードは、おもしろいほどぐちゃぐちゃになるんだよね(^_^;)
コードを書くところが の間なので、HTMLのどこにコードを書いても問題がないのがPHP。だから、モジュールをインクルードするところも自由と言ったら自由になってしまう。

それに、Cのようにヘッダファイルというものがないし、Pythonのようにファイル名がそのままクラス名になったりするわけでもないし、インクルードファイルがHTMLでも問題ない。PHPはプログラム言語と言ってしまっていいのかわからないほど、マークアップ言語に限りなく近いベースになっている感じがする。

だからなのか、今までPHPをやってこなかった自分でもどこのPHPの書籍を読んでなくてもすんなりとPHPを書けてしまった。初めてじっくりかいたけど、なんていうか・・・なにかひっかかるものがあった。このもやもやを解決するためにも、Pythonを見習ってPHPでプログラミングするためのプログラムデザインを考えてみようと思います。

.htaccess」でどのディレクトリのファイルにアクセスしてもindex.phpに飛ばすようにする

PHPは「.php」ファイルに直接アクセスしてその処理をサーバーサイドで表示させますが、ディレクトリのどのphpファイルにも自由にHTTPからアクセスできるようになるのは、セキュリティ上リスクがあるのではないかと考えます。例えば、index.phpからインクルードするための内部だけで使われるPHPファイルがあったとしたら、そのファイルにindex.phpを経由せずともアクセスすることが可能になってしまいます。*1

.htaccessではこのように書きます。

#Rewriteを使う
RewriteEngine On

#ベースのディレクトリ
RewriteBase /

#アクセスを許可するディレクトリを指定
RewriteCond %{REQUEST_URI} !^/css/(.*)
RewriteCond %{REQUEST_URI} !^/js/(.*)
RewriteCond %{REQUEST_URI} !^/img/(.*)

#全てのアクセスをindex.phpに飛ばす
RewriteRule .* index.phpCode language: PHP (php)

とりあえずこんなふうにすれば、index.phpにディレクトリ配下のファイルへのアクセスがあった場合index.phpに飛ばすことが出来ます。ただ、Rewriteを使えるようにするには、Apache側で、モジュールを追加する必要があります。

詳しくが「mod_rewrite.so」で検索するか、下記URLで調べてみるといです。
mod_rewriteのインストール・設定 – RewriteRuleのサンプル [Fedora, RedHat, CentOS] – Linux


クラスは「classes」フォルダにまとめる

とりあえずどこでもインクルードできるのがPHP。だから気づけばディレクトリがファイルの山で、しかもファイル名が適当で何がなんなのかわからなくなってしまうことを避けるためにも、クラスは「classes」フォルダに纏めることにします。

<?php

class Hoge {

    public $hage = 1;

    public function hoge(){
        print($hage -> var);
    }

    
}
?>Code language: HTML, XML (xml)

こんなファイルを作ったら、classesフォルダに「hoge.php」という名前で保存します。*2

このクラスが使いたくなったら、

include("classes/Hoge.php");
$hoge = new Hoge();Code language: PHP (php)

として使用します。classesフォルダより前に何か書かなくてもいいの? という場合でも問題はありません。なぜからphpファイルへのアクセスは全て「index.php」を介しているので、カレントディレクトリが変わるようなことはまずありえません。index.phpにアクセス解析を仕込むことも可能になります(笑)

ページは「views」フォルダにまとめる

別に「pages」でもいいと思います。「pages」フォルダを作成したら、そこに作りたいページのファイルを設置します。

しかし、設置しただけでは表示できることができませんので、index.phpを編集します。

$url = $_SERVER["REQUEST_URI"];
if (preg_match("/^welcome\\/?$/", $url)){
    include("views/welcome.php");
}
else if (preg_match("/^information\\/?$/", $url)){
    include("views/information.php");
}Code language: PHP (php)

これで呼び出せるようになる上にアドレスバーにはちゃんと/welcome/と表示することができます。

「modules」フォルダを作成する

外部からダウンロードしたphpのライブラリや、ひとつの機能だけをもったphpファイルを入れておきます。classesフォルダと分けるのは、他からDLしてきたファイルは必ずファイル名=クラス名となっているわけではないので分ける必要があります。

一つの機能だけを持ったファイルというのは

modules/hoge.php

function hoge() {
    return "hoge";
}Code language: JavaScript (javascript)

のようなそんなかんじのものです。

index.phpの先頭には、デバッグ変数やサイトの設定用変数を定義しておく

将来的にサイトを全体的に変更する必要がでてきた場合などに対処するために、index.phpの先頭にはサイトそのものの設定用の変数や言語パックのインクルードなど用意しておきます。

index.php

$DEBUG = true;
$SITE_TITLE = "Hoge Site";
$SITE_VARTION = "1.00";
include("language.php");
〜Code language: PHP (php)

共有のUIを使用する場合は「ui.php」を用意する。

ブログのように、どのページにアクセスしても同じデザインのページで、本文だけ違うといったサイトをよく見かけると思います。そのように実装する場合は、index.phpにui.phpをインクルードするようにし、「ui.phpのインクルード」 → 「views/xxx.php」というふうにすることで全てのページに共通したuiで表示させることができます。

その他細かい決め事

だいたい重要なことは上に書きましたが、やってはいけないこととして箇条書きにしていきます。

  • index.phpに必要なクラスや関数をまとめてインクルードしない。*3
  • モジュールとクラスは必ず「views/xxx.php」の先頭でインクルードする。*4
  • クラスやモジュール内でクラスからグローバルインスタンスを生成しない。
  • ファイル名とクラス名の一致のルールは必ず守る
  • ファイル名と関数名の一致のルールは必ず守る
  • module.phpに関数まとめてしまえなんてことはしない
  • classes.phpにクラスまとめてしまえなんてことはしない
  • config.phpファイルを作ってそこにサイトの情報まとめてindex.phpの先頭にインクルードさせるなんてことはしない
  • upload.phpというファイルが必要になったら、ページ扱いとしてviewsフォルダ内に入れる。
  • ページの中に更にページが必要になるような挙動が必要になる場合は、「views」フォルダ内にフォルダを作成し、「index.php」とそれ以外のファイルを設置するようにする。

*1:PHPファイル側からもアクセスを制限する方法や、.htaccsessを使わずにディレクトリやファイルのパーミッションを変更させる方法もあります。

*2:このときにファイル名を大文字小文字にするか悩みます・・。ここは個人の判断でお願いします。

*3:Pythonだとこれが可能になるのですが、PHPだと重くなるだけです。残念。

*4:ソースコードの間間でインクルードすると混乱するだけ。