2014年1月30日木曜日

CakePHP Ajaxを使う

Ajaxを使って動的にMySQLに接続。テーブルに対する処理を行う。
ボタンが押されたらページ遷移せずにデータをテーブルに追加するor持ってくるなど。

CakePHPにはAjaxヘルパーなるものが存在しているが、どうやら古いものなうえ、
どこかからダウンロードしてこないと使えないようだ。
jQueryを使えば問題なく動作するようなので、jQueryを使用する。

参考サイト

上の参考サイトが分かりやすいがCakePHPを使っていないので、今回は上のサイトの例を
下のサイトを参考にしながらCakePHPに落とし込んで行く。
なので細かい部分は参考サイトを参考に。

テーブルとモデルを作成する


Ajaxで操作するテーブルを作成。

/*---------------------------------------------------------------------------*/
CREATE TABLE `Telephones` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 64 ) NOT NULL ,
`phone` VARCHAR( 16 ) NOT NULL ,
PRIMARY KEY ( `id` ) 
);
/*---------------------------------------------------------------------------*/

モデルをDirectoryで作成するとCakePHPのデフォルトのクラスと被るので名前だけ変える。
変えた名前に対応したモデルを作って適当なデータを挿入すればテーブル周りは完了。

jQueryを使用したviewファイルを作成する


jQueryでMySQLに接続。ヒアドキュメントの存在を知ってたけど初めて使ったのでメモ代わりに。

/*---------------------------------------------------------------------------*/
<?php
echo $this->Html->script("jquery-1.10.2.js", array('inline' => false));
$this->Html->scriptStart(array('inline' => false));
echo <<<EOT
$(document).ready(function(){ 
$("#search_results").slideUp(); 
   $("#search_button").click(function(e){ 
       e.preventDefault(); 
       ajax_search(); 
   }); 
   $("#search_term").keyup(function(e){ 
       e.preventDefault(); 
       ajax_search(); 
   }); 
});

