メイン

PHP アーカイブ

2007年07月24日

PHPスクリプトの文字コード

PHPスクリプトの文字コードについて。

PHPスクリプトに使用できる文字コード

PHPのスクリプトに使用できる日本語の文字コードは、「EUC-JP」と「UTF-8」です。
「シフトJIS」や「UCS-2」は使用できません。

ただしPHPの構築時に、オプションとして「--enable-zend-multibyte」を指定すれば、「シフトJIS」や「UCS-2」を使用することができるようになります。

国内のサーバーであれば、「--enable-zend-multibyte」は有効になっていると思いますが、環境によって使用できない可能性のある「シフトJIS」や「UCS-2」よりも、確実に使用できる「EUC-JP」や「UTF-8」を使用した方が良いと思います。

PHPスクリプトの文字コードの指定

PHPスクリプトの文字コードの指定するには、いくつかの方法があります。

  1. 設定ファイル(php.ini)の「mbstring.script_encoding」で指定する。

    シフトJISを指定する例

    mbstring.script_encoding=sjis-win
    

    複数の候補の中から自動検出する例

    mbstring.script_encoding=sjis-win,eucjp-win,ascii
    

    mbstring.languageの設定から自動検出する例

    mbstring.script_encoding=auto
    
  2. PHPスクリプト内で、「declare(encoding=文字コード)」で指定する。

    EUC-JPを指定する例

    declare(encoding="EUC-JP");
    
  3. PHPスクリプトにBOMを付加する。(Unicode限定、PHP5以降?)

2007年07月25日

PHPスクリプトに送信されたデータの文字コードの変換

PHPスクリプトに送信されたデータの文字コードの変換について

Webアプリケーションでは、ブラウザから送信されてくるデータの文字コードを指定することはできません。
そこで、データを受信した後に文字コードを判別し、変換する必要があります。

mbstring.encoding_translation

設定ファイル(php.ini)のmbstring.encoding_translationを「On」にすると、受信したデータを自動的に内部エンコーディングに変換します。

mbstring.encoding_translationの初期値は「Off」です。
アプリケーションの互換性を考えると「Off」のまま使用する方が良いと考えます。

mb_convert_encoding

文字コードを変換するには、「mb_convert_encoding」を使用します。

/* 内部文字エンコーディングからSJISに変換 */
$str = mb_convert_encoding($str, "SJIS");

/* EUC-JPからUTF-7に変換 */
$str = mb_convert_encoding($str, "UTF-7", "EUC-JP");

/* JIS, eucjp-win, sjis-winの順番で自動検出し、UCS-2LEに変換 */
$str = mb_convert_encoding($str, "UCS-2LE", "JIS, eucjp-win, sjis-win");

mb_convert_encoding」の3番目の引数に"auto"を指定する場合は、あらかじめ設定ファイル(php.ini)で「mbstring.language=Japanese」を指定するか、「mb_language」を使用して、言語を指定します。

/* "auto" は、"ASCII,JIS,UTF-8,EUC-JP,SJIS" に展開される */
mb_language('japanese');
$str = mb_convert_encoding($str, "EUC-JP", "auto");

携帯電話の絵文字など、規格外のコードが含まれている場合は、「mb_substitute_character」を使用して変換し、内部で処理します。
(参考)docomo(ドコモ)やauの絵文字の抽出をPHPで最も簡単にする方法

2007年08月13日

PHPの$_POST、$_GET、$_COOKIE配列の要素に配列を使う機能

この「$_POST、$_GET、$_COOKIE配列の要素に配列を使う機能」はよく知られていない機能の一つと言っても良いかも知れません。

PHPの$_POST, $_GET, $_COOKIEの要素に配列を使用する

このページを見て、初めて知りました。

早速実験してみる。

test.php

<?php
print_r($_GET);
?>

に、http://localhost/test.php?a[b]=1&a[c]=2 でアクセスしてみると、

Array
(
    [a] => Array
        (
            [b] => 1
            [c] => 2
        )
)

これは便利かも。

2007年08月14日

PHPの内部文字エンコーディング

内部文字エンコーディングはphp.iniのmbstring.internal_encodingで指定する。
また、スクリプト内ではmb_internal_encoding()で設定・取得ができる。

この内部文字エンコーディングは何に使われるのか、というと次の3つである。

  • HTTP入力文字エンコーディング変換
  • HTTP出力文字エンコーディング変換
  • マルチバイト文字列(mbstring)関数においてデフォルトの文字エンコーディング

ちなみに、PHPスクリプトの文字コードは「mbstring.script_encoding」で指定する。

HTTP入力文字エンコーディング変換

php.iniのmbstring.encoding_translationの値が「On」の場合、 HTTP入力文字エンコーディングが自動的に内部文字エンコーディングに変換される。

mbstring.encoding_translationの値が「Off」の場合は、何もしない。

HTTP出力文字エンコーディング変換

