[php][pear]HTTP_Request2のサンプル#2

Posted under php by uechoco on 水曜日 21 1月 2009 at 23 : 30 : 06

この記事は、HTTP_Requestのマニュアルに載っている全サンプルコードをHTTP_Request2対応で書き換えてみる企画の2回目です。HTTP_Request2クラスの概要を知りたい方は、下記リンクの#1を参照ください。 全記事へのリンク:

#3 Basic 認証

php:
  1. <?php
  2. /**
  3.  * 例 48-3 Basic 認証
  4.  *
  5.  * @link http://pear.php.net/manual/ja/package.http.http-request.basic-auth.php
  6.  */
  7. require_once 'HTTP/Request2.php';
  8.  
  9. try {
  10.     $req = new HTTP_Request2("http://example.com/protected.html");
  11.     $req->setAuth("johndoe", "foo", HTTP_Request2::AUTH_BASIC);
  12.     $response = $req->send();
  13.     echo $response->getBody();
  14.  
  15. } catch (HTTP_Request2_Exception $e) {
  16.     die($e->getMessage());
  17. } catch (Exception $e) {
  18.     die($e->getMessage());
  19. }
  20.  
  21. /*****************************
  22.  * HTTP_Request::setBasicAuth()はHTTP_Request2->setAuth()に変更されました。
  23.  * 第3引数で認証の種類(AUTH_BASIC、AUTH_DIGEST)が指定できますが、
  24.  * Basic認証(AUTH_BASIC)がデフォルト値なので、今回は省略してもかまいません。
  25.  *****************************/
  26.  
  27. /*
  28. require_once "HTTP/Request.php";
  29.  
  30. $req =& new HTTP_Request("http://example.com/protected.html");
  31. $req->setBasicAuth("johndoe", "foo");
  32.  
  33. $response = $req->sendRequest();
  34.  
  35. if (PEAR::isError($response)) {
  36.     echo $response->getMessage();
  37. } else {
  38.     echo $req->getResponseBody();
  39. }
  40.  
  41. */
  42. ?>

#4 リクエストにクッキーを追加する

php:
  1. <?php
  2. /**
  3.  * 例 48-4 リクエストにクッキーを追加する
  4.  *
  5.  * この例では、version というクッキーが HTTP リクエストに追加されます。
  6.  * このクッキーの値は、 HTTP_Request2 インスタンスが動作している PHP インタプリタのバージョン文字列です。
  7.  *
  8.  * @link http://pear.php.net/manual/ja/package.http.http-request.cookie.php
  9.  */
  10. require_once 'HTTP/Request2.php';
  11.  
  12. try {
  13.     $req = new HTTP_Request2("http://example.com/");
  14.     $req->addCookie("version", phpversion());
  15.     $response = $req->send();
  16.     echo $response->getBody();
  17.  
  18. } catch (HTTP_Request2_Exception $e) {
  19.     die($e->getMessage());
  20. } catch (Exception $e) {
  21.     die($e->getMessage());
  22. }
  23.  
  24. /*****************************
  25.  * HTTP_Request::addCookie()はHTTP_Request2->addCookie()としてそのまま受け継がれています。
  26.  *****************************/
  27.  
  28. /*
  29. require_once "HTTP/Request.php";
  30.  
  31. $req =& new HTTP_Request("http://example.com/");
  32. $req->addCookie("version", phpversion());
  33.  
  34. $response = $req->sendRequest();
  35.  
  36. if (PEAR::isError($response)) {
  37.     echo $response->getMessage();
  38. } else {
  39.     echo $req->getResponseBody();
  40. }
  41. */
  42. ?>

#5 HTTP レスポンスからクッキーを読み込む

