VagrantとChefでDigitalOceanにLAMP環境をつくる

LINEで送る
Pocket

最近ちまたでよく名前を聞くDigitalOceanにVagrantを使って開発環境を一発で作成する設定を作ってみる事にした。ProvisioningにはChefを使う。作る開発環境はLAMP。それでは以下解説。

続きを読む VagrantとChefでDigitalOceanにLAMP環境をつくる

LINEで送る
Pocket

TwitterのAPIコール時に時々HTTP通信が止まってしまう

LINEで送る
Pocket

TwitterのAPIコールを何回も実行していると時々通信が止まってしまい、プログラムに制御が戻ってこない事があった。 環境はLAMP環境にCakePHPで実装したものだ。通信がとまるとPHPに制御が戻らなくなりゾンビ化する。HTTP headerを調査し、Twitter APIのバグと判明するまでの記録。

続きを読む TwitterのAPIコール時に時々HTTP通信が止まってしまう

LINEで送る
Pocket

hostsとmysql_connect()

LINEで送る
Pocket

CakePHP でsimpletest の実行がアホ程遅くなった。遅さ加減がシャレにならないし時折タイムアウトする。いつから遅くなったのかわかんないけど、気がついたらこうなっていた。いろいろ試してみた経緯を記録しておく。

続きを読む hostsとmysql_connect()

LINEで送る
Pocket

CakePHPのセッションの期限について

LINEで送る
Pocket

CakePHPでセッション期限を設定する

セッションが切断される機構にはいくつかの要素が絡んでいるので、一つのパラメータを操作しても思った様に動作しない場合がある。

【設定要素】

yourpath/app/config/core.php

・Configure::write('Session.timeout', '2016');
・Configure::write('Security.level', 'low');

/etc/php.ini

・session.gc_probability = 1
・session.gc_divisor = 1000
・session.gc_maxlifetime = 1440 ←単位は秒

【設定要素の説明】

Session.timeout

Session用のCookieをブラウザに保持しておく期間を設定。
単位は秒だが、Security.level の値による係数がかかる。
Cookieは更新されないので、この期間がそのままセッション保持の期間となる。

Security.level
ここでは、セッションの秒数にかかる係数値のみ述べるが、実際にはlevelによって様々な事が変わってくるので注意。
high:       x 10
medium: x 100
low:        x 300

例として、timeout = 2016, level = low の場合以下となる。
2,016s x 300 = 6,048,000s = 7 days となる。

session.gc_probability と session.gc_divisor
サーバー側でガベージコレクションを実施する確率を設定。
ユーザーによるアクセスの度にガベージコレクションが行われるのは負荷が高いので、実施する確率を設定している。
session.gc_probability = 1, session.gc_divisor = 1000 の場合 1/1000 の確率でガベージコレクションが行われる。
例えば1分間に1000PV程度のサイトであればだいたい毎分gcが行われている事になる。

session.gc_maxlifetime
Sessionファイル(*) をサーバーに保持しておく期間を設定。
ただし、Sessionファイルの最終更新日時は同一セッションからのアクセスがある度に更新される。
maxlifetimeは最終更新日時からの経過時間を指定しているものなので、頻繁にアクセスするセッションは維持されやすい。

PHP側でgc_maxlifetimeを設定する場合

ini_set("session.gc_maxlifetime", $time);

をsession_startより前に書く。

*:core.phpの設定により、ファイルではなくDBやmemcacheの場合もある。

【セッション維持とタイムアウトの仕組み 】

管理されるファイル

・ブラウザ側のセッション用Cookie
・サーバー側のSessionファイル(ファイルとは限らない)

フロー

  1. ユーザーのアクセスにより、CookieとSessionファイル(*)が作成される。
  2. Cookieは作成された時を基準にして core.phpに記載した Session.timeout の時間だけ保持される。
  3. Sessionファイルは最終アクセス日時を基準にして、php.iniの gc_maxlifetime の時間だけ保持される。
  4. gc_probability / gc_divisor の確率でガベージコレクションが発生し、その際に期限切れSessionファイルは削除される。
  5. ガベージコレクションで削除されずに残ったセッションもCookieのtimeoutにより最終的に削除される。

 

LINEで送る
Pocket

Google App Engine で CakePHPを使うトライ

LINEで送る
Pocket

とりあえずローカルのMountain lionでGoogle App Engine PHP SDKを入れてHelloworldを表示する事に成功した。次はCakePHPが使えないか試してみたい。

まず前回の記事で作ったアプリをCakePHPで置き換えよう。CakePHPはこちらからダウンロードしてディレクトリ毎展開すればOK。例えば、


~/Sites/gaecake/

というディレクトリにCakePHPを置いたとする。


$ cd ~/Sites/gaecake

$ touch app.yaml

$ touch php.ini

としてapp.yamlとphp.iniを作っておこう。そしてそれぞれ以下の様にかき込む。

app.yaml for CakePHP


application: cakegae
version: 1
runtime: php
api_version: 1

handlers:

- url: /css
static_dir: app/webroot/css

- url: /js
static_dir: app/webroot/js

- url: /img
static_dir: app/webroot/img

- url: /.*
script: app/webroot/index.php

次は、php.iniに以下をかき込む。


date.timezone = "Asia/Tokyo"

前回の記事に従って、


$ google_appengine/dev_appserver.py --php_executable_path=<path to php-cgi> ~/Sites/gaecake/

としてウェブサーバーを立ち上げ「http://localhost:8080」でブラウザからアクセスする。

これでCakePHPがローカル開発環境で表示されたはずた!

あれ?でもいろいろやってると不具合が出てくる。$this->redirectとかすると baseUrlの指定が壊れていててんで変なURLにリダイレクトしようとしよる。

こまった。。。なんか解決方法はないかのぉ。

app/config/core.phpの以下のラインをコメント解除したりもためした。


Configure::write('App.baseUrl', env('SCRIPT_NAME'));

でもダメだった。うーん。とりあえず今のところは解決策がみつからぬ。。

LINEで送る
Pocket

Google App Engine で PHPが使える様になった ~ SDKインストール

LINEで送る
Pocket

 こちらの記事の続きです。

前回の記事では、PHP 5.4のcgiバイナリをhomebrewでインストールしましたので、今回はApp Engine PHP SDKをインストールして、実際にサンプルアプリを作るところまでやってみます。

App Engine PHP SDKをインストールします。まず、ホームディレクトリに移動して、curlでzipファイルをダウンロードして、unzip。たったそれだけです。


$ cd

$ curl -O http://commondatastorage.googleapis.com/appengine-php/appengine-php-sdk-1.8.0.zip

$ unzip appengine-php-sdk-1.8.0.zip

これでSDKの準備が整いました。信じられないくらい簡単です。

では、次にアプリを作ります。

~/Sites/helloworld

などのフォルダを作りましょう。そして以下2つのファイルを作り終了です。

~/Sites/helloworld/helloworld.php

<?php
  echo 'Hello, World!';

~/Sites/helloworld/app.yaml


application: helloworld
version: 1

runtime: php

api_version: 1

 

handlers:

- url: /.*

script: helloworld.php

以上です。

さあ実行してみましょう。


$ cd ~/

$ google_appengine/dev_appserver.py --php_executable_path=<path to php-cgi> ~/Sites/helloworld/

<path to php-cgi>の部分は前回記事でインストールしたphp-cgiの場所になります。たぶん、


~/.phpenv/versions/5.4.10/bin/php-cgi

とかにあります。これでウェブサーバーが起動しましたので実際にブラウザから http://localhost:8080

としてアクセスしてみましょう。

LINEで送る
Pocket

Google App EngineでPHPが使える様になった!

LINEで送る
Pocket

長年PythonとJavaしか使えなかったGAEにてPHPが使える様になった模様。現在試験期間中なので、実際にサーバにデプロイするにはGoogleに申請して返答を待つ必要があるのだが、まずは開発環境を作るところから準備しておきたいので、自分のMac OS X 10.8.3 Mountain lionで環境を作ってみた。

詳しくはこちらを参照してください。

今回の記事の特徴としては、本家Google様はMac Portを使用したやり方を書いてあるところをHomebrewにした件。こちらのGAEドキュメントに従って以下をこなしていく。

  1. PHP 5.4のインストール
  2. App Engine PHP SDKのインストール
  3. サンプルアプリ作成&起動

前提事項として、今回の開発環境は上記したMac OS X 10.8のMountain lionであります。したがって、GAEの必要項目に挙げられているPython2.7に関してはプリインストールされています。反対に、この環境のデフォルトPHPは残念ながらPHP 5.3系統であるため、PHP 5.4を入れる必要があります。

PHP 5.4のインストール

PHP 5.4のインストールですが、注意点として、

  1. 現在のバージョンを残したい(既存開発環境を壊したくない)
  2. php-cgiバイナリが必要
  3. Mac Portは使いたくない

という事があります。なので、Homebrewで、php-envを使って、php-cgiバイナリを含む形でインストールする必要があります。

※php-cgiとありますが、PHPはモジュールモードやCGIモードで動作させる事ができ、環境や条件によってそれらを使い分けます。通常Apacheなどでそのまま使っているとモジュールモードになります。GAEはphp-cgiバイナリを使ったCGIモードでの動作となりますので、php-cgiを作成する必要があります。

必ず先にHomebrewをインストールしてください。では順を追って。

$ brew doctor

$ brew update

$ brew tap josegonzalez/php

$ brew install --HEAD phpenv

ここで、PATHの設定等が必要になります。 ~/.bashrc を開いて以下を追加してください。


if [ -f $HOME/.phpenv/bin/phpenv ]; then
export PATH=$PATH:~/.phpenv/bin
eval "$(phpenv init -)"
fi

で、シェルを再起動してください。


$ source ~/.bashrc

$ brew install php-build

$ php-build --definitions

これでビルドできるPHPのバージョンを確認できます。次に、ビルドする時の設定をする必要がありますので、configureのファイルを編集します。


$ vi /usr/local/Cellar/php-build/0.9.0/share/php-build/default_configure_options

内容を見て、以下が存在する事を確認してください。

  • –enable-cgi
  • –enable-bcmath

無ければ追加してください。

次に、ビルドします。


$ php-build 5.4.10 ~/.phpenv/versions/5.4.10

が、いちいちビルドエラーがでます。ビルドエラーがでる理由は依存するモジュールがインストールされていない事が原因ですので、足りないと言われたモジュールを全てインストールして再度php-buildしましょう。

因に、当方の環境で依存モジュールとしてインストールしたのは以下。


$ brew install re2c

$ brew install mcrypt

$ brew install jpeg

$ brew install libpng

さて、ビルドに成功したとして、以下にphp-cgiが作成されているはずです。


$ ls ~/.phpenv/versions/5.4.10/bin/php-cgi

実際にApache等でPHPを使う場合はこの後いろいろバージョンの変更とかの手順を踏むのだが、GAEではこのPHP 5.4版のphp-cgiバイナリさえあれば良いので、これでPHPのインストールを終了する。

さて、今回はここまで、

次は、「App Engine PHP SDKのインストール」です。

続きは次回「Google App Engine で PHPが使える様になった ~ SDKインストール」

LINEで送る
Pocket

CakePHP2.1で英語と日本語の二言語対応サイトを作る(前編)

LINEで送る
Pocket

最低限の要素で2言語対応のサイトを実際にCakePHP2.1で作る方法を紹介します。
完成イメージは以下のサイト
九寨溝国家級名勝区の紹介
上記サイトをブラウザの言語を切り替えながら表示してみると、英語モードでは英語、日本語モードでは日本語で表示されることがわかります。
ブラウザの設定を切り替える方法はこちら
ブラウザの設定を切り替える

やる事

  • ・文字は直接書き込まず、特殊関数「__()」を使って書く
  • ・翻訳ターゲットをcakeシェルにて翻訳ファイルに出力
  • ・翻訳ファイルを翻訳する
  • ・URLが言語毎に区別できるようにする(※)
  • ・ブラウザの言語と逆のURLにアクセスした場合の補正
  • ・解析ツール(adsenseタグ)の読み分け
  • ・botからのアクセスへの考慮(いいねボタンとか)
  • ・長文コンテンツは翻訳ファイルを使わずに、別viewとして管理
 ここで再び「九寨溝国家級名勝区」のサイトを見てください。
サブドメインによって日本語と英語を切り分けているのがわかります。

 


 

文字は直接書き込まず、特殊関数「__()」を使って書く

通常viewに書き込む文字は直接書き込まず、下記のように記述します。

<?= __('type message here in english.') ?>

例:通常の書き方(app/View/Jiuzhaigou/index.ctp)

