PHP

PHP軽量フレームワークLimonade 1

setup

Limonade
githubからソースダウンロードして、ドキュメントルートに配置。
いつものように、バーチャルホストを設定してexamplesを試してみる。

hostsファイル設定

127.0.0.1       test.limonade.com

vhost

#test.limonade.com
<VirtualHost *:80>
	DocumentRoot "/home/limonade/public_html"
	ServerName test.limonade.com
	<Directory "/home/limonade/public_html">
		AllowOverride All
		order deny,allow
		allow from All
	</Directory>
</VirtualHost> 

ダウンロードしたファイルを”/home/limonade/public_html”にコピー。

ブラウザから確認

http://test.limonade.com/examples

WEBアプリケーション開発

とりあえず分かった事。
MVCのフレームワークでモデルは別途抽象化するライブラリ使う。

Controllerにあたる部分では

  • /lib/limonade.phpをrequire
  • configureで設定
  • beforeでdispatchする前の事前処理記述
  • dispatchでurlと関数のマッピング
  • dispatch('/', 'hello_world');
    function hello_world () {
        return "Hello world!";
    }
    

有る程度サンプル見れば分かるけど、実際にサイト作成するとなるとsinatra系のフレームワークは初めてなので少し大変そう。
あと、日本語のドキュメント少ないので自分サイトをまず作ってなれるようにしたい。

CakePHPでktai libraryを使う

構成

いつもの通りバーチャルホストでテスト。

hosts

127.0.0.1       test.sample.com

vhost

#test.sample.com
<VirtualHost *:80>
    DocumentRoot "/home/sample/public_html"
    ServerName test.sample.com
    <Directory "/home/sample/public_html">
        AllowOverride All
        order deny,allow
        allow from All
    </Directory>
</VirtualHost>

ディレクトリ

http://sample.com/ ← ユーザー
http://sample.com/admin ← 管理画面
http://sample.com/mobile ← モバイル
と分けたい。

/home/sample/
		cake_core ← [vendors、cake、plugins]
		public_html ← [appのwebrootをコピー]
		cake_app ← [appをコピーしてuser,admin,mobileにリネーム]

index.phpの変更

public_html/index.php

/**
 * These defines should only be edited if you have cake installed in
 * a directory layout other than the way it is distributed.
 * When using custom settings be sure to use the DS and do not add a trailing DS.
 */
    if (PHP_OS == "WIN32" || PHP_OS == "WINNT") {
        define('C', 'C:');
    } else {
        define('C', '');
    }
/**
 * The full path to the directory which holds "app", WITHOUT a trailing DS.
 *
 */
	if (!defined('ROOT')) {
		//define('ROOT', dirname(dirname(dirname(__FILE__))));
		define('ROOT', C.DS.'home'.DS.'sample'.DS.'cake_app');
	}
/**
 * The actual directory name for the "app".
 *
 */
	if (!defined('APP_DIR')) {
		//define('APP_DIR', basename(dirname(dirname(__FILE__))));
		define ('APP_DIR', 'user');
	}
/**
 * The absolute path to the "cake" directory, WITHOUT a trailing DS.
 *
 */
	if (!defined('CAKE_CORE_INCLUDE_PATH')) {
		//define('CAKE_CORE_INCLUDE_PATH', ROOT);
		define('CAKE_CORE_INCLUDE_PATH', C.DS.'home'.DS.'sample'.DS.'cake_core');
	}

public_html/mobile/index.phpは[APP_DIR]を’mobile’に変更

Ktai Libraryをコピー

githubからパッケージをダウンロードしてappディレクトリをmobileにコピー。
Ktai Library本体をmobile/vendorsにコピー。

routes.php

Router::connectNamed(array(), array('argSeparator' => '~'));

ktai_app_controller.php

ktai_app_controller.phpをapp_controller.phpにリネームする。

$ktaiプロパティの追加

今回は各コントローラーに追加。
ソースファイルは全て、UTF-8で作成しcharset=Shift-JISとして出力とした。

    var $ktai = array(
        'input_encoding'            => 'UTF-8',
        'output_encoding'           => 'SJIS-win',
        'use_binary_emoji'          => true,
        'output_auto_convert_emoji' => true,
        'output_auto_encoding'      => true,
        //'output_convert_kana'       => 'knrs',
        'output_convert_kana'       => 's',
        //'use_xml'                   => true,
    );