php:
  1. <?php
  2. /**
  3.  * 例 48-5 HTTP レスポンスからクッキーを読み込む
  4.  *
  5.  * HTTP レスポンスのクッキーを読み込みは、以下の例で示されます。
  6.  *
  7.  * @link http://pear.php.net/manual/ja/package.http.http-request.cookie.php
  8.  */
  9. require_once 'HTTP/Request2.php';
  10.  
  11. try {
  12.     $req = new HTTP_Request2("http://example.com/");
  13.     $response = $req->send();
  14.     print_r($response->getCookies());
  15.  
  16. } catch (HTTP_Request2_Exception $e) {
  17.     die($e->getMessage());
  18. } catch (Exception $e) {
  19.     die($e->getMessage());
  20. }
  21.  
  22. /*****************************
  23.  * HTTP_Request::getResponseCookies()はHTTP_Request2_Response->getCookies()に変更されました。
  24.  *****************************/
  25.  
  26. /*
  27. require_once "HTTP/Request.php";
  28.  
  29. $req =& new HTTP_Request("http://example.com/");
  30.  
  31. $response = $req->sendRequest();
  32.  
  33. if (PEAR::isError($response)) {
  34.     echo $response->getMessage();
  35. } else {
  36.     print_r($req->getResponseCookies());
  37. }
  38. */
  39. ?>


[php][pear]HTTP_Request2のサンプル#1

Posted under php by uechoco on 水曜日 21 1月 2009 at 23 : 21 : 55