function ajax_search(){ 
$("#search_results").show(); 
var search_val=$("#search_term").val(); 
$.post("/hoge/fuga/find", {search_term : search_val}, function(data){
if (data.length>0){ 
$("#search_results").html(data); 
}) 
EOT;
$this->Html->scriptEnd();
/*---------------------------------------------------------------------------*/

普通のphpファイルで操作していた要素をCakePHPのviewファイルに合わせて
書き換えるだけなので難しいことは無いはず。

コントローラにAjaxからアクセスする操作を記述する


上の記述どおりだとFugaControllerにfindメソッドを記述する。

/*---------------------------------------------------------------------------*/
public function find() {
$this->layout = "ajax";
if($this->RequestHandler->isAjax()) {
$term = strip_tags(substr($this->request->data("search_term"), 0, 100));
$sql = "select name,phone
from directory
where name like '%$term%'
or phone like '%$term%'
order by name asc";
$result = $this->Telephone->query($sql);
$string = "";
foreach($result as $row) {
   $string .= "<b>".$row["Telephone"]["name"]."</b> - ";
   $string .= $row["Telephone"]["phone"]."</a>";
   $string .= "<br/>\n";
}
if($string === "") {
$string = "No matches!";
}
$this->set("data", $string);
}
}
/*---------------------------------------------------------------------------*/

これもほぼ参考サイト丸コピ。レイアウトの変更やAjaxからの送信かを確認しているくらい。

ここまでできたら一度ちゃんと動くかを普通にアクセスして確かめたほうがいいと思う。
条件がよくわからないが、エラーがあると普通にエラーメッセージを表示してくれるときと、
500エラーになるときで動作が分かれることがある
最初に普通にエラーメッセージが出てきたので、500エラーが出ている理由が
コントローラ側でエラーを吐いているのだと気づかずにしばらく積んだ。

最後にビューのポストに値を入力して動けば完了。

2014年1月28日火曜日

CentOS インストール

なにかがどうにかこうにかして、「そうだ! 自宅サーバーを作ろう!」と思い立った。
というわけで使わずに放置していた古いPCにCentOSをインストールしてみる。

CentOSはRedHatというディストリビューションから有償の部分を取り除きリビルドしたものらしい。
RedHatとの完全互換がテーマで、ネットにも大変情報が多い。

参考サイト
CentOS 6インストール
CentOSのダウンロードについて | Linux系OSのQ&A【OKWave】

isoをダウンロードする


CentOSの公式ページからisoをダウンロード。
今回は参考サイトに倣い、minimalという最小構成のものをダウンロード。

色々なisoファイルがあって戸惑ったので調べたそれぞれの違いをメモ。
  • bin : 多分全部入っているイメージ。直接インストール。
  • minimal : 最小構成のイメージ。最小なのはいいけどなにが入っているのですか?
  • live : CDやDVDから直接CentOSを起動できる。インストールする気が無いなら。

ネットに転がっているスクリーンショットからデザインが変わっているがそれっぽいリンクを
クリックして行けば辿り着く。最新のバージョンをいただきます。

ダウンロードしたisoはディスクメディアに焼いてやってインストール準備完了。

CentOSをインストールする


イメージを焼き付けたディスクメディアを使って早速PCにインストール開始。
手順が多くて面倒なので、参考サイトに丸投げ。
とりあえず日本的な選択をしていけばオーケーだと思う。

インストールが完了して、設定したパスワードでログイン。

2014年1月27日月曜日

CakePHP2.x Datepickerを使ってみる

HTMLのフォームに簡単に日付を入力する素敵なjQueryのライブラリがあるそうな。
その名もDatepicker! 早速使ってみよう。

参考サイト

jQueryUIをダウンロードする


サイトから普通にダウンロードしてくる。最新のものをダウンロードしてくれば問題なかろう。
使うのは以下の通り。
  • js/jquery-1.10.2.js
  • js/jquery-ui-1.10.4.custom.min.js
  • development-bundle/ui/jquery.ui.datepicker.js
  • css/ui-lightness/jquery-ui-1.10.4.custom.min.css
ファイルに付いている数値はバージョンなので時期によっては違う。
解凍したzipのフォルダ構成に基づいてファイル名を記述しているので、
これもバージョンによっては違うかも。

テスト用のHTMLを作成する


/*---------------------------------------------------------------------------*/
echo $this->Html->css('jquery-ui-1.10.4.custom.min.css', null, array('inline' => false));
echo $this->Html->script('jquery-1.10.2.js', array('inline' => false));
echo $this->Html->script('jquery-ui-1.10.4.custom.min.js', array('inline' => false));
echo $this->Html->script('jquery.ui.datepicker.js', array('inline' => false));
echo $this->Html->scriptStart(array('inline' => false));
   $(function() {
       $("#datepicker").datepicker();
   });
echo $this->Html->scriptEnd();
echo $this->Form->input("Test", array("type" => "text", "id" => "datepicker"));
/*---------------------------------------------------------------------------*/

テストしていないからエラーが出るかも。
IEだとinlineにfalseを指定してheadタグに構文を記述しないと動かないっぽい。
しかし、ブラウザキャッシュに気づかずテストを繰り返したため、原因は全然別かも。
とりあえずIE8だと動いた。

2014年1月24日金曜日

CakePHP2.x BASIC認証を使ってみた

色々あってCakePHPでBASIC認証を使うことに。パスワードを平文のままサーバに送って処理を
行うためセキュリティはあまりよろしくないとのことなので、ダイジェスト認証ももしかしたらやるかも
しれない。やらないかもしれない。

参考サイト

認証用のユーザーを登録するテーブルを作る


多分usernameとpasswordカラムがあればなんとかなる。

/*---------------------------------------------------------------------------*/
CREATE TABLE IF NOT EXISTS admin_user (
   username VARCHAR(64),
   password VARCHAR(64)
);
/*---------------------------------------------------------------------------*/

でも大抵管理ページのユーザー管理用に使うと思うので、参考サイトのようにそれなりにデータは
持っておいたほうがいいかも。

モデルを作成する


作成したテーブルを操作するモデルを作ろう。
今回は作成したテーブルからしてCakePHPのデフォルトから外れているのでモデルも外れる。

/*---------------------------------------------------------------------------*/
class AdminUser extends AppModel {
public function beforeSave($options = array()) {
$password = &$this->data['User']['password'];
password = AuthComponent::password($password);
return true;
}
}
/*---------------------------------------------------------------------------*/

Authコンポーネントをコントローラに設定する前に、
このモデルを使用して管理ユーザーを作っておくことをオススメする。
パスワード照合の際はハッシュ化された文字列で行うので、テーブル側にもハッシュ化済みの
文字列が入っていないと認証に失敗するからだ。

Authコンポーネントを設定する


AppControllerにAuthコンポーネントを設定する。

/*---------------------------------------------------------------------------*/
class AppController extends Controller {
public $components = array(
"Session",
"Auth" => array(
"loginAction" => array(
"controller" => "AdminUser",
"action" => "login",
"admin" => true,
),
"loginRedirect" => array(
"controller" => "applies",
"actopm" => "index",
"admin" => true,
),
"authenticate" => array(
"Basic" => array("userModel" => "AdminUser"),
),
),
);

public function beforeFileter()
{
$this->Auth->logoutRedirect = $this->webroot;
}
}
/*---------------------------------------------------------------------------*/

loginActionのコントローラに次で作成するコントローラを指定。
認証用のモデルに作成しておいたモデルを指定。

ログイン用コントローラを作成する


ログイン処理用のコントローラ。

/*---------------------------------------------------------------------------*/
class AdminUserController extends AppController
{
public $uses = array("AdminUser");

public function login()
{
if($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
}
else {
$this->Session->setFlash(
__('Username or password is incorrect'),
'default',
array(),
'auth'
);
}
}

public function logout()
{
$this->Auth->logout();
}
}
/*---------------------------------------------------------------------------*/

参考サイトをほぼもろパクリさ! 違いと言えばコントローラとモデル名?


これでちゃんとユーザーを作っていればBASIC認証ができるようになったはず。

2014年1月23日木曜日

CakePHP2.x 環境変数を調べる

CakePHPには環境変数を調べるための便利関数が用意されている。

/*---------------------------------------------------------------------------*/
env("HTTP_HOST");
/*---------------------------------------------------------------------------*/

これで指定した環境変数の中身が返ってくる。

2014年1月22日水曜日

CentOS php-mysqlndをインストールする

なぜかCakeを通してのデータベース接続ができない。

/*---------------------------------------------------------------------------*/
Cake is NOT able to connect to the database.
Database connection “Mysql” is missing, or could not be created.
/*---------------------------------------------------------------------------*/

Cake側ではこんな感じのエラーが出る。
調べるphp_pdo_mysqlなるものが無いせいらしい。
確かにphpinfoで調べてみてもそんなものは見当たらない。

しかし、ネットにあるのはどうにもwindows側の情報ばかりでlinux側の情報が見当たらない。
yumで検索かけてみてもないぞう。

で、四苦八苦した挙句、近くに解決策を知ってる人がいてあっさり解決。

php-mysqlndをインストールするのが正解らしい。
バージョンアップを重ねて今ではこっちが標準になっているらしいので、yumになかったのかな?
とにかくインストール。

/*---------------------------------------------------------------------------*/
yum install --enablerepo=remi mysqlnd
/*---------------------------------------------------------------------------*/

remiは新しめのパッケージをインストールするための外部レポジトリ。
インストールしたらapache再起動。
動いた。

CentOS PHPUnitを入れる

外部のサーバーを通してユニットテストを実行しようとしたら、PHPUnitが入っていないと怒られた。
なので、なぜかサーバーなんぞ全く触ったことないのに、自力でPHPUnitを入れた。
最近自分がどこに向かっているのかさっぱり分からない。
技術が増えるのは全然構わないんだけどもね。
なにかに尖らないといずれ食いっぱぐれそうな恐ろしい予感がある。

参考サイト

PEARを入れる


と書きつつ、この記事では入れない。もう入ってた。
PHPUnitを入れるにはPEARを入れようねメモ。

PHPUnitをインストール


PEARを使ってPHPUnitをインストール。

/*---------------------------------------------------------------------------*/
pear install --force --alldeps pear.phpunit.de/PHPUnit
/*---------------------------------------------------------------------------*/

ここで気をつけねばならないのがオプションだ。
参考サイトではなんもオプション指定してないんだけど、
それだと一部のデータしかインストールされない。
forceオプションとalldepsオプションで問題は解決さ! 強制的に全部入れちゃる。
ここで大体二時間近く積んだ。

php.iniにパスを通す


PEARでインストールしたディレクトリがどこにあるのか確認して、php.iniにパスの設定を追加する。

/*---------------------------------------------------------------------------*/
$ pear config-show
Configuration (channel pear.php.net):
=====================================
...
PEAR directory                 php_dir          /usr/share/pear
...
/*---------------------------------------------------------------------------*/

php_dirの右側にあるのがインストールされたディレクトリ。
こいつをphp.iniの設定に追加する。

/*---------------------------------------------------------------------------*/
include_path=".:/usr/share/pear"
/*---------------------------------------------------------------------------*/

.はカレントディレクトリ。:は区切り文字だそうな。:はWindos環境だと;になる。

apacheを再起動だ


/*---------------------------------------------------------------------------*/
apachectl restart
/*---------------------------------------------------------------------------*/

上記コマンドで再起動して、phpunitコマンドが問題なく動作すればインストール完了。

追記


php.iniの設定いらなかった。前windows環境でやったときやった覚えないなと思って試してみた。