ラベル PHP の投稿を表示しています。 すべての投稿を表示
ラベル PHP の投稿を表示しています。 すべての投稿を表示

2012年8月25日土曜日

Ubuntu 12.04 にて dotCloud の MySQL を試してみる (PHP編)


二回続けてのdotCloudエントリ
本エントリはUbuntu 12.04 にて dotCloud の MySQL を試してみる (コマンドライン編) の続きです。
前回はコマンドラインで、helloworldサービスを作り、データベースとテーブルを作って、データをINSERTするところまでやりました。

今回はPHPからMySQLを操作してみます。

このエントリの目次
  1. PHP + MySQLのサービスにする
  2. environment.json
  3. PHPでMySQLに接続する
  4. PHPでMySQLを操作する
  5. 参考にさせて頂いたサイト
  6. さいごに

1.PHP + MySQLのサービスにする
dotcloud.ymlを下のように書きます。
my_www:
    type: php 
my_database:
    type: mysql
my_wwwmy_database は好きな文字列を指定できます。
あとは、下のコマンドを打てばOKです。
dotcloud push helloworld
# upload ~/work/dotcloud/helloworld ssh://dotcloud@uploader.dotcloud.com:443/helloworld
# rsync
building file list ... done
./
(中略)
Deployment finished. Your application is available at the following URLs
my_www: http://helloworld1-windblue.dotcloud.com/
www: http://helloworld-windblue.dotcloud.com/

2.environment.json
dotCloudにはenvironment.jsonという設定ファイルがあり、そこに色々な情報が入っています。
ホスト名やポート番号などのMySQLに関する情報も入っていて、それらはDOTCLOUD_MY_DATABASE_MYSQL_XXXというキーに格納されています。

PHPからMySQLに接続するにあたって、その設定ファイルを確認します。

詳しくはdotCloudのドキュメントにも載っているのでそちらも参照して下さい。

PHPからenvironment.jsonを確認
ローカルにてdotcloud.ymlと同じディレクトリにindex.phpを作り、下のようなソースを書いて dotcloud push します。
<?php

// environment.json ファイルから接続に必要な情報を取得
$filepath = $_SERVER['HOME'].'/environment.json';

$env = json_decode(file_get_contents($filepath), true);
foreach ($env as $key => $value) {
    print_r($key . "=" . $value . "<br />");
}

作ったページにアクセスすると、設定値一覧が見れます。

SSH接続して直接environment.jsonを確認
PHPからじゃなくても、直接dotCloudのサーバに入って確認することもできます。
下のコマンドでサーバに入ります。
dotcloud ssh helloworld.my_www
helloworld.my_wwwは <作ったサービス名>.<dotcloud.ymlに書いたキー です。

サーバに入ると、カレントディレクトリは
/home/dotcloud/
になります。
ls コマンドで見ると、environment.json がありました。
$ ls
code  current  environment.json  environment.yml  php-env  revisions  rsync-1345870675271

environment.yml というファイルもありましたが、内容は大体同じのようです。

3.PHPでMySQLに接続する
index.php を下のように書けばOKです。
<?php

// environment.json ファイルから接続に必要な情報を取得
$filepath = $_SERVER['HOME'].'/environment.json';

// 'DOTCLOUD_MY_DATABASE_MYSQL_MYSQL_XXX' というキーでMySQL関連のデータが入っている
$host = $env['DOTCLOUD_MY_DATABASE_MYSQL_HOST'];
$user = $env['DOTCLOUD_MY_DATABASE_MYSQL_LOGIN'];
$pass = $env['DOTCLOUD_MY_DATABASE_MYSQL_PASSWORD'];
$port = $env['DOTCLOUD_MY_DATABASE_MYSQL_PORT'];

//前回のエントリで作成したデータベース「nujabes」
$dbName = 'nujabes';

//mysqliオブジェクト作成
$mysqli = new mysqli($host, $user, $pass, $dbName, $port);

