2018-10-28

phpbb掲示板を別サーバーに移行する

概要

オープンソースの掲示板phpbbをGMOのレンタルサーバーからさくらのレンタルサーバに移行した際の備忘録です。
※今回は、ほとんどの作業を各サービス(phpbb、さくら、お名前.com)が用意しているwebのUIから実行しています。

サーバー移行の理由:2012年頃に契約したGMOのレンタルサーバーを当時の料金のまま利用しており、サービス内容に対して割高になっていたため安価なサーバーに移行したい。
ついでにSSL対応したい。

結果:phpbb掲示板の移行は成功し、設置先のサーバーの月額料金を1700円から510円に削減できた。
SSL対応できた。

この記事の各見出し
  • さくらのレンタルサーバを契約
  • さくらのレンタルサーバにデータベースを作成
  • レンタルした新サーバにphpbbをインストール
  • phpbbバックアップファイルの取得と復元
  • 他社で管理中のドメインをサブドメインとして利用する
  • サブドメインのSSL証明書を発行
  • 旧サーバから新サーバへのリダイレクト設定
  • httpからhttpsへのリダイレクト設定

技術的な収穫
  • MySQLのみでUTF8との区別が行われる文字コードUTF8(utf8mb4)を知った。utf8mb4は4バイト文字を格納でき、絵文字に対応している。
  • ドメイン名とネームサーバの運用に触れることが出来た。
  • .htaccessのmod_rewriteを使ったリダイレクト設定

ここからは、実際の作業です。

さくらのレンタルサーバを契約

今回は自分で環境設定が必要なVPSではなく、既にPHPとDBMSがインストールされているレンタルサーバを契約しました。

さくらのレンタルサーバにデータベースを作成

サーバーコントロールパネルからログインします。
https://1.bp.blogspot.com/-TACEFKMwy3w/W9VxohB3wJI/AAAAAAAAHQM/6WbBjw9GXkkNqDlAZf9KnO5GYam52F7kgCLcBGAs/s1600/00_01.png
サーバーコントロールパネルから「データベースの設定」を選択します。
「データベースの新規作成」で、データベースバージョン、データベース ユーザー名、データベース名、接続用パスワードを入力し、データベース文字コードを選択します。絵文字を使用する場合はデーターベース文字コードはUTF8(utf8mb4)を選択します。

レンタルした新サーバにphpbbをインストール

phpbbの最新版をダウンロードし、解凍します。
WinSCPで新サーバに接続し、解凍したフォルダの中身を新サーバーの/home/(新サーバーのドメイン名)/www/phpbbにアップロードします。

「http://(新サーバーのドメイン名).sakura.ne.jp/phpbb/install」にアクセスし、phpbbのインストール画面から「INSTALL」タブを選択します。
「Install」ボタンをクリック後は、ナビゲーションにしたがってインストールしていきます。
Database configurationではさくらのサーバーコントロールパネルで設定した内容を入力します。
この画面が表示されると新サーバへのphpbbのインストールは終了です。
WinSCPで /home/(新サーバーのドメイン名)/www/phpbb/install フォルダを削除します。
「http://(新サーバーのドメイン名).sakura.ne.jp/phpbb/index.php」にアクセスすると、phpbbの最初のフォーラムが表示されます。

phpbbバックアップファイルの取得と復元

※旧サーバーのphpbbが最新バージョンでない場合は、バックアップファイル取得前にphpbbの最新版をダウンロードし、アップデートしておきます。phpbb3系のアップデート方法はこちら

旧サーバーのAdministration Control Panelからバックアップファイルをダウンロードします。
https://4.bp.blogspot.com/-qz8dTbBgp2Q/W9VyRS6z1nI/AAAAAAAAHRs/_CvUdop8H28blvf20vXPDeh5HwA5MAHgwCLcBGAs/s1600/21_%25E6%2597%25A7.png
WinSCPで /home/(新サーバーのドメイン名)/www/phpbb/sotreにバックアップファイルをアップロードします。

「http://(新サーバーのドメイン名).sakura.ne.jp/phpbb/index.php」の「Addministration Control Panel」リンクから管理人権限でログインします。
Addministration Control Panelで「MAINTENANCE」タブを選択します。

「MAINTENANCE」タブで画面左側の「DATABASE」メニューから「Restore」を選択します。