mb_output_handler()は、内部文字エンコーディングからHTTP出力文字エンコーディングに変換する。

マルチバイト文字列(mbstring)関数においてデフォルトの文字エンコーディング

マルチバイト文字列(mbstring)関数のうち、文字エンコーディングが必要な一部の関数では、 文字エンコーディングを指定しない場合は内部文字エンコーディングが指定されたことになる。

毎回、文字エンコーディングを指定する手間が省ける。

PHPスクリプトが出力するデータの文字コード

PHPスクリプトが出力するデータの文字コードについて。

mbstring.http_outputは出力する文字コードを指定します。
指定するだけなので、これだけでは自動的に変換しません。

変換するにはmb_output_handler()を実行します。
mb_output_handler()を実行したときに、内部エンコーディング(mbstring.internal_encoding)からmbstring.http_outputで指定した文字コードに変換して出力されます。

何もしない場合は、PHPスクリプトの文字コードで出力されます。

Firefox用PHPマニュアル検索プラグイン

Firefox用PHPマニュアル検索プラグインを調べてみたところ2つ発見

php.iniの設定を.htaccessで変更する

php.iniの設定を.htaccessで変更する方法。

設定可能な項目

「.htaccess」ファイルで設定出来る項目は、PHPマニュアル(php.ini ディレクティブ)において 「変更の可否」が「PHP_INI_PERDIR」または「PHP_INI_ALL」と指定されているものです。

.htaccessで変更できる項目を調べるスクリプト

<?php
print_r('.htaccessで変更できる項目は:<br>');
foreach (ini_get_all() as $name => $value) {
  if ($value['access'] & 2) {
    print_r($name . '<br>');
  }
}
?>

参考:ini_set()でどの設定を変えることが出来るか調べる

文法

.htaccessに記述する形式

php_value

php_value 項目名 値

セット済みの値をクリアしたい場合は、値に「none」を指定します。

php_value mbstring.language "Japanese"

php_flag

php_flag 項目名 on|off

php_flag  mbstring.encoding_translation Off

2007年08月15日

php.iniの設定をPHPスクリプト内で変更する

php.iniの設定をPHPスクリプト内で変更する方法。

PHPスクリプトの可搬性を高めるために、php.iniの設定にできるだけ依存しないようにしたい。

設定可能な項目

「.htaccess」ファイルで設定出来る項目は、PHPマニュアル(php.ini ディレクティブ)において 「変更の可否」が「PHP_INI_USER」または「PHP_INI_ALL」と指定されているものです。

.htaccessで変更できる項目を調べるスクリプト

<?php
print_r('ini_set()で変えてしまえる設定は:<br>');
foreach (ini_get_all() as $name => $value) {
  if ($value['access'] & 1) {
    print_r($name . '<br>');
  }
}
?>

参考:ini_set()でどの設定を変えることが出来るか調べる

ini_set

設定は、ini_set()で行います。
ini_set()は、成功した場合は変更前の値を、失敗した場合にFALSEを返します。

設定は、関連する関数を使用する前に行う必要があります。
たとえば、「session.use_trans_sid」は、session_start()を使用する前に設定します。

ini_get

現在の設定を取得するには、ini_get()を使用します。

また、ini_get_all()を使用すると、すべての項目の設定を取得できます。

オープンソースソフトウェアの設定

オープンソースソフトウェアではどのように設定しているか調べてみました。

mbstring.http_input、mbstring.http_outputを「pass」に変更しています。
文字化け対策として無難な設定だと思います。

PukiWiki 1.4.7 UTF8版

init.php

mb_language(MB_LANGUAGE);
mb_internal_encoding(SOURCE_ENCODING);
ini_set('mbstring.http_input', 'pass');
mb_http_output('pass');
mb_detect_order('auto');

XOOPS Cube V2.1

Legacy_LanguageManager.class.php

ini_set( 'mbstring.http_input', 'pass');
ini_set( 'mbstring.http_output', 'pass');
ini_set( 'mbstring.func_overload', 0);
ini_set( 'mbstring.substitute_character', 'none');

OpenPNE 1.8.2

config.phpで設定。
mbstring.http_inputが「auto」です。

mb_language('Japanese');
ini_set('mbstring.detect_order', 'auto');
ini_set('mbstring.http_input'  , 'auto');
ini_set('mbstring.http_output' , 'pass');
ini_set('mbstring.internal_encoding', 'UTF-8');
ini_set('mbstring.script_encoding'  , 'UTF-8');
ini_set('mbstring.substitute_character', 'none');
mb_regex_encoding('UTF-8');

2007年08月16日

レシピ1.1.今日の日付の割り出し(RubyクックブックをPHPに翻訳する)

RubyクックブックをPHPに翻訳してみる。

レシピ1.1.今日の日付の割り出し

getdate()は、引数を指定しない場合、現在のローカルな時間に関する情報を返します。

<?php
//現在の時間を取得する
print_r(getdate());
?>

Array
(
    [seconds] => 4
    [minutes] => 29
    [hours] => 12
    [mday] => 16
    [wday] => 4
    [mon] => 8
    [year] => 2007
    [yday] => 227
    [weekday] => Thursday
    [month] => August
    [0] => 1187234944
)

time()は、現在のUnixタイムスタンプを返します。

<?php
//現在のUnixタイムスタンプを返します。
print_r(time());
// => 1187589754
?>

date()は、ローカルの日付/時刻を書式化します。

<?php
//書式を指定して、現在の時間を取得する。
print_r(date('Y/n/j G:i:s'), time());
// => 2007/8/16 12:38:29

print_r(date('Y/n/j G:i:s'));
// => 2007/8/16 12:38:29
?>

mktime()は、日付を Unix のタイムスタンプとして取得します。

<?php
//1999年12月31日23時21分5秒のタイムスタンプを取得する
print_r(mktime(23, 21, 5, 12, 31, 1999));
// => 946650065
?>

昨日の日付を取得するには、date()mktime()を組み合わせて使用します。
ポイントは「date("d") - 1」です。

<?php
//昨日の日付を取得する
$time = mktime(date("H"), date("i"), date("s"), date("m"), date("d") - 1, date("Y"));
print_r(date('Y/n/j G:i:s', $time));
// => 2007/8/15 12:50:22
?>

明日の日付を取得するには、「date("d") + 1」です。

<?php
//明日の日付を取得する
$time = mktime(date("H"), date("i"), date("s"), date("m"), date("d") + 1, date("Y"));
print_r(date('Y/n/j G:i:s', $time));
// => 2007/8/17 12:51:45
?>

2007年08月17日

1.2.日付の正確な解析とファジィ解析(RubyクックブックをPHPに翻訳する)

RubyクックブックをPHPに翻訳してみる。

レシピ1.2.日付の正確な解析とファジィ解析

checkdate()は、グレグリオ歴の日付/時刻の妥当性を確認します。

<?php
var_dump(checkdate(12, 31, 2000));
var_dump(checkdate(2, 29, 2001));
?> 

bool(true)
bool(false)

strtotime()は、英文形式の日付を Unix タイムスタンプに変換します。

<?php
echo date('Y/n/j G:i:s', strtotime("now")), "\n";
// => 2007/8/16 13:16:01

echo date('Y/n/j G:i:s', strtotime("10 September 2000")), "\n";
// => 2000/9/10 0:00:00

echo date('Y/n/j G:i:s', strtotime("+1 day")), "\n";
// => 2007/8/17 13:16:01

echo date('Y/n/j G:i:s', strtotime("+1 week")), "\n";
// => 2007/8/23 13:16:01

echo date('Y/n/j G:i:s', strtotime("+1 week 2 days 4 hours 2 seconds")), "\n";
// => 2007/8/25 17:16:03

echo date('Y/n/j G:i:s', strtotime("next Thursday")), "\n";
// => 2007/8/23 0:00:00

echo date('Y/n/j G:i:s', strtotime("last Monday")), "\n";
// => 2007/8/13 0:00:00
?>

strptime()は、strftime()が生成した日付/時刻をパースします。
※注意: この関数は Windows 環境にはまだ実装されていません。

<?php
print_r(strptime('2007/8/18 13:25:37', '%Y/%m/%d %H:%M:%S'));
?php

Array
(
    [tm_sec] => 37
    [tm_min] => 25
    [tm_hour] => 13
    [tm_mday] => 18
    [tm_mon] => 7
    [tm_year] => 107
    [tm_wday] => 6
    [tm_yday] => 229
    [unparsed] =>
)
?>

2007年08月20日

1.3.日付の出力(RubyクックブックをPHPに翻訳する)

RubyクックブックをPHPに翻訳してみる。

レシピ1.3.日付の出力

strftime()は、ロケールの設定に基づいてローカルな日付・時間をフォーマットします。

<?php
echo date('Y/n/j G:i:s', strtotime("now")), "\n";
// => 2007/8/16 13:16:01

echo date('Y/n/j G:i:s', strtotime("10 September 2000")), "\n";
// => 2000/9/10 0:00:00

echo date('Y/n/j G:i:s', strtotime("+1 day")), "\n";
// => 2007/8/17 13:16:01

echo date('Y/n/j G:i:s', strtotime("+1 week")), "\n";
// => 2007/8/23 13:16:01

echo date('Y/n/j G:i:s', strtotime("+1 week 2 days 4 hours 2 seconds")), "\n";
// => 2007/8/25 17:16:03

echo date('Y/n/j G:i:s', strtotime("next Thursday")), "\n";
// => 2007/8/23 0:00:00

echo date('Y/n/j G:i:s', strtotime("last Monday")), "\n";
// => 2007/8/13 0:00:00
?>

date()は、ローカルの日付/時刻を書式化します。