PDOで接続したい場合はDotCloudでのMySQL,Redis,MongoDBの使い方 | Rest Termが非常に参考になります(ただしenvironment.jsonの、MySQLに関するキーが古いようですので そこだけご注意を)。
4.PHPでMySQLを操作する
もうあとは通常のMySQL操作と同様です。
//前回のエントリで作成した「songs」というテーブルから全行取得するSQLを発行
$result = $mysqli->query('SELECT * FROM songs;');

//結果を取得していく
$rows = array();
while ($row = mysqli_fetch_assoc($result)) {
    $rows[] = $row;
}

//実行結果を表示
print_r($rows);
これで作ったページにアクセスすると、
Array ( [0] => Array ( [id] => 0 [title] => Luv (Sic) Pt. 2 ) )
と表示されます。

やったね!

5.参考にさせて頂いたサイト
  1. DotCloud で PHP アプリを設置してみたときの色々 | 肉とご飯は甘いもの @ sotarok
  2. DotCloudでのMySQL,Redis,MongoDBの使い方 | Rest Term

5.さいごに
あとはnginx、cronの使い方を覚えれば、超基本的なバックエンドサービスは実現できそうです。
PHP のフレームワークはどうするかと悩んでいるところですが…。

あと、少し日付が古いですが、dotcloudのpostgres(たぶんmysqlも)はデフォルトで全接続を許可するので気をつけよう | uuu という不穏な記事も見つけたので、こちらも確認していきます。

それでは。

2012年2月29日水曜日

PHP でプライベート変数やメソッドをクラスの外から操作する

何のために操作するのか
※本エントリはPHP 5.3.2以上で正常に動きます。

何のためかというと、例えばテストのときに使います。

プログラムの構造を変更するコトを、リフレクションといいます。
リフレクションとは、

プログラムの実行過程でプログラム自身の構造を読み取ったり書き換えたりする技術のことである。
リフレクション (情報工学) | Wikipediaより。

PHPのリフレクションまわりのManualはコチラです。

このエントリの目次
1.このエントリで使うサンプルクラス
2.プライベート変数をクラスの外から操作する
3.プライベートメソッドをクラスの外から操作する
4.最後に

1.このエントリで使うサンプルクラス
<php

class HideyoshiToyotomi {
    //建前
    //(書いてるだけで本エントリでは特に触れません)
    public $statedReason = '信長さまー!';
    //本音
    private $_realIntention = '信長うぜー!';

    //表向きは信長に心酔して仕えているように見えます
    //(書いてるだけで本エントリでは特に触れません)
    public function serveNobunaga() {
        echo '信長様のためなら命も惜しくありませぬ!';
    }   

    //外からは見えませんが、
    //内には天下取りの夢を秘めています
    private function _getTenka(){
        echo 'よっしゃ俺が天下取ったるで!';
    }   
}
HideyoshiToyotomi.php

秀吉の枷という小説を読んでいるので、秀吉クラスを例にしてみました。
(信長に仕えていた頃は「豊臣」ではないですが…豊臣の方が分かりやすいと思ったので。)

以下、秀吉クラスの概要です。

外から見えるのは、
    public $statedReason = '信長さまー!';
という建前と、
    public function serveNobunaga() {
        echo '信長様のためなら命も惜しくありませぬ!';
    } 
という信長への尽力です。

でも外から見えないところには
    private $_realIntention = '信長うぜー!';
という本音と
    private function _getTenka(){
        echo 'よっしゃ俺が天下取ったるで!';
    }
という天下取りの行動が隠されています!

こんなサンプルでよいのか。

2.プライベート変数をクラスの外から操作する
<どうでもいい>
本能寺の変が起こり、秀吉は弔い合戦として光秀を討つことを決めます。
秀吉の本音はいかに…?
</どうでもいい>

private変数である $_realIntention にアクセスできるようにして、秀吉の本音を暴いてみます。

サンプルコードです。
<?php
include './HideyoshiToyotomi.php';

$hideyoshiToyotomi = new HideyoshiToyotomi();
$reflectionClass = new ReflectionClass($hideyoshiToyotomi);

//変数名を文字列で指定します
$realIntention = $reflectionClass
    ->getProperty('_realIntention');
//private変数にアクセスできるようにします。
$realIntention->setAccessible(true);

