PHPのコーディング規則、PSRを学ぶ(5)

PHPのコーディング規則、PSRを学ぶ(4)の続きです。
この記事では、PHPのコーディング規則PSRの規則をまとめます。

1.規則概要

  1. 文字コードはUTF-8(BOM無し)
  2. 改行コードはLF
  3. PHP(開始)コードは「<?php」または 「<?=」
  4. PHPのみのファイルの場合は最後の「?>」を省略してよい
  5. 最後は改行して終わる
  6. インデント(字下げ)は「半角スペース4つ」でタブを使わない
  7. 開き「{」は改行して記述
  8. シンボル(クラス、関数、定数など)を宣言するためのファイルと、副作用のある処理(出力の生成、ini設定の変更など)を行うためのファイルは、分けるべき
  9. クラス名は、StudlyCaps(単語の先頭文字を大文字で表記する記法)記法で定義
  10. メソッド名はcamelCase(単語の先頭文字を大文字で表記するが、最初の1文字目は小文字とする記法)記法で定義
  11. クラス定数(const)は全て大文字とし、区切り文字にはアンダースコアを用いて定義
  12. 名前空間定義・use定義のあとには空行を挟む
  13. プロパティの命名規則は「StudlyCaps」「camelCase」「under_score」どれでもよいがファイル内で一貫させること
  14. PHPの予約語は小文字で使用
  15. PHP定数であるtrue、false、nullは小文字で使用
<?php
namespace Vendor\Package;

use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class Foo extends Bar implements FooInterface
{
    public function sampleFunction($a, $b = null)
    {
        if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }

    final public static function bar()
    {
        // メソッド本文
    }
}

2.名前空間とオートローダーについて

  1. PHP5.3.0以上が必要
  2. (namespaceを利用するためです。オートローダーを使わない場合は問題ありません。オートローダーについてはPSR-0(日本語)をご覧ください。)

  3. 名前空間は「\<ベンダー名>\(<名前空間>\)*<クラス名>」と設定すること。
  4. 言い換えると、「\製作者名\(機構名)\機能名」と設定して名前空間を汚染しないようにしてください。

  5. クラス名のアンダースコア「_」はディレクトリの区切りになる
  6. 名前空間の中のアンダースコア「_」はディレクトリの区切りにはならない

初心者の方の目線で見た名前空間は、PHPのコーディング規則、PSRを学ぶ(3)にまとめています。

最後に

サイトの改修が完了しましたにいただいたコメントをヒントに「PHPのコーディング規則、PSRを学ぶ」が始まりました。コメントありがとうございました。

参考にさせていただいたサイトの運営者の方々、ありがとうございました。すごく勉強になりました。

PHP・CGIプログラムは使われてこそ価値があります。PHPプログラムを配布し始めたのは最近ですが、それを誰もが改修出来るようにすることによって、さらに良いものが生まれてくることを願っています。

「面白い(個人制作の)ゲームをやりたい!」「いいプログラムを使いたい!」からこそやっております。もし面白いと感じるゲームや便利なプログラムがあったらコメントなどで紹介してください。( ^^)

各記事へのリンク

  1. PHPのコーディング規則、PSRを学ぶ(1)
  2. PHPのコーディング規則、PSRを学ぶ(2)
  3. PHPのコーディング規則、PSRを学ぶ(3)
  4. PHPのコーディング規則、PSRを学ぶ(4)
  5. PHPのコーディング規則、PSRを学ぶ(5)(当記事)

参考

PHPのコーディング規則、PSRを学ぶ(4)

PHPのコーディング規則、PSRを学ぶ(3)の続きです。
今回は実際にクラス名定義を自宅サーバーで試してみます。

1.「SplClassLoader.php」を手に入れる

「ダウンロード」または「直接入力」の方法があります。

・ダウンロードでの方法
http://gist.github.com/221634にアクセスして「Download Gist」をクリック。
ダウンロード
ダウンロードファイルは「.tar.gz」形式なので、「7Zip」などで解凍します。
「SplClassLoader.php」を「C:\xampp\htdocs\phptest」フォルダにコピー&ペーストします。
文字コードは「UTF-8(BOMなし)」、改行コードは「LF」で保存します。
(文字コード・改行コードの設定方法がわからない方はこちらの記事(詳細は5章)で解説しています)

・直接入力での方法
「C:\xampp\htdocs\phptest」フォルダに「SplClassLoader.php」ファイルを新規作成。
そのファイルをテキストエディタで開いておきます。

http://gist.github.com/221634にアクセスして「<>」(View Raw)をクリック。
直接入力
「SplClassLoader.php」のコードのみが表示されるので、「Ctrlボタン+Aキー」または「右クリック > 全てを選択」で全てを選択し、コピーします。

テキストエディタで開いておいた「SplClassLoader.php」に貼り付け(ペースト)します。
文字コードは「UTF-8(BOMなし)」、改行コードは「LF」で保存します。
(文字コード・改行コードの設定方法がわからない方はこちらの記事(詳細は5章)で解説しています)

2.ローカルサーバーにあるファイルを編集

「C:\xampp\htdocs\phptest」フォルダに「test.php」ファイルを新規作成。
そのファイルに以下のコードを記述します。

&lt;?php
require_once 'SplClassLoader.php';

$classloaderTest = new SplClassLoader('Test', __DIR__);
$classloaderTest-&gt;register();

$obj = new Test\Call();
echo $obj-&gt;SayHello();

この「test.php」では、「Test」ベンダーの呼び出しと「Test\Clas」クラスの「SayHello」関数を呼び出します。
文字コードは「UTF-8(BOMなし)」、改行コードは「LF」で保存します。

「C:\xampp\htdocs\phptest」フォルダに「Test」フォルダを新規作成。
「C:\xampp\htdocs\phptest\Test」フォルダに移動して、「Call.php」を新規作成。
そのファイルに以下のコードを記述します。

&lt;?php
namespace Test;

class Call
{
    public function SayHello()
    {
        return 'Hello';
    }
}

この「Call.php」では、「Test」ベンダー中で「Call」クラスを定義し、「SayHello」関数をpublic(外でも呼び出せる)に設定します。
文字コードは「UTF-8(BOMなし)」、改行コードは「LF」で保存します。

「SayHello」関数が正常に呼び出されれば「Hello」と表示されます。

3.テストしてみる

XAMPPからApache(サーバー)を開始します。
(紹介しているPHP記述法はPHP5.3以上でないと動かないようです。PHP5.3未満の方は自宅サーバーの作り方を参考にしてください)
「http://localhost/phptest/test.php」にアクセスします。

「Hello」と表示されれば完了です。
表示されない場合はもう1度見直してください。

4.関数を追加してみる

「C:\xampp\htdocs\phptest\test.php」に以下のコードを追加します。

echo $obj-&gt;SayGoodBye(); // GoodByeを追加

「C:\xampp\htdocs\phptest\Test\Call.php」の「Call」クラス内に以下の関数を追加します

    public function SayGoodBye()
    {
        return '?GoodBye';
    }

「http://localhost/phptest/test.php」にアクセスします。

「Hello?GoodBye」と表示されます。

役割としては、赤が「SayHello」、青が「SayGoodBye」関数に分割されています。
Hello?GoodBye

いろいろと試してみてください。
変数とか定数はどうなの?という方は40分濃縮 PHP classの教室で解説されています。
今回は以上で終了します。

次の記事

次は、「PSRの規則をまとめてみる」を行います。
PHPのコーディング規則、PSRを学ぶ(5)へ

参考

40分濃縮 PHP classの教室

PHPのコーディング規則、PSRを学ぶ(3)

PHPのコーディング規則、PSRを学ぶ(2)の続きです。
今回はPSR-0, 1, 2を日本語に翻訳してみましたさんのPSR-0(日本語)を読んでみます。

1.本文の冒頭を読んでみる

以下、オートローダー連携のための要件を説明します。

必須要件

  • 完全な名前空間とクラス名のために下記構造としてください。\<ベンダー名>\(<名前空間>\)*<クラス名>
  • いずれの名前空間もトップレベルの名前空間である「ベンダー名」を持つ必要があります。
  • 名前空間は複数の自由な名前空間を持つことができます。
  • 名前空間の区切りは読み込まれる際に、「DIRECTORY_SEPARATOR」に変換されます。
  • クラス名に含まれるアンダースコア「_」は、「DIRECTORY_SEPARATOR」に変換されます。アンダースコアは特別な意味を持ちません。
  • 名前空間とクラス名に「.php」をつけて完全なファイルとなり読み込まれます。
  • ベンダー名、名前空間及びクラス名のアルファベット文字列における小文字・大文字の組み合わせは自由です。
  • 2.冒頭を読んでみて考えてみる

    疑問点1:「ベンダー名って何?」

    IT業界では、ハードウェアや・ソフトウェアの供給元企業を「ITベンダー」と呼ぶ。対義語は「ユーザー企業」。(Wikipediaより)

    つまり、個人製作の場合「自分の名前またはサイト名」をベンダー名として付ければいいのか。

    なぜこういうことをするのか?を考えてみると・・・
    PHPは同じ名前の関数やクラス名を指定すると「二重定義」でエラーが出ます。その防止策でしょう。これが「名前空間の汚染」防止なのかもしれません。

    疑問点2:「名前空間って何?」

  • 名前空間は複数の自由な名前空間を持つことができます。
  • 見た感じ、機能の名前を付けていい感じですね。

    もう少し読み進めてみると・・・

    例

    \Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
    \Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php
    \Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php
    \Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php

    なるほど!

    「\Zend\Mail\Message」のクラス名を分解してみると、
    「Zend」という製品の
    「Mail」機構の
    「Message」機能
    というわけですね。

    それを、「~/Zend/Mail/Message.php」から読み込むようにしなさいと。
    それなら誰でもどこから読んでいるか理解できるし。

    あと、「\Zend\Acl」のように機構を分けなくてもいいくらい短ければ、「~/Zend/Acl.php」から読み込むようにしなさいと。

    疑問点3:「DIRECTORY_SEPARATORって何?」

  • 名前空間の区切りは読み込まれる際に、「DIRECTORY_SEPARATOR」に変換されます。
  • クラス名に含まれるアンダースコア「_」は、「DIRECTORY_SEPARATOR」に変換されます。アンダースコアは特別な意味を持ちません。
  • 直訳すると「DIRECTORY_SEPARATOR」=ディレクトリの区切り・・・これでなんとなくわかったような気がします。

    さらに少し読み進めてみると、

    名前空間及びクラス名におけるアンダースコアの扱い

    \namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php
    \namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php

    つまり、
    ・「\<ベンダー名>\(<名前空間>\)*<クラス名>」の構成で、ディレクトリが区切られる
    ・クラス名のアンダースコア「_」はディレクトリの区切りになる
    ・名前空間の中のアンダースコア「_」はディレクトリの区切りにはならない
    3つのことが示されているわけですね!

    私のサイトとこの記事で言い換えると、「\Rei-Farms(ベンダー名)\BLOG(名前空間)\Web製作_PSRの説明(クラス名)」とクラス名を設定して、ファイルは「/Rei-Farms/BLOG/Web製作/PSRの説明」にあると。

    それだったら他人のコードを読んでいても混乱する可能性が非常に低くなりますね。

    3.最後まで読み進めてみる

    ここでは余計な混乱を防ぐための最低限のオートローダー連携基準を示します。 下記のPHP 5.3上におけるSplClassLoader実装例により、これらの基準を確認することができます。

    実装例

    以下は、上記基準に従ったクラスのオートロードにおける振る舞いを確認するための例です。

    SplClassLoader実装について

    以下のgistで、上記のオートローダー互換運用を満たした上で実装クラスがロードされるというSplClassLoaderの簡単な実装例を示します。 基準を満たしたうえで、PHP 5.3クラスをロードするための推奨方法となります。
    http://gist.github.com/221634

    「これまでの基準(上記)に適合したクラス設定をしても大丈夫な”クラス名ローダー”を作ってね」というわけですね。

    「http://gist.github.com/221634」に推奨の方法があるよとも書かれています。

    4.「http://gist.github.com/221634」にアクセスする

    Loader
    OK!英語だ!/(^o^)\
    英語が苦手だとどうしても読むのをためらいますよね。
    ですが、重要なことは先頭付近に書いてあることが多いです。

    重要そうなところを抜粋してみます。
    直訳
    “Doctrine Commonパッケージ”の”Doctrine\Commone”のクラスをロードする例。

    // Example which loads classes for the Doctrine Common package in the Doctrine\Common namespace.
    $classLoader = new SplClassLoader(‘Doctrine\Common’, ‘/path/to/doctrine’);
    $classLoader->register();

    上記のように、このSplClassLoader.phpのクラスSplClassLoaderを使えばこの基準通りにクラス名が設定できるというわけですね。

    これは試してみるしかない!と思いましたが、そろそろ長くなってきているのでこれにて終了します。

    次の記事

    次は、実際に「クラス名定義を自宅サーバーで試してみる」を行います。
    PHPのコーディング規則、PSRを学ぶ(4)へ

    参考

    PHPのコーディング規約 PSR-0、PSR-1、PSR-2、PSR-3とは
    PSR-0 を和訳してみた
    5分で分かる名前空間とオートロード

    PHPのコーディング規則、PSRを学ぶ(2)

    PHPのコーディング規則、PSRを学ぶ(1)の続きです。
    今回は基本中の基本、文字コードと改行コードを設定します。

    自宅サーバーで試します。(自宅サーバーの作り方はこちら)
    そのための基本設定も行います。

    1.「php.ini」の編集(開発者モードへ変更)

    「C:\xampp\php」フォルダにある「php.ini」をテキストエディタで開きます。

    「php.ini」の535行目(error_reporting)を以下のコードに変更し、保存します。

    error_reporting=E_ALL
    

    これで全てのエラーが表示されるようになります。

    2.自宅サーバーを起動する

    「XAMPP」を起動します。
    XAMPPの項目の「Apache」の「Start」をクリックして自宅サーバーを起動します。

    3.テスト用フォルダ「phptest」の作成

    デフォルトでは「C:\xampp\htdocs」が自宅サーバーのルートアドレス(http://localhost/)です。
    そこに「phptest」フォルダを作成します。

    4.PHPを書いてみる

    「phptest」フォルダに移動し、「test.php」ファイルを作成します。
    「test.php」をテキストエディタで開きます。

    以下のコードをコピー&ペーストします。

    <?php
    namespace Vendor\Package;
    
    class ClassName
    {
        public function fooBarBaz($arg1, &$arg2, $arg3 = [])
        {
            // method body
        }
    }
    

    注意する点としては以下の通りです。
    ・開始は必ず「<?php」から行い、ファイルがPHPのみの場合最後の「?>」は必要なし
    ・字下げは「半角スペース4つ」でタブを使わない
    ・括弧の前後にスペースは入れない。波括弧は独立した行に。引数のカンマの後に空白を(改行して書く書き方もあり)。
    ・PHPファイルの改行はLF(Unixフォーマット)で。←これがよくわからないので、次の章で説明します。
    ・文字コードは「UTF-8のBOMなし」を使う
    (【php】いまどきのPHPコーディング規約 PSRより)

    5.PHPの改行をLF(Unix)フォーマットに変更 & 文字コードを「UTF-8のBOMなし」に変更

    Windowsでは1つの改行を「CR+LF(\r\n)」で表し、Macでは「CR(\r)」、Unixでは「LF(\n)」と表します。
    統一しないとまずいのでUnixのLF(\n)が選ばれたようです。

    1.Notepad++の場合
    上部メニューの「編集」から「改行コードを変更」を選択。
    Unixフォーマット(LF)に変換をクリック。
    上部メニューの「エンコード」から「UTF-8(BOMなし)に変換」をクリック。
    ファイルを保存。

    2.TeraPadの場合
    上部メニューの「ファイル」から「文字/改行コード指定保存」をクリック。
    改行コードを「LF」、文字コードを「UTF-8N」にして上書き保存にチェックし「OK」をクリック。

    まとめ

    今回は文字コードや改行コードなどを設定しました。
    基本中の基本ですが、それをやっておかないと後々苦労します。
    (今現在私がその状況に陥っていますorz)
    少しずつですが頑張っていきましょう!

    次の記事

    PHPのコーディング規則、PSRを学ぶ(3)へ

    参考

    改行コードの話

    PHPのコーディング規則、PSRを学ぶ(1)

    PHPはかなり自由に書けることが魅力なのですが「自由に書ける」=「独自化する」=「その人以外わからない」等式が成り立ってしまいます。

    これは困った。

    つまり、コーディング(コードの書き方)の一般的な規則があれば、「誰が書いたコードでも簡単に読める」素晴らしい効果が得られます。

    この記事のねらい

    「でも、初心者だしよく語句がわからん」という方のために書きます。

    私も初心者なので、いろいろとわからないことがあります。
    つまり、自分のために書きます。/(^o^)\

    個人的に「名前空間の汚染って何?」「PHPの今風の書き方ってどうするの?」など多くの疑問がありました。加えて、新標準PSRに学ぶきれいなPHPの19ページ、「名前空間はベンダー名から必ず始める」「名前空間の区切りはディレクトリ階層になる」・・・なんとなく意味がわかるのですが、固有名詞の「ベンダー名」「名前空間の区切り」がわかりません。
    ということで、この「PSRを学ぶ」には自分がわかりにくいと感じた所、わからなかった所には詳細な解説をします。

    次の記事

    PHPのコーディング規則、PSRを学ぶ(2)

    参考にさせていただくページ

    (2013/11/11 18:14訂正しました)
    PHP-FIG
    新標準PSRに学ぶきれいなPHP
    PSR-0, 1, 2を日本語に翻訳してみました
    【php】いまどきのPHPコーディング規約 PSR

    独自ドメイン取得

    ねんがんの どくじどめいんを しゅとくしたぞ!( ^^)

    「http://rei-farms.jp/」を独自ドメインとして取得しました。
    ブログは「http://rei-farms.jp/webmaking/」からも読めるようになります。
    ミニ四駆系は「http://mini4wd.rei-farms.jp/」に格納。

    記念に、わかりにくかったブログ名を「R@schticks.」から「Rの考え方」に変更しました。
    “独自ドメイン取得” の続きを読む

    JavaScriptで特定地域にターゲット広告を表示

    javascript-
    ある特定の都道府県だけ表示したい広告を作ったので、そのコードを公開します!

    1.Google AJAX APIを読み込み

    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    

    外部JavaScriptファイルを読み込みます。

    2.広告リンクの設定

    JavaScriptで以下のように記述します。

    (function(){
      // Google AJAX APIで都道府県を取得し、your_regionに格納
      var your_region=google.loader.ClientLocation.address.region;
      //リンク設定
      links = new Array
      links[0] = 'リンク0';
      //地域設定(links[n]と連動)
      regions = new Array
      regions[0] = new Array('長崎県','佐賀県','福岡県','熊本県','大分県');
      //表示する広告を選択
      select = new Array;
      select_i = 0
      for(i=0;i<regions.length;i++){
        if(regions[i].indexOf(your_region)!=-1){
          select[select_i]=links[i];
          select_i++;
        }
      } //表示
      if(select_i>0){
        var number = select.length;
        var number2 = Math.random();
        var random = Math.round( (number-1) * number2);
        document.write(select[random]);
      }
    })();
    

    3.解説

    リンク0(links[0])は、長崎県付近の方のみ表示されるように設定されています。

    これを応用すると、長崎県なら長崎・佐賀・福岡・熊本・大分に表示、熊本県なら・・・というのを全て設定しておきます。そうすると有効に広告が出せるんじゃないでしょうか?

    PHPで祝日判定

    elephpants-side
    PHP 祝日判定で検索すると、「GoogleカレンダーAPIで祝日を取得する」ばかりです。
    しかし、GoogleカレンダーAPIは抜け落ちている祝日が存在することが知られています。

    今回は、抜け落ちが無いようなコードをお伝えします。すごく原始的なやり方です。

    1.「$holidays」に休日を格納

    無名関数を使用しているため、動作環境はPHP5.3以上が必要です

    $holidays = function(){
    	$holidays = array();
    	$file_array = file(&quot;./holiday.log&quot;);
    	for($i=0;$i&lt;count($file_array);$i++){
    		if($file_array[$i]){
    			$file_array[$i] = str_replace(array(&quot;\r\n&quot;,&quot;\r&quot;,&quot;\n&quot;),'',$file_array[$i]);
    			$val = explode(',',$file_array[$i]);
    			$holidays[&quot;$val[1]&quot;] = $val[0];
    		}
    	}
    	return $holidays;
    };
    

    2.祝日用ファイル「holiday.log」を設定

    以下のデータを「holiday.log」にコピーして保存。

    3.判定

    配列「$holidays」の中に全て格納されています。
    keyの形式は「year/month/day」(例:2013/1/1)であり、
    valの出力は「祝日名」(例:$holidays[“2013/1/1”]で「元旦」)となっています。

    4.祝日法が変わった場合には

    祝日についてのトップページの少し下にある、祝日一覧に、入手したい年を記入して「Outlook祝日更新」をクリックします。

    そうすると新しいウィンドウが出てくるので、下の方にある【 *~*年 Outlook 祝日更新データ 】を確認してください。

    以下のようなデータが出てくると思います。(例:2013~2015年)

    一番上の[日本] 51だけを外したデータを「holiday.log」にコピー&ペーストします。

    そして、アップロードすると完了です。

    5.注意点

    異常なデータを削除する機能は付いていませんのでご注意ください。

    ユーザーのフォントを統一できる、Google Fontsの紹介

    131664241abb6e24fe0a685346ae6726
    Web制作で困ることが多いのは「ユーザー全員が使えるフォントがない」ことでしょう。
    ユーザーのパソコンに入っているフォントによって見え方が異なるためです。
    つまり「見え方が統一できない」ことが多いです。

    それを解決するために、Google Fontsを使います。

    使い方

    トップページ(上図)から、使いたいフォントを「Add to Collection」で追加。
    右下に「USE」が出てくるのでそれをクリック。
    6f5ac8c355603d74886ec113a21225c6

    1. Choose the styles you want: ・・・使いたいスタイルを選択

    2. Choose the character sets you want: ・・・使いたい文字設定を選択
    が出てきます。基本的に触らなくてOK。

    3. Add this code to your website: ・・・コードを入れたいページに貼り付け
    例:<link href=’http://fonts.googleapis.com/css?family=Molle:400italic’ rel=’stylesheet’ type=’text/css’>

    4. Integrate the fonts into your CSS: ・・・導入したいところにCSSで記述
    例:<font style=”font-family: ‘Molle’, cursive;”>test</font>
    例2:CSS設定の中に
    .font{font-family: ‘Molle’, cursive;}

    まとめ

    これで導入したページ内なら、このフォントがだれでも見れるようになります!

    ミニ四駆ブログまとめ RSS読み込み速度の改善

    更新時、非常に重い思いをしていたRSS読み込み速度が改善されました。
    読み込み時間が約1/3くらいになったと思います。

    わかったブログ – 複数のRSSフィードを高速でまとめる方法を参考にしました。ありがとうございました。( ^^)