<ul>
    <li><?= $this->Html->link('Rizegou Valley', '/jiuzhaigou/rizegou')?>
    <li><?= $this->Html->link('Zezhawagou Valley', '/jiuzhaigou/zezhawagou')?>
   <li><?= $this->Html->link('Shuzhenggou Valley', '/jiuzhaigou/shuzhenggou')?>
</ul>

例:多言語対応の書き方

<ul>
    <li><?= $this->Html->link(__('Rizegou Valley'), '/jiuzhaigou/rizegou')?>
    <li><?= $this->Html->link(__('Zezhawagou Valley'), '/jiuzhaigou/zezhawagou')?>
   <li><?= $this->Html->link(__('Shuzhenggou Valley'), '/jiuzhaigou/shuzhenggou')?>
</ul>

この段階では上記は両方ともレンダー後に同じhtmlになります。

レンダー後

<ul>
    <li><a href="/jiuzhaigou/rizegou">Rizegou Valley</a>
    <li><a href="/jiuzhaigou/zezhawagou">Zezhawagou Valley</a>
   <li><a href="/jiuzhaigou/shuzhenggou">Shuzhenggou Valley</a>
</ul>

 

翻訳ターゲットをcakeシェルにて翻訳ファイルに出力

コンソールからソースのrootに移動して cake i18n コマンドを実行

$ cd {project root}/app
$ Console/cake i18n
Welcome to CakePHP v2.1.2 Console
-------------------------------------------------------
App : app
Path: C:\xampp\jiuzhai\trunk\app\
-------------------------------------------------------
I18n Shell
-------------------------------------------------------
[E]xtract POT file from sources
[I]nitialize i18n database table
[H]elp
[Q]uit
What would you like to do? (E/I/H/Q)
> E            <--------------------------------------------type E and Enter
What is the path you would like to extract?
[Q]uit [D]one
[C:\xampp\jiuzhai\trunk\app\] > <---------------------------type Enter

What is the path you would like to extract?
[Q]uit [D]one
[D] > <-----------------------------------------------------type Enter

What is the path you would like to output?
[Q]uit
[C:\xampp\jiuzhai\trunk\app\Locale] > <---------------------type Enter

Would you like to merge all domains strings into the default.pot file? (y/n)
[n] > <-----------------------------------------------------type Enter

Processing ..............

Error: default.pot already exists in this location. Overwrite? [Y]es, [N]o, [A]ll (y/n/a)
[y] > <-----------------------------------------------------type Enter

Error: cake.pot already exists in this location. Overwrite? [Y]es, [N]o, [A]ll (y/n/a)
[y] > <-----------------------------------------------------type Enter

Error: cake_dev.pot already exists in this location. Overwrite? [Y]es, [N]o, [A]ll (y/n/a)
[y] > <-----------------------------------------------------type Enter

[E]xtract POT file from sources
[I]nitialize i18n database table
[H]elp
[Q]uit
What would you like to do? (E/I/H/Q)
> Q <-------------------------------------------------------type Q and Enter

上記により以下に翻訳ファイルが生成されます。

app/Locale/cake.pot
app/Locale/cake_dev.pot
app/Locale/defalut.pot

 

翻訳ファイルを翻訳する

翻訳ファイルのエディタ(Poedit)を入手してください。

「app/Locale/default.pot」ファイルをPoeditで開いてください。

原文を順に選択していき、対訳の日本語を記述して以下の場所に保存してください。

app/Locale/jpn/LC_MESSAGES/default.po

たったこれだけで日本語と英語に対応したサイトができます。

まずは、先ほどの「ブラウザの設定を切り替える」で英語と日本語を切り替えながら表示を確認してみてください。

各設定に従って表示が変わる事が分かると思います。

それでは今回はこのへんで。

次回は「URLが言語毎に区別できるようにする」から。

LINEで送る
Pocket

CakePHPプレフィックスル-ティング(Prefix Routing)

LINEで送る
Pocket

CakePHPにおいてURLの構成を自由に変えたい時にコントローラーとアクション名から自動生成されてしまうURLでは都合が悪いケースがあります。その様な場合にも多くの場合は、/app/config/routes.phpに記述すれば回避する事ができます。しかし、URLパスの始めに(コントローラー名より前に)階層をつけたい場合は/app/config/core.phpに設定する特別なルーティング方法を使います。それがプレフィックスルーティング