//getValueメソッドで
//$_realIntention の値を外から取得します
echo $realIntention
    ->getValue($hideyoshiToyotomi) . "\n";

15行目の echo で、$_realIntention = 秀吉の本音 の「信長うぜー!」が外から見えました。

<どうでもいい>
さて、ここで秀吉は黒田官兵衛の言葉で、考えが変わります。
</どうでもいい>

では次に、private変数である $_realIntention = 秀吉の本音について、外から値をセットして変えてみます。

以下がそのコードです。
上記サンプルコードの最後に追加します。
//setValueメソッドで外から値をセットする
$realIntention->setValue(
    $hideyoshiToyotomi,
    '俺が天下人じゃー!'
);
echo $realIntention
    ->getValue($hideyoshiToyotomi) . "\n";

private変数である$_realIntention の値を外から変更し、「俺が天下人じゃー!」という本音になりました!

3.プライベートメソッドをクラスの外から操作する
<どうでもいい>
秀吉は光秀を討つこときっかけに、天下取りの行動をとり始めます。
</どうでもいい>

privateメソッドである_getTenka を外から見えるようにしてみます。

以下がサンプルコードです。
<?php
include './HideyoshiToyotomi.php';

$hideyoshiToyotomi = new HideyoshiToyotomi();

$reflectionClass = new ReflectionClass($hideyoshiToyotomi);

//メソッド名を文字列で指定します
$getTenka = $reflectionClass
    ->getMethod('_getTenka');
//privateメソッドにアクセスできるようにします。
$getTenka->setAccessible(true);
//invokeメソッドにて、_getTenkaメソッドを実行します
$getTenka->invoke($hideyoshiToyotomi);

privateで隠蔽されていた_getTenka メソッドが実行され「よっしゃ俺が天下取ったるで!」と表示されました。

4.最後に
テストで重宝するので書きました。
他にもPHPUnit の モックオブジェクトという便利なものがあるのですが、それはまたの機会に…。

無駄な情報が多くて例が分かりにくかったかもしれません。
ドラゴンボールとかの方がまだ分かりやすかったかしら、と思ってます。

でもCarクラスなどの味気ないサンプルもあれかなあ…と思ったので、秀吉クラスを例としました。

以上です。

2012年1月29日日曜日

PHPでCSVファイルを処理する(その1)

という訳で。
ヒトカラから帰ってきました。
受付のすぐそばの部屋に案内されて、ちょっと歌いづらかったです。
それはおいておいて。

このエントリの目的
本エントリでは、PHPでCSVを読み込んで処理するコトを想定しています。
POSTやGETでデータを取得することは想定していません。

このエントリの目次
本エントリではCSVの仕様と、付随する文字コードの問題を調べるまでです。
PHPでの処理までは書けていません(それは次のエントリで書く予定)。

・1.CSVとは
・2.CSVの仕様で個人的に重要と思った箇所
・3.CSVの文字コードはShift-JISが多い
・4.Shift-JISの問題 = 5C問題
・5.長くなったのでここで一旦切ります

1.CSVとは
Comma Separated Valuesの略。
その名の通り、それぞれの値が「,」で区切られたデータのことです。

実は「標準」の規格はなく、RFCで「広報」として仕様をまとめているようです。
RFCの原文は以下。RFC4180です。
Common Format and MIME Type for Comma-Separated Values (CSV) Files

(ちなみに、RFCのドキュメント区分は色々あるようで、rfc-index.txt の見方 | よっち@ほ~むさんにまとまっています。)

2.CSVの仕様で個人的に重要と思った箇所
以下のようなサイトを見てみました。
CSVファイルの一般的書式 (RFC4180 日本語訳) | アルプス登山の玄関口・笠井家
CSVファイルフォーマットの解説 | CodeZine
Comma Separated Values (CSV) Standard File Format | Edoceo, inc

個人的に重要と思った箇所をまとめてみました(誤解や齟齬があるといけないので、自分で調べてみるコトをおすすめします。また、間違った記述がある場合はご指摘頂けると助かります。)。