<?php
//書式を指定して、現在の時間を取得する。
print_r(date('Y/n/j G:i:s'));
// => 2007/8/16 12:38:29
?>

idate()は、ローカルな時刻/日付を整数として整形します。

<?php
//年
print_r(idate('Y'));
// => 2008

//月
print_r(idate('m'));
// => 8
?>

2007年08月21日

レシピ1.4.日付の反復

RubyクックブックをPHPに翻訳してみる。

レシピ1.4.日付の反復

mktimeはUNIXのタイムスタンプを返します。
このタイムスタンプは秒数を表しています。

<?php
///1999年12月31日から2000年1月10日までの繰り返し
$day = 60 * 60 * 24; //1日の秒数
$from = mktime(0, 0, 0, 12, 31, 1999);
$to = mktime(0, 0, 0,  1, 10, 2000);
for ($date = $from;
     $date <= $to;
     $date += $day) {
  print_r(date('Y/m/d', $date) . '<br />');
}
?>

2007年08月22日

レシピ1.5.日付の演算

RubyクックブックをPHPに翻訳してみる。

レシピ1.5.日付の演算

タイムスタンプに秒数を加減して計算する

<?php
//タイムスタンプに秒数を加減して計算する
//2008年9月1日の10日後を求める
$date = mktime(0, 0, 0, 9, 1, 2008); //2008年9月1日
$inc_day = 10; //10日後
$one_day = 60 * 60 * 24; //1日の秒数
print_r(date('Y年m月d日', $date + $inc_day * $one_day));
// => 2008年9月11日
?>

mktime()の引数を加減して求める。

<?php
//[mktime()][3]の引数を加減して求める。
//2008年9月1日の10日後を求める
$inc_day = 10; //10日後
$date = mktime(0, 0, 0, 9, 1 + $inc_day, 2008); //2008年9月1日
print_r(date('Y年m月d日', $date));
// => 2008年9月11日

//2008年9月1日の10日前を求める
$inc_day = -10; //10日前。負の数を指定する
$date = mktime(0, 0, 0, 9, 1 + $inc_day, 2008); //2008年9月1日
print_r(date('Y年m月d日', $date));
// => 2008年8月22日
?>

月末の日付を求める。
mktime()の日に「0」を指定すると、前月の月末の日付を取得できます。

<?php
$date = mktime(0, 0, 0, 9, 0, 2008); //2008年9月0日
print_r(date('Y年m月d日', $date));
// => 2008年8月31日
?>

2つの日付の間隔を求めるには、タイムスタンプの差から日数を計算します。

<?php
$from = mktime(0, 0, 0, 9, 1, 2008); //2008年9月1日
$to = mktime(0, 0, 0, 9, 11, 2008); //2008年9月1日
$one_day = 60 * 60 * 24; //1日の秒数
$period = ($to - $from) / $one_day;
print_r($period);
// => 10
?>

2007年08月23日

レシピ1.6 任意の日付からの経過日数

RubyクックブックをPHPに翻訳してみる。

レシピ1.6 任意の日付からの経過日数

特定の日付から何日が経過したか、あるいは未来の日付まであと何日残っているか知りたい。

特定の日付から何日が経過したか

<?php
//2007年1月1日から何日が経過したか
$t1 = mktime(0, 0, 0, 1, 1, 2007); //2007年1月1日のタイムスタンプ
$t2 = time(); //現在のタイムスタンプ
$one_day = 60 * 60 * 24; //1日の秒数
echo ($t2 - $t1) / $one_day; //2007年1月1日からの経過日数
// => 234.69549768519
?>

未来の日付まであと何日残っているか

<?php
//未来の日付まであと何日残っているか
$t1 = mktime(0, 0, 0, 1, 1, 2008); //2008年1月1日のタイムスタンプ
$t2 = time(); //現在のタイムスタンプ
$one_day = 60 * 60 * 24; //1日の秒数
echo ($t1 - $t2) / $one_day;
// => 130.30420138889
?>

レシピ1.7 タイムゾーンの変換

RubyクックブックをPHPに翻訳してみる。

レシピ1.7 タイムゾーンの変換

ほかのタイムゾーンで同じ瞬間を表したい。

datedefaulttimezone_set()は、スクリプト中の日付/時刻関数で使用されるデフォルトタイムゾーンを設定します。

<?php
echo date('r', time());
// => Thu, 23 Aug 2007 16:56:02 +0900

//タイムゾーンをUTCに設定する
date_default_timezone_set('UTC');
echo date('r', time());
// => Thu, 23 Aug 2007 07:56:03 +0000
?>

timezoneidentifierslist()は、すべてのタイムゾーン識別子を含む配列を返します。

<?php
//すべてのタイムゾーンで現在時刻を表示する
$now = $time;
foreach (timezone_identifiers_list() as $timezone) {
  date_default_timezone_set($timezone);
  echo date("r", $now).": {$timezone}\n";
}
?>

2007年08月25日

phpDocumentor PHPのAPI仕様書作成プログラム

