バカンス駆動開発

この前バカンスって言ったら「古っ」って言われました

PHPのサブクラスでコンストラクタを書くときにはまった話

PHPでサブクラス内でコンストラクタを書くときの注意点はマニュアルに書いてあります。まずはそちらを引用。

PHP: コンストラクタとデストラクタ - Manual

注意: 子クラスがコンストラクタを有している場合、親クラスのコンストラクタが 暗黙の内にコールされることはありません。 親クラスのコンストラクタを実行するには、子クラスのコンストラクタの 中で parent::__construct() をコールすることが 必要です。 子クラスでコンストラクタを定義していない場合は、親クラスのコンストラクタを継承します (ただし、private 宣言されている場合は除く)。 これは、通常のクラスメソッドと同様です。

<?php
class BaseClass {
   function __construct() {
       print "In BaseClass constructor\n";
   }
}

class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();
       print "In SubClass constructor\n";
   }
}

はまったコード

<?php
class BaseClass {
   function __construct($value) {  //インスタンス時に引数を取る
       print "In BaseClass constructor\n";
   }
}

class SubClass extends BaseClass {
   function __construct() {
      //空っぽ
   }
}

PHPマニュアルと変わった所はコメント部分の箇所、親クラスのコンストラクタが引数を取るところと、子クラスのコンストラクタが空っぽというところ。

なんで子クラスのコンストラクタが空っぽなのかというと、なんか入れようとして放置してただけなんですが、そのせいでえらい目に会いました。ありがとうございました。

空にしてるから何も影響しないと思ってました。そう思うことは自然の摂理だと思います。でもわざわざ(空とはいえ)コンストラクタを定義してしまっているので親クラスのコンストラクタがオーバーライドされてしまったという話でした。

コンストラクタもオーバーライドされるとは盲点だったぜ。

web開発のためのapacheやコンテンツディレクトリのパーミッション関連まとめ

apacheを安全に動かすために

// apacheの設定ファイル内にapacheの実行ユーザーを
// 指定している項目があるのでそれを確認
 
# vi /etc/httpd/conf/httpd.conf

// apacheの実行ユーザーをapache:apacheに指定
User apache
Group apache

// httpdを再起動
# /etc/rc.d/init.d/httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]

// コンテンツディレクトリの所有者と所有グループをapacheにする
// chownの-Rオプションは指定ディレクトリ以下の全てのディレクトリとファイルを含める
# chown -R apache:apache /home/httpd/html

// 今後コンテンツディレクトリ以下に作成されるファイルの所有グループをapacheに固定する
// 方法としてはSGIDを仕様する。SGIDについては参考の3を見てね。
# chmod -R 2770 /home/httpd/html/

// コンテンツディレクトリ以下のディレクトリのパーミッションを770、
// ファイルのパーミッションを660にしてその他のユーザーがアクセス出来ないようにする
# find /home/httpd/html -type d -exec chmod 770 {} \;
# find /home/httpd/html -type f -exec chmod 660 {} \;

// 最後にweb開発用ユーザー(webdev)をapacheグループに入れる
// 以後、wevdevユーザーを使って開発を行う
# usermod -g apache webdev

ファイルをアップロードするスクリプトを使用する場合、 ファイルの保存場所の所有者をapache、所有グループをapacheにする。

# chown apache:apache /var/uploads
# chmod 755 /var/uploads

httpdの実行ユーザーを独自に作成して(上記ではapache)、web公開のために必要なディレクトリやファイル以外へのapacheの権限をきちんと制限することで、悪意のスクリプトが放り込まれてもwebサーバーの権限を絞っているので被害を抑えれる可能性が増します。

参考

  1. httpd.conf の設定
  2. Apacheのセキュリティ
  3. SGID(Set Group ID) - 特殊なアクセス権

MySQL脱初心者に向けてのまとめ

パーフェクトPHPフレームワークを読解し終わりました。 途中にSQL文で「JOIN」とかテーブル作成時のインデックスとか出て来てわからなかったので、MySQLについてまとめました。

まぁまずは初心者へ

MySQL入門 (全19回) - プログラミングならドットインストール

おなじみのドットインストールです。データベースやテーブルの生成削除、データの挿入、削除等基本的なことを学習。 見てるだけでいい。それがすばらしい。

脱初心者になるために

SELECTやWHEREやAND/ORはわかった。次はどうすればいいの?という人(というか自分)へ。

インデックスって何?必要?

MySQL Index勉強会外部公開用

インデックスについても詳しいけれど、MySQLってこんなシステムなんだよ、というのがとても良くわかります。すばらしい。

MySQLのインデックス - Archiva

漢(オトコ)のコンピュータ道: オトコのソートテクニック2008

さー自分で複合インデックスを作ってみよう!という時はこの二つの記事がとても参考になります。すばらしいですね。

JOIN LEFTって?

SQL講座 LEFT JOIN とRIGHT JOIN(表の外部結合)

このサイトは他にもSQLの扱い方が書かれています。

Tips的な

MySQL :: MySQL 5.1 リファレンスマニュアル

公式リファレンス。

