PHP

PHPにてgetaddrinfo failedにぶち当たった。

例えばfile_get_contentsでURLを指定した時。
sshからphpを叩くと正常に返ってくるのにapacheを通したブラウザから叩くと下記のようなエラーになる。

php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution

これが調べたけど全然解決しない。ただ分かったことはDNSの名前解決周りでこけているであろうという事。

視点を切り替えapache、DNSといったキーワードで調べていると、HostnameLookupsをどうのこうのという記事を発見。
そこでhttpd.conf内にあるHostnameLookupsの項目を調査してみたところOffになっているではありませんか。
とりあえず下記のように設定をOnに変更しhttpdを再起動。

HostnameLookups On

するとapacheを介してもfile_get_contentsが動いた!やった!!けどクッソ遅い!!!なんで!!!!
再度調査開始である。今回はapache、遅い、で検索すると意外とすんなりヒット。
しかし見つけた記事はといえば、HostnameLookupsをOffにしろと書いているではありませんか。
いやいや、それやるとネットワークが外でていってくれないんすよ、とか思いつつとりあえずやってみる。

変更後httpdを再起動してアクセスしてみると、あれ?ちゃんと動いてる。しかも早い!なんで!!
エラー吐いて終わるだろうと予想していたのに、じゃあ最初の状態はなにがよろしくなかったんすかね…。

これがまれによくある気にしちゃいけないヤーツーである。
※原因が判明し次第まとめよう。笑

CakePHP2系にてヘッダーのContent-Typeをjsonに設定する。

メモ。

$this->response->type('json');
$this->response->send();

以上!

最後のsend()関数は通常リクエストの最後Dispatcherによって自動的に行われるが、自ら処理を殺している場合などはヘッダの送信処理が行われないため、自分で実行してあげないと想定した挙動にならないので注意。

例えば以下のような場合。

// 何かしらのデータ配列
$data = array('my' => 'apple', 'favorite' => 'banana', 'food' => 'orange');

$this->response->type('json');
$this->response->send();

// jsonデータとして出力して処理終了
echo json_encode($data);
die();

Ajaxの処理とかでjson形式のデータをコールバック関数に渡したい時などにやるやーつー。

CakePHP2系にて通信手段がAjaxかどうか判定する。

メモ。

if($this->request->is('ajax')){
	// Ajaxによる通信です。
}

これはシンプルかつ強力。リクエストオブジェクト便利だね。

jQueryによるAjax、もっとシンプルに。

この記事←で書いたAjaxの処理部分、わざわざdone()、fail()、に無名関数を入れてやら無くてもよかった模様。

関数を定義した後以下の書き方でOK。

$.ajax({
	url: 'http://example.com/',
}).done(success).fail(error);

ちなみに値をPOSTで送信したい時などはこんな感じ。

var data = {"my":"apple","favorite":"banana","food":"orange"};
$.ajax({
	url: 'http://example.com/',
	type: 'POST',
	data: data,
}).done(success).fail(error);

簡単だね!
ちなみにCakePHPだとPOSTされた値は以下の、

$this->request->data;
$this->params->data;

どっちでも参照できるけど、どっちがいいんだろうね。せっかくリクエストオブジェクトが用意されているならそっちを使ったほうが良いような気もするけど、ついつい$this->paramsの中に都合の良いパラメーターが入ってきてないか確認しにいっちゃうよね。笑

だって$this->paramsちゃん万能なんですもの!!

EclipseのPDTにて半角スペースのインデントを取り除く方法。

ソースコード内のインデントがTabではなく半角スペース4つ分とかだった場合、デフォルト状態だとShift+Tabでインデントを下げることが出来なかったので、どうしたらいいか調べたときのメモ。(※英語環境なのでご了承を。)

bc8cdb7b1b343fc8c9691ae6c62eab99

1, 上部メニューバーより「Window」→「Preferences」を選択

21da0303b4936dcefb348bb40aae7990

2, 出てきたウィンドウの左メニューツリーの「PHP」→「Code Style」→「Formatter」を選択

3, 右ウィンドウの「Tab policy:」を「Tabs」から「Spaces」に変更

4, 最後にウィンドウ下部の「OK」を押せば完了

この設定を行うことで、Tab文字だろうが半角スペースだろうがShift+Tabでインデントを下げることが可能になった。
他人が書いたコードのインデントルールを自分好みに整形しなおしたいときにこれは便利。

※インデントを消し去った後、この項目の設定を戻し忘れないように注意

PHP5.4にて関数内配列への直アクセスが可能に。

PHP5.4からFunctionArrayDereferencingが取り込まれたため、いちいち関数の返り値(配列)を変数に入れてあげなくても、要素への直アクセスが出来るようになった。例えば以下のような感じ。

$this->hogeFunction()[2];
$this->fugaFunction()[0]->piyo;

PHP5.3ではいったん変数に突っ込んであげないとエラーになるけど、逆になんで出来ないんだろうと疑問に思っていたのでこれはありがたい。
自分は返り値をいちいち変数にこめたりして行数がちょっとでも増えるのが嫌なので、これだけで5.4環境に乗り換えようかと思うくらい魅力的である。
if, for, foreachとかも(単純な処理の場合は)極力1行で書きたい病気だったりする。

ワンライナー万歳?(^o^)/

CakePHP2系の$this->fetch()の使い方。

Cake2系におけるデフォルトレイアウトなどを覗くと$this->fetch(‘css’)だったり$this->fetch(‘content’)といった記述が見つかる。
これは任意の文字列をビューの好きな位置で読み込める関数である。但し変数を渡す側もビューから出ないとエラーになるので注意。
主にビューファイルからレイアウトファイルに変数を渡すときなどに使う。
説明するより流れを見たほうが早いかな。使い方は以下みたいな感じ。

まずはレイアウトファイルの変数を出力したい位置にfetch()関数を記述。

<?php echo $this->fetch('str'); ?>

次に、ビュー側からassign()関数を使って特定のキーに変数を渡す。

<?php $this->assign('str', 'hogehogehoge'); ?>

上記の処理を走らせるとレイアウトのフェッチの位置に「hogehogehoge」が出力される。
主な用途としては、ビューから動的にtitleを書き換えたり、読み込むcss, jsを切り替えたりする用かな。
ほかにもエレメントを直接受け渡したりなど色々と応用も利きそうな感じ。
処理の流れとしては、fetch()関数が実行された後にassign()関数を実行しても変数は受け渡されないので注意。必ずassign()、fetch()の順番でなければならない。
またassign()していないビューのソースコードは自動的に$this->fetch(‘content’)にぶち込まれる点も覚えておきたい。実際は大抵この使い方をしてる気がしなくもない。笑

PHPの正規表現にて指定文字列間の値を抽出する。

ある一定のパターンの間にある文字列を抽出したかったときにやった方法メモ。
たとえば以下の○○○の部分が欲しい時とかに使う。

<input type="text" name="hoge" value="○○○" />

以下分かりやすいようにマルチバイトの例を記述。

$str = '人生は退屈すれば長く、充実すれば短い。';
preg_match("/(人生は)(.*)(長く)/is", $str, $return);
var_dump($return);

↓

array(4) {
  [0]=>
  string(30) "人生は退屈すれば長く"
  [1]=>
  string(9) "人生は"
  [2]=>
  string(15) "退屈すれば"
  [3]=>
  string(6) "長く"
}

正規表現は奥が深い。。。