・改行コードはCRLFとする (← えぇー…って感じ)。
・半角スペースは値の一部として扱われる
・値自体に「"」(ダブルクォーテーション)や「,」(カンマ)や改行(CRLF)を含ませる場合は、値を「"」で囲まなくてはならない。そして値自体に「"」を含ませたい場合は「""」と二つ重ねてエスケープする
・ファイル末尾のレコード終端には、改行があってもなくてもよい。

3.CSVの文字コードはShift-JISが多い
文字コードは全部UTF-8でいいでしょ!と言いたいところですが、CSVはExcelで読み込みや出力できるなど密接な関係があります。
Excelのデフォルトの文字コードはShift-JISです。

で、ExcelでCSVを読み込むとき、文字コードがShift-JIS以外だと日本語が文字化けしてしまうそうです。
つまり、CSVはShift-JISで扱われるコトが多いっぽいです。

4.Shift-JISの問題 = 5C問題
さて、このShift-JISで問題になってくるのが5C問題です(初めて知りましたが…)。

5C問題とは…
Shift_JISでは、「ソ」「噂」など一部の字の2バイト目に、5C16を使用している。
多くのプログラミング環境ではこの5C16エスケープ文字としている
なのでShift-JISを想定していない環境では問題が起こる
とのコトです。
うあああ。

5.長くなったのでここで一旦切ります
次のエントリで、5C問題の解決方法を検証し、本題であるCSVのパースをします。

調べながらエントリを書いてるんですが、こんなに長くなる話題だとは思わなんだ…。
それでは。

2012年1月28日土曜日

Ubuntu 11.10 で PHPからSQLite3を試してみる

最近寒いですね
そんなときはヒトカラしてカラオケルームに引きこもります。
もしくは家に引きこもってコーディングします。
というコトで、PHPからSQLite3 を試してみました。

(SQLiteについてはsqlite3の基本操作まとめ [PCメモ] | てりぶろさんのブログが詳しいです(手抜き))

PHPのバージョンはPHP 5.3.6-13です。

で、インストールにちょっと詰りどころがあったのでメモとして残します。

このエントリの目次
1.パッケージ類のインストール
2.適当なディレクトリにDBを作成してみる
3.適当にコード書いてDBに接続を試みる
4.エラーの解決を試みる(これでいいのかは不明)
5.適当なテーブルを作成しデータ突っ込む
6.PHPからSELECT文を実行してみる
7.最後に

1.パッケージ類のインストール
下記のコマンドで必要なパッケージをインストールします。
sudo apt-get install sqlite3
sudo apt-get install php5-sqlite

2.適当なディレクトリにDBを作成してみる
コマンドラインで下記を入力します。
sqlite3 testdb

すると、「testdb」という名前のDBができ、かつSQLiteとの対話モードに入ります。
.quitと入力してとりあえず脱出。
sqlite> .quit

3.適当にコード書いてDBに接続を試みる
下記のようなPHPを書いてindex.phpという名前で保存します。
<?php
try {
    //下記はPDO('sqlite:<作成したSQLiteのDBのファイルパス>');です
    $db = new PDO('sqlite:testdb');
} catch (Exception $e) {
    error_log(print_r($e, true));
}

コマンドラインから実行してみます。
$ php index.php

PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/sqlite.so' - /usr/lib/php5/20090626+lfs/sqlite.so: cannot open shared object file: No such file or directory in Unknown on line 0

エラー出た!

4.エラーの解決を試みる(これでいいのかは不明)
ヤフったら、Launchpadで同様の問題が書かれているページを発見。
読み進めていると、15番目のコメントに書かれてる手順で解決する様子。

同様の手順を実施してみる。
$ cd /etc/php5/conf.d/
$ sudo mv sqlite.ini sqlite.NOTini

で、もう一度コマンドラインから実行してみると、エラーが出なくなった!
$ php index.php

やったね!

ちなみに、10番目のコメントでは別の解決策が示されています。
ですが、僕が実施した15番目のコメントの方法を示した人が、14番目のコメントにて、
「それはまた別の話だよ (Your workaround is regarding a different issue.)」
と言っているので、この人を信じました(楽な方法だし)。