例えば、以下のようなパスを組みたいとします。

/settings/user/add
/settings/user/delete
/settings/music/add
/settings/music/delete

このような場合に、settingsコントローラーのuserアクションをaddやdeleteのidで処理分けするのはどう考えてもナンセンスです。そこで、このようなケースはuserコントローラーのadd/deleteアクションとmusicコントローラーのadd/deleteアクションで対応したいわけです。つまり、コントローラー名の前の階層として、URLの都合上settingsを付けたいというルーティングをする事になります。

/app/config/core.phpの設定

  • Configure::write('Routing.prefixes', array('settings'));  ※v1.3の場合
  • Configure::write('Routing.admin', 'settings');                ※v1.2の場合

コントローラーの設定

コントローラ(controller)内では、プレフィックスとして settings_ をメソッドの前につけたすべてのアクション(action)が呼び出されます。user を例にすると、/settings/user/edit/5 というURLへのアクセスで、UserController の settings_edit メソッドが、引数5で呼び出されます。ビューファイルはapp/views/user/settings_edit.ctpとなります。

複数のプレフィックスを使う方法

【v1.3の場合】

Routing.prefixesに値を追加することによって、複数のプレフィックスを使うように Router を設定することもできます。もし、

  • Configure::write('Routing.prefixes', array('admin', 'manager'));

と設定すると、Cakeはadminとmanagerの両方のプレフィックスに対するルートを自動的に生成します。各々の設定されたプレフィックスのために、以下のルートが生成されるでしょう。

  1. $this->connect("/{$prefix}/:plugin/:controller", array('action' => 'index', 'prefix' => $prefix, $prefix => true));
  2. $this->connect("/{$prefix}/:plugin/:controller/:action/*", array('prefix' => $prefix, $prefix => true));
  3. Router::connect("/{$prefix}/:controller", array('action' => 'index', 'prefix' => $prefix, $prefix => true));
  4. Router::connect("/{$prefix}/:controller/:action/*", array('prefix' => $prefix, $prefix => true));

adminルーティングのように、全てのプレフィックス付きアクションはプレフィックス名を接頭辞としてつけるべきです。/manager/posts/addPostsController::manager_add()にマッピングされるからです。

【v1.2の場合】

/app/config/routes.phpに以下の設定をする。

  • Router::connect('/profiles/:controller/:action/*', array('prefix' => 'profiles', 'profiles' => true));

プレフィックスルートを使うときに重要な点は、HTML ヘルパーを使用してリンクを作成するなら、プレフィックスを用いた呼び出しの管理も楽になります。HTML ヘルパーを使ったリンクの例は次のようになります。

Copy to Clipboard
  1. // プレフィックスがつけられたルートに行く
  2. echo $html->link('Manage posts', array('manager' => true, 'controller' => 'posts', 'action' => 'add'));
  3. // プレフィックスとお別れする
  4. echo $html->link('View Post', array('manager' => false, 'controller' => 'posts', 'action' => 'view', 5));

 

LINEで送る
Pocket

Qdmailのbccに気をつけろ

LINEで送る
Pocket

先日文字化けに悩まされてQdmailを使う事にしたんだけど、
複数のbccにメールを送ろうとしたら上手くいかなかった。

こちら本家マニュアルを参照

http://hal456.net/qdmail/oopbase#p1.3

これによると、


$mail -> to( [email protected]' , '宛先日本語名' ); $mail -> bcc( [email protected]' );

※bccでは、宛先表示名は意味がありませんので、指定できません。

複数宛先指定方法1

$to = array( [email protected]',[email protected]',[email protected]' );
$toName = array( '宛先1の日本語名','宛先2の日本語名','宛先3の日本語名' );
$mail -> to( $to , $toName );

cc,bccも同様です。from,reply-toは、ひとつしか設定できません。


という事はだよ。
bccに複数指定する場合は

$this->Qdmail->bcc(array([email protected]', [email protected]'));

となりそう。
だから僕はこう設定して「できねぇっす!」ともがいていたけど、
でも実際は、

$this->Qdmail->bcc([email protected],[email protected]');

これが答え。

うそつきー、「bccも同様」ぢゃねーじゃん!!!!

LINEで送る
Pocket