MySQLノウハウ

チューニングTips。この通りにする、というよりこれを目次に一つ一つ調べたらいいと思う。

SQLアンチパターン - ジェイウォーク

SQLアンチパターン - ナイーブツリー

アンチパターンの提示は初心者にはありがたいです。

他には?

あとはトランザクション、デットロックあたりを学習すればとりあえず脱初心者でしょうか。

おまけ

信じられないDB文化「Join禁止」に「固定長DB」、、でも、合うんです。大規模コンシューマ向けサービスのRDB設計 - 山本大@クロノスの日記

世の中にはJOIN禁止文化なんてのもあるようです。要はちゃんと考えてやりましょうってことですね。

PHPでクラスをspl_autoload_registerを使ってオートロードする

PHPインスタンスを生成する際はその対象となるクラスが実装されたファイルがあらかじめ読み込まれてなければなりません。

<?php
require 'someClass.class.php';

$instance = new someClass;

ですが、生成するインスタンスが多くなるとその分たくさんrequireしないといけません。 またファイルごとにどのクラスファイルを読み込むかチェックするのも面倒です。 なので、インスタンスを生成時に必要なクラスファイルを自動で読み込む仕組み、オートロードというやり方を使います。

__autoload()について

__autoload()とは、インスタンス生成時に対象となるクラスが読み込まれていない時に呼ばれる関数 です。呼び出し時にそのクラス名を引数として与えます。__autoloadの使い方としては、その引数(=クラス名)をもとにクラスファイルを読み込むメソッドを実装するようにします。

<?php
function __autoload($className)
{
    //渡された引数(=クラス名)をもとにクラスファイルのフルパスを定義
    $file = '/path/' . '/' . $className . '.php';  
    require $file;
}

上記の様な使い方をするので、原則としてクラスファイルの作成にあたって以下の条件が要求されます。

  • 一つのクラスにつきクラスファイルを作成
  • クラス名とクラスファイル名は同じにする

しかし、読み込むライブラリによってクラス名とクラスファイル名の関係がばらばらだったりします。__autoload()は一つしか定義できませんが、spl_autoload_register()を使えば複数の関数を__autoload()にスタックすることが出来ます。

spl_autoload_register()について

spl_autoload_register()は__autoload()が呼ばれた時に実行する関数を定義する関数です。spl_autoload_register()を使う事で、クラス名とクラスファイル名の対応の仕方が違う複数のライブラリを使用する場合に対応できます。 とは言ったものの今回は1パターンの関数だけを__autoload()にスタックします。

<?php

class AutoLoader
{
    /*
        オートローダーが探しにいくディレクトリ
    */
    protected $dirs;

    /*
        __autoload()の実装として、下記のautoLoad()を登録する
    */
    public function register()
    {
        spl_autoload_register(array($this, 'autoLoad'));
    }

    /*
        探索ディレクトリを登録するメソッド
    */
    public function registerDir($dir)
    {
        $this->dirs[] = $dir;
    }

    /*
        autoloadはインスタンス生成時に呼ばれるがそのとき対象となるクラス名を引数として引き受ける
    */
    public function autoLoad($className)
    {
        foreach ($this->dirs as $dir) {
            $file = $dir . '/' . $className . '.php';
            if (is_readable($file)) {
                require $file;

                return;
            }
        }
    }
}

下記の用に使う

<?php

require 'AutoLoader.php';

$autoLoader = new AutoLoader();
$autoLoader->registerDir(dirname(__FILE__). '/directory');   //directoryをサーチ対象として登録
$autoLoader->register();    //

参考

PHP5.1.2以降のspl_autoload_registerを使う | AkisiのWEB制作日記

柿の種が降ってきてあわててミドリゾウリムシを持って逃げる防空頭巾姿の白い生き物がクラスの定義ファイルを読み込む手段に spl_autoload_register() をお勧めする7つの理由。 - 親方、空から覚え書きが!

VagrantとVirtualboxのバージョンについて

Vagrantの使い方についてはこちらの記事がとてもわかりやすいです。

Vagrant で自分の PC に「作って、壊して、元に戻せる」サーバを作る - Shin x blog

記事にそってVagrantを使ってVirtualbox上に仮想サーバーを作る際に、各々のバージョンに気をつけないといけません。

記事内ではsaharaという便利なVagrantプラグインを使うためにバージョンを1.0.xにすると説明してありますが、このバージョンに対応しているVirtualboxは4.0.xか4.1.xか4.2.xなので、ここから一番新しい4.2.18をインストールします。

Download_Old_Builds_4_2 – Oracle VM VirtualBox

2013年11月16日現在Virtualboxの最新バージョンは「4.3.2」。なのでトップページから拾ってくると途中でエラー吐きます。

chefというものを使うと、ほんとにボタン一発で様々な環境を構築できるようです。

今っぽい Vagrant + Chef Solo チュートリアル - Qiita [キータ]

ちなみにVagrantについて入門ガイドが出版されています。電子ブックです。400円とリーズナブル。

Vagrantをはじめてみたい方へ「Vagrant入門ガイド」を書きました - Shin x blog