旧サーバのバックアップファイルが選択されている状態で、「Start restore」ボタンをクリックします。
確認画面で「Yes」ボタンをクリックします。
旧サーバのデータを使用した復元が終了しました。
「http://(新サーバーのドメイン名).sakura.ne.jp/phpbb/index.php」を表示すると、旧サーバのデータで復元されていることが確認できます。

他社で管理中のドメインをサブドメインとして利用する

今回は、「お名前.com」で管理しているドメインを「さくらのレンタルサーバ」のサブドメインとして使用します。
「お名前.com」の管理画面でサブドメインとして利用するドメイン名を選択します。
表示された画面の「ネームサーバー情報」領域で、「ネームサーバーの変更」をクリックします。
「ネームサーバーの選択」で「その他」タブを選択し、「ネームサーバー1」と「ネームサーバー2」にさくらのネームサーバー情報を設定し、確認ボタンをクリックします。
さくらのコントロールパネルのメニューで「ドメイン/SSL設定」をクリックします。
ドメイン一覧を表示し、「新しいドメインの追加」をクリックします。
「5.他者で取得したドメインを移管せずに使う」領域の「ドメインの追加へ進む」リンクをクリックします。
お名前.comで管理中のドメインを入力し、「送信する」ボタンをクリックします。
確認画面で「送信する」ボタンをクリックします。

サブドメインのSSL証明書を発行

サブドメインのSSL証明書の発行を行います。さくらのレンタルサーバで採用されている無料証明書はLet's Encryptです。
 https://2.bp.blogspot.com/-UyoVpUh7AMk/W9VyI9K4zsI/AAAAAAAAHRQ/irdeYSOd0Oo6BRwApd3J6AmCta6XgYG_QCLcBGAs/s1600/52_0_2.png
デフォルトの値で「送信」ボタンをクリックします。

旧サーバから新サーバへのリダイレクト設定

旧サーバphpbbのURL:http://(お名前.comで管理中のドメイン)/bbs
新サーバphpbbのURL:http://(お名前.comで管理中のドメイン)/phpbb

旧サーバと新サーバのphpbbのURLを比較すると、リダイレクト時に変換が必要な部分は、(お名前.comで管理中のドメイン)以下のディレクトリ名ですので、.httaccessに下記のように記載します。参考にしたのはこちらのサイトです。
RewriteEngine On
RewriteBase /
RewriteRule bbs/(.*) phpbb/$1 [R,L]

httpからhttpsへのリダイレクト設定

.httpaccessに下記を追記します。参考にしたのはこちらのサイトです。

RewriteEngine on
RewriteCond %{ENV:HTTPS} !on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]


.httaccessを新サーバの/home/(新サーバーのドメイン名)/www/phpbb/install にアップロードします。

終わりに

以上で作業は終了です。旧サーバーから新サーバーへのphpbbの移行とSSL対応が終了しました。 Let's Encryptについては、今回はUIからの証明書発行でしたが次はVPSでコンソールからコマンドを叩いて実行してみようと思います。

2018-04-15

遅延静的束縛について理解しよう

PHPで「static」というキーワードの使われ方は複数あります。
今日は、スコープ定義演算子(ダブルコロン::)とともに用いるstatic、つまり
遅延静的束縛の意味でのstaticについて見てみましょう。

この記事では、次のようにパートを分けています。
§1.PHPでのstaticキーワード
§2.スコープを表す方法

§1.PHPでのstaticキーワード

PHPにおいて、staticというキーワードの使い方には次の場合があります。
1.静的なメソッド・プロパティを定義するためのstatic
2.静的変数を定義するためのstatic
3.メソッドのスコープを定義するための遅延静的束縛の意味でのstatic

今日は3の遅延静的束縛の意味でのstaticを理解することが目的ですが、1と2についても触れておきましょう。

1-1.静的なメソッド・プロパティを定義するためのstatic

<?php
class Foo {
    public $aProperty = 'foo';    //静的でないプロパティの宣言
    public static $aStaticProperty = 'bar';    //静的なプロパティの宣言
    public function aMethod() {    //静的でないメソッドの宣言
        echo 'baz';
    }
    public static function aStaticMethod() {    //静的なメソッドの宣言
        echo 'qux';
    }
}
// 静的でないプロパティを動的にコールする
$sample = new Foo;
echo $sample->aProperty;  // foo

// 静的でないプロパティを静的にコールする
echo Foo::aProperty;  // エラー

// 静的プロパティを静的にコールする
echo Foo::$aStaticProperty;  // bar
 