shift-jisでデータがサブミットされるので、

    function beforeFilter () {
        parent::beforeFilter();
        mb_convert_variables("UTF-8", "SJIS-Win", $this->data);
    }

とした。

また、フォームの「accept-charset」はApp.encodingの値が設定されるので

<?php echo $this->Form->create('Regist', array('encoding' => 'shift-jis'));?>

とする。

最後に

app_error.phpでエラー処理しているのですが、Ktaiコンポーネントのshutdownメソッドが呼ばれずshift-jisで出力できないので、エラーページだけshift-jisで対応しました。

Snow Leopard に PHP5.3 の環境に PHP4.4.9 をインストール

普段は迷わずPHP5.3使うのですが、今やってるサイトがPHP4なのでインストールしたときのログを残しておきます。

前提

  • PHPはシステムにもともと入ってるPHP5.3(portsでインストールしたものでない)
  • ApacheはportsでインストールしたApache2.2
  • どのようにするか

    PHP4はソースからインストールする。makeしてできるApahceのモジュールのMIMEタイプを『application/x-h-httpd-php4』で作成する。バーチャルホストの設定でPHP4で動くようにする。

    make準備

    [suusuke@macbook ~]$ curl -o php-4.x.tar.gz -L http://jp2.php.net/get/php-4.4.9.tar.gz/from/this/mirror
    [suusuke@macbook ~]$ tar zxvf php-4.x.tar.gz
    [suusuke@macbook ~]$ cd php-4.4.49
    

    sapi/apache2handler/sapi_apache2.cを変更する。

    #define PHP_MAGIC_TYPE "application/x-httpd-php"
    

    #define PHP_MAGIC_TYPE "application/x-httpd-php4"
    

    configure

    とりあえず最低限、必要そうなものをオプションに追加しました。
    また、Snow Leopardでconfigureする時はlresolvを有効にする必要があるようなので、『EXTRA_LIBS=-lresolv』で指定する。

    [suusuke@macbook ~]$ EXTRA_LIBS=-lresolv \ 
     ./configure --prefix=/usr/local/lib/php-4.4.9 \
     --with-apxs2=/usr/sbin/apxs \
     --enable-mbstring \
     --with-pgsql=/opt/local/lib/postgresql83 \
     --with-pdo-pgsql=/opt/local/lib/postgresql83 \
     --with-mysql \
     --with-pdo \
     --with-gd \
     --with-png-dir=/opt/local \
     --with-jpeg-dir=/opt/local \
     --with-zlib-dir=/opt/local
    

    ないものは基本portでインストール。
    今回インストールしたのは

    [suusuke@macbook ~]$ sudo port install libpng
    [suusuke@macbook ~]$ sudo port install jpeg
    

    の二つ。

    MySQL、PostgreSQLのインストールについてはSnow Leopard に PostgreSQL インストールSnow Leopard に MySQL 再インストールを参照。

    make

    [suusuke@macbook ~]$ make
    [suusuke@macbook ~]$ sudo make install
    

    設定

    [suusuke@macbook ~]$ sudo cp php.ini-recommended /usr/local/lib/php-4.4.9/lib/php.ini
    

    PHP.iniのinclude_pathにPEARのパスを追加。。。したいところだったんだけど、PEARがインストールされない。。。
    とりあえず、PEARは未だにPEAR::DB使ってるんみたいなんで、手動で入れることに。

    aliasの設定

    ~/.bashrc

    alias php4=/usr/local/lib/php-4.4.9/bin/php
    

    反映

    [suusuke@macbook ~]$ source ~/.bashrc
    

    確認

    [suusuke@macbook ~]$ php4 -v
    PHP 4.4.9 (cli) (built: Mar 26 2011 10:08:22)
    Copyright (c) 1997-2008 The PHP Group
    Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
    

    バーチャルホストの設定

    # test.php5.info
    <VirtualHost *:80>
        DocumentRoot "/Library/WebServer/Documents/php5/public_html"
        ServerName test.php5.info
        <Directory "/Library/WebServer/Documents/php5/public_html">
            AllowOverride All
            order deny,allow
            allow from All
        </Directory>
    </VirtualHost>
    
    # test.php4.info
    <VirtualHost *:80>
        DocumentRoot "/Library/WebServer/Documents/php4/public_html"
        ServerName test.php4.info
        <Directory "/Library/WebServer/Documents/php4/public_html">
            AllowOverride All
            order deny,allow
            AddType application/x-httpd-php4 .php
            allow from All
        </Directory>
    </VirtualHost>
    

    phpinfo();で確認してみる。

    削除したいときは

    /usr/local/lib/php-4.4.9
    php-x.x.x/
          bin/ 	PHPコマンドなど
          etc/ 	pear設定ファイル
          include/ 	ヘッダファイルなど
          lib/php 	PEARライブラリディレクトリ
          man/ 	マニュアル
    
    /opt/local/apache2/modules/libphp4.so
    

    を削除するだけ。

    参考にさせてもらったサイト

    http://www.atmarkit.co.jp/fcoding/articles/macxphp/02/macxphp02a.html

    CakePHPのSecurity.levelまとめ

    まずは、Security.levelについて

    Security.level session.cookie_lifetime(セッションクッキーの有効期間) session.referer_check SESSION IS
    high 0(ブラウザを閉じるまで) $_SERVER[“HTTP_HOST”]; リクエストごとに作成される
    medium 7日間 $_SERVER[“HTTP_HOST”];
    low 25年間 なし

    session.cookie_lifetimeはセッションクッキーの有効期間なので、セッションタイムアウトは別に[core.php]の

    /**
     * 'high'	Session timeout in 'Session.timeout' x 10
     * 'medium'	Session timeout in 'Session.timeout' x 100
     * 'low'		Session timeout in 'Session.timeout' x 300
     */
    Configure::write('Session.timeout', '120');
    

    で指定する。(Security.levelの設定によって変わる)

    また、session.cookie_lifetimeの値はCakePHP 1.3 のもので、1.3.5だと

    if ($this->security == 'high') {
    	$this->cookieLifeTime = 0;
    } else {
    	$this->cookieLifeTime = Configure::read('Session.timeout') * (Security::inactiveMins() * 60);
    }
    

    Security::inactiveMins()は

    function inactiveMins() {
    	switch (Configure::read('Security.level')) {
    		case 'high':
    			return 10;
    		break;
    		case 'medium':
    			return 100;
    		break;
    		case 'low':
    		default:
    			return 300;
    			break;
    	}
    }
    

    なので、Session.timeoutに依存する。(デフォルトは120m)

    session.referer_checkとは

    session.referer_check には、HTTP Referer に おいて確認を行う文字列を指定します。Refererがクライアントにより 送信されており、かつ、指定した文字列が見付からない場合、埋め込 まれたセッションIDは無効となります。デフォルトは空の文字列です。 
    

    セッションハイジャックとかを防止するためには必要だと思う。

    どうしたいか

    • ブラウザ閉じたらセッションは削除したい(自動ログインの機能は別途作成)
    • session.referer_checkできれば有効にする

    ブラウザ閉じたらセッションは削除したい(自動ログインの機能は別途作成)

    Security.level = ‘high’ だと リクエストごとにSESSION ID が作られるので、それだと携帯サイトの場合、都合が悪い、SESSION IDはそのままで、ブラウザ閉じたらセッションは削除したい。

    /app/config/my_session.phpという設定ファイルを作成し、[core.php]に設定する。

    Configure::write('Session.save', 'my_session');
    

    my_session.phpは[cake_session.php]のcase ‘cake’:をコピーして

    if (empty($_SESSION)) {
    	if ($iniSet) {
    		ini_set('session.use_trans_sid', 0);
    		ini_set('url_rewriter.tags', '');
    		ini_set('session.serialize_handler', 'php');
    		ini_set('session.use_cookies', 1);
    		ini_set('session.name', Configure::read('Session.cookie'));
    		//ini_set('session.cookie_lifetime', $this->cookieLifeTime);
    		ini_set('session.cookie_lifetime', 0); // 変更
    		ini_set('session.cookie_path', $this->path);
    		ini_set('session.auto_start', 0);
    		ini_set('session.save_path', TMP . 'sessions');
    	}
    }
    

    session.cookie_lifetimeを’0’にして、ブラウザが閉じたらセッションを削除するようにする。

    session.referer_checkできれば有効にする

    Security.level は ’high’ or ‘medium’ にする。
    このチェックに引っ掛かるとセッションが消えてしまうので、WEBサービス何かと連携する時は’low’にした方が無難。
    ※proxyを使っててもリファラーチェックに引っ掛かる事が有った。

    ただ、セッションが切れないように作り方を変えれば良い場合も有るので、なるべくそっちで対応した方が良い。

    最後に

    今回は
    仮登録メール⇒メールに記載のURLクリック⇒(内部でリダイレクトして)プロフィールフォーム⇒登録完了
    という機能を作成していて、開発時のメールサーバーはRadishを使っていたので、問題無かったが本番にリリースした際(yahooメール等)、セッションが切れて登録出来ないという不具合が起きてしまった。
    その為、リダイレクトの必要は特に無かったので、リダイレクトをしないようにして事なきを得た。
    しかし、本番でもテストはしていたのだが、リリースしたのが結構前だった為、この現象が起きたかどうか覚えていない。
    ※普通にURLをコピーしてアドレスバーに貼り付けてテストしたのかも・・・

    色々ありましたが、勉強になりました。

    PHPのarray_mergeは良い

    array_margeは便利だと思う。

    $attributes = array(
        'var1' => 'aaa',
        'var3' => 'bbb',
    );
    $defaults = array(
        'var1' => null,
        'var2' => null,
        'var3' => '-',
        'var4' => '-',
        'var5' => '-',
    );
    $attributes = array_merge($defaults, $attributes);
    
    echo '<PRE>';
    print_r($attributes);
    echo '</PRE>';
    

    実行結果↓

    Array
    (
        [var1] => aaa
        [var2] => 
        [var3] => bbb
        [var4] => -
        [var5] => -
    )
    

    配列にデフォルト設定するとき良く使う。

    ちなみに、配列のキーの差分を取得するarray_diff_keyも便利です。

    $attributes = array(
        'var1' => 'aaa',
        'var3' => 'bbb',
        'var6' => 'ccc',
    );
    $defaults = array(
        'var1' => null,
        'var2' => null,
        'var3' => '-',
        'var4' => '-',
        'var5' => '-',
    );
    
    $attributes = array_diff_key($attributes, $defaults);
    
    echo '<PRE>';
    print_r($attributes);
    echo '</PRE>';
    

    実行結果↓

    Array
    (
        [var6] => ccc
    )
    

    PHPを使い始めてそろそろ1年・・・

    html_select_date のメモ

    {html_select_date prefix='' time=$date|default:'--' field_array=date field_order=YMD month_format='%m' end_year='+1' year_empty='' month_empty='' day_empty='' year_extra="id=y"|cat:$id month_extra="id=m"|cat:$id day_extra="id=d"|cat:$id}
    

    ServersMan@VPS契約

    仕事の方も余裕が出てきたのでServresManのVPSを契約してみました。

    http://dream.jp/vps/

    導入〜WordPress設定まで

    VPS、ドメイン契約

    VPSはServersManのスタンダードプランを契約して、ドメインはお名前.comで取得しました。

    スタンダードプランで固定IPが2つ使えるので、取り合えず一つはWordPress用(blog.suusuke.info)に割り当ててもう一つは勉強用(www.suusuke.info)に。

    お名前.comで「レンタルDNSレコード設定」、「ネームサーバーの変更」して無事ドメインでアクセスできるようになりました。

    サーバー初期設定

    1. ユーザー追加、パスワード設定
    2. ssh設定
    3. PHP、MySQLインストール
    4. バーチャルホスト設定

    ユーザー追加、パスワード設定

    管理ユーザー(suusuke)追加とパスワードの設定。

    useradd suusuke // ←管理ユーザー
    passwd suusuke // ←パスワード設定
    usermod -G wheel suusuke // ←whellに追加
    

    ssh設定

    昔はてなで書いた記事そのまま実行して設定

    http://d.hatena.ne.jp/suusuke/20080724/1216828604

    • rootでログイン禁止
    • パスワード認証禁止
    • 公開鍵と秘密鍵で認証

    あと、macだとOpenSSHなので秘密鍵をOpenSSH用にPuttyGenでコンバートして完了。

    PHP、MySQLインストール

    ネット探すと沢山情報が載ってるので参考に

    リポジトリ追加

    wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
    wget http://rpms.famillecollet.com/el5.i386/remi-release-5-7.el5.remi.noarch.rpm
    rpm -Uvh remi-release-5-7.el5.remi.noarch.rpm epel-release-5-3.noarch.rpm
    vi /etc/yum.repos.d/remi.repo
    # この行の下に priority=1 を追記
    failovermethod=priority
    priority=1
    

    PHP インストール

    yum --enablerepo=remi install php-devel php-mbstring php-mysql
    

    確認

    php -v
    
    
    phpinfo(); // ←phpinfoで環境確認
    
    

    MySQLインストール

    
    yum --enablerepo=remi info mysql-server // ←バージョン確認
    
    yum --enablerepo=remi install mysql-server // ←インストール
    
    

    MySQL設定

    
    vi /etc/my.cnf
    
    [mysql]
    
    default-character-set=utf8
    
    [mysqld]
    
    datadir=/var/lib/mysql
    
    socket=/var/lib/mysql/mysql.sock
    
    user=mysql
    
    symbolic-links=0
    
    default-character-set=utf8
    
    [mysqld_safe]
    
    log-error=/var/log/mysqld.log
    
    pid-file=/var/run/mysqld/mysqld.pid
    
    
    
    chkconfig mysqld on // ←自動起動する場合
    
    

    WordPress用にDB作成

    
    /etc/init.d/mysqld start // ←mysql起動
    mysql> delete from mysql.user where user = ''; // ←不要ユーザー削除
    
    mysql> update mysql.user set password=password('任意のパスワード') where user = 'root'; // ←rootパスワード設定
    mysql> create database wp; // ←WordPress用データベース作成
    mysql> grant all privileges on wp.* to blog@localhost identified by 'パスワード'; //←WordPress用にユーザー追加(blog)
    

    バーチャルホスト設定

    自分ルールとして公開するWEBサイトはサイト毎にユーザー(サーバーの)を追加して

    
    /home/[user名]/public_html/
    
    

    をバーチャルホストでドキュメントルートにする。

    バーチャルホストの設定ファイルは

    
    /etc/httpd/conf.d/
    
    

    にWEBサイト毎にファイルを作成する。

    
    useradd blog // ←WordPress用にユーザー追加
    
    passwd blog
    
    mkdir ~/public_html
    
    

    バーチャルホスト設定ファイルを作成する。

    
    vi /etc/httpd/conf.d/httpd-vhosts-blog.conf
    
    <VirtualHost *:80>
    ServerName blog.suusuke.info
    DocumentRoot /home/blog/public_html
    ErrorLog logs/blog.suusuke.info-error_log
    CustomLog logs/blog.suusuke.info-access_log combined env=!no_log
    <Directory "/home/blog/public_html">
    Options FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
    </Directory>
    </VirtualHost>
    
    

    hostsファイル追記

    
    vi /etc/hosts
    
    182.163.74.64 suusuke.info
    182.163.74.66 blog.suusuke.info
    
    

    WordPressのインストールはファイルダウンロードして、DBの設定ファイル書き換えてアップするだけ。

    これでOKだと思ったんだけど、上手く行かなかった。

    
    chown -R apache.apache /home/blog/
    
    

    WordPress用のディレクトリのオーナーをapacheに変更したら上手く行きました。

    (これやんなくても上手く行くと思ったんだけどな・・・)

    設定変更後はapache再起動。

    取り合えず、ブログ公開まで出来ました。

    でも、この記事書くのに3時間くらいかかった。(書いてる途中にWordPressのプラグイン探したりいろいろしすぎ!)

    やっぱり書くのは時間かかるです。