PHPで可変長の引数を扱う

 PHPで可変長の引数を渡したいときは、 call_user_func_array という関数を使う。可変長の変数を配列に入れて、第1引数に文字列で関数名を書いて、第2引数に可変長の引数を渡す。

例えば、sprintf みたいな書き方でエスケープした文字列を作る関数を定義してみると、以下のように書く。

// パラメータをエスケープするための処理。(MySQLにつないでからじゃないと使えない)
function escape_query($condition_ary)
{
    _db_connect();
    // フォーマットを取得(第1引数)
    $format = array_shift($condition_ary);
 
    // 第2引数以降が、エスケープすべき値
    $escaped_value_ary = array();
    foreach($condition_ary as $_val)
    {
        $_escaped_val = mysql_real_escape_string($_val);
        array_push($escaped_value_ary, $_escaped_val);
    }
 
    array_unshift($escaped_value_ary, $format);
 
    return call_user_func_array('sprintf', $escaped_value_ary);
}
 
//呼ぶとき Railsぽく
$conditions = array("select * from fruits where color = '%s' and name = '%s'", $_POST['color'], $_POST['name']);
$escaped_str = escape_query($conditions);
PHPで可変長の引数を扱う

Akelosのmigration

PHP の RailsコピーのAkelosを触ってる。まだVersin0.8だけど、良さそうなので使ってみたい。CakePHPはRailsコピーかと思ったら全然違ったので使うのやめた。

migration

$ php script/generate model Book

上記のコマンドで、Bookモデルが作られる。そうすると、migrateファイルにあたるものが app/installers/book_installesr.php に出来る。デフォルトだと以下のような形になって、バージョンUPとDOWNに対応した処理を書くようになっている。

< ?php
class DrinkInstaller extends AkInstaller
{
    function up_1()
    {
        $this->createTable('drinks', "
          id,
          name
        ");
    }
 
    function down_1()
    {
        $this->dropTable('drinks');
    }
}
?>

createTableの第一引数がテーブル名、第二引数がテーブルの中身になる。第二引数は、カンマでカラム名を区切っていく。型を指定しないと、自動的に最適な型にしてくれるということだが、怪しいので指定したほうが良さそう。以下のように書く。

        $this->createTable('drinks', "
          id,
          name varchar(255),
          descrption text,
          isbn varchar(20) not null
        ");

これをDBに反映させるには script/migrate book install と書く。install をやると up が順に実行され、 uninstall を実行すると down が実行される。

chu@chu-mac:~/Sites/sample$ php script/migrate book install
Upgrading-----
(mysqlt): SET AUTOCOMMIT=0
-----
-----
(mysqlt): BEGIN
-----
-----
(mysqlt): SHOW COLUMNS FROM books
-----
1146: Table 'sample_dev.books' doesn't exist
ADOConnection._Execute(SHOW COLUMNS FROM books, false)% line  854, file: /Users/chu/Sites/akelos/vendor/adodb/adodb.inc.php
ADOConnection.Execute(SHOW COLUMNS FROM books)% line  393, file: /Users/chu/Sites/akelos/vendor/adodb/drivers/adodb-mysql.inc.php
ADODB_mysql.MetaColumns(books, true, false)% line  202, file: /Users/chu/Sites/akelos/vendor/adodb/adodb-datadict.inc.php
ADODB_DataDict.MetaColumns(books)% line  723, file: /Users/chu/Sites/akelos/vendor/adodb/adodb-datadict.inc.php
ADODB_DataDict.ChangeTableSQL(books, id I NOTNULL AUTO KEY,
name varchar(255),
desctipntion XL,
isbn varchar(20) NOTNULL,
updated_at T,
created_at T, Array[1])% line  279, file: /Users/chu/Sites/akelos/lib/AkInstaller.php
-----
(mysqlt): CREATE TABLE books (
id                       INTEGER NOT NULL AUTO_INCREMENT,
name                     VARCHAR(255),
desctipntion             LONGTEXT,
isbn                     VARCHAR(20) NOT NULL,
updated_at               DATETIME,
created_at               DATETIME,
                 PRIMARY KEY (id)
)TYPE=InnoDB
-----
-----
(mysqlt): COMMIT
-----
-----
(mysqlt): SET AUTOCOMMIT=1
-----
Smart Commit occurred

途中にエラーっぽいメッセージがあるが、公式のScreenshot見てもこれが正常な動作のようだ。

ちなみに、以下のように書いておくと migration を uninstall した時にbooksテーブルがdropされます。Railsだと、デフォじゃテーブルやバージョン別のmigrationをサポートしてないからこれは結構便利かも。ただ、みんなで別々にやってたらどうなるのか。全部一気にやる方法がまだわからない。同じファイルに全部書いておけば問題はないと思うけど、要調査。

    function down_1()
    {
        $this->dropTable('books');
    }
Akelosのmigration

PHP5ではデフォルトの時間設定が必要

Strict Standards: date() [function.date]: It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier

PHP5で date()関数を使おうとしたら、上のようなエラーが出た。php.inidate.timezone = Asia/Tokyo (日本の場合)としなきゃいけないっぽい。したら、Webサーバーを再起動すればおk

PHP5ではデフォルトの時間設定が必要

PHP実行時間が長すぎて・・・

120回近くループさせてたら怒られた(´・ω・`)

Fatal error: Maximum execution time of 30 seconds exceeded

PHPはデフォルトだと、30秒以上スクリプト実行してると強制終了されてしまうみたい。

php.ini の max_execution_time を延ばすか、set_time_limit( int seconds ) をスクリプト内に記述するしかないとか。

amazon への SOAP リクエストが毎秒1コールに制限されているので、sleep(1); をスクリプト内に記述してるんだが、1コールで10件までしか検索結果を呼び出せないので、ループさせてキーワードに対応するデータをとってきてDBに落としてみる。一般的な単語だと、検索結果が100ページを越すので、最低でも100秒かかっちゃうので、 set_time_limit(300); と記述したらうまくいった。ほんとにダメなスクリプト書いちゃったときに max_exection_time を増やしてたらなんか怖いのでデフォルトの30秒のままにしといた。

EDEN600MHz サーバいつ公開できるかなぁ。

続きを読む “PHP実行時間が長すぎて・・・”

PHP実行時間が長すぎて・・・

PHP5 を入れた【Debian/GNU】

 sarge の stable だと、デフォルトでは apt で PHP5 を入れることができないので、/etc/apt/source.list を編集。

deb http://people.debian.org/~dexter php5.0 sarge
deb-src http://people.debian.org/~dexter php5.0 sarge

を追加。

新しいバージョンなら、以下のよう。

deb http://people.debian.org/~dexter php5.1 sarge
deb-src http://people.debian.org/~dexter php5.1 sarge
PHP5 を入れた【Debian/GNU】