// 静的メソッドを静的にコールする
Foo::aStaticMethod();  // qux
?> 

staticメソッドはオブジェクトのインスタンスを生成せずに コールすることができます。これを静的コールと言います。
インスタンス化されたクラスオブジェクトからメソッドやプロパティにアクセスすることを動的コールと言います。
静的なプロパティを動的コールすることは出来ませんが、静的なメソッドを動的コールすることは可能です。
これを整理してみましょう。
  動的コール   静的コール
静的でないプロパティー エラー
静的なプロパティー エラー
静的でないメソッド PHP5ではE_STRICT レベルの警告
PHP7では非推奨、E_DEPRECATED レベルの警告
将来的にサポートされなくなる見込み
静的なメソッド

1-2.静的変数を定義するためのstatic

静的変数のスコープは、自信が定義されたローカル関数内のみですが、プログラム実行がこのスコープの外で行われるようになってもその値を保持します。
<?php
function test()
{
    static $a = 0;
    echo $a.PHP_EOL;
    $a++;
}

test();  //0
test();  //1
test();  //2
?>

1-3.遅延静的束縛の意味でのstatic

遅延静的束縛の意味でのstaticについては、§2で詳述します。
PHPのマニュアルのサンプルコードのコメントには次のように書かれています。
"PHP5.3.0から'static'をスコープの値として使用できます。selfと比較してより柔軟に継承の仕組みを使えるようになります。"
このコメントは、遅延静的束縛のstaticの役割を理解する大きなヒントになります。
<?php 
// As of php 5.3.0, you can use 'static' as scope value as in below example 
// (add flexibility to inheritance mechanism compared to 'self' keyword...) 
class A { 
    const C = 'constA'; 
    public function m() { 
        echo static::C; //遅延静的束縛の意味でのstatic
    } 
} 

class B extends A { 
    const C = 'constB'; 
} 

$b = new B(); 
$b->m(); 

// output: constB 
?>


§2.スコープを表す方法


PHPでのstaticキーワードの使用方法について見て来ましたが、
次は遅延静的束縛の意味でのstaticとともに用いられるスコープ定義演算子「::」について見てみましょう。 スコープ定義演算子を使用してスコープを表すには、下記の方法があります。
記載方法 スコープ 記載できる場所
1 クラス名:: 明示されたクラス クラス定義の外or中
2 self:: self::が記載されたクラス クラス定義の中
3 parent:: parent::が記載されたクラスの親クラス クラス定義の中
4 static:: 直近の "非転送コール" のクラス クラス定義の中


2-1. クラス名::

明示されたクラスのメソッド(またはプロパティー)をコールします。
§1で見た、メソッドやプロパティーを静的にコールする方法でもあります。次のサンプルでは、メソッドをクラス定義の外からコールしています。
<?php
class Foo {
    public function myMethod() {
        echo 'baz';

    }
} 
// メソッドを静的にコールする
Foo::myMethod();  // baz

// メソッドを静的にコールする PHP 5.3.0 以降で対応
$classname = 'Foo';  // baz
$classname::myMethod();  // baz
?>
あまり意味はありませんが、クラス内からもクラス名を明示してコールしてみましょう。
<?php
class Foo {
    public static function methodA() {
        Foo::methodB();  // 自クラス内から自クラスを明示してメソッドをメソッドをコールする
    }
    
    public static function methodB() {
        echo 'baz';
    }
} 

Foo::methodA();  // baz
?>
上のサンプルのクラス名のFoo::の部分をself::と書き換えても同じ結果になります。

2-2. self::

self::が記載されたクラスのメソッド(またはプロパティー)をコールします。
<?php
class Foo {
    public static function methodA() {
        self::methodB();  // 自クラス内から自クラスを明示してメソッドをメソッドをコールする
    }
    
    public static function methodB() {
        echo 'baz';
    }
} 

Foo::methodA();  // baz
?>

2-3. parent::

parent::が記載されたクラスの親クラスのメソッド(またはプロパティー)をコールします。
次のサンプルは、子クラスで親クラスのメソッドをオーバーライドしていても、親クラスのメソッドをコールできるという例です。
<?php
class MyClass
{
    protected function myFunc() {
        echo "foo";
    }
}

class OtherClass extends MyClass
{
    // 親の定義をオーバーライドします
    public function myFunc()
    {
        // それでも親の関数をコールできます
        parent::myFunc();
    }
}