PHPのAPI仕様書作成プログラムは、phpDocumentorが標準的のようです。

phpDocumentorの文法は、Javadocと非常によく似ています。

これなら、すぐに使えそう。

2007年08月27日

レシピ1.10 曜日の検出

RubyクックブックをPHPに翻訳してみる。

レシピ1.10 曜日の検出

特定の曜日を知りたい。

date()は、与えられたフォーマット文字列によりフォーマットし、日付文字列を返します。

フォーマット文字列に「w」を指定すると、曜日を数値(0(日曜)から6(土曜))で返します。

<?php
echo date('w', mktime(0, 0, 0, 9, 1, 2007)); //2007年9月1日
# => 6

$day = array("日", "月", "火", "水", "木", "金", "土");
$i = date('w', mktime(0, 0, 0, 9, 1, 2007));
echo $day[$i];
# => "土"
?>

フォーマット文字列に「D」を指定すると、曜日を3文字のテキスト形式で返します。

<?php
echo date('D', mktime(0, 0, 0, 9, 1, 2007)); //2007年9月1日
# => Sat
?>

フォーマット文字列に「D」を指定すると、曜日をフルスペル形式で返します。

<?php
echo date('l', mktime(0, 0, 0, 9, 1, 2007)); //2007年9月1日
# => Saturday
?>

getdate()は、日付情報を連想配列で返します。 連想配列の「wday」キーには、曜日が数値(0(日曜)から6(土曜))で設定されます。

<?php
$date = getdate(mktime(0, 0, 0, 9, 1, 2007)); //2007年9月1日
echo $date['wday']
# => 6
?>

2007年08月28日

レシピ1.8 夏時間のチェック

RubyクックブックをPHPに翻訳してみる。

レシピ1.8 夏時間のチェック

現在のロケールの時刻が夏時間がどうかを知りたい。

date()は、与えられたフォーマット文字列によりフォーマットし、日付文字列を返します。

フォーマット文字列に「I」(大文字のi)を指定すると、夏時間なら1、そうでなければ0を返します。

<?php
echo date('I', mktime(0, 0, 0, 9, 1, 2007)); //2007年9月1日
# => 0
?>

2007年08月29日

レシピ1.11 商業日の処理

RubyクックブックをPHPに翻訳してみる。

レシピ1.11 商業日の処理

暦日ではなく商業日を扱う必要がある。

[date()]は、与えられたフォーマット文字列によりフォーマットし、日付文字列を返します。