誰もが愛用しているPEAR::HTTP_Requestクラスですが、最近は後継のPEAR::HTTP_Request2クラスがリリースされてちょっと話題になりました。2009/01/21現在、バージョンは0.2.0(alpha)になっています。今後は利用される場面が増えてくると思いますので、HTTP_Requestのマニュアルに載っている全サンプルコードをHTTP_Request2対応で書き換えてみました。ソースコードやAPIリファレンスから推測して書いているので、100%正しいソースコードという保証はできませんが、そこら辺はあなたの技量でカバーしてください(笑。

とはいえ、HTTP_Request2の概要を知らない方も多いと思いますので、まずは0.2.0(alpha)時点でのHTTP_Request2の概要をまとめておきます。

  • 特徴
    • HTTP_RequestをPHP5対応に書きなおした
    • アダプタに対応
      • SocketAdapter : 従来のHTTP_Requestに相当する
      • CurlAdapter : cURL拡張のラッパー
      • MockAdapter : HTTP_Request2に依存しているパッケージのテスト用
    • POSTリクエストにおいて以下の項目に対応
      • データとファイルのアップロード
      • クッキー認証
      • プロキシ
      • gzipとdeflateエンコーディング
      • Observerを用いたリクエスト処理のモニタリング
  • 動作環境
  • 0.3.0のロードマップ
    • Socketアダプタにて、HTTPSプロキシのサポート
    • Socketアダプタにて、ダイジェスト認証のサポート

個人的にはcURL拡張以外でダイジェスト認証が使えるようになるのか?っていうのがちょっと期待しているところです。今まで探してもなかったもので・・・。

さてさて、本題のサンプルですね。HTTP_Requestのマニュアルには、全13個のサンプルソースコードが載っています。ブログが長くなるのも面倒なので、小分けにして紹介していきたいと思います。一応、記述の根拠となるように、変更点もコメントしておきましたので、参考にしてください。

#1 yahoo.com の内容を取得し、それを表示する

php:
  1. /**
  2. * 例 48-1 yahoo.com の内容を取得し、それを表示する
  3. *
  4. * @link http://pear.php.net/manual/ja/package.http.http-request.intro.php
  5. */
  6. require_once 'HTTP/Request2.php';
  7.  
  8. try {
  9. $req = new HTTP_Request2("http://www.yahoo.com/");
  10. $response = $req-&gt;send();
  11. echo $response-&gt;getBody();
  12.  
  13. } catch (HTTP_Request2_Exception $e) {
  14. die($e-&gt;getMessage());
  15. } catch (Exception $e) {
  16. die($e-&gt;getMessage());
  17. }
  18.  
  19. /*****************************
  20. * クラス名はHTTP_Request2になりました。
  21. *
  22. * コンストラクタも内部で使用するメソッドが例外を吐く可能性があるので、
  23. * HTTP_Request2を使用する箇所全体をtry/catchで囲みましょう。
  24. *
  25. * HTTP_Request::sendRequest()はHTTP_Request2-&gt;send()に変更されました。
  26. * このとき、返り値はHTTP_Request2_Responseクラスになります。
  27. *
  28. * HTTP_Request::getResponseBody()はHTTP_Request2_Response::getBody()に変更されました。
  29. *****************************/
  30.  
  31. /*
  32. ///////////////////////////////
  33. // 旧ソースコード
  34. ///////////////////////////////
  35. require_once 'HTTP/Request.php';
  36.  
  37. $req =&amp; new HTTP_Request("http://www.yahoo.com/");
  38. if (!PEAR::isError($req-&gt;sendRequest())) {
  39. echo $req-&gt;getResponseBody();
  40. }
  41. */
  42. ?&gt;

#2 二つの Web サイトの内容を取得し、一行で表示する

php:
  1. /**
  2. * 例 48-2 二つの Web サイトの内容を取得し、一行で表示する
  3. *
  4. * この例では、二つの Web サイトの内容が取得され、表示されます。
  5. * 前者は POST パラメータが処理されます。POST データスタックは、
  6. * 二番目の Web サイトの内容が取得される前にクリアされます。
  7. *
  8. * @link http://pear.php.net/manual/ja/package.http.http-request.intro.php
  9. */
  10. require_once 'HTTP/Request2.php';
  11.  
  12. try {
  13. $req = new HTTP_Request2("http://www.php.net", HTTP_Request2::METHOD_POST);
  14. // $req-&gt;setMethod(HTTP_Request2::METHOD_POST);
  15. $req-&gt;addPostParameter('Foo', 'bar');
  16. $response1 = $req-&gt;send();
  17.  
  18. $req-&gt;setMethod(HTTP_Request2::METHOD_GET);
  19. $req-&gt;setURL("http://pear.php.net");
  20. // $req-&gt;clearPostData();
  21. $response2 = $req-&gt;send();
  22.  
  23. echo $response1-&gt;getBody();
  24. echo $response2-&gt;getBody();
  25.  
  26. } catch (HTTP_Request2_Exception $e) {
  27. die($e-&gt;getMessage());
  28. } catch (Exception $e) {
  29. die($e-&gt;getMessage());
  30. }
  31.  
  32. /*****************************
  33. * クラス名はHTTP_Request2になりました。
  34. *
  35. * HTTP_Request2::setMethod()は健在ですが、コンストラクタの第2引数にHTTPメソッドを指定するのが楽です。
  36. *
  37. * HTTP_Request::addPostData()はHTTP_Request2-&gt;addPostParameter()に変更されました。
  38. * このとき、返り値はHTTP_Request2_Responseクラスになります。
  39. *
  40. * HTTP_Request2::setUrl()は今まで通りURLの文字列を受け付けますが、Net_URL2クラスも受け付けます。
  41. *
  42. * HTTP_Request::clearPostData()に当たるメソッドはHTTP_Request2には見受けられません。
  43. * POSTメソッドの後にGETメソッドを送信しても、HTTP_Request2-&gt;addPostParameter()で設定したパラメータは
  44. * 送信されることはありませんでした。(Wiresharkでパケットキャプチャをして確認済みです)
  45. *****************************/
  46.  
  47. /*
  48. require_once "HTTP/Request.php";
  49.  
  50. $req =&amp; new HTTP_Request("http://www.php.net");
  51. $req-&gt;setMethod(HTTP_REQUEST_METHOD_POST);
  52. $req-&gt;addPostData("Foo", "bar");
  53. if (!PEAR::isError($req-&gt;sendRequest())) {
  54. $response1 = $req-&gt;getResponseBody();
  55. } else {
  56. $response1 = "";
  57. }
  58.  
  59. $req-&gt;setMethod(HTTP_REQUEST_METHOD_GET);
  60. $req-&gt;setURL("http://pear.php.net");
  61. $req-&gt;clearPostData();
  62. if (!PEAR::isError($req-&gt;sendRequest())) {
  63. $response2 = $req-&gt;getResponseBody();
  64. } else {
  65. $response2 = "";
  66. }
  67.  
  68. echo $response1;
  69. echo $response2;
  70.  
  71. */
  72. ?&gt;

全記事へのリンク:


[php][PEAR]PEAR::Date_Holidays_Driver_Japanese 0.2.2リリース

Posted under php by uechoco on 日曜日 11 5月 2008 at 20 : 22 : 53

PEAR::Date_Holidays_Driver_Japanese 0.2.2 - Do You PHP はてな

うえちょこ@ぼろぐ ? [php][pear]Date_Holidays_Driver_Japaneseを使ってみた

うえちょこ@ぼろぐ ? [php][PEAR]Date_Holidays_Driver::setYear()が変

眠る開発屋blog ? Date_Holidays_Driver::setYear()とか

うえちょこ@ぼろぐ ? [php][PEAR]Date_Holidays_Driver::setYear()が変の原因調査

4連荘で同じライブラリの記事を書くことも珍しいです。今朝方、Date_Holidays_Driver::setYear()の挙動がおかしいとつぶやいたところ、Date_Holidays_Driver_Japaneseの開発者のshimookaさんに伝わってしまったようで、対応してくださいました。ありがとうございます。

どうやらトリッキーな方法でうまく解決したようです。これによって、Date_Holidays_Driver::setYear()の挙動がおかしいために、毎回インスタンスを作り直して翻訳ファイルを再設定していたところを、setYear()だけで済むようになりました。ただし、内部で同等の処理をするようにしただけなので、コストはほぼ変わっていません。

ところで、

眠る開発屋blog ? Date_Holidays_Driver_Japaneseを使ってみるとか2

にもありますが、Date_Holidays_Driver::isHoliday()は非常にコストが高いので、使わないほうがいいですよ。私の代替案としてはDate_Holidays_Driver::getHolidayForDate()がnullかどうかを調べます。こちらのほうが断然早いです。


[php][PEAR]Date_Holidays_Driver::setYear()が変の原因調査

Posted under php by uechoco on 日曜日 11 5月 2008 at 18 : 36 : 59

今朝のうえちょこ@ぼろぐ ? [php][PEAR]Date_Holidays_Driver::setYear()が変がやっぱり気になったので、少しだけ調査。

※PEAR::Date_Holidays_Driver_Japanese 0.2.2がリリースされました。下記不具合を包括的に解決しています。0.2.0以前を使用してる方は、アップグレードすることを強くお勧めします。

PEAR::Date_Holidays_Driver_Japanese 0.2.2 - Do You PHP はてな

1.$this->_internalNamesが増殖する件 ===================

Date_Holidays_Driver::serYear()メソッドを呼び出すと、内部の仕様でDate_Holidays_Driver::_buildHolidays()メソッドが呼ばれます。_buildHolidays()メソッドは、各国別のドライバがその国々の祝日を登録するメソッドです。

_buildHolidays()メソッドの内部では、祝日の数だけDate_Holidays_Driver::_addHoliday()メソッドを呼び出して、祝日を登録します。_addHoliday()メソッドだけ抜き出してみます。

php:
  1. /**
  2. * Adds a holiday to the driver's holidays
  3. *
  4. * @param string $internalName internal name - must not contain characters
  5. *                              that aren't allowed as variable-names
  6. * @param mixed  $date         date (timestamp | string | PEAR::Date object)
  7. * @param string $title        holiday title
  8. *
  9. * @access   protected
  10. * @return   void
  11. */
  12. function _addHoliday($internalName, $date, $title)
  13. {
  14. if (! is_a($date, 'Date')) {
  15. $date = new Date($date);
  16. }
  17.  
  18. $this-&gt;_dates[$internalName]       = $date;
  19. $this-&gt;_titles['C'][$internalName] = $title;
  20. $isodate                           = mktime(0, 0, 0,
  21. $date-&gt;getMonth(),
  22. $date-&gt;getDay(),
  23. $date-&gt;getYear());
  24. if (!isset($this-&gt;_holidays[$isodate])) {
  25. $this-&gt;_holidays[$isodate] = array();
  26. }
  27. array_push($this-&gt;_holidays[$isodate], $internalName);
  28. array_push($this-&gt;_internalNames, $internalName);
  29. }

$this->_internalNamesが増殖する原因は、この_addHoliday()メソッドの最後のarray_push() x 2です。2回目以降のビルドのときに呼び出されると、$this->_datesや$this->_titlesは与えられた$internalNamesの祝日情報を上書きするのですが、$this->_holidays[$isodate]と$this->_internalNamesだけは上書きせず、後ろに追加します。これが増殖の原因。ただし、増殖することがバグであるかどうかは知りません(そういう仕様が正しいかもしれない)。しかし、素人目ではバグの気がしてなりません。

なお、ライブラリの修正方法としては、最後のarray_push()の前に、しっかりとif (! in_array())の条件分岐をしてあげることです。

2.振替休日と国民の祝日が表示されない件 ===================

2回目以降の再構築のとき、振替休日と国民の祝日が表示されなくなります。実は

$obj->getHolidayForDate($d, 'ja_JP');

つまり、日本語の翻訳ファイルを使用したときには表示されないのですが、

$obj->getHolidayForDate($d, 'C');

('C'というのは、内部仕様で、内部英名を現すロケール)を用いて英名にすると振替休日と国民の祝日が表示されます。

ここからわかることは、翻訳ファイルがらみで何かがおかしいということです。

さてさて、中身を見ていきます。

Date_Holidays_Driver_Japaneseでは、2回目以降の再構築の際、振替休日と国民の祝日の祝日情報を消去します。消去にはDate_Holidays_Driver::_removeHoliday()メソッドを用いています。そして、消去し終わると、すべての祝日を_addHolidays()メソッドで登録し、その上で振替休日と国民の祝日を計算します。

_removeHoliday()メソッドでは、指定した祝日に関する(翻訳情報を含む)すべての祝日情報を消去します。
_addHolidays()メソッドでは、内部英名の祝日情報を登録します。

よろしくないのは、_removeHoliday()は、翻訳情報を消してしまうのです。

安易な考えですが、_removeHoliday()メソッドでの翻訳情報の削除部分を取り除いてしまえばいいのでは!?と思いついてやってみたのですが、うまくいきませんでした。翻訳ファイルを読み込むDate_Holidays_Driver::addTranslationFile()メソッドは、どうやら、現在登録されている祝日だけの翻訳情報を読み込むようです。余分なデータを読み込まないのはいいことですが、年が変わって再構築でひょっこり新しい祝日が出てきてしまうと翻訳情報がないので、そのロケールでは表示できないのです。これが原因です。

エンドユーザー側の解決策としては、setYear()したら、addTranslationFile()で翻訳ファイルを読み直すのが手っ取り早いです。

ライブラリ自体の解決策としては、「this->_titles」とは別の系統に翻訳情報のマッピング変数を用意して、そこに「現在登録されている祝日のものだけ」読み込むのではなく「すべて」読み込んで、内部ロケール以外のロケールで表示するような要求があった場合、マッピング変数を用いて表示するとか、そういう感じですかね。とっても面倒な変更です。他にスマートな方法があればいいのですが。。。

そんなわけで、調査終了。原因がわかったのでスッキリ。ライブラリ自体にはモヤっとだけど。


[php][PEAR]Date_Holidays_Driver::setYear()が変

Posted under php by uechoco on 日曜日 11 5月 2008 at 03 : 39 : 33

正確に言うと、Date_Holidays_Driver_Japanese::setYear()の挙動が変。

※PEAR::Date_Holidays_Driver_Japanese 0.2.2がリリースされました。下記不具合を包括的に解決しています。0.2.0以前を使用してる方は、アップグレードすることを強くお勧めします。

PEAR::Date_Holidays_Driver_Japanese 0.2.2 - Do You PHP はてな

Date_Holidaysクラスのfactory()メソッドはDriver名を指定するのと同時に、西暦を指定して祝日リストを生成します。西暦を指定していない場合は、内部で自動的に現在の西暦が採用されます。もし西暦が違う祝日を一緒に扱う場合(たとえば2008年と2009年)、ドライバをもう1度生成し、翻訳ファイルを登録しなければなりません。

それは面倒だと思って、APIドキュメントをあさっていると、Date_Holidays_Driver::setYear()というメソッドを見つけました。どうやら、西暦をセットしなおした上で祝日の再構築を行ってくれるようです。エンドユーザー・マニュアルがないので100%とは言い切れませんが、ソースコードからはそう判断できます。

で、早速使ってみたソースコードがこちら。

php:
  1. /**
  2. * Date_Holidays_Driver_Japanseを用いて
  3. * 祝日名を取得する(挙動がおかしい)
  4. *
  5. * 2008/05/11
  6. *
  7. * Author:   uechoco
  8. * 動作確認: PHP 5.2.5
  9. * require:  Date_Holidays (推奨バージョン:0.18.0)
  10. * require:  Date_Holidays_Driver_Japanese 0.2.0
  11. *
  12. */
  13.  
  14. // Date_Holidaysクラスの読み込み
  15. require_once "Date/Holidays.php";
  16.  
  17. // 言語ファイルの読み込み(PEARのdataディレクトリ内)
  18. define('LANG_FILE', 'C:/php5/pear/data/Date_Holidays_Driver_Japanese/lang');
  19.  
  20. // Date_Holidaysオブジェクトの生成(西暦を省略すると現在の西暦になる)
  21. $obj =&amp; Date_Holidays::factory('Japanese');
  22. if (Date_Holidays::isError($obj)) {
  23. die('Factory was unable to produce driver-object');
  24. }
  25.  
  26. // 翻訳ファイルをロケール=ja_JPとして登録
  27. $obj-&gt;addTranslationFile(LANG_FILE . '/Japanese/ja_JP.xml', 'ja_JP');
  28. if (Date_Holidays::isError($obj)) {
  29. die($obj-&gt;getMessage());
  30. }
  31.  
  32. $lastYear = 0;
  33. $beginTime = mktime(0, 0, 0, 1, 1, 2008);
  34. for ($i = 0; $i &lt;731; $i++) {
  35. $t = $beginTime + $i * 86400;
  36. $d = strftime('%Y-%m-%d', $t);
  37. // 西暦が更新されたら祝日の再構成
  38. $y = strftime('%Y', $t);
  39. if ($lastYear != $y) {
  40. $obj-&gt;setYear(intval($y));
  41. $lastYear = $y;
  42. //デバッグ用にオブジェクトを直接吐く
  43. //echo "
  44.  
  45. <hr /><span style="color: red;">\n\n";
  46. //print_r($obj-&gt;_internalNames);
  47. //echo "</span>
  48.  
  49. <hr />\n\n";
  50.  
  51. }
  52.  
  53. $holiday = $obj-&gt;getHolidayForDate($d, 'ja_JP');
  54. if (!is_null($holiday))
  55. printHolidayInfo($holiday, $d);
  56. }
  57.  
  58. function printHolidayInfo($holiday, $date = '')
  59. {
  60. echo $date . " =========
  61. \n";
  62. printf("名前:%s
  63. \n", $holiday-&gt;getTitle());
  64. //printf("内部名:%s
  65. \n", $holiday-&gt;getInternalName());
  66. //printf("プロパティ:%s
  67. \n", print_r($holiday-&gt;getProperties(), true));
  68. //printf("Dateクラス:%s
  69. \n", print_r($holiday-&gt;getDate(), true));
  70. }
  71. exit;
  72. ?&gt;

で、出力結果がこちら。

CODE:
  1. 2008-01-01 =========
  2. 名前:元日
  3. 2008-01-14 =========
  4. 名前:成人の日
  5. 2008-02-11 =========
  6. 名前:建国記念の日
  7. 2008-03-20 =========
  8. 名前:春分の日
  9. 2008-04-29 =========
  10. 名前:昭和の日
  11. 2008-05-03 =========
  12. 名前:憲法記念日
  13. 2008-05-04 =========
  14. 名前:みどりの日
  15. 2008-05-05 =========
  16. 名前:こどもの日
  17. 2008-07-21 =========
  18. 名前:海の日
  19. 2008-09-15 =========
  20. 名前:敬老の日
  21. 2008-09-23 =========
  22. 名前:秋分の日
  23. 2008-10-13 =========
  24. 名前:体育の日
  25. 2008-11-03 =========
  26. 名前:文化の日
  27. 2008-11-23 =========
  28. 名前:勤労感謝の日
  29. 2008-12-23 =========
  30. 名前:天皇誕生日
  31. 2009-01-01 =========
  32. 名前:元日
  33. 2009-01-12 =========
  34. 名前:成人の日
  35. 2009-02-11 =========
  36. 名前:建国記念の日
  37. 2009-03-20 =========
  38. 名前:春分の日
  39. 2009-04-29 =========
  40. 名前:昭和の日
  41. 2009-05-03 =========
  42. 名前:憲法記念日
  43. 2009-05-04 =========
  44. 名前:みどりの日
  45. 2009-05-05 =========
  46. 名前:こどもの日
  47. 2009-07-20 =========
  48. 名前:海の日
  49. 2009-09-21 =========
  50. 名前:敬老の日
  51. 2009-09-23 =========
  52. 名前:秋分の日
  53. 2009-10-12 =========
  54. 名前:体育の日
  55. 2009-11-03 =========
  56. 名前:文化の日
  57. 2009-11-23 =========
  58. 名前:勤労感謝の日
  59. 2009-12-23 =========
  60. 名前:天皇誕生日

パッと見でよさそうに見えますが、よく見てみると、振替休日と国民の休日が表示されていないことに気がつきます。動作確認環境はWindows/XAMPP PHP5.2.5です。

少しだけ動作確認してみました。

★まず、オブジェクトを西暦が変わるたびに生成しなおすと、正常な結果になります。

php:
  1. $lastYear = 0;
  2. $beginTime = mktime(0, 0, 0, 1, 1, 2008);
  3. for ($i = 0; $i &lt;731; $i++) {
  4. $t = $beginTime + $i * 86400;
  5. $d = strftime('%Y-%m-%d', $t);
  6. // 西暦が更新されたら祝日の再構成
  7. $y = strftime('%Y', $t);
  8. if ($lastYear != $y) {
  9. // 西暦を指定してDate_Holidaysオブジェクトの生成
  10. $obj =&amp; Date_Holidays::factory('Japanese', $y);
  11. if (Date_Holidays::isError($obj)) {
  12. die('Factory was unable to produce driver-object');
  13. }
  14. // 翻訳ファイルをロケール=ja_JPとして登録
  15. $obj-&gt;addTranslationFile(LANG_FILE . '/Japanese/ja_JP.xml', 'ja_JP');
  16. if (Date_Holidays::isError($obj)) {
  17. die($obj-&gt;getMessage());
  18. }
  19. $lastYear = $y;
  20. }
  21. $holiday = $obj-&gt;getHolidayForDate($d, 'ja_JP');
  22. if (!is_null($holiday))
  23. printHolidayInfo($holiday, $d);
  24. }

★setYear()の直後に、$obj->_internalNamesを吐き出してみると、serYear()する度に$_internalNames配列が初期化されておらず、末尾に追加されていることがわかります。おそらく、$objに含まれる他のプロパティにも似たような現象が見られるかもしれません。

CODE:
  1. Array
  2. (
  3. [0] =&gt; newYearsDay
  4. [1] =&gt; comingOfAgeDay
  5. [2] =&gt; nationalFoundationDay
  6. [3] =&gt; Vernal Equinox Day
  7. [4] =&gt; showaDay
  8. [5] =&gt; constitutionMemorialDay
  9. [6] =&gt; greeneryDay
  10. [7] =&gt; childrensDay
  11. [8] =&gt; marineDay
  12. [9] =&gt; respectfortheAgedDay
  13. [10] =&gt; autumnalEquinoxDay
  14. [11] =&gt; healthandSportsDay
  15. [12] =&gt; nationalCultureDay
  16. [13] =&gt; laborThanksgivingDay
  17. [14] =&gt; emperorsBirthday
  18. [17] =&gt; newYearsDay
  19. [18] =&gt; comingOfAgeDay
  20. [19] =&gt; nationalFoundationDay
  21. [20] =&gt; Vernal Equinox Day
  22. [21] =&gt; showaDay
  23. [22] =&gt; constitutionMemorialDay
  24. [23] =&gt; greeneryDay
  25. [24] =&gt; childrensDay
  26. [25] =&gt; marineDay
  27. [26] =&gt; respectfortheAgedDay
  28. [27] =&gt; autumnalEquinoxDay
  29. [28] =&gt; healthandSportsDay
  30. [29] =&gt; nationalCultureDay
  31. [30] =&gt; laborThanksgivingDay
  32. [31] =&gt; emperorsBirthday
  33. [32] =&gt; substituteHolidayForgreeneryDay
  34. [33] =&gt; substituteHolidayForlaborThanksgivingDay
  35. )
  36. Array
  37. (
  38. [0] =&gt; newYearsDay
  39. [1] =&gt; comingOfAgeDay
  40. [2] =&gt; nationalFoundationDay
  41. [3] =&gt; Vernal Equinox Day
  42. [4] =&gt; showaDay
  43. [5] =&gt; constitutionMemorialDay
  44. [6] =&gt; greeneryDay
  45. [7] =&gt; childrensDay
  46. [8] =&gt; marineDay
  47. [9] =&gt; respectfortheAgedDay
  48. [10] =&gt; autumnalEquinoxDay
  49. [11] =&gt; healthandSportsDay
  50. [12] =&gt; nationalCultureDay
  51. [13] =&gt; laborThanksgivingDay
  52. [14] =&gt; emperorsBirthday
  53. [17] =&gt; newYearsDay
  54. [18] =&gt; comingOfAgeDay
  55. [19] =&gt; nationalFoundationDay
  56. [20] =&gt; Vernal Equinox Day
  57. [21] =&gt; showaDay
  58. [22] =&gt; constitutionMemorialDay
  59. [23] =&gt; greeneryDay
  60. [24] =&gt; childrensDay
  61. [25] =&gt; marineDay
  62. [26] =&gt; respectfortheAgedDay
  63. [27] =&gt; autumnalEquinoxDay
  64. [28] =&gt; healthandSportsDay
  65. [29] =&gt; nationalCultureDay
  66. [30] =&gt; laborThanksgivingDay
  67. [31] =&gt; emperorsBirthday
  68. [34] =&gt; newYearsDay
  69. [35] =&gt; comingOfAgeDay
  70. [36] =&gt; nationalFoundationDay
  71. [37] =&gt; Vernal Equinox Day
  72. [38] =&gt; showaDay
  73. [39] =&gt; constitutionMemorialDay
  74. [40] =&gt; greeneryDay
  75. [41] =&gt; childrensDay
  76. [42] =&gt; marineDay
  77. [43] =&gt; respectfortheAgedDay
  78. [44] =&gt; autumnalEquinoxDay
  79. [45] =&gt; nationalHolidayBeforeAutumnalEquinoxDay
  80. [46] =&gt; healthandSportsDay
  81. [47] =&gt; nationalCultureDay
  82. [48] =&gt; laborThanksgivingDay
  83. [49] =&gt; emperorsBirthday
  84. [50] =&gt; substituteHolidayForconstitutionMemorialDay
  85. )

setYear()を使うと振替休日と国民の休日だけ表示されないので、Date_Holidays_Driver_Japaneseがおかしいのかな?って思ったりもしたんですが、内部名が初期化されていないのはDate_Holidays_Driverもおかしい気がしないでもないのですが、今眠くて深追いする気が起きません(ぉぃ。

解決策としては、西暦が変わったら、オブジェクトを新規に生成しなおすのが早そうです。


« 前ページへ次ページへ »

Copyright © 2012 うえちょこ@ぼろぐ. WP Theme created by Web Top.