$class = new OtherClass();
$class->myFunc();  // foo
?>

2-4. static::

やっと本題に辿り着きました。
遅延静的束縛(Late Static Bindings)とは、「非転送コール」によって呼ばれたメソッド・クラス名を保持する機能です。
static::では、遅延静的束縛によって保持するクラスのメソッド(またはプロパティー)をコールします。
<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // これで、遅延静的束縛が行われます
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();  // B
?>

「転送コール」と「非転送コール」とは

非転送コール: Foo::test()や$foo->test()といったクラス名(もしくはオブジェクト)を明示した呼び出し
転送コール: メソッド内でself::、parent::、static::を使用して行われる呼び出し

遅延静的束縛が導入された背景

self::は、「self::」が記載されたクラスのメソッド(またはプロパティー)しかコールすることが出来ません。
遅延静的束縛で実行時に最初にコールされたクラスを参照することにより、この制限を取り払っています。
下記はself::による制限の例です。
<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        self::who();  // クラスBを明示して呼び出しても、クラスAのwho()がコールされる
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();  // A
?>
「2-4. static::」のサンプルコードは、上記のコードと7行目が異なるだけですが、static::を使用することでクラスBのwho()のコールを可能にしています。


参考リンク

PHPマニュアル staticキーワード
PHPマニュアル スコープ定義演算子 (::)
PHPマニュアル 遅延静的束縛 (Late Static Bindings)
maeharinの日記 PHPを愛する試み 〜self:: parent:: static:: および遅延静的束縛〜
明滅するプログラマの思索 クラス内 static プロパティについてまとめ

2018-03-12

PHPerKaigi2018に行ってきた

PHPerKaigi2018に行ってきました。
PHP歴9ヶ月のエンジニアによる感想とメモ。
各トークについて

3/9

PHPでテスティングフレームワークを実装する前に知っておきたい勘所 
概要:テスティングフレームワークの機能の要件、PHP標準機能を使ったテスティングフレームワークの実装
感想:フレームワークについての説明で、フレームワークとライブラリで制御が反転するするというのが分かりやすかった。実装されていた機能→テストを失敗した時の処理、結果表示の方式、エラーハンドリング
キーワード:phpt, run-tests.php, Hamcrest

php と SAPI と ZendEngine3 と
概要:PHPの実行環境について
感想:普段意識しない部分だったので話についていけなかったが、メモリ管理(ZMM)の環境変数については調べてみようと思った。
キーワード:Server API(SAPI), Zend Thread Safety(ZTS), Zend Engine, PHPバイナリ

大統一PHP
概要:PHPとhttpdを統一しよう
感想:httpdはApacheだけではないのか。nginxって知らなかった。中国で開発されたswooleというツール群?(networking communication engineとサイトに書いてある)がすごいらしい。まったく理解が追いつかなかったが、スピーカーのuzullaさんのテンションが高かったのでトークの最後には熱い感動が湧いた。
キーワード:Slim framework, PSR-7, reactPHP aerys, swoole, HHVM

3/10

今からでも出来る!Webサービスモニタリング!! 
概要:Webサービスモニタリングについての汎用的な内容とPHPのモニタリングに特化した内容
感想:モニタリングをする目的から述べられているのが良かった。モニタリングの対象→サーバーサイド、アプリケーション、クライアントサイド、インターネット。PHPのモニタリングではプロセスとイベント、キャッシュを見る。質疑応答で、スピーカーの壮大さんが質問を繰り返してから答えるところがとても慣れていらっしゃるなあと思った。
キーワード:OPCache, APCu

SOLIDの原則って、どんなふうに使うの?
概要:SOLIDの原則(オブジェクト指向設計における5大原則の頭文字を並べたもの)のうちの開放・閉鎖原則(オープン・クローズドの原則)の実践
感想:バリエーションの追加があった時に、既存部分を修正せずコードの追加だけで機能を満たせるようにする。最初にバリエーションの軸をどのように捉えるかが重要。クラス設計という一つの体系化された世界への扉を開いてもらったトークだった。
キーワードアジャイルソフトウェア開発の奥義

15分でわかる!WBMPビューアー実装から始めるPHPバイナリ超初心者入門 / php_wbmp
概要:PHPでバイナリデータを扱う例をwbmp(ワイヤレス・ビットマップ)形式ファイルを使用して紹介。
感想:バイナリデータの中身自体を扱うこと考えたことがなかったので、PHPではstringとして扱えるというのが興味深かった。
キーワード:wbmp, bindec

サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
概要:MySQLデータベースのバックアップとリストア手法
感想:リストアの順番とか、バックアップの種類(フルバックアップ、バイナリーログバックアップ)とかいろいろあるんだなあ。フルバックアップとバイナリーログバックアップでバックアップをとる頻度や何日分残しておくかなども異なる。自分が開発しているシステムのバックアップの体制がどうなってるのか聞いてみようと思った。
キーワード:GTID
 
Hackで作るマイクロフレームワーク
概要:PHPからHack(Facebookが開発した言語)への移行、Hackでフレームワークを作る
感想:Hackは静的型付言語で、PHPと互換性がある。HHVM上で動く。あまり理解が追いつかなかったが、Hack自体がどういうものかちょっと書いてみたい。
キーワードHack

BEAR.Sunday
概要:DI、AOP、RESTの3つのBEAR.Sundayフレームワークのコア技術を、同フレームワークでどのように適用しているか紹介。
感想:TrackBに移動していたので聴講できず。とても評判が良かったトークのようなので、運営様、動画の公開をお願いします。
キーワードBEAR.Sundayフレームワーク, DI, AOP, REST

PHPStanで始める継続的型検査
概要コードを動かさずに検査する静的解析について。静的解析ツールPHPStanの紹介
感想:コードを実行しないとうたいながらも、実は実行しているとのこと(ミサイルの発射システムを扱う時は注意!)。コードに書いてある型やPHPDocをもとに検査する。CIとの連携が可能。動的テストと組み合わせて使うとコードの信頼性が向上する。
キーワードPHPStan


LTについては後日追記

講演全体について
PHPだけでなく、派生した言語、ソフトウェア設計、実行環境、DBなどの知識も得られて視野が広がった。 

運営・その他について
・会場がとても綺麗。 
・イベント全体が暖かい雰囲気で、参加者のみなさんのマナーがとても良かった。
・講演がメインのTrackAと、スピーカーや参加者との交流をはかれるTrackBの2構成でシンプルだけど充実したイベントになっていた。
・1日目、2日目ともビールが提供され、アルコールが入ったことで会場がリラックスムードになってよかった。
・2日目はお弁当とコーヒー、お菓子まで提供された。暖かい飲物が常に提供されていて会場の外に買いに出る必要がなくてよかった。
・ネームホルダーに工夫がされていた。両面印刷なので裏返っても大丈夫。

自分の反省と今後
登壇者になって誰かに伝えるつもりで、まとまった知識を身に付けることを普段から意識したい。

最後に
スピーカーの皆様、運営の皆様、スタッフの皆様、楽しくて勉強になるイベントをありがとうございました。来年も楽しみにしています。

2018-03-10

PHPerKaigi2018 スライド リンクまとめ

PHPerKaigi2018に行ってきたのでスライドのリンクをメモ。
スピーカーの皆様、素晴らしいトークをありがとうございました。

3/9

PHPでテスティングフレームワークを実装する前に知っておきたい勘所 
うさみけんた @tadsan

php と SAPI と ZendEngine3 と
do_aki @do_aki

大統一PHP
uzulla @uzulla

3/10

今からでも出来る!Webサービスモニタリング!! 
曽根 壮大 @soudai1025

SOLIDの原則って、どんなふうに使うの?
後藤秀宣 @hidenorigoto

15分でわかる!WBMPビューアー実装から始めるPHPバイナリ超初心者入門 / php_wbmp
Jun Watanabe @rela1470

サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
yoku0825 @yoku0825

Hackで作るマイクロフレームワーク
竹澤有貴 @ex_takezawa

BEAR.Sunday
郡山昭仁 @koriym

PHPStanで始める継続的型検査
hiraku @Hiraku

Lightning Talks(LT)

HackのAsyncCurlで死んだ話
久保田賢二朗 @mottenai

忘れた頃にMcryptは廃止される
川原

レビューをもらいやすい細かいプルリクの切り分け方
東口和暉 @Khigashiguchi

速習・Dockerと学ぶPHP
アヤト @ayato_tw

Lumenで堅牢なAPIを設計する
えんどぅー @Fendo181

4年前にスタートアップして引き起こしてしまったいくつもの障害・失敗から学ぶ
中村剛 @nakamura_tsuyo4

ISUCONを社内向け1人参加型ISUCONにアレンジしてみた
白井 英 @goodoo

(敬称略)