フォーマット文字列に「o」を指定すると商業年度、 「W」を指定すると商業週、 「N」を指定すると商業曜日を返します。
(それぞれRubyのDate#cwyear、Date#cweek、Date#cwdayに対応している、と 思う)

<?php
$sunday = mktime(0, 0, 0, 1, 1, 2006);

echo date('o', $sunday); //2006年1月1日
# => 2005

echo date('W', $sunday); //2006年1月1日
# => 52

echo date('N', $sunday); //2006年1月1日
# => 7
?>

2007年10月31日

『CakePHPガイドブック』レビュー

CakePHPガイドブック』を一通り流して読みました。
まだ実際にコードは書いていません。

ざっと読んでみた感想ですが、この本一冊あればCakePHPで開発できるようなるに思います。
CakePHPの導入から実際の開発に必要な情報まで、十分に詳しく解説されています。
おそらく定番の一冊のなることでしょう。

Chapter9のセキュリティに関する章はいいですね。
セキュリティについて、どういった点に注意しなければならないかというのは、CakePHPに精通しており、かつ、実際に開発している人でないと、なかなかわからないことです。
開発する段階では、とても参考になると思います。

日本語環境用(文字コード)の設定手順の解説も嬉しいです。

あと、ソースコードが読みやすいように感じました。
ソースコードの重要な箇所は網掛けしてありコメントがつくため、ポイントがわかりやすいです。
重要箇所だけが掲載されるのではなく、前後のソースコードが省略されずにちゃんと掲載されているので、プログラムを理解しやすいと思いました。

CakePHP 1.2についての記載があるのもいいですね。
CakePHP 1.2の登場が楽しみです。
1.2がリリースされたら、1.2対応版もぜひ出版していただきたい。

初版第一刷なので、多少の誤字・脱字・コードの間違いがあるのは仕方がないですね。
検索してみたのですが、正誤表が見つかりませんでした。そのうち公開されることと思います。

Chapter7のModelについての章で、メソッドの返値についての記載がないのが、不便に思いました。
たとえば、executeについての説明(117ページ)は次の一行だけです。

queryと同様にSQLコマンドを実行します。実行結果の返却方法に違いがあります。

executeの存在価値は、queryとの返値の違いだけです。
ならば、返値がどのように違うのかの説明がないと、実際に使用することができません。

その他にも、Chapter7では全般に返値の説明が不足しているように思いました。
詳細は「CakePHP プログラマーズ リファレンスガイド」を見るとわかりますので、問題ないかもしれません。

179ページのsubmitされているかのチェックが、他の箇所と異なっていました。
なぜここだけ違うのか、理解できませんでした。

// submitされていない場合は初期表示
if (!isset($this->params['form']['submit'])) {

他の箇所では、$this->data を確認しています。

if(empty($this->data)) {

実際にコードを書いてみると、違いに気がつくかもしれません。

206ページの「updateUser()」はおそらく「updateStatus()」の間違い。

218ページのtoLowerメソッドは、無限ループしそう。(未確認)
引数が配列の時、SimpleFilterComponent::toLower($elem) が呼ばれて、その中でもまた、SimpleFilterComponent::toLower($elem)が呼ばれて…、となりませんか。

function toLower(&$elem)
{
    if (is_array($elem)) {
        SimpleFilterComponent::toLower($elem);
    }
    $elem = strtolower($elem);
}

226ページの「DboSimpler」はおそらく「DboSimple」の間違い。

まあ、ともかくCakePHPをこれから始めるには、間違いなくお薦めの一冊です。

追記: 正誤表が公開されていますね。

2007年11月11日

PHP用のRSSパーサー MagpieRSS

PHP用のRSSパーサーであるMagpieRSSを使ってみる。

インストール方法

  1. MagpieRSSからファイルをダウンロードする。

  2. ダウンロードしたファイルを展開する。

  3. phpスクリプトと同じフォルダに、拡張子が「.inc」のファイルと「extlib」フォルダをコピーする。

  4. 「cache」フォルダを作成し、アクセス権を設定する。

    chmod 775 cache (サーバーの設定によっては、777)

  5. 最終的な構成は次のようになる。

    ├index.php
    ├rss_cache.inc
    ├rss_fetch.inc
    ├rss_parse.inc
    ├rss_utils.inc
    ├extlib
    │└Snoopy.class.inc
    └cache
    

次に、必要に応じてプログラム側の設定を行う。
「MAGPIE_OUTPUT_ENCODING」は設定を怠ると、日本語が文字化けするので注意。

<?php
//キャッシュフォルダの場所
//define('MAGPIE_CACHE_DIR', '/tmp/magpierss');
//キャッシュを無効にする
//define('MAGPIE_CACHE_ON', 0);
//キャッシュの寿命
//define('MAGPIE_CACHE_AGE', 60*60); //1時間
//文字コード
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
?>

簡単な使い方は、次のサイトを見るとわかる。

RSSのキーワード抽出

RSSから指定されたキーワードを含むフィードを抽出して表示するプログラムを作成しました。

2007年12月05日

PHPの文法チェック

「-l」オプションでPHPの文法をチェックできます。

php -l filename.php

CakePHPのインストールで404 Not Foundが表示されたとき

CakePHPのインストールは簡単で、公式サイトからファイルをダウンロードして展開するだけ。
のはずだったのですが、「404 Not Found」と表示されてしまいました。

feedtailor Inc. 大石裕一の開発ブログCakePHPのチュートリアルで気をつけたいことという記事を発見して無事に解決。
初期設定では、/に設置されることを前提になっているんですね。
ありがとうございます。

以下、メモを残しておきます。

CakePHPをインストールしたディレクトリにある.htaccessに以下の行を追加。

RewriteBase /~yamamoto/cake/

CakePHPをインストールしたディレクトリ/app にある.htaccessに以下の行を追加。

RewriteBase /~yamamoto/cake/app/

CakePHPをインストールしたディレクトリ/app/webroot にある.htaccessに以下の行を追加。

RewriteBase /~yamamoto/cake/app/webroot/

2007年12月06日

半角カタカナを全角カタカナに変換する

PHPでメールを送信するときなど、半角カタカナを全角カタカナに変換する処理が必要になることがあります。

PHPではこの変換を行う専用の関数 mb_convert_kana が用意されています。

//半角カタカナを全角カタカナに変換する
$zenkaku = mb_convert_kana($hankaku, 'KV', 'UTF-8');

2007年12月21日

CakePHPのModel.generateListの引数

Model.generateListのキーとカラムの引数について。

CakePHPガイドブック』には、「モデル名.フィールド名」のような形で指定すると記載されています。

Bookmark.id

ところがこの方法ではうまくいかず。

調べてみたところ、キーとカラムの指定は、「{n}.モデル名.フィールド名」のような形で指定するようです。

{n}.Bookmark.id

バージョンの違いでしょうか。

2007年12月26日

「PHP5徹底攻略」レビュー

PHP5徹底攻略』は、PHP5の入門書です。
PHPプログラミングの経験のない入門者が対象です。

この本の構成は、ステップアップ編とリファレンス編からなります。
ステップアップ編では、PHPスクリプトをコマンドラインから動かして学んでいきます。

しかし、PHPをこれから学びたいという人はWebアプリを作りたいと思っているはずです。
PHPはWebアプリを簡単に作れるのが特徴であるのに、最初にコマンドラインを使って学ぶことに疑問を感じます。
PHPスクリプトをブラウザでアクセスして、プログラムが動作する感動を体験することで、興味とやる気が出てくると思うのです。

サンプルコードの難易度も疑問です。
ステップアップ編ではほとんど文法についての説明がありませんが、サンプルコードにはさまざまな関数が使用されています。
これから学ぼうとする人にとっては、わからないことばかり。
挫折感を味わうことにならないでしょうか。

リファレンス編は、一般的な内容です。
PHP関数リファレンスは、WebのPHP マニュアルとほとんど同じような印象を受けました。

それから、PHP5で大幅に強化されたオブジェクト指向については、説明がありません。
PHP4を知っていてPHP5をこれから学ぼうと考えている人は、『PHP5徹底攻略』はやめたほうがいいです。

『独習PHP』レビュー

『独習PHP』は、PHP5の入門書です。
PHP5ならPHP5と、ちゃんと書名に書いてもらいたいところです。
解説もわかりやすいですし、構成もわかりやすく、後から読み直す時も使いやすそうに感じました。

『PHP5徹底攻略』と違い、ちゃんとオブジェクト指向についても解説されています。
PEARやSmaryなどの説明のあり、ちょっとお得な感じです。

PHPの入門書として、お薦めできる本であると思います。

2007年12月29日

CakePHPのdebugレベルをproductionにするとThe requested address was not found on this server.になる問題

CakePHPのdebugレベルをproductionにすると、「The requested address was not found on this server.」というエラーメッセージが表示され、解決に時間をとられました。

開発中はdebugレベルが1以上でしたので、問題なく動作していました。

define('DEBUG', 1);

debugレベルをproductionに変更して、

define('DEBUG', 0);

運用サーバーに設置すると、「The requested address was not found on this server.」というエラーメッセージが表示されます。

試しにdebugレベルをdevelopmentにすると、問題なく動作します。

問題があったのは、app/tmpフォルダとその下のフォルダのアクセス権でした。
tmpフォルダの下には、cacheフォルダやlogフォルダがあります。
おそらく、ここにファイルを作成できなかったためエラーが発生していたのではないかと思います。

tmpフォルダのアクセス権にはご注意ください。

2008年01月07日

CakePHPのModelのわかりにくいところ

CakePHP1.1を使ってみて、特にController内のModelを理解するのに時間がかかりました。
ということで、そのまとめ。

まず、Controller内の「$this->Model」はModelクラスのインスタンスということ。

idが$idのデータを読み込む方法。

$this->Model->read(null, $id);

以下のコードも同じ結果になります。

$this->Model->id = $id;
$this->Model->read();

落とし穴は、自動的にid属性が設定される場合があること。

2回続けて保存したとき、1件しか登録されません。

$this->Model->save($this->data); //新規保存
$this->Model->save($this->data); //更新保存になる

原因は、1回目の「$this->Model->save()」で保存したときに「$this->Model->id」が自動的に設定されるため。

対策は、「$this->Model->id」をクリアするか、「$this->Model」を新規にすること。

「$this->Model->id」をクリアする方法。

$this->Model->save($this->data);
$this->Model->id = NULL;
$this->Model->save($this->data);

「$this->Model」を新規にする方法。

$this->Model->save($this->data);
$this->Model->create();
$this->Model->save($this->data);

「$this->Model」はインスタンスで、状態を持っていることに気がつけば、原因に気づくことができるでしょう。

次に関連モデルの結果を取得する方法について。

findAll()の6番目の引数で、取得する関連モデルの階層を指定することができます。

$this->Model->findAll(null, null, null, null, null, 2);

ただ、この方法だと「null, null, …, 」というのが、あまり見た目が良くないように思います。

$this->Model->recursive = 2;
$this->Model->findAll($conditions);

多少は見やすいのではないかと。

モデルの定義で、$recursiveの初期値を指定することもできます。

class モデル名 extends AppModel {
  var $recursive = 2; //初期値を指定

他にも何かあったような気がしますが、忘れました。
思い出したら、追記します。

2008年02月10日

第2回CakePHP勉強会が大人気らしい

2月20日に第2回CakePHP勉強会が行われます。
場所は、やっぱり東京。
島根にいたらダメだな。

朝10時ごろに募集が始まってから正午すぎには座席が埋まってしまうとは予想外です。

yandodの日記

すごい人気ですね。

2008年02月19日

WordPressのデータベースにアクセスするプログラムの作り方

WordPressのデータベースにアクセスするプログラムの簡単な作り方。

使用したのは、wordpress-2.2.3-multilingual-edition。

wp-cofig.phpをrequireします。

require('wordpress/wp-config.php');

これだけで、$wpdbを通してデータベースにアクセスできます。
$wpdbはwp-includes/wp-db.phpで定義されています。

データの登録には、$wpdb->query(sql) を使用します。

$wpdb->query("INSERT INTO …");

レコードを1行だけ取得するには、$wpdb->get_row(sql) を使用します。

$mylink = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id = 10");
echo $mylink->link_id; // prints "10"

複数行のレコードを取得するには、$wpdb->get_results(sql) を使用します。

$rows = $wpdb->get_results("SELECT * FROM …");
foreach ($rows as $row) {
  echo $row->post_title;
}

テーブル名は、データベースのテーブル名から接頭辞を除いた名称で取得できます。

$wpdb->posts
$wpdb->categories

2008年05月24日

レンタルサーバーでフルパスがわからないときに調べる方法

レンタルサーバーでフルパスがわからないときに調べる方法。

次のコードを記述したファイルをアップロードして、ブラウザからアクセスします。

sample.php

<?php
echo __FILE__;
?>

ブラウザに表示されたパスが、アップロードしたファイルのフルパスになります。

2008年05月25日

NetBeansがPHPに対応しているらしい。

最近NetBeansがよさげ+PHPにも対応したみたいなので試してみた」の記事によると、NetBeansがPHPに対応しているらしい。
この記事では、NetBeansのインストールからCakePHPの使い始めのところまで、解説されています。

デバッグ機能がどうなっているのか、興味のあるところ。
一度、試してみたいです。

2008年10月04日

IBM developerWorks:CodeIgniter入門

IBM developerWorksでCodeIgniter入門という記事が公開されています。

CodeIgniterは以前にも使用したことがあり、使い方を間違わなければ、便利なフレームワークだと思います。

おすすめは小規模なWebアプリケーションです。

その理由。

その1。学習コストが低いこと。
フレームワーク自体の規模が小さいので学ぶことが少なくてすみます。
また、CodeIgniter ユーザガイド 日本語版という非常に優れたオンラインドキュメントがあります。
ファイルの設置場所はRuby on Railsに似ていますので、Ruby on Railsを知っている人は理解しやすいと思います。

その2。安価なレンタルサーバーでも動作すること。
PHP4とPHP5の両方に対応しています。
インストールはコピーするだけ。
フレームワークは軽量でサーバーのスペックを要求しません。
要するに、ロリポップなどの安価なレンタルサーバーでも問題なく動作します。

欠点は、Active Recordが貧弱なこと。
データベースの処理が多いアプリケーションだと、面倒かもしれません。

2008年11月22日

NetBeans 6.5 リリース(PHPに正式対応)

NetBeansの6.5がリリースされました。
6.5ではPHPに正式対応したようです。

フリーで使えるPHPのIDEは、優秀なものがありませんでしたので、
NetBeansには期待してしまいます。

Pythonのアーリーアクセス版が公開されていますので、
次に対応する言語はPythonになりそうです。
これも期待。

2009年09月22日

小規模なWebアプリにCodeIgniterが向いている理由

小規模なWebアプリを作成するのに、CodeIgniterを使用しました。
以前にも同じようなことを書いたような気もしますが、 CodeIgniterはやっぱり偉い。

小規模なWebアプリにCodeIgniterが向いている理由

  • インストールはコピーするだけ
    小規模アプリなのに、導入コストが高いなんてあり得ない。

  • 安価なレンタルサーバでも動作可能
    小規模アプリなので、サーバにお金はかけられない。

  • シンプルな作りで学習コストが低い
    小規模アプリなのに、学習時間が長いと本末転倒

  • 充実した日本語マニュアル
    使い方を学ぶのにお金がかかりません。

  • CodeIgniter日本語化で日本語環境にも完全対応
    安心して使えます。

  • 充実したバリデーション機能
    とても便利。開発効率もいい。

  • 付属のユニットテストは簡易だが必要十分
    ただし、大規模アプリには辛いかも。

以下、備忘録

バリデーション機能CodeIgniter日本語化を導入すると、エラーメッセージが日本語になります。
インストール方法は単純にファイルを上書きするだけ。
インストール後はconfig.phpを編集して、languageを"japanese"に修正します。

//$config['language']   = "english";
$config['language'] = "japanese";

メールの送信もCodeIgniter日本語化で日本語に対応できるようです。 使い方はとても簡単。詳細はマニュアルのEmail Classを参照。

$this->load->library('email');

$this->email->from('your@example.com', 'Your Name');
$this->email->to('someone@example.com');
$this->email->cc('another@another-example.com');
$this->email->bcc('them@their-example.com');

$this->email->subject('Email Test');
$this->email->message('Testing the email class.');

$this->email->send();
//echo $this->email->print_debugger();

バリデーションは便利。使わないと損。
$this->validation->set_error_delimiters()は、$this->validation->run() の前に行うこと。

About PHP

ブログ「山本隆の開発日誌」のカテゴリ「PHP」に投稿されたすべてのエントリーのアーカイブのページです。過去のものから新しいものへ順番に並んでいます。

前のカテゴリはOpenPNEです。

次のカテゴリはPerlです。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 3.35