5.適当なテーブルを作成しデータ突っ込む
という訳で、まずはコマンドラインでテーブルを作成します。
//先ほど作成したtestdbを使う
$ sqlite3 testdb

//対話モードになったので、テーブルを作成する。
sqlite> create table testtable (id integer primary key);
//適当なデータを突っ込む
sqlite> insert into testtable values(1000);
//対話モードから脱出
sqlite> .quit

6.PHPからSELECT文を実行してみる
で、下記のようなPHPコードを書きます。
<?php

try {
    $db = new PDO('sqlite:testdb');
    $sql  = $db->prepare('select * from testtable');
    if (! $sql->execute()) {
        echo 'failed 1';
    }
    echo print_r($sql->fetchALl(), true);
} catch (Exception $e) {
    echo (print_r($e, true));
}

で、実行。
$ php index.php
Array
(
[0] => Array
(
[id] => 1000
[0] => 1000
)

)

問題なく値が取れています!

7.最後に
英語力をもっとつけなければいけないなと思いました。
最初にエラーに遭遇したとき、日本語のブログを見ていました。

が、話題が本件とずれていたり解決していなかったりして、調べる→実行する→違うエラー出る→調べる→実行する→(ryを繰り返し、どんどんおかしな方向に進んでいってました。

ですが、やる気出して英語記事を読んだらすんなり解決しました。
実はLaunchpadを見ると解決するコトが多いのでは?なんて思いました。
(見たのは今回初めてなんですが)

あと、そろそろSyntaxHighlighter入れようかな…。

それでは。

2011年9月5日月曜日

DotCloud + PHPで「Hello World」をUbuntu 11.04で試してみた

本当に簡単にできました
「Ubuntu?あれだよ、Linuxだよね!」
レベルの僕でも簡単にできました。

このエントリーの目次
1. DotCloudとは
2. まずはDotCloudにサインアップ
3. DotCloudの開発環境を整える
4. DotCloudでHello Worldを作成してみる
5. Hello Worldサービスを公開、Webで確認してみる
6. もし403 Forbiddenと表示されたら。。
7. まとめ

1. DotCloudとは
Paasです。
2サービスまでは無料のようです。
詳しくは以下のエントリーなどから(手抜き)

1. プログラミング言語やデータベースが選べる新世代PaaS「DotCloud」が正式サービス開始 | Publickey
2. PythonでWebアプリつくるのにDotCloudに登録しない手はない | YAMAGUCHI::weblog
3. DotCloudは開発者のための優良なプラットフォーム | ゆーすけべー日記

2. まずはDotCloudにサインアップ
という訳で、まずはDotCloudにアクセスし、サインアップします。

3. DotCloudの開発環境を整える
DotCloudのチュートリアルに従って。

ターミナルにて。
dotcloud環境をインストールするにはeasy_installが必要なので、まずそれをインストールします。
$ sudo apt-get install python-setuptools

続いてチュートリアルに従ってdotcloudをインストールします。
$ sudo easy_install pip && sudo pip install dotcloud

インストール完了したら、まずdotcloudコマンドを実行してAPI Keyを入力します。
$ dotcloud

Enter your api key (You can find it at http://www.dotcloud.com/account/settings):
API KeyはDotCloudのsettingsページから確認できます。

これで環境が構築できました。

4. DotCloudでHello Worldを作成してみる
まずは、これから作るHello Worldサービスに対してdotcloudにおける名前空間を設定します。
$ dotcloud create helloworld

こんなふうに表示されれば成功。
Created application "helloworld"

次にHelloWorld用のディレクトリを適当に作成します。
僕は例えば以下のように作成しました。
~/work/dotcloud/helloworld/

(設定した名前空間と同じ「helloworld」でディレクトリ作ってますが、本来は一致させる必要はありません)

以降はこのhelloworldディレクトリで作業をし、ここにプログラムなどを配置していきます。
今回作るHello Worldサービスは、最終的には以下のようなファイル構成になります。
$ tree ~/work/dotcloud/helloworld/
~/work/dotcloud/helloworld/
├── dotcloud.yml
└── index.php

それでは、簡単なindex.phpを作成します。
<?php

echo 'hello world! ';

次にdotcloud.ymlです。
これはHello Worldサービスンについての設定ファイルで、このファイル名にしないといけないようです。
以下の記述をします(インデントを表すために全角スペースにしてますが、半角スペースにしてください)。
www:

type: php

これでHello Worldサービスの作成が完了しました。
次はいよいよリリースです。

5. Hello Worldサービスを公開、Webで確認してみる
リリースもコマンド一発で簡単にできます。

まずは、念の為カレントディレクトリを確認。
~/work/dotcloud/helloworld/

ではリリースです。
コマンドは以下。
$ dotcloud push helloworld .

僕の場合、リリース完了まで10秒くらいかかりました。

ターミナルの表示を見てると、sshで接続してrsyncしてbuildして〜みたいなコトが行われています。

最終的には以下の表示がされれば完了です!
「このサービスは以下のURLで見れるよー」って書かれてますね。
The build finished successfully
2011-09-04 16:01:55 [api] Deploy finished

Deployment finished. Your application is available at the following URLs
www: http://helloworld-<username>.dotcloud.com/

<username>の前の「helloworld」は、設定した名前空間と一致します。

という訳で、実際にHello Worldのページを確認してみてください。
ちなみに、以下のコマンドを打つとURLが確認できます。
$ dotcloud url helloworld

「index.php」だとドメインだけでアクセスできるのかな??
ちなみに、index.phpと同時にhoge.phpを作成したとき、hoge.phpへのアクセスは
「http://helloworld-<username>.dotcloud.com/hoge.php」
でできます。

6. もし403 Forbiddenと表示されたら。。
ファイル構成などが間違っている可能性があります。
僕も一回403になりました。

繰り返しになりますが、今回の例では以下のファイル構成にして
$ tree ~/work/dotcloud/helloworld/
~/work/dotcloud/helloworld/
├── dotcloud.yml
└── index.php

以下のディレクトリにて
~/work/dotcloud/helloworld/
以下のコマンドでリリースしています。
$ dotcloud push helloworld

7. まとめ
という訳で、簡単にですがまずはとにかくHello Worldを試してみました。
環境構築がかなり苦手な僕ですが、それでも非常に簡単にできました。
すごい!

DotCloudを試した理由はNode.jsが動くからです。
これで何か作ってみたいなーと。
個人的に勉強中のErlangもalphaになっているけど、一応使えるのかな。。?

ちなみに、DotCloudのPHPは、Apacheではなくnginxで動いているようです(nginxのWikipedia)。
何それおいしいの。。。

以上です。
繰り返しになりますが、本当に簡単なのでサクッと試してみてはいかがでしょうか。

2011年3月7日月曜日

PHPのCGI版とモジュール版についてネットの記事を読んでみた

  1. PHP における「モジュール版」と「CGI 版」の比較 + WordPress の適用例 - 小粋空間
  2. PHPのCGI版、モジュール版とは… - phpとmysqlが使える格安レンタルサーバ比較


とても簡単に言うと、メリデメは以下のよう。
モジュール版
  • メリット:Apacheのプロセスの中で実行されるため、CGI版と比較してパフォーマンスが早い
  • デメリット:Apacheのプロセスの中で実行されるため、問題のあるプロセスが分からない

CGI版
  • メリット:一つ一つプロセスとして立ち上がるため、問題のあるプロセスがすぐに分かる。またそのプロセスをkillすれば解決。
  • デメリット:一つ一つプロセスとして立ち上がるため、モジュール版と比較してパフォーマンスが遅い

2010年11月15日月曜日

PHPで、1つのリクエストに対するcurlとcurl_multiとのパフォーマンスの差

複数リクエストの場合は
勿論、並列にリクエストを実行するcurl_multiの方が早いでしょう。
curl_multiを使っての実装方法はAPIとの通信効率をよくする実装例(1) curl_multi (Yahoo!JapanのTechBlog)に詳しく載っています。

じゃあ、リクエストが1つだけの場合は?
勿論、無駄な処理のないただのcURLの方が早いでしょう。
それは分かるけどどれくらいの差があるのでしょうか?
実験してみます。
PHPは5.2.5です。

ただのcURL場合
以下のプログラム(抜粋ですが)を10回試行して平均を取ってみます。
$url = "http://www.yahoo.co.jp/";

$start = microtime();

$res = my_curl($url);

if($res["info"]["http_code"] == 200){
  print("success");
}else{
  print("error");
}

$end = microtime();

function my_curl($url){
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $res = curl_exec($ch);

  $info = curl_getinfo($ch);
 
  return array("res" => $res, "info" => $info);
}


平均すると0.1679922秒かかりました。

curl_multiの場合
同じく、以下のプログラム(抜粋ですが)を10回試行して平均を取ってみます。
$url = "http://www.yahoo.co.jp/";

$start = microtime();

$res = my_curl_multi(array($url));

if($res[0]["info"]["http_code"] == 200){
  print("success");
}else{
  print("error");
}

$end = microtime();

function my_curl_multi($urls){

  $mh = curl_multi_init();
  $chs = array();
  foreach($urls as $url){
    $ch = curl_init($url);
    $chs[] = $ch;
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_multi_add_handle($mh, $ch);
  }

  do{
    curl_multi_exec($mh, $running);
  }while($running);

  $res = array();
  foreach($chs as $ch){
    $info = curl_getinfo($ch);
    $body = curl_multi_getcontent($ch);
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
  
    $res[] = array("res" => $body, "info" => $info);
  }

  curl_multi_close($mh);
 
  return $res;

}


平均すると0.300859秒かかりました。

まとめ
秒数自体は通信環境に因るところが大きいと思うので参考程度に…ですが、それにしてもコンマ数秒のオーダーで違ってきています。
並列処理をする必要がない場合は、極力通常のcURLを使用するのがよさそうです。

2010年11月3日水曜日

PHPで一時的なファイルを作成するときに、ファイル名の重複がないようにする

テンポラリファイルを作成して後で利用する処理などの場合、ファイル名が同じだとテンポラリファイルが上書きされてしまうかもしれない。
そのときの時分秒をファイル名に使用しても、重複する可能性はある。

ファイル名の重複を避ける便利な関数がある
tempnam関数を使えばよい。
この関数は、重複しないファイル名でサイズ0バイトのファイルを生成する。
返り値は生成したファイル名。
どういう原理で重複を避けてるのか。。

パフォーマンスへの影響は?
tempnam関数を使ってファイルを生成→削除した場合と、使用しないで生成→削除した場合の比較してみる。
PHP 5.2.5を使っています。

tempnam関数を使った場合
$time_start = microtime();
for($i = 0; $i < 1000; $i++){
 $filename = tempnam($dir, $prefix);
 unlink($filename);
}
$time_end = microtime();

上のようなサンプルを書いて試した(主要な部分のみ抜粋)。
tempnam関数を使ってファイル生成→削除を1000回ループまわしています。
10回試して平均した結果。
4.3750467(秒)

tempnam関数を使わない場合
$time_start = microtime();
for($i = 0; $i < 1000; $i++){
 $fp = fopen($dir.$prefix, "w");
 fclose($fp);
 unlink($dir.$prefix);
}
$time_end = microtime();

単純にファイル生成→削除を1000回ループまわしています。
10回試して平均した結果。
2.738844(秒)

1.5倍くらい違うという結果になった
tempnam関数を使用すると1.5倍くらい遅くなる、という結果になった。
そこまで劇的には変わらないようです。

でもどういう原理なんでしょうねー。

2009年11月21日土曜日

XAMPPでcURLなどのExtensionを使う方法

XAMPPでcurlやopensslなどのPHPエクステンションを有効にする方法 (PHP SPOT)

こちらに載っています。
(なぜか家のOpera 10.01では見られませんでした。Google ChromeやSleipnirでは見れました。)

2009年11月11日水曜日

PHPでbooleanの「true」「false」を文字列に変換する関数

例えば、true(boolean型)を"true"(String型)に変換するには。
var_export関数を使う。

<?php 
$a = true;                  //$aはboolean型
$b = var_export($a, true)   //$bはString型
?>

知らなかったので。

Related Posts Plugin for WordPress, Blogger...