SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ますます便利になるPHPの新機能を探ろう!

より使いやすくなったPHP 8.3の新機能──クラスや変数定義、エラーと例外の強化ポイントを解説

ますます便利になるPHPの新機能を探ろう! 第3回


  • X ポスト
  • このエントリーをはてなブックマークに追加

エラーや例外に関する機能強化

 続けて、一部の拡張機能におけるエラーや例外のハンドリングに関する機能強化について紹介します。

SQLiteにおける例外発生のデフォルト化

 PHP 8.3以降から、SQLite3拡張モジュールにおける例外発生の設定が変化していきます。PDOなどではすでにデフォルトで例外を発生するようになっているので、これに合わせる形になります。PHP 8.3ではSQLite3Exceptionが新設され、表のように例外の発生について変更されていきます。ちなみにenableExceptionsメソッドは、例外の発生の有無を引数(既定値はfalse)で設定し、直前の状態を返します。

表 SQLite3拡張モジュールにおける例外発生の変化
バージョン 既定でのenableExceptions()の戻り値 enableExceptions(false)の結果
8.2 false(例外発生なし) 実行可(例外なしに戻せる)
8.3 false、E_DEPRECATED発生(例外発生なし) E_DEPRECATED発生(例外なしに戻せる)
9 true(例外発生あり) エラー(例外なしに戻せない)、E_DEPRECATED発生(引数をtrueにした場合)
10 メソッド未定義のエラー メソッド未定義のエラー

 このように、PHP 8.3では例外のあり/なしを使い分けることができますが、将来的には例外なしの状態に戻せなくなり、最終的にはenableExceptionsメソッドそのものも廃止されます。

 PHP 8.3のみで関数の呼び出し結果を見てみると、以下のようになります。enableExceptions(true)によって例外発生に設定できるが、元に戻そうとするとE_DEPRECATEDとなるわけです。

リスト sqlite_except.php
var_dump($sqlite3->enableExceptions());		// false(E_DEPRECATED)
var_dump($sqlite3->enableExceptions(true));	// false
var_dump($sqlite3->enableExceptions(false));	// true(E_DEPRECATED)

Date/Timeにおけるエラーハンドリング強化

 PHP 8.3では、Date/Time拡張機能について、固有のエラーと例外を発生するようになりました。以前は、エラーはErrorクラス、例外はExceptionクラスがスローされるだけでしたので、エラーと例外のハンドリングが困難でした。今回、固有のエラーと例外によって、問題発生時のハンドリングが容易になります。

 以下の9つのエラー/例外のクラスが追加されています。

Throwable
  ├── Error
  |     └── DateError
  |             ├── DateObjectError		未初期化のオブジェクトで発生
  │             └── DateRangeError		整数値の上限を超えたら発生
  └── Exception
        └── DateException
                ├── DateInvalidTimeZoneException	不正なタイムゾーン文字列
                ├── DateInvalidOperationException	DateTimeオブジェクトの不正な操作
                ├── DateMalformedStringException	日付/時刻文字列が不正
                ├── DateMalformedIntervalStringException	間隔文字列が不正
                └── DateMalformedPeriodStringException	期間文字列が不正

 DataError派生クラスは、主にコーディングミスなどに由来するエラーにより発生します。ただし、関数などに不正な値が渡された場合のValueError、TypeError、Errorは従来通り発生します。新しいDateErrorクラスを継承するDateObjectErrorとDateRangeErrorは、それぞれ未初期化のオブジェクトの使用、日付処理でエポック値(1970年1月1日午前0時0分0秒からの秒数)がPHPの扱える整数値の上限を超えるような場合に発生します。

 DataException派生クラスは、主にタイムゾーン、日付/時刻、間隔(インターバル)、期間(ピリオド)文字列のパースの失敗により発生します。以下のリストは、これらを確かめる例です。

リスト datetime_exception.php
// DateInvalidTimeZoneException
$utc_tz = new DateTimeZone("UTC");              // OK
$bad_tz = new DateTimeZone("NotValidTZ");      // エラー	(1)
// エラー:Uncaught DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (NotValidTZ)

// DateInvalidOperationException
$now_dt = new DateTimeImmutable("2023-11-23 12:34:56 JST");
$seven_day = DateInterval::createFromDateString('7 days');
$now_dt = $now_dt->add($seven_day);             // OK         
$next_thrsday = DateInterval::createFromDateString('next thursday');
$now_dt = $now_dt->sub($next_thrsday);          // エラー	(2)
// エラー:Uncaught DateInvalidOperationException: DateTimeImmutable::sub(): Only non-special relative time specifications are supported for subtraction

// DateMalformedStringException
$good_dt = new DateTime('now');        // OK
$bad_dt = new DateTime('not now');     // エラー	(3)
// エラー:Uncaught DateMalformedStringException: Failed to parse time string (not now) at position 0 (n): The timezone could not be found in the databas

// DateMalformedIntervalStringException
$good_di = new DateInterval('P7D');     // OK
$bad_di = new DateInterval('now');      // エラー	(4)
// エラー:Uncaught DateMalformedIntervalStringException: Unknown or bad format (now) in

// DateMalformedPeriodStringException
$good_dp = new DatePeriod('R4/2023-11-23T00:00:00Z/P7D');   // OK
$bad_dp = new DatePeriod('10D');        // エラー	(5)
// エラー:Uncaught DateMalformedPeriodStringException: Unknown or bad format (10D)
  • (1)'UTC'は有効なタイムゾーン文字列ですが、'BadTimeZone'は文字通り不正なタイムゾーン文字列です。
  • (2)DateIntervalオブジェクトが「次の木曜日」を意味していますが、DateTimeImmutableオブジェクトに対してsubメソッド(減算)を実行しようとしているので不正な操作となります。
  • (3)'now'は有効な日付時刻文字列ですが、'not now'は不正な日付時刻文字列です。
  • (4)'P7D'は有効な間隔文字列ですが、'now'は不正な間隔文字列です。
  • (5)'R4/2023-11-23T00:00:00Z/P7D'は有効な期間文字列ですが、'10D'は不正な期間文字列です。

まとめ

 今回は、PHP 8.3の新機能のうち、クラスや変数の定義、エラーと例外発生に関連する強化ポイントを中心に紹介しました。

 次回は、言語仕様や関数の強化・改良ポイントを中心に紹介します。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ますます便利になるPHPの新機能を探ろう!連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook <個人紹介> WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18818 2024/01/15 17:32

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング