{"id":3479,"date":"2025-03-24T08:46:05","date_gmt":"2025-03-23T23:46:05","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=3479"},"modified":"2025-03-24T08:46:35","modified_gmt":"2025-03-23T23:46:35","slug":"%e3%80%90%e5%ae%8c%e5%85%a8%e3%82%ac%e3%82%a4%e3%83%89%e3%80%91php-enum%e3%82%92%e5%be%b9%e5%ba%95%e8%a7%a3%e8%aa%ac%ef%bc%81%e5%9f%ba%e6%9c%ac%e3%81%8b%e3%82%89%e5%bf%9c%e7%94%a8%e3%81%be%e3%81%a75-2","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=3479","title":{"rendered":"\u3010\u5b8c\u5168\u30ac\u30a4\u30c9\u3011PHP Enum\u3092\u5fb9\u5e95\u89e3\u8aac\uff01\u57fa\u672c\u304b\u3089\u5fdc\u7528\u307e\u30675\u3064\u306e\u5b9f\u8df5\u4f8b"},"content":{"rendered":"\n<p>PHP\u30d7\u30ed\u30b0\u30e9\u30de\u30fc\u306a\u3089\u8ab0\u3082\u304c\u7d4c\u9a13\u3057\u305f\u3053\u3068\u304c\u3042\u308b\u3067\u3057\u3087\u3046\u3002\u30b9\u30c6\u30fc\u30bf\u30b9\u3084\u7a2e\u5225\u306a\u3069\u306e\u56fa\u5b9a\u5024\u3092\u6271\u3046\u969b\u3001\u30af\u30e9\u30b9\u5b9a\u6570\u3084\u914d\u5217\u3092\u4f7f\u3063\u3066\u4f55\u3068\u304b\u578b\u5b89\u5168\u6027\u3092\u78ba\u4fdd\u3057\u3088\u3046\u3068\u596e\u95d8\u3059\u308b\u65e5\u3005\u3092\u3002\u300c\u3053\u306e\u5024\u304c\u9069\u5207\u304b\u3069\u3046\u304b\u3001\u5b9f\u884c\u6642\u307e\u3067\u308f\u304b\u3089\u306a\u3044\u300d\u300cIDE\u306e\u88dc\u5b8c\u304c\u52b9\u304b\u305a\u3001\u30bf\u30a4\u30d7\u30df\u30b9\u306b\u6c17\u3065\u3051\u306a\u3044\u300d\u3068\u3044\u3063\u305f\u554f\u984c\u306b\u982d\u3092\u60a9\u307e\u305b\u3066\u304d\u305f\u306e\u3067\u306f\u306a\u3044\u3067\u3057\u3087\u3046\u304b\u3002<\/p>\n\n\n\n<p>PHP 8.1\u3067\u5c0e\u5165\u3055\u308c\u305f\u300cEnum\uff08\u5217\u6319\u578b\uff09\u300d\u306f\u3001\u305d\u3093\u306a\u9577\u5e74\u306e\u8ab2\u984c\u3092\u89e3\u6c7a\u3059\u308b\u5f85\u671b\u306e\u6a5f\u80fd\u3067\u3059\u3002\u5f37\u529b\u306a\u578b\u30c1\u30a7\u30c3\u30af\u3068\u512a\u308c\u305f\u958b\u767a\u8005\u4f53\u9a13\u3092\u4e21\u7acb\u3057\u306a\u304c\u3089\u3001\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u3068\u4fdd\u5b88\u6027\u3092\u5927\u304d\u304f\u5411\u4e0a\u3055\u305b\u308b\u53ef\u80fd\u6027\u3092\u79d8\u3081\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u672c\u8a18\u4e8b\u3067\u306f\u3001PHP Enum\u306e\u57fa\u672c\u6982\u5ff5\u304b\u3089\u5b9f\u8df5\u7684\u306a\u6d3b\u7528\u6cd5\u307e\u3067\u30015\u3064\u306e\u5177\u4f53\u7684\u306a\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u3092\u901a\u3057\u3066\u5fb9\u5e95\u89e3\u8aac\u3057\u307e\u3059\u3002Enum\u3092\u30de\u30b9\u30bf\u30fc\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u5805\u7262\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u8a2d\u8a08\u304c\u53ef\u80fd\u306b\u306a\u308a\u3001\u30d0\u30b0\u306e\u5c11\u306a\u3044\u30af\u30ea\u30fc\u30f3\u306a\u30b3\u30fc\u30c9\u3078\u306e\u9053\u304c\u958b\u3051\u308b\u3067\u3057\u3087\u3046\u3002\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u9023\u643a\u304b\u3089\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u624b\u6cd5\u307e\u3067\u3001\u73fe\u5834\u3067\u5373\u5f79\u7acb\u3064\u77e5\u8b58\u3092\u7db2\u7f85\u7684\u306b\u304a\u5c4a\u3051\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<p>PHP\u306e\u8868\u73fe\u529b\u3068\u578b\u5b89\u5168\u6027\u3092\u6b21\u306e\u30ec\u30d9\u30eb\u3078\u5f15\u304d\u4e0a\u3052\u308b\u65c5\u306b\u3001\u305c\u3072\u3054\u53c2\u52a0\u304f\u3060\u3055\u3044\u3002<\/p>\n\n\n\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">PHP Enum\u3068\u306f\uff1fPHP 8.1\u3067\u5c0e\u5165\u3055\u308c\u305f\u65b0\u6a5f\u80fd\u306e\u5168\u5bb9<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">PHP\u306e\u578b\u30b7\u30b9\u30c6\u30e0\u9032\u5316\u306e\u96c6\u5927\u6210\u3068\u3057\u3066\u306eEnum<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-2\">\u4ed6\u8a00\u8a9e\u306eEnum\u3068PHP Enum\u306e\u9055\u3044<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-4\">PHP Enum\u306e\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u3068\u69cb\u6587<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-5\">Enum\u306e\u57fa\u672c\u7684\u306a\u5ba3\u8a00\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-6\">Enum\u306e\u57fa\u672c\u7684\u306a\u4f7f\u7528\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-7\">Enum\u306e\u7d44\u307f\u8fbc\u307f\u30e1\u30bd\u30c3\u30c9\u3068\u7279\u6027<\/a>      <\/li>      <li>        <a href=\"#i-8\">Backed Enum\u306e\u5ba3\u8a00\u3068\u4f7f\u7528<\/a>      <\/li>      <li>        <a href=\"#i-9\">Enum\u306e\u30e1\u30bd\u30c3\u30c9\u5b9a\u7fa9<\/a>      <\/li>      <li>        <a href=\"#i-10\">Pure Enum\u3068Backed Enum\u306e\u9055\u3044\u3068\u5ba3\u8a00\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-15\">Enum\u306e\u30e1\u30f3\u30d0\u30fc\u3068\u30b1\u30fc\u30b9\u5b9a\u6570\u306e\u5b9a\u7fa9\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-20\">Enum\u306b\u5b9f\u88c5\u3067\u304d\u308b\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3068\u30c8\u30ec\u30a4\u30c8<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-25\">\u5f93\u6765\u306e\u5b9a\u6570\u3068\u6bd4\u8f03\uff1aPHP Enum\u306e\u30e1\u30ea\u30c3\u30c8\u3068\u9650\u754c<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-26\">\u5f93\u6765\u306ePHP\u3067\u306e\u5b9a\u6570\u8868\u73fe\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-30\">PHP Enum\u3068\u5f93\u6765\u624b\u6cd5\u306e\u6bd4\u8f03<\/a>      <\/li>      <li>        <a href=\"#i-31\">PHP Enum\u306e\u4e3b\u306a\u30e1\u30ea\u30c3\u30c8<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-32\">PHP Enum\u306e\u5236\u9650\u4e8b\u9805\u3068\u6ce8\u610f\u70b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-33\">\u5f93\u6765\u306e\u5b9a\u6570\u3068\u6bd4\u8f03\uff1aPHP Enum\u306e\u30e1\u30ea\u30c3\u30c8\u3068\u9650\u754c<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-34\">\u5f93\u6765\u306ePHP\u3067\u306e\u5b9a\u6570\u8868\u73fe\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-38\">PHP Enum\u3068\u5f93\u6765\u624b\u6cd5\u306e\u6bd4\u8f03<\/a>      <\/li>      <li>        <a href=\"#i-39\">PHP Enum\u306e\u4e3b\u306a\u30e1\u30ea\u30c3\u30c8<\/a>      <\/li>      <li>        <a href=\"#i-40\">PHP Enum\u306e\u5236\u9650\u4e8b\u9805\u3068\u6ce8\u610f\u70b9<\/a>      <\/li>      <li>        <a href=\"#i-41\">\u578b\u5b89\u5168\u6027\u306e\u5411\u4e0a\u3068IDE\u30b5\u30dd\u30fc\u30c8\u306e\u5145\u5b9f<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-45\">Enum\u3092\u4f7f\u7528\u3059\u308b\u969b\u306e\u5236\u9650\u4e8b\u9805\u3068\u6ce8\u610f\u70b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-52\">PHP Enum\u306e\u5b9f\u8df5\u7684\u6d3b\u7528\u6cd5\uff1a5\u3064\u306e\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-53\">\u30d1\u30bf\u30fc\u30f3\u6982\u8981<\/a>      <\/li>      <li>        <a href=\"#i-54\">\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u306e\u9078\u629e\u57fa\u6e96<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-55\">\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u306e\u7d44\u307f\u5408\u308f\u305b<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-56\">\u5b9f\u8df5\u4f8b1\uff1a\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u3068\u30d5\u30ed\u30fc\u5236\u5fa1<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-57\">\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u306e\u5f93\u6765\u306e\u8ab2\u984c<\/a>      <\/li>      <li>        <a href=\"#i-58\">Enum\u306b\u3088\u308b\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u306e\u30e1\u30ea\u30c3\u30c8<\/a>      <\/li>      <li>        <a href=\"#i-59\">\u5b9f\u88c5\u4f8b\uff1a\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406<\/a>      <\/li>      <li>        <a href=\"#i-60\">\u5b9f\u969b\u306e\u4f7f\u7528\u4f8b<\/a>      <\/li>      <li>        <a href=\"#i-61\">\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u69cb\u7bc9<\/a>      <\/li>      <li>        <a href=\"#i-62\">\u5b9f\u88c5\u4e0a\u306e\u6ce8\u610f\u70b9\u3068\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-63\">\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u3092Enum\u3067\u8868\u73fe\u3059\u308b\u5b9f\u88c5\u4f8b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-68\">Enum\u3092\u4f7f\u3063\u305f\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u69cb\u7bc9\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-74\">\u5b9f\u8df5\u4f8b2\uff1a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u30c7\u30fc\u30bf\u6574\u5408\u6027\u306e\u78ba\u4fdd<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-75\">\u5f93\u6765\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u624b\u6cd5\u306e\u8ab2\u984c<\/a>      <\/li>      <li>        <a href=\"#i-76\">Enum\u306b\u3088\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5229\u70b9<\/a>      <\/li>      <li>        <a href=\"#i-77\">\u5b9f\u88c5\u4f8b\uff1a\u30d5\u30a9\u30fc\u30e0\u5165\u529b\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/a>      <\/li>      <li>        <a href=\"#i-78\">\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u4f7f\u7528\u4f8b<\/a>      <\/li>      <li>        <a href=\"#i-79\">\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u975e\u4f9d\u5b58\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30af\u30e9\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-80\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u306e\u6574\u5408\u6027\u78ba\u4fdd<\/a>      <\/li>      <li>        <a href=\"#i-81\">API\u30ec\u30b9\u30dd\u30f3\u30b9\u3067\u306e\u6574\u5408\u6027\u78ba\u4fdd<\/a>      <\/li>      <li>        <a href=\"#i-82\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u5b9f\u88c5\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-83\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u9023\u643a\u6642\u306eEnum\u306e\u6271\u3044\u65b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-90\">\u5b9f\u8df5\u4f8b3\uff1a\u30dd\u30ea\u30b7\u30fc\u3068\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-91\">\u6a29\u9650\u7ba1\u7406\u306e\u5f93\u6765\u306e\u8ab2\u984c<\/a>      <\/li>      <li>        <a href=\"#i-92\">Enum\u306b\u3088\u308b\u6a29\u9650\u7ba1\u7406\u306e\u30a2\u30d7\u30ed\u30fc\u30c1<\/a>      <\/li>      <li>        <a href=\"#i-93\">\u5b9f\u88c5\u4f8b\uff1a\u30ed\u30fc\u30eb\u30d9\u30fc\u30b9\u306e\u6a29\u9650\u7ba1\u7406<\/a>      <\/li>      <li>        <a href=\"#i-94\">\u5b9f\u88c5\u4f8b\uff1a\u7d30\u7c92\u5ea6\u306e\u6a29\u9650Enum<\/a>      <\/li>      <li>        <a href=\"#i-95\">\u5b9f\u88c5\u4f8b\uff1a\u30d3\u30c3\u30c8\u30d5\u30e9\u30b0\u3092\u4f7f\u3063\u305f\u52b9\u7387\u7684\u306a\u6a29\u9650\u7ba1\u7406<\/a>      <\/li>      <li>        <a href=\"#i-96\">\u6761\u4ef6\u4ed8\u304d\u6a29\u9650\u30dd\u30ea\u30b7\u30fc\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-97\">\u6a29\u9650\u30b7\u30b9\u30c6\u30e0\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-98\">\u6a29\u9650\u7ba1\u7406\u3092Enum\u3067\u5b9f\u88c5\u3059\u308b\u4f8b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-105\">\u8907\u96d1\u306a\u6761\u4ef6\u5206\u5c90\u3092Enum\u3067\u30af\u30ea\u30fc\u30f3\u306b\u66f8\u304f\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-111\">\u5b9f\u8df5\u4f8b4\uff1a\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-112\">\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u306f<\/a>      <\/li>      <li>        <a href=\"#i-113\">Enum\u3092\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u6d3b\u7528\u3059\u308b<\/a>      <\/li>      <li>        <a href=\"#i-114\">\u3088\u308a\u8907\u96d1\u306a\u30c9\u30e1\u30a4\u30f3\u6982\u5ff5\u306e\u8868\u73fe<\/a>      <\/li>      <li>        <a href=\"#i-115\">DDD\u306b\u304a\u3051\u308b\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/a>      <\/li>      <li>        <a href=\"#i-116\">\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u4f7f\u7528\u3059\u308b\u969b\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-117\">Enum\u3092\u6d3b\u7528\u3057\u305f\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u5b9f\u88c5\u4f8b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-122\">\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3092Enum\u306b\u9589\u3058\u8fbc\u3081\u308b\u8a2d\u8a08\u30d1\u30bf\u30fc\u30f3<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-127\">\u5b9f\u8df5\u4f8b5\uff1aAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u3068\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-128\">API\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u6a19\u6e96\u5316<\/a>      <\/li>      <li>        <a href=\"#i-129\">\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u7ba1\u7406<\/a>      <\/li>      <li>        <a href=\"#i-130\">\u5b9f\u969b\u306e\u4f7f\u7528\u4f8b<\/a>      <\/li>      <li>        <a href=\"#i-131\">\u30b0\u30ed\u30fc\u30d0\u30eb\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-132\">Enum\u3092\u6d3b\u7528\u3057\u305fAPI\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u30e1\u30ea\u30c3\u30c8<\/a>      <\/li>      <li>        <a href=\"#i-133\">\u4e00\u8cab\u6027\u306e\u3042\u308bAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u3092Enum\u3067\u69cb\u7bc9\u3059\u308b<\/a>      <\/li>      <li>        <a href=\"#i-142\">\u4f8b\u5916\u51e6\u7406\u3068\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3092Enum\u3067\u7ba1\u7406\u3059\u308b\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-150\">Laravel\u3067\u306eEnum\u5bfe\u5fdc\u3068\u6d3b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-161\">Symfony\u3067\u306eEnum\u6d3b\u7528\u3068FormType\u9023\u643a<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-170\">PHP Enum\u3092\u4f7f\u3044\u3053\u306a\u3059\u305f\u3081\u306e\u6b21\u306e\u30b9\u30c6\u30c3\u30d7<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-171\">\u8a2d\u8a08\u306e\u898b\u76f4\u3057\u3068Enum\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306e\u30dd\u30a4\u30f3\u30c8<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-177\">\u30c6\u30b9\u30c8\u3068\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\uff1aEnum\u3092\u542b\u3080\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u7ba1\u7406<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-189\">\u307e\u3068\u3081\uff1aPHP Enum\u3067\u5b9f\u73fe\u3059\u308b\u578b\u5b89\u5168\u3067\u5805\u7262\u306a\u30b3\u30fc\u30c9\u8a2d\u8a08<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-190\">Enum\u304c\u63d0\u4f9b\u3059\u308b\u4e3b\u8981\u306a\u30e1\u30ea\u30c3\u30c8<\/a>      <\/li>      <li>        <a href=\"#i-191\">\u5b9f\u8df5\u3067\u306e\u6d3b\u7528\u30b7\u30fc\u30f3<\/a>      <\/li>      <li>        <a href=\"#i-192\">\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3068\u306e\u9023\u643a<\/a>      <\/li>      <li>        <a href=\"#i-193\">Enum\u3092\u8d85\u3048\u3066\uff1aPHP\u578b\u30b7\u30b9\u30c6\u30e0\u306e\u9032\u5316<\/a>      <\/li>      <li>        <a href=\"#i-194\">\u958b\u767a\u30d7\u30ed\u30bb\u30b9\u3078\u306e\u7d71\u5408<\/a>      <\/li>      <li>        <a href=\"#i-195\">\u6b21\u306e\u30b9\u30c6\u30c3\u30d7<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-196\">\u304a\u308f\u308a\u306b<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-0\">PHP Enum\u3068\u306f\uff1fPHP 8.1\u3067\u5c0e\u5165\u3055\u308c\u305f\u65b0\u6a5f\u80fd\u306e\u5168\u5bb9<\/h2>\n\n\n\n<p>PHP 8.1\u306e\u76ee\u7389\u6a5f\u80fd\u3068\u3057\u30662021\u5e7411\u6708\u306b\u6b63\u5f0f\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u305f\u300cEnum\uff08\u5217\u6319\u578b\uff09\u300d\u306f\u3001\u591a\u304f\u306ePHP\u30a8\u30f3\u30b8\u30cb\u30a2\u304c\u9577\u5e74\u5f85\u3061\u671b\u3093\u3067\u3044\u305f\u6a5f\u80fd\u3067\u3059\u3002\u30b7\u30f3\u30d7\u30eb\u306b\u8a00\u3048\u3070\u3001Enum\u306f\u95a2\u9023\u3059\u308b\u5b9a\u6570\u306e\u96c6\u5408\u3092\u578b\u3068\u3057\u3066\u5b9a\u7fa9\u3067\u304d\u308b\u8a00\u8a9e\u6a5f\u80fd\u3067\u3059\u3002\u3057\u304b\u3057\u3001\u305d\u306e\u610f\u7fa9\u3068\u53ef\u80fd\u6027\u306f\u5358\u306a\u308b\u5b9a\u6570\u7fa4\u3092\u306f\u308b\u304b\u306b\u8d85\u3048\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>Enum\u306e\u6838\u5fc3\u306f\u300c\u9650\u5b9a\u3055\u308c\u305f\u5024\u306e\u30bb\u30c3\u30c8\u300d\u3092\u578b\u3068\u3057\u3066\u6271\u3048\u308b\u3053\u3068\u306b\u3042\u308a\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001\u66dc\u65e5\u3084\u65b9\u89d2\u3001HTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u306a\u3069\u3001\u3042\u3089\u304b\u3058\u3081\u6c7a\u307e\u3063\u305f\u5024\u306e\u96c6\u5408\u3092\u53b3\u5bc6\u306b\u5b9a\u7fa9\u3057\u3001\u578b\u5b89\u5168\u306b\u6271\u3048\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u57fa\u672c\u7684\u306aEnum\u306e\u4f8b\nenum Status\n{\n    case DRAFT;\n    case PUBLISHED;\n    case ARCHIVED;\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nfunction updateArticleStatus(Article $article, Status $newStatus): void\n{\n    $article-&gt;status = $newStatus;\n    $article-&gt;save();\n}\n\n\/\/ \u547c\u3073\u51fa\u3057\u4f8b\nupdateArticleStatus($article, Status::PUBLISHED);\n<\/pre>\n\n\n\n<p>PHP\u306eEnum\u306b\u306f\u300cPure Enum\uff08\u7d14\u7c8b\u5217\u6319\u578b\uff09\u300d\u3068\u300cBacked Enum\uff08\u30d0\u30c3\u30af\u30c9\u5217\u6319\u578b\uff09\u300d\u306e2\u7a2e\u985e\u304c\u3042\u308a\u307e\u3059\u3002Pure Enum\u306f\u30b1\u30fc\u30b9\u540d\u306e\u307f\u3092\u6301\u3061\u3001Backed Enum\u306f\u5404\u30b1\u30fc\u30b9\u306b\u6587\u5b57\u5217\u3084\u6574\u6570\u5024\u3092\u95a2\u9023\u4ed8\u3051\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u3053\u306e\u67d4\u8edf\u6027\u306b\u3088\u308a\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3084API\u3068\u306e\u9023\u643a\u306a\u3069\u3001\u69d8\u3005\u306a\u5834\u9762\u3067\u6d3b\u7528\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Backed Enum\u306e\u4f8b (\u6587\u5b57\u5217\u5024\u3092\u6301\u3064)\nenum StatusWithValue: string\n{\n    case DRAFT = 'draft';\n    case PUBLISHED = 'published';\n    case ARCHIVED = 'archived';\n}\n<\/pre>\n\n\n\n<p>PHP Enum\u306e\u7279\u7b46\u3059\u3079\u304d\u70b9\u306f\u3001\u5358\u306a\u308b\u5b9a\u6570\u96c6\u5408\u3067\u306f\u306a\u304f\u3001\u5b8c\u5168\u306a\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6307\u5411\u6a5f\u80fd\u3092\u5099\u3048\u3066\u3044\u308b\u3053\u3068\u3067\u3059\u3002\u30e1\u30bd\u30c3\u30c9\u3001\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u5b9f\u88c5\u3001\u30c8\u30ec\u30a4\u30c8\u4f7f\u7528\u306a\u3069\u3001\u30af\u30e9\u30b9\u3068\u540c\u69d8\u306e\u6a5f\u80fd\u3092\u6d3b\u7528\u3067\u304d\u307e\u3059\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u5024\u3060\u3051\u3067\u306a\u304f\u632f\u308b\u821e\u3044\u3082\u542b\u3081\u305f\u30c9\u30e1\u30a4\u30f3\u306e\u6982\u5ff5\u3092\u8868\u73fe\u53ef\u80fd\u306b\u306a\u308a\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<p>PHP\u306e\u578b\u30b7\u30b9\u30c6\u30e0\u304c\u5e74\u3005\u5f37\u5316\u3055\u308c\u308b\u6d41\u308c\u306e\u4e2d\u3067\u3001Enum\u306f\u300c\u6b63\u3057\u3044\u30c7\u30fc\u30bf\u69cb\u9020\u3067\u6b63\u3057\u3044\u5024\u3060\u3051\u3092\u6271\u3046\u300d\u3068\u3044\u3046\u73fe\u4ee3\u7684\u306a\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30d1\u30e9\u30c0\u30a4\u30e0\u3092\u5f37\u529b\u306b\u5f8c\u62bc\u3057\u3057\u307e\u3059\u3002\u5f93\u6765\u306ePHP\u3067\u306f\u5b9f\u73fe\u304c\u96e3\u3057\u304b\u3063\u305f\u578b\u5b89\u5168\u6027\u3068\u8868\u73fe\u529b\u3092\u4e21\u7acb\u3055\u305b\u305f\u753b\u671f\u7684\u306a\u6a5f\u80fd\u3068\u8a00\u3048\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<p>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001PHP\u306e\u578b\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u306b\u304a\u3051\u308bEnum\u306e\u4f4d\u7f6e\u3065\u3051\u3068\u3001\u4ed6\u8a00\u8a9e\u3068\u306e\u9055\u3044\u306b\u3064\u3044\u3066\u6398\u308a\u4e0b\u3052\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">PHP\u306e\u578b\u30b7\u30b9\u30c6\u30e0\u9032\u5316\u306e\u96c6\u5927\u6210\u3068\u3057\u3066\u306eEnum<\/h3>\n\n\n\n<p>PHP\u8a00\u8a9e\u306e\u6b74\u53f2\u3092\u632f\u308a\u8fd4\u308b\u3068\u3001\u578b\u30b7\u30b9\u30c6\u30e0\u306e\u6bb5\u968e\u7684\u306a\u9032\u5316\u304c\u4e00\u8cab\u3057\u3066\u898b\u3089\u308c\u307e\u3059\u3002\u304b\u3064\u3066\u306e\u300c\u30a6\u30a7\u30d6\u7528\u30b9\u30af\u30ea\u30d7\u30c8\u8a00\u8a9e\u300d\u304b\u3089\u300c\u30a8\u30f3\u30bf\u30fc\u30d7\u30e9\u30a4\u30ba\u958b\u767a\u306b\u582a\u3048\u308b\u8a00\u8a9e\u300d\u3078\u3068\u6210\u9577\u3059\u308b\u904e\u7a0b\u3067\u3001\u578b\u5b89\u5168\u6027\u306e\u5411\u4e0a\u306f\u6700\u3082\u91cd\u8981\u306a\u9032\u5316\u306e\u4e00\u3064\u3067\u3057\u305f\u3002<\/p>\n\n\n\n<p>PHP 5\u6642\u4ee3\u306f\u300c\u52d5\u7684\u578b\u4ed8\u3051\u300d\u3092\u524d\u9762\u306b\u62bc\u3057\u51fa\u3057\u305f\u67d4\u8edf\u306a\u8a00\u8a9e\u3067\u3057\u305f\u304c\u3001\u5927\u898f\u6a21\u958b\u767a\u306b\u304a\u3051\u308b\u4e88\u6e2c\u53ef\u80fd\u6027\u3084\u4fdd\u5b88\u6027\u306e\u8ab2\u984c\u304c\u6d6e\u304d\u5f6b\u308a\u306b\u306a\u3063\u3066\u3044\u307e\u3057\u305f\u3002PHP 7\u304b\u3089\u306f\u578b\u5ba3\u8a00\u306e\u5f37\u5316\u304c\u672c\u683c\u5316\u3057\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u6bb5\u968e\u7684\u9032\u5316\u3092\u9042\u3052\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n<div id=\"id-e6810e62-7ee4-4c62-b97c-882299f307b6\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u30d0\u30fc\u30b8\u30e7\u30f3<\/th><th>\u5c0e\u5165\u3055\u308c\u305f\u578b\u95a2\u9023\u6a5f\u80fd<\/th><\/tr><\/thead><tbody><tr><td>PHP 7.0<\/td><td>\u30b9\u30ab\u30e9\u30fc\u578b\u306e\u5f15\u6570\u5ba3\u8a00\u3001\u623b\u308a\u5024\u306e\u578b\u5ba3\u8a00\u3001strict_types\u30c7\u30a3\u30ec\u30af\u30c6\u30a3\u30d6<\/td><\/tr><tr><td>PHP 7.1<\/td><td>Nullable\u578b\u3001void\u623b\u308a\u5024\u578b<\/td><\/tr><tr><td>PHP 7.4<\/td><td>\u30d7\u30ed\u30d1\u30c6\u30a3\u578b\u5ba3\u8a00\u3001\u5171\u5909\u623b\u308a\u5024\u578b\u30fb\u53cd\u5909\u5f15\u6570\u578b<\/td><\/tr><tr><td>PHP 8.0<\/td><td>Union\u578b\u3001\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u30d7\u30ed\u30d1\u30c6\u30a3\u30d7\u30ed\u30e2\u30fc\u30b7\u30e7\u30f3\u3001Match\u5f0f<\/td><\/tr><tr><td>PHP 8.1<\/td><td><strong>Enum\u578b<\/strong>\u3001Readonly \u30d7\u30ed\u30d1\u30c6\u30a3\u3001Intersection\u578b<\/td><\/tr><tr><td>PHP 8.2<\/td><td>Readonly \u30af\u30e9\u30b9\u3001DNF\u578b<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>\u3053\u306e\u6d41\u308c\u3092\u898b\u308b\u3068\u3001PHP 8.1\u306eEnum\u578b\u306f\u5358\u306a\u308b\u65b0\u6a5f\u80fd\u3067\u306f\u306a\u304f\u3001\u9577\u5e74\u7d9a\u3044\u305f\u578b\u30b7\u30b9\u30c6\u30e0\u9032\u5316\u306e\u96c6\u5927\u6210\u3068\u4f4d\u7f6e\u3065\u3051\u3089\u308c\u307e\u3059\u3002Enum\u306f\u300c\u5024\u306e\u7a2e\u985e\u3092\u5236\u9650\u3059\u308b\u578b\u300d\u3068\u3044\u3046\u65b0\u305f\u306a\u8868\u73fe\u529b\u3092PHP\u306b\u3082\u305f\u3089\u3057\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u6069\u6075\u3092\u3082\u305f\u3089\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u9759\u7684\u89e3\u6790\u306e\u3055\u3089\u306a\u308b\u5f37\u5316<\/strong> \u2013 PHPStan\u3084Psalm\u306a\u3069\u306e\u9759\u7684\u89e3\u6790\u30c4\u30fc\u30eb\u304cEnum\u3092\u8a8d\u8b58\u3057\u3001\u3088\u308a\u7cbe\u5ea6\u306e\u9ad8\u3044\u5206\u6790\u304c\u53ef\u80fd\u306b<\/li>\n\n\n\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u306e\u6b63\u78ba\u306a\u8868\u73fe<\/strong> \u2013 \u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306b\u57fa\u3065\u304f\u5236\u7d04\u3092\u578b\u30b7\u30b9\u30c6\u30e0\u30ec\u30d9\u30eb\u3067\u8868\u73fe\u53ef\u80fd\u306b<\/li>\n\n\n\n<li><strong>\u30b3\u30fc\u30c9\u88dc\u5b8c\u306e\u5411\u4e0a<\/strong> \u2013 IDE\u304c\u5229\u7528\u53ef\u80fd\u306a\u5024\u3092\u6b63\u78ba\u306b\u628a\u63e1\u3057\u3001\u958b\u767a\u8005\u4f53\u9a13\u3092\u5411\u4e0a<\/li>\n\n\n\n<li><strong>\u30d0\u30b0\u306e\u65e9\u671f\u767a\u898b<\/strong> \u2013 \u30b3\u30f3\u30d1\u30a4\u30eb\u6642\uff08\u5b9f\u884c\u524d\uff09\u306b\u578b\u306e\u4e0d\u4e00\u81f4\u3092\u691c\u51fa\u53ef\u80fd<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ PHP 5\u6642\u4ee3: \u6587\u5b57\u5217\u3067\u72b6\u614b\u7ba1\u7406\uff08\u578b\u5b89\u5168\u6027\u306a\u3057\uff09\n$status = 'published'; \/\/ 'publshed'\u3068\u30bf\u30a4\u30d7\u30df\u30b9\u3057\u3066\u3082\u691c\u51fa\u4e0d\u53ef\n\n\/\/ PHP 7+\u30af\u30e9\u30b9\u5b9a\u6570: \u82e5\u5e72\u6539\u5584\u3059\u308b\u3082\u578b\u3068\u3057\u3066\u306f\u6587\u5b57\u5217\u306e\u307e\u307e\n$status = ArticleStatus::PUBLISHED; \/\/ \u5b9a\u6570\u306f\u5b58\u5728\u30c1\u30a7\u30c3\u30af\u3055\u308c\u308b\u304c\u578b\u306f\u6587\u5b57\u5217\n\n\/\/ PHP 8.1 Enum: \u5b8c\u5168\u306a\u578b\u5b89\u5168\u6027\n$status = Status::PUBLISHED; \/\/ Status\u3068\u3044\u3046Enum\u578b\u3068\u3057\u3066\u53b3\u5bc6\u306b\u6271\u308f\u308c\u308b\n<\/pre>\n\n\n\n<p>PHP Enum\u306e\u767b\u5834\u306b\u3088\u308a\u3001\u578b\u30b7\u30b9\u30c6\u30e0\u306f\u300c\u4f55\u304c\u5165\u308b\u304b\u300d\u3060\u3051\u3067\u306a\u304f\u300c\u3069\u306e\u3088\u3046\u306a\u5024\u304c\u8a31\u5bb9\u3055\u308c\u308b\u304b\u300d\u307e\u3067\u3092\u53b3\u5bc6\u306b\u5b9a\u7fa9\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002\u3053\u308c\u306fPHP\u304c\u76ee\u6307\u3057\u3066\u304d\u305f\u300c\u67d4\u8edf\u3055\u3092\u4fdd\u3061\u3064\u3064\u5805\u7262\u6027\u3092\u9ad8\u3081\u308b\u300d\u3068\u3044\u3046\u9032\u5316\u306e\u91cd\u8981\u306a\u30de\u30a4\u30eb\u30b9\u30c8\u30fc\u30f3\u3068\u8a00\u3048\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">\u4ed6\u8a00\u8a9e\u306eEnum\u3068PHP Enum\u306e\u9055\u3044<\/h3>\n\n\n\n<p>\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u8a00\u8a9e\u306b\u3088\u3063\u3066Enum\u306e\u5b9f\u88c5\u65b9\u6cd5\u306f\u5927\u304d\u304f\u7570\u306a\u308a\u307e\u3059\u3002PHP Enum\u3092\u6df1\u304f\u7406\u89e3\u3059\u308b\u306b\u306f\u3001\u4ed6\u8a00\u8a9e\u3068\u306e\u6bd4\u8f03\u304c\u5f79\u7acb\u3061\u307e\u3059\u3002\u3053\u3053\u3067\u306f\u4e3b\u8981\u8a00\u8a9e\u306eEnum\u5b9f\u88c5\u3068PHP\u306e\u9055\u3044\u3092\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-3\">\u4e3b\u8981\u8a00\u8a9e\u306eEnum\u5b9f\u88c5\u6bd4\u8f03<\/h4>\n\n\n<div id=\"id-5e380ceb-d63a-48a5-a446-a74650f100d4\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u8a00\u8a9e<\/th><th>Enum\u7279\u6027<\/th><th>\u5024\u306e\u578b<\/th><th>\u30e1\u30bd\u30c3\u30c9\u5b9a\u7fa9<\/th><th>\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u5b9f\u88c5<\/th><\/tr><\/thead><tbody><tr><td>Java<\/td><td>\u30af\u30e9\u30b9\u30d9\u30fc\u30b9<\/td><td>\u4efb\u610f\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8<\/td><td>\u2705<\/td><td>\u2705<\/td><\/tr><tr><td>C#<\/td><td>\u5024\u578b\uff08struct\uff09<\/td><td>\u6574\u6570\u578b\u306e\u307f<\/td><td>\u274c\uff08\u62e1\u5f35\u30e1\u30bd\u30c3\u30c9\u306f\u53ef\uff09<\/td><td>\u274c<\/td><\/tr><tr><td>TypeScript<\/td><td>\u6570\u5024\/\u6587\u5b57\u5217\u30de\u30c3\u30d4\u30f3\u30b0<\/td><td>\u6570\u5024\/\u6587\u5b57\u5217<\/td><td>\u274c<\/td><td>\u274c<\/td><\/tr><tr><td>Rust<\/td><td>\u4ee3\u6570\u7684\u30c7\u30fc\u30bf\u578b<\/td><td>\u8907\u5408\u578b\u30fb\u30b8\u30a7\u30cd\u30ea\u30c3\u30af<\/td><td>\u2705<\/td><td>\u2705\uff08Trait\uff09<\/td><\/tr><tr><td>Swift<\/td><td>Associated Values<\/td><td>\u8907\u5408\u578b<\/td><td>\u2705<\/td><td>\u2705\uff08Protocol\uff09<\/td><\/tr><tr><td>PHP<\/td><td>\u30af\u30e9\u30b9\u306b\u8fd1\u3044\u7279\u6b8a\u578b<\/td><td>\u6587\u5b57\u5217\/\u6574\u6570\uff08Backed\uff09or \u306a\u3057\uff08Pure\uff09<\/td><td>\u2705<\/td><td>\u2705<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>PHP\u306eEnum\u306f\u3001Java\u306eEnum\u306b\u8fd1\u3044\u5b9f\u88c5\u65b9\u6cd5\u3092\u63a1\u7528\u3057\u3066\u3044\u307e\u3059\u304c\u3001\u3044\u304f\u3064\u304b\u306e\u91cd\u8981\u306a\u9055\u3044\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<p><strong>Java vs PHP:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Java Enum\nenum Status {\n    DRAFT(\"draft\"), PUBLISHED(\"published\"), ARCHIVED(\"archived\");\n    \n    private final String value;\n    \n    Status(String value) {\n        this.value = value;\n    }\n    \n    public String getValue() {\n        return value;\n    }\n}\n<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ PHP Enum (\u540c\u7b49\u306e\u6a5f\u80fd)\nenum Status: string {\n    case DRAFT = 'draft';\n    case PUBLISHED = 'published';\n    case ARCHIVED = 'archived';\n    \n    public function getValue(): string {\n        return $this-&gt;value;\n    }\n}\n<\/pre>\n\n\n\n<p>PHP\u306eEnum\u306f\u3001Java\u307b\u3069\u67d4\u8edf\u306a\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u3092\u6301\u305f\u306a\u3044\u4ee3\u308f\u308a\u306b\u3001\u30b3\u30fc\u30c9\u304c\u3088\u308a\u7c21\u6f54\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p><strong>TypeScript vs PHP:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ TypeScript Enum\nenum Status {\n    DRAFT = 'draft',\n    PUBLISHED = 'published',\n    ARCHIVED = 'archived'\n}\n<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ PHP Backed Enum\nenum Status: string {\n    case DRAFT = 'draft';\n    case PUBLISHED = 'published';\n    case ARCHIVED = 'archived';\n}\n<\/pre>\n\n\n\n<p>\u8868\u9762\u4e0a\u306f\u985e\u4f3c\u3057\u3066\u3044\u307e\u3059\u304c\u3001TypeScript\u306eEnum\u306f\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306b\u5358\u306a\u308b\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u5909\u63db\u3055\u308c\u308b\u306e\u306b\u5bfe\u3057\u3001PHP\u306eEnum\u306f\u5b9f\u884c\u6642\u306b\u3082\u578b\u3068\u3057\u3066\u6a5f\u80fd\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<p><strong>\u7279\u7b46\u3059\u3079\u304dPHP Enum\u306e\u7279\u5fb4:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30e1\u30bd\u30c3\u30c9\u5b9f\u88c5\u306e\u67d4\u8edf\u6027<\/strong> \u2013 PHP\u306eEnum\u306fJava\u306b\u8fd1\u3044\u5f62\u3067\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3067\u304d\u307e\u3059<\/li>\n\n\n\n<li><strong>\u30c8\u30ec\u30a4\u30c8\u4f7f\u7528\u53ef\u80fd<\/strong> \u2013 \u5171\u901a\u306e\u6a5f\u80fd\u3092\u30c8\u30ec\u30a4\u30c8\u3068\u3057\u3066\u5b9f\u88c5\u3057\u3001\u8907\u6570\u306eEnum\u3067\u518d\u5229\u7528\u3067\u304d\u307e\u3059<\/li>\n\n\n\n<li><strong>\u30af\u30e9\u30b9\u3068\u306e\u89aa\u548c\u6027<\/strong> \u2013 \u30af\u30e9\u30b9\u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u578b\u3001\u5f15\u6570\u578b\u3001\u623b\u308a\u5024\u578b\u3068\u3057\u3066\u30b7\u30fc\u30e0\u30ec\u30b9\u306b\u4f7f\u7528\u3067\u304d\u307e\u3059<\/li>\n\n\n\n<li><strong>Pure\/Backed\u4e8c\u7a2e\u985e\u306e\u5b9f\u88c5<\/strong> \u2013 \u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u306b\u5fdc\u3058\u3066\u9069\u5207\u306a\u5f62\u5f0f\u3092\u9078\u629e\u3067\u304d\u307e\u3059<\/li>\n\n\n\n<li><strong>\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u5236\u9650<\/strong> \u2013 \u4ed6\u8a00\u8a9e\u3068\u7570\u306a\u308a\u3001PHP\u306eEnum\u306f\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u3067\u304d\u307e\u305b\u3093\uff08\u5185\u90e8\u5b9f\u88c5\u306e\u5236\u7d04\uff09<\/li>\n<\/ol>\n\n\n\n<p>PHP Enum\u306e\u5b9f\u88c5\u306f\u3001\u67d4\u8edf\u306a\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6a5f\u80fd\u3092\u6301\u3061\u306a\u304c\u3089\u3082\u3001\u5217\u6319\u578b\u3068\u3057\u3066\u7d5e\u308a\u8fbc\u307e\u308c\u305f\u7279\u6027\u3092\u6301\u3064\u3088\u3046\u8a2d\u8a08\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u4ed6\u306e\u8a00\u8a9e\u304b\u3089PHP\u306b\u79fb\u884c\u3059\u308b\u958b\u767a\u8005\u306f\u3001\u7279\u306b\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u306e\u5236\u9650\u3068\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u306e\u5236\u7d04\u3092\u7406\u89e3\u3057\u3066\u304a\u304f\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<p>PHP\u306eEnum\u306f\u3001\u9759\u7684\u578b\u4ed8\u3051\u8a00\u8a9e\u306e\u5805\u7262\u3055\u3068\u52d5\u7684\u8a00\u8a9e\u306e\u8868\u73fe\u529b\u3092\u30d0\u30e9\u30f3\u30b9\u3088\u304f\u53d6\u308a\u5165\u308c\u305f\u5b9f\u88c5\u3068\u306a\u3063\u3066\u304a\u308a\u3001\u53e4\u304f\u304b\u3089\u3053\u306e\u6a5f\u80fd\u3092\u6301\u3063\u3066\u3044\u305f\u8a00\u8a9e\u306e\u826f\u3044\u90e8\u5206\u3092\u53c2\u8003\u306b\u3057\u3064\u3064\u3001PHP\u7279\u6709\u306e\u30a8\u30b3\u30b7\u30b9\u30c6\u30e0\u306b\u9069\u5408\u3059\u308b\u3088\u3046\u8a2d\u8a08\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-4\">PHP Enum\u306e\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u3068\u69cb\u6587<\/h2>\n\n\n\n<p>PHP Enum\u3092\u5b9f\u969b\u306e\u30b3\u30fc\u30c9\u3067\u4f7f\u3044\u3053\u306a\u3059\u305f\u3081\u306b\u3001\u57fa\u672c\u7684\u306a\u69cb\u6587\u3068\u30d1\u30bf\u30fc\u30f3\u3092\u62bc\u3055\u3048\u3066\u304a\u304d\u307e\u3057\u3087\u3046\u3002Enum\u306e\u5ba3\u8a00\u304b\u3089\u4f7f\u7528\u307e\u3067\u3001\u6bb5\u968e\u7684\u306b\u898b\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">Enum\u306e\u57fa\u672c\u7684\u306a\u5ba3\u8a00\u65b9\u6cd5<\/h3>\n\n\n\n<p>PHP Enum\u306e\u5ba3\u8a00\u306f<code>enum<\/code>\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002\u6700\u3082\u30b7\u30f3\u30d7\u30eb\u306a\u5f62\u5f0f\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum PaymentStatus\n{\n    case PENDING;\n    case COMPLETED;\n    case FAILED;\n    case REFUNDED;\n}\n<\/pre>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306a\u30b1\u30fc\u30b9\u5024\u306e\u307f\u3092\u6301\u3064\u5217\u6319\u578b\u3092\u300cPure Enum\uff08\u7d14\u7c8b\u5217\u6319\u578b\uff09\u300d\u3068\u547c\u3073\u307e\u3059\u3002Pure Enum\u306f\u30b1\u30fc\u30b9\u81ea\u4f53\u304c\u5024\u3068\u306a\u308a\u3001\u6587\u5b57\u5217\u3084\u6574\u6570\u5024\u3092\u6301\u3061\u307e\u305b\u3093\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">Enum\u306e\u57fa\u672c\u7684\u306a\u4f7f\u7528\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u5b9a\u7fa9\u3057\u305fEnum\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u4f7f\u7528\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Enum\u306e\u5024\u3092\u5909\u6570\u306b\u4ee3\u5165\n$status = PaymentStatus::COMPLETED;\n\n\/\/ \u95a2\u6570\u306e\u5f15\u6570\u3068\u3057\u3066\u4f7f\u7528\uff08\u578b\u5ba3\u8a00\u53ef\u80fd\uff09\nfunction processPayment(Order $order, PaymentStatus $status): void\n{\n    \/\/ Enum\u306e\u30b1\u30fc\u30b9\u3067\u6761\u4ef6\u5206\u5c90\n    if ($status === PaymentStatus::COMPLETED) {\n        $order-&gt;markAsPaid();\n    }\n    \n    \/\/ match\u5f0f\u3068\u306e\u7d44\u307f\u5408\u308f\u305b\uff08PHP 8.0\u4ee5\u964d\uff09\n    $message = match($status) {\n        PaymentStatus::PENDING =&gt; '\u652f\u6255\u3044\u5f85\u3061',\n        PaymentStatus::COMPLETED =&gt; '\u652f\u6255\u3044\u5b8c\u4e86',\n        PaymentStatus::FAILED =&gt; '\u652f\u6255\u3044\u5931\u6557',\n        PaymentStatus::REFUNDED =&gt; '\u8fd4\u91d1\u6e08\u307f',\n    };\n    \n    echo $message;\n}\n\n\/\/ \u95a2\u6570\u547c\u3073\u51fa\u3057\nprocessPayment($order, PaymentStatus::COMPLETED);\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-7\">Enum\u306e\u7d44\u307f\u8fbc\u307f\u30e1\u30bd\u30c3\u30c9\u3068\u7279\u6027<\/h3>\n\n\n\n<p>PHP\u306eEnum\u306b\u306f\u4fbf\u5229\u306a\u7d44\u307f\u8fbc\u307f\u6a5f\u80fd\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u5168\u3066\u306e\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\n$allStatuses = PaymentStatus::cases();\n\/\/ \u7d50\u679c: [PaymentStatus::PENDING, PaymentStatus::COMPLETED, PaymentStatus::FAILED, PaymentStatus::REFUNDED]\n\n\/\/ \u30b1\u30fc\u30b9\u540d\u3092\u53d6\u5f97\uff08Pure Enum\uff09\n$statusName = PaymentStatus::COMPLETED-&gt;name;\n\/\/ \u7d50\u679c: \"COMPLETED\"\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-8\">Backed Enum\u306e\u5ba3\u8a00\u3068\u4f7f\u7528<\/h3>\n\n\n\n<p>Pure Enum\u306b\u52a0\u3048\u3066\u3001\u6587\u5b57\u5217\u3084\u6574\u6570\u5024\u3092\u6301\u3064\u300cBacked Enum\uff08\u30d0\u30c3\u30af\u30c9\u5217\u6319\u578b\uff09\u300d\u3082\u5b9a\u7fa9\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u6587\u5b57\u5217\u5024\u3092\u6301\u3064Backed Enum\nenum PaymentMethod: string\n{\n    case CREDIT_CARD = 'credit_card';\n    case BANK_TRANSFER = 'bank_transfer';\n    case PAYPAL = 'paypal';\n    case CRYPTO = 'cryptocurrency';\n}\n\n\/\/ \u6574\u6570\u5024\u3092\u6301\u3064Backed Enum\nenum HttpStatus: int\n{\n    case OK = 200;\n    case CREATED = 201;\n    case BAD_REQUEST = 400;\n    case NOT_FOUND = 404;\n    case SERVER_ERROR = 500;\n}\n<\/pre>\n\n\n\n<p>Backed Enum\u3067\u306f\u3001\u5024\u3092\u53d6\u5f97\u3057\u305f\u308a\u5024\u304b\u3089\u30b1\u30fc\u30b9\u3092\u9006\u5f15\u304d\u3057\u305f\u308a\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u5024\u3092\u53d6\u5f97\n$methodValue = PaymentMethod::PAYPAL-&gt;value; \/\/ 'paypal'\n\n\/\/ \u5024\u304b\u3089\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\n$method = PaymentMethod::from('paypal'); \/\/ PaymentMethod::PAYPAL\n$status = HttpStatus::from(404); \/\/ HttpStatus::NOT_FOUND\n\n\/\/ \u5b89\u5168\u306b\u5024\u304b\u3089\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\uff08\u5b58\u5728\u3057\u306a\u3044\u5834\u5408\u306fnull\uff09\n$method = PaymentMethod::tryFrom('unknown_method'); \/\/ null\n<\/pre>\n\n\n\n<p>Backed Enum\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u6587\u5b57\u5217\u5024\u3084API\u901a\u4fe1\u306e\u5024\u3068\u3001\u30bf\u30a4\u30d7\u30bb\u30fc\u30d5\u306aEnum\u578b\u3068\u306e\u9593\u3067\u5909\u63db\u304c\u5bb9\u6613\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">Enum\u306e\u30e1\u30bd\u30c3\u30c9\u5b9a\u7fa9<\/h3>\n\n\n\n<p>PHP\u306eEnum\u306f\u30af\u30e9\u30b9\u306b\u8fd1\u3044\u6027\u8cea\u3092\u6301\u3061\u3001\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum PaymentStatus\n{\n    case PENDING;\n    case COMPLETED;\n    case FAILED;\n    case REFUNDED;\n    \n    \/\/ \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u30e1\u30bd\u30c3\u30c9\n    public function getLabel(): string\n    {\n        return match($this) {\n            self::PENDING =&gt; '\u652f\u6255\u3044\u5f85\u3061',\n            self::COMPLETED =&gt; '\u652f\u6255\u3044\u5b8c\u4e86',\n            self::FAILED =&gt; '\u652f\u6255\u3044\u5931\u6557',\n            self::REFUNDED =&gt; '\u8fd4\u91d1\u6e08\u307f',\n        };\n    }\n    \n    \/\/ \u9759\u7684\u30e1\u30bd\u30c3\u30c9\n    public static function getDefaultStatus(): self\n    {\n        return self::PENDING;\n    }\n    \n    \/\/ \u30d8\u30eb\u30d1\u30fc\u30e1\u30bd\u30c3\u30c9\n    public function canRefund(): bool\n    {\n        return $this === self::COMPLETED;\n    }\n}\n\n\/\/ \u30e1\u30bd\u30c3\u30c9\u306e\u4f7f\u7528\n$status = PaymentStatus::COMPLETED;\necho $status-&gt;getLabel(); \/\/ '\u652f\u6255\u3044\u5b8c\u4e86'\n$canRefund = $status-&gt;canRefund(); \/\/ true\n<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u57fa\u672c\u69cb\u6587\u3092\u62bc\u3055\u3048\u3066\u304a\u304f\u3053\u3068\u3067\u3001PHP\u306eEnum\u3092\u52b9\u679c\u7684\u306b\u6d3b\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001Pure Enum\u3068Backed Enum\u306e\u9055\u3044\u306b\u3064\u3044\u3066\u3055\u3089\u306b\u8a73\u3057\u304f\u6398\u308a\u4e0b\u3052\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">Pure Enum\u3068Backed Enum\u306e\u9055\u3044\u3068\u5ba3\u8a00\u65b9\u6cd5<\/h3>\n\n\n\n<p>PHP\u306eEnum\u306b\u306f\u300cPure Enum\uff08\u7d14\u7c8b\u5217\u6319\u578b\uff09\u300d\u3068\u300cBacked Enum\uff08\u30d0\u30c3\u30af\u30c9\u5217\u6319\u578b\uff09\u300d\u306e2\u3064\u306e\u7a2e\u985e\u304c\u3042\u308a\u307e\u3059\u3002\u3069\u3061\u3089\u3092\u9078\u3076\u304b\u306b\u3088\u3063\u3066\u3001\u4f7f\u7528\u3067\u304d\u308b\u6a5f\u80fd\u3084\u9069\u3057\u305f\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u304c\u7570\u306a\u308b\u305f\u3081\u3001\u4e21\u8005\u306e\u9055\u3044\u3092\u6b63\u78ba\u306b\u7406\u89e3\u3057\u3066\u304a\u304f\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-11\">Pure Enum vs Backed Enum: \u57fa\u672c\u7684\u306a\u9055\u3044<\/h4>\n\n\n<div id=\"id-f35fab9f-fdad-421b-b085-bd167b90f472\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u7279\u6027<\/th><th>Pure Enum<\/th><th>Backed Enum<\/th><\/tr><\/thead><tbody><tr><td>\u5ba3\u8a00\u65b9\u6cd5<\/td><td><code>enum Name {...}<\/code><\/td><td><code>enum Name: string\/int {...}<\/code><\/td><\/tr><tr><td>\u30b1\u30fc\u30b9\u306e\u5024<\/td><td>\u5024\u3092\u6301\u305f\u306a\u3044\uff08\u30b1\u30fc\u30b9\u81ea\u4f53\u304c\u5024\uff09<\/td><td>\u6587\u5b57\u5217\u307e\u305f\u306f\u6574\u6570\u5024\u3092\u6301\u3064<\/td><\/tr><tr><td>\u578b\u5909\u63db<\/td><td>\u6587\u5b57\u5217\/\u6574\u6570\u3078\u306e\u76f4\u63a5\u5909\u63db\u4e0d\u53ef<\/td><td><code>-&gt;value<\/code>\u3067\u57fa\u672c\u578b\u306b\u5909\u63db\u53ef\u80fd<\/td><\/tr><tr><td>\u5024\u304b\u3089\u306e\u751f\u6210<\/td><td><code>from()\/tryFrom()<\/code>\u306f\u4f7f\u7528\u4e0d\u53ef<\/td><td><code>from()\/tryFrom()<\/code>\u3067\u5024\u304b\u3089\u751f\u6210\u53ef\u80fd<\/td><\/tr><tr><td>\u4e3b\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9<\/td><td>\u5185\u90e8\u7684\u306a\u578b\u5b89\u5168\u6027\u304c\u91cd\u8981\u306a\u5834\u5408<\/td><td>\u5916\u90e8\u30c7\u30fc\u30bf\u3068\u306e\u9023\u643a\u304c\u5fc5\u8981\u306a\u5834\u5408<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"i-12\">Pure Enum\u306e\u5ba3\u8a00\u3068\u7279\u5fb4<\/h4>\n\n\n\n<p>Pure Enum\u306f\u5024\u3092\u6301\u305f\u305a\u3001\u30b1\u30fc\u30b9\u81ea\u4f53\u304c\u4e00\u610f\u306e\u5024\u3068\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Pure Enum\u306e\u5ba3\u8a00\nenum UserRole\n{\n    case ADMIN;      \/\/ \u5024\u3092\u6301\u305f\u306a\u3044\n    case EDITOR;\n    case AUTHOR;\n    case SUBSCRIBER;\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$role = UserRole::ADMIN;\n\n\/\/ \u6bd4\u8f03\nif ($role === UserRole::ADMIN) {\n    \/\/ \u7ba1\u7406\u8005\u6a29\u9650\u306e\u51e6\u7406\n}\n\n\/\/ \u5168\u30b1\u30fc\u30b9\u53d6\u5f97\n$allRoles = UserRole::cases();\n\n\/\/ \u30b1\u30fc\u30b9\u540d\u306e\u53d6\u5f97\n$roleName = $role-&gt;name;  \/\/ \"ADMIN\"\n<\/pre>\n\n\n\n<p>Pure Enum\u306e\u7279\u5fb4\u306f\u5358\u7d14\u3055\u3068\u30b7\u30f3\u30d7\u30eb\u3055\u3067\u3059\u3002\u5185\u90e8\u7684\u306a\u5217\u6319\u578b\u3068\u3057\u3066\u4f7f\u7528\u3059\u308b\u5834\u5408\u3084\u3001\u5024\u3088\u308a\u3082\u578b\u5b89\u5168\u6027\u304c\u91cd\u8981\u306a\u5834\u5408\u306b\u9069\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-13\">Backed Enum\u306e\u5ba3\u8a00\u3068\u7279\u5fb4<\/h4>\n\n\n\n<p>Backed Enum\u306f\u5404\u30b1\u30fc\u30b9\u306b\u5bfe\u5fdc\u3059\u308b\u5024\uff08\u6587\u5b57\u5217\u307e\u305f\u306f\u6574\u6570\uff09\u3092\u6301\u3061\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u6587\u5b57\u5217\u5024\u3092\u6301\u3064Backed Enum\nenum UserRoleWithValue: string\n{\n    case ADMIN = 'administrator';     \/\/ \u6587\u5b57\u5217\u5024\u3092\u6301\u3064\n    case EDITOR = 'editor';\n    case AUTHOR = 'author';\n    case SUBSCRIBER = 'subscriber';\n}\n\n\/\/ \u6574\u6570\u5024\u3092\u6301\u3064Backed Enum\nenum PermissionLevel: int\n{\n    case READ = 1;\n    case WRITE = 2;\n    case DELETE = 4;\n    case ALL = 7;  \/\/ \u30d3\u30c3\u30c8\u30d5\u30e9\u30b0\u306e\u7d44\u307f\u5408\u308f\u305b\u3082\u53ef\u80fd\n}\n\n\/\/ \u5024\u306e\u53d6\u5f97\n$roleValue = UserRoleWithValue::ADMIN-&gt;value;  \/\/ \"administrator\"\n\n\/\/ \u5024\u304b\u3089Enum\u3092\u751f\u6210\uff08\u5b58\u5728\u3057\u306a\u3044\u5024\u306e\u5834\u5408\u306f\u4f8b\u5916\u767a\u751f\uff09\n$role = UserRoleWithValue::from('editor');  \/\/ UserRoleWithValue::EDITOR\n\n\/\/ \u5b89\u5168\u306b\u5024\u304b\u3089Enum\u3092\u751f\u6210\uff08\u5b58\u5728\u3057\u306a\u3044\u5024\u306e\u5834\u5408\u306fnull\uff09\n$role = UserRoleWithValue::tryFrom('unknown');  \/\/ null\n<\/pre>\n\n\n\n<p>Backed Enum\u306f\u5916\u90e8\u30b7\u30b9\u30c6\u30e0\u3068\u306e\u9023\u643a\u306b\u7279\u306b\u9069\u3057\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u6587\u5b57\u5217\/\u6574\u6570\u3068\u3057\u3066\u4fdd\u5b58<\/li>\n\n\n\n<li>JSON\u3084API\u30ec\u30b9\u30dd\u30f3\u30b9\u3067\u306e\u5024\u306e\u53d7\u3051\u6e21\u3057<\/li>\n\n\n\n<li>\u65e2\u5b58\u30b3\u30fc\u30c9\u304b\u3089\u306e\u79fb\u884c\u6642\u306e\u4e92\u63db\u6027\u7dad\u6301<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-14\">\u3069\u3061\u3089\u3092\u9078\u3076\u3079\u304d\u304b\uff1f<\/h4>\n\n\n\n<p>\u9078\u629e\u306e\u57fa\u6e96\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Pure Enum<\/strong> \u3092\u9078\u3076\u5834\u5408\uff1a\n<ul class=\"wp-block-list\">\n<li>\u5b8c\u5168\u306b\u5185\u90e8\u7684\u306a\u4f7f\u7528\u3067\u3001\u5916\u90e8\u3068\u306e\u9023\u643a\u304c\u4e0d\u8981<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u578b\u5b89\u5168\u6027\u3068\u660e\u78ba\u3055\u304c\u6700\u512a\u5148<\/li>\n\n\n\n<li>\u30b7\u30f3\u30d7\u30eb\u3055\u3092\u91cd\u8996<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Backed Enum<\/strong> \u3092\u9078\u3076\u5834\u5408\uff1a\n<ul class=\"wp-block-list\">\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u306e\u9023\u643a\u304c\u3042\u308b<\/li>\n\n\n\n<li>API\u3084\u30d5\u30a9\u30fc\u30e0\u304b\u3089\u306e\u5165\u529b\u5024\u3068\u9023\u643a\u3059\u308b<\/li>\n\n\n\n<li>\u65e2\u5b58\u306e\u6587\u5b57\u5217\/\u6574\u6570\u5b9a\u6570\u304b\u3089\u306e\u79fb\u884c<\/li>\n\n\n\n<li>\u4eba\u9593\u53ef\u8aad\u306a\u5024\u304c\u5fc5\u8981<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>\u591a\u304f\u306e\u5b9f\u969b\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001Backed Enum\u306e\u67d4\u8edf\u6027\u304c\u5f79\u7acb\u3064\u30b1\u30fc\u30b9\u304c\u591a\u3044\u3067\u3059\u304c\u3001\u7d14\u7c8b\u306b\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u3092\u8868\u73fe\u3059\u308b\u3060\u3051\u306a\u3089Pure Enum\u3067\u3082\u5341\u5206\u3067\u3059\u3002\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u8981\u4ef6\u306b\u5fdc\u3058\u3066\u9069\u5207\u306a\u30bf\u30a4\u30d7\u3092\u9078\u629e\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">Enum\u306e\u30e1\u30f3\u30d0\u30fc\u3068\u30b1\u30fc\u30b9\u5b9a\u6570\u306e\u5b9a\u7fa9\u65b9\u6cd5<\/h3>\n\n\n\n<p>Enum\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528\u306b\u306f\u3001\u9069\u5207\u306a\u30b1\u30fc\u30b9\u5b9a\u6570\u306e\u5b9a\u7fa9\u304c\u4e0d\u53ef\u6b20\u3067\u3059\u3002\u3053\u3053\u3067\u306f\u3001Enum\u306e\u30e1\u30f3\u30d0\u30fc\u5b9a\u7fa9\u306b\u304a\u3051\u308b\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3068\u8a2d\u8a08\u30d1\u30bf\u30fc\u30f3\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-16\">\u30b1\u30fc\u30b9\u540d\u306e\u547d\u540d\u898f\u5247<\/h4>\n\n\n\n<p>Enum\u306e\u30b1\u30fc\u30b9\u540d\u306e\u6a19\u6e96\u7684\u306a\u547d\u540d\u898f\u5247\u306f\u5927\u6587\u5b57\u306e\u30b9\u30cd\u30fc\u30af\u30b1\u30fc\u30b9\u3067\u3059\u3002\u3053\u308c\u306fPHP\u306e\u5b9a\u6570\u547d\u540d\u898f\u5247\u306b\u5408\u308f\u305b\u305f\u3082\u306e\u3067\u3001\u4e00\u76ee\u3067\u30b1\u30fc\u30b9\u5b9a\u6570\u3067\u3042\u308b\u3053\u3068\u304c\u5206\u304b\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum OrderStatus\n{\n    case AWAITING_PAYMENT;    \/\/ \u63a8\u5968\uff1a\u5927\u6587\u5b57\u30b9\u30cd\u30fc\u30af\u30b1\u30fc\u30b9\n    case PROCESSING;\n    case SHIPPED;\n    case DELIVERED;\n    \/\/ case awaitingPayment;  \/\/ \u975e\u63a8\u5968\uff1a\u30ad\u30e3\u30e1\u30eb\u30b1\u30fc\u30b9\u3084\u5c0f\u6587\u5b57\n}\n<\/pre>\n\n\n\n<p>Backed Enum\u306e\u5834\u5408\u3001\u5024\u306e\u547d\u540d\u306f\u4f7f\u7528\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u9069\u3057\u305f\u5f62\u5f0f\u3092\u9078\u3073\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum OrderStatus: string\n{\n    \/\/ \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3084API\u3067\u4f7f\u3046\u5834\u5408\u306f\u30b9\u30cd\u30fc\u30af\u30b1\u30fc\u30b9\u304c\u4e00\u822c\u7684\n    case AWAITING_PAYMENT = 'awaiting_payment';\n    case PROCESSING = 'processing';\n    \n    \/\/ JSON\u3084\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u306e\u9023\u643a\u3067\u306f\u30ad\u30e3\u30e1\u30eb\u30b1\u30fc\u30b9\u3082\n    \/\/ case AWAITING_PAYMENT = 'awaitingPayment';\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-17\">\u95a2\u9023\u3059\u308b\u30b1\u30fc\u30b9\u306e\u30b0\u30eb\u30fc\u30d7\u5316<\/h4>\n\n\n\n<p>\u95a2\u9023\u3059\u308b\u30b1\u30fc\u30b9\u3092\u8ad6\u7406\u7684\u306b\u30b0\u30eb\u30fc\u30d7\u5316\u3059\u308b\u3068\u3001\u30b3\u30fc\u30c9\u306e\u7406\u89e3\u304c\u5bb9\u6613\u306b\u306a\u308a\u307e\u3059\u3002\u30b3\u30e1\u30f3\u30c8\u3084\u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u3063\u3066\u95a2\u9023\u6027\u3092\u8868\u73fe\u3057\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum OrderStatus\n{\n    \/\/ \u6ce8\u6587\u53d7\u4ed8\u4e2d\u30b9\u30c6\u30fc\u30bf\u30b9\n    case CART;\n    case CHECKOUT;\n    case AWAITING_PAYMENT;\n    \n    \/\/ \u51e6\u7406\u4e2d\u30b9\u30c6\u30fc\u30bf\u30b9\n    case PROCESSING;\n    case PACKING;\n    case SHIPPED;\n    \n    \/\/ \u5b8c\u4e86\u30b9\u30c6\u30fc\u30bf\u30b9\n    case DELIVERED;\n    case COMPLETED;\n    case CANCELLED;\n    case REFUNDED;\n    \n    \/\/ \u30b0\u30eb\u30fc\u30d7\u5316\u3092\u52a9\u3051\u308b\u30d8\u30eb\u30d1\u30fc\u30e1\u30bd\u30c3\u30c9\n    public function isActive(): bool\n    {\n        return in_array($this, [\n            self::PROCESSING,\n            self::PACKING,\n            self::SHIPPED\n        ]);\n    }\n    \n    public function isCompleted(): bool\n    {\n        return in_array($this, [\n            self::DELIVERED,\n            self::COMPLETED\n        ]);\n    }\n    \n    public function isTerminated(): bool\n    {\n        return in_array($this, [\n            self::CANCELLED,\n            self::REFUNDED\n        ]);\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$status = OrderStatus::PROCESSING;\nif ($status-&gt;isActive()) {\n    \/\/ \u51e6\u7406\u4e2d\u306e\u6ce8\u6587\u306b\u5bfe\u3059\u308b\u64cd\u4f5c\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-18\">\u30d5\u30e9\u30b0\u5024\u3068\u3057\u3066\u306eEnum\u5b9a\u7fa9<\/h4>\n\n\n\n<p>\u6574\u6570\u578b\u306eBacked Enum\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u30d3\u30c3\u30c8\u30d5\u30e9\u30b0\u306e\u3088\u3046\u306a\u8907\u5408\u7684\u306a\u6a29\u9650\u8a2d\u5b9a\u3092\u8868\u73fe\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum Permission: int\n{\n    case READ = 1;     \/\/ 2^0 = 1\n    case WRITE = 2;    \/\/ 2^1 = 2\n    case DELETE = 4;   \/\/ 2^2 = 4\n    case ADMIN = 8;    \/\/ 2^3 = 8\n    \n    \/\/ \u7d44\u307f\u5408\u308f\u305b\u305f\u6a29\u9650\n    case EDITOR = 3;   \/\/ READ + WRITE = 1 + 2 = 3\n    case MANAGER = 7;  \/\/ READ + WRITE + DELETE = 1 + 2 + 4 = 7\n    case SUPER = 15;   \/\/ READ + WRITE + DELETE + ADMIN = 1 + 2 + 4 + 8 = 15\n    \n    \/\/ \u7279\u5b9a\u306e\u6a29\u9650\u3092\u6301\u3063\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b\u30d8\u30eb\u30d1\u30fc\u30e1\u30bd\u30c3\u30c9\n    public function hasPermission(self $permission): bool\n    {\n        return ($this-&gt;value &amp; $permission-&gt;value) === $permission-&gt;value;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$role = Permission::EDITOR;\nif ($role-&gt;hasPermission(Permission::WRITE)) {  \/\/ true\n    \/\/ \u66f8\u304d\u8fbc\u307f\u6a29\u9650\u304c\u3042\u308b\u51e6\u7406\n}\nif ($role-&gt;hasPermission(Permission::DELETE)) { \/\/ false\n    \/\/ \u524a\u9664\u6a29\u9650\u304c\u3042\u308b\u51e6\u7406\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-19\">\u30e1\u30f3\u30d0\u30fc\u9593\u306e\u95a2\u4fc2\u3092\u8868\u73fe\u3059\u308b\u30c6\u30af\u30cb\u30c3\u30af<\/h4>\n\n\n\n<p>Enum\u306e\u30b1\u30fc\u30b9\u9593\u306e\u95a2\u4fc2\u3092\u30e1\u30bd\u30c3\u30c9\u3067\u8868\u73fe\u3059\u308b\u3053\u3068\u3067\u3001\u30c9\u30e1\u30a4\u30f3\u30ed\u30b8\u30c3\u30af\u3092Enum\u306b\u30ab\u30d7\u30bb\u30eb\u5316\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum TaskStatus\n{\n    case TODO;\n    case IN_PROGRESS;\n    case REVIEW;\n    case DONE;\n    \n    \/\/ \u6b21\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u53d6\u5f97\n    public function next(): ?self\n    {\n        return match($this) {\n            self::TODO =&gt; self::IN_PROGRESS,\n            self::IN_PROGRESS =&gt; self::REVIEW,\n            self::REVIEW =&gt; self::DONE,\n            self::DONE =&gt; null,\n        };\n    }\n    \n    \/\/ \u524d\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u53d6\u5f97\n    public function previous(): ?self\n    {\n        return match($this) {\n            self::TODO =&gt; null,\n            self::IN_PROGRESS =&gt; self::TODO,\n            self::REVIEW =&gt; self::IN_PROGRESS,\n            self::DONE =&gt; self::REVIEW,\n        };\n    }\n    \n    \/\/ \u6b21\u3078\u9032\u3081\u308b\u304b\u306e\u30c1\u30a7\u30c3\u30af\n    public function canTransitionTo(self $newStatus): bool\n    {\n        return $this-&gt;next() === $newStatus;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$currentStatus = TaskStatus::IN_PROGRESS;\n$nextStatus = $currentStatus-&gt;next(); \/\/ TaskStatus::REVIEW\n<\/pre>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306b\u30b1\u30fc\u30b9\u5b9a\u6570\u3092\u5358\u306a\u308b\u5024\u306e\u96c6\u5408\u3067\u306f\u306a\u304f\u3001\u95a2\u9023\u6027\u3092\u6301\u3063\u305f\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u3068\u3057\u3066\u8a2d\u8a08\u3059\u308b\u3053\u3068\u3067\u3001Enum\u306e\u771f\u4fa1\u3092\u767a\u63ee\u3067\u304d\u307e\u3059\u3002\u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\u3059\u308b\u3053\u3068\u3067\u3001\u30b1\u30fc\u30b9\u5b9a\u6570\u306b\u632f\u308b\u821e\u3044\u3092\u6301\u305f\u305b\u3001\u3088\u308a\u8868\u73fe\u529b\u8c4a\u304b\u306a\u30b3\u30fc\u30c9\u3092\u5b9f\u73fe\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-20\">Enum\u306b\u5b9f\u88c5\u3067\u304d\u308b\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3068\u30c8\u30ec\u30a4\u30c8<\/h3>\n\n\n\n<p>PHP\u306eEnum\u306f\u30af\u30e9\u30b9\u306b\u8fd1\u3044\u7279\u6027\u3092\u6301\u3063\u3066\u304a\u308a\u3001\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u306e\u5b9f\u88c5\u3068\u30c8\u30ec\u30a4\u30c8\u306e\u4f7f\u7528\u304c\u53ef\u80fd\u3067\u3059\u3002\u3053\u308c\u306b\u3088\u308aEnum\u306b\u5f37\u529b\u306a\u6a5f\u80fd\u3092\u8ffd\u52a0\u3057\u3001\u3088\u308a\u8868\u73fe\u529b\u8c4a\u304b\u306a\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-21\">\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u306e\u5b9f\u88c5<\/h4>\n\n\n\n<p>Enum\u306f\u30af\u30e9\u30b9\u3068\u540c\u69d8\u306b\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u5b9f\u88c5\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30ab\u30b9\u30bf\u30e0\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u306e\u5b9a\u7fa9\ninterface LabelProvider\n{\n    public function getLabel(): string;\n    public function getDescription(): string;\n}\n\n\/\/ Enum\u3067\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u5b9f\u88c5\nenum PaymentStatus implements LabelProvider\n{\n    case PENDING;\n    case PROCESSING;\n    case COMPLETED;\n    case FAILED;\n    \n    \/\/ \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u30e1\u30bd\u30c3\u30c9\u306e\u5b9f\u88c5\n    public function getLabel(): string\n    {\n        return match($this) {\n            self::PENDING =&gt; '\u652f\u6255\u3044\u5f85\u3061',\n            self::PROCESSING =&gt; '\u51e6\u7406\u4e2d',\n            self::COMPLETED =&gt; '\u5b8c\u4e86',\n            self::FAILED =&gt; '\u5931\u6557',\n        };\n    }\n    \n    public function getDescription(): string\n    {\n        return match($this) {\n            self::PENDING =&gt; '\u304a\u652f\u6255\u3044\u304c\u78ba\u8a8d\u3067\u304d\u308b\u307e\u3067\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002',\n            self::PROCESSING =&gt; '\u304a\u652f\u6255\u3044\u3092\u51e6\u7406\u4e2d\u3067\u3059\u3002',\n            self::COMPLETED =&gt; '\u304a\u652f\u6255\u3044\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f\u3002',\n            self::FAILED =&gt; '\u304a\u652f\u6255\u3044\u51e6\u7406\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002',\n        };\n    }\n}\n<\/pre>\n\n\n\n<p>\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u5b9f\u88c5\u306e\u4e3b\u306a\u30e1\u30ea\u30c3\u30c8\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u578b\u306e\u7d71\u4e00<\/strong>: \u7570\u306a\u308bEnum\u578b\u3067\u3082\u540c\u3058\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u5171\u901a\u306e\u632f\u308b\u821e\u3044\u3092\u4fdd\u8a3c<\/li>\n\n\n\n<li><strong>\u30dd\u30ea\u30e2\u30fc\u30d5\u30a3\u30ba\u30e0\u306e\u6d3b\u7528<\/strong>: \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u578b\u3068\u3057\u3066\u6271\u3046\u3053\u3068\u3067\u3001\u7570\u306a\u308bEnum\u3092\u540c\u3058\u3088\u3046\u306b\u51e6\u7406<\/li>\n\n\n\n<li><strong>\u95a2\u5fc3\u306e\u5206\u96e2<\/strong>: \u30c9\u30e1\u30a4\u30f3\u30ed\u30b8\u30c3\u30af\u3068\u30d7\u30ec\u30bc\u30f3\u30c6\u30fc\u30b7\u30e7\u30f3\u30ed\u30b8\u30c3\u30af\u3092\u5206\u3051\u3089\u308c\u308b<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027<\/strong>: \u30e2\u30c3\u30af\u3084\u30b9\u30bf\u30d6\u306e\u4f5c\u6210\u304c\u5bb9\u6613\u306b\u306a\u308b<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-22\">\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u6d3b\u7528\u3057\u305f\u5b9f\u8df5\u4f8b<\/h4>\n\n\n\n<p>\u8907\u6570\u306eEnum\u306b\u540c\u3058\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u4e00\u8cab\u3057\u305f\u51e6\u7406\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u5171\u901a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\ninterface Displayable\n{\n    public function display(): string;\n    public function getColor(): string;\n}\n\n\/\/ \u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9Enum\nenum OrderStatus implements Displayable\n{\n    case NEW;\n    case PROCESSING;\n    case SHIPPED;\n    case DELIVERED;\n    \n    public function display(): string\n    {\n        return match($this) {\n            self::NEW =&gt; '\u65b0\u898f\u6ce8\u6587',\n            self::PROCESSING =&gt; '\u51e6\u7406\u4e2d',\n            self::SHIPPED =&gt; '\u767a\u9001\u6e08\u307f',\n            self::DELIVERED =&gt; '\u914d\u9054\u5b8c\u4e86',\n        };\n    }\n    \n    public function getColor(): string\n    {\n        return match($this) {\n            self::NEW =&gt; 'blue',\n            self::PROCESSING =&gt; 'orange',\n            self::SHIPPED =&gt; 'purple',\n            self::DELIVERED =&gt; 'green',\n        };\n    }\n}\n\n\/\/ \u652f\u6255\u3044\u30b9\u30c6\u30fc\u30bf\u30b9Enum\nenum PaymentStatus implements Displayable\n{\n    case PENDING;\n    case PAID;\n    case REFUNDED;\n    \n    public function display(): string\n    {\n        return match($this) {\n            self::PENDING =&gt; '\u652f\u6255\u3044\u5f85\u3061',\n            self::PAID =&gt; '\u652f\u6255\u3044\u6e08\u307f',\n            self::REFUNDED =&gt; '\u8fd4\u91d1\u6e08\u307f',\n        };\n    }\n    \n    public function getColor(): string\n    {\n        return match($this) {\n            self::PENDING =&gt; 'yellow',\n            self::PAID =&gt; 'green',\n            self::REFUNDED =&gt; 'red',\n        };\n    }\n}\n\n\/\/ \u4e21\u65b9\u306eEnum\u3092\u540c\u3058\u3088\u3046\u306b\u6271\u3048\u308b\nfunction renderStatusBadge(Displayable $status): string\n{\n    return sprintf(\n        '&lt;span class=\"badge badge-%s\"&gt;%s&lt;\/span&gt;',\n        $status-&gt;getColor(),\n        $status-&gt;display()\n    );\n}\n\n\/\/ \u4f7f\u7528\u4f8b\necho renderStatusBadge(OrderStatus::PROCESSING);\necho renderStatusBadge(PaymentStatus::PAID);\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-23\">\u30c8\u30ec\u30a4\u30c8\u306e\u6d3b\u7528<\/h4>\n\n\n\n<p>\u30c8\u30ec\u30a4\u30c8\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u8907\u6570\u306eEnum\u3067\u5171\u901a\u306e\u6a5f\u80fd\u3092\u518d\u5229\u7528\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u5171\u901a\u6a5f\u80fd\u3092\u30c8\u30ec\u30a4\u30c8\u3068\u3057\u3066\u5b9a\u7fa9\ntrait EnumMapTrait\n{\n    \/\/ \u5168\u3066\u306e\u30b1\u30fc\u30b9\u3092\u9023\u60f3\u914d\u5217\u306b\u30de\u30c3\u30d4\u30f3\u30b0\n    public static function toArray(): array\n    {\n        $result = [];\n        foreach (self::cases() as $case) {\n            $key = $case-&gt;name;\n            $value = $case instanceof \\BackedEnum ? $case-&gt;value : $case-&gt;name;\n            $result[$key] = $value;\n        }\n        return $result;\n    }\n    \n    \/\/ \u9078\u629e\u80a2\u3068\u3057\u3066\u4f7f\u7528\u3059\u308b\u305f\u3081\u306e\u914d\u5217\u3092\u53d6\u5f97\n    public static function getOptions(): array\n    {\n        $options = [];\n        foreach (self::cases() as $case) {\n            $value = $case instanceof \\BackedEnum ? $case-&gt;value : $case-&gt;name;\n            $label = method_exists($case, 'getLabel') ? $case-&gt;getLabel() : $case-&gt;name;\n            $options[$value] = $label;\n        }\n        return $options;\n    }\n}\n\n\/\/ \u30c8\u30ec\u30a4\u30c8\u3092\u4f7f\u7528\u3057\u305fEnum\nenum ProductCategory: string\n{\n    use EnumMapTrait;\n    \n    case ELECTRONICS = 'electronics';\n    case CLOTHING = 'clothing';\n    case BOOKS = 'books';\n    case FOOD = 'food';\n    \n    public function getLabel(): string\n    {\n        return match($this) {\n            self::ELECTRONICS =&gt; '\u96fb\u5316\u88fd\u54c1',\n            self::CLOTHING =&gt; '\u8863\u985e',\n            self::BOOKS =&gt; '\u66f8\u7c4d',\n            self::FOOD =&gt; '\u98df\u54c1',\n        };\n    }\n}\n\n\/\/ \u30c8\u30ec\u30a4\u30c8\u306e\u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u7528\n$categories = ProductCategory::toArray();\n$options = ProductCategory::getOptions();\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-24\">\u6ce8\u610f\u70b9\u3068\u5236\u9650\u4e8b\u9805<\/h4>\n\n\n\n<p>Enum\u306b\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3084\u30c8\u30ec\u30a4\u30c8\u3092\u5b9f\u88c5\u3059\u308b\u969b\u306e\u5236\u9650\u4e8b\u9805\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u306e\u5236\u9650<\/strong> \u2013 Enum\u306f\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u306b\u30a2\u30af\u30bb\u30b9\u4fee\u98fe\u5b50\u3092\u6307\u5b9a\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li><strong>\u7d99\u627f\u4e0d\u53ef<\/strong> \u2013 Enum\u306f\u30af\u30e9\u30b9\u3084Enum\u3092\u7d99\u627f\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li><strong>\u62bd\u8c61\u30e1\u30bd\u30c3\u30c9\u5236\u9650<\/strong> \u2013 Enum\u306b\u30c8\u30ec\u30a4\u30c8\u306b\u3088\u308b\u62bd\u8c61\u30e1\u30bd\u30c3\u30c9\u3092\u5f37\u5236\u3067\u304d\u306a\u3044\u5834\u5408\u304c\u3042\u308b<\/li>\n<\/ol>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5236\u9650\u3092\u5ff5\u982d\u306b\u7f6e\u3044\u3066\u3001\u9069\u5207\u306a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3068\u30c8\u30ec\u30a4\u30c8\u306e\u8a2d\u8a08\u3092\u884c\u3044\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-25\">\u5f93\u6765\u306e\u5b9a\u6570\u3068\u6bd4\u8f03\uff1aPHP Enum\u306e\u30e1\u30ea\u30c3\u30c8\u3068\u9650\u754c<\/h2>\n\n\n\n<p>PHP Enum\u306e\u4fa1\u5024\u3092\u6b63\u3057\u304f\u7406\u89e3\u3059\u308b\u305f\u3081\u306b\u306f\u3001\u5f93\u6765\u306ePHP\u3067\u306e\u5b9a\u6570\u8868\u73fe\u3068\u6bd4\u8f03\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002\u9577\u5e74\u306ePHP\u958b\u767a\u3067\u306f\u3001\u5217\u6319\u578b\u306e\u4ee3\u66ff\u3068\u3057\u3066\u69d8\u3005\u306a\u65b9\u6cd5\u304c\u4f7f\u308f\u308c\u3066\u304d\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-26\">\u5f93\u6765\u306ePHP\u3067\u306e\u5b9a\u6570\u8868\u73fe\u65b9\u6cd5<\/h3>\n\n\n\n<p>PHP 8.1\u4ee5\u524d\u3067\u306f\u3001\u5217\u6319\u578b\u306e\u5024\u3092\u8868\u73fe\u3059\u308b\u305f\u3081\u306b\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u65b9\u6cd5\u304c\u4f7f\u308f\u308c\u3066\u3044\u307e\u3057\u305f\uff1a<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-27\">1. \u30b0\u30ed\u30fc\u30d0\u30eb\u5b9a\u6570\uff08define\uff09<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30b0\u30ed\u30fc\u30d0\u30eb\u5b9a\u6570\u306b\u3088\u308b\u5b9f\u88c5\ndefine('STATUS_DRAFT', 'draft');\ndefine('STATUS_PUBLISHED', 'published');\ndefine('STATUS_ARCHIVED', 'archived');\n\n\/\/ \u4f7f\u7528\u4f8b\nfunction updateStatus($status) {\n    if ($status === STATUS_PUBLISHED) {\n        \/\/ \u51e6\u7406\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-28\">2. \u30af\u30e9\u30b9\u5b9a\u6570<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30af\u30e9\u30b9\u5b9a\u6570\u306b\u3088\u308b\u5b9f\u88c5\nclass ArticleStatus {\n    public const DRAFT = 'draft';\n    public const PUBLISHED = 'published';\n    public const ARCHIVED = 'archived';\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u7528\u306e\u88dc\u52a9\u30e1\u30bd\u30c3\u30c9\n    public static function isValid(string $status): bool {\n        return in_array($status, [\n            self::DRAFT,\n            self::PUBLISHED,\n            self::ARCHIVED\n        ]);\n    }\n    \n    \/\/ \u30e9\u30d9\u30eb\u53d6\u5f97\u7528\u306e\u30d8\u30eb\u30d1\u30fc\u30e1\u30bd\u30c3\u30c9\n    public static function getLabel(string $status): string {\n        return match($status) {\n            self::DRAFT =&gt; '\u4e0b\u66f8\u304d',\n            self::PUBLISHED =&gt; '\u516c\u958b\u6e08\u307f',\n            self::ARCHIVED =&gt; '\u30a2\u30fc\u30ab\u30a4\u30d6\u6e08\u307f',\n            default =&gt; '\u4e0d\u660e'\n        };\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nif (ArticleStatus::isValid($status)) {\n    echo ArticleStatus::getLabel($status);\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-29\">3. \u7591\u4f3cEnum\u7684\u306a\u30af\u30e9\u30b9<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6307\u5411\u3067\u7591\u4f3cEnum\u3092\u5b9f\u88c5\nclass Status {\n    private string $value;\n    \n    private function __construct(string $value) {\n        $this-&gt;value = $value;\n    }\n    \n    public static function DRAFT(): self {\n        return new self('draft');\n    }\n    \n    public static function PUBLISHED(): self {\n        return new self('published');\n    }\n    \n    public static function ARCHIVED(): self {\n        return new self('archived');\n    }\n    \n    public function getValue(): string {\n        return $this-&gt;value;\n    }\n    \n    public function equals(self $other): bool {\n        return $this-&gt;value === $other-&gt;value;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$status = Status::PUBLISHED();\nif ($status-&gt;equals(Status::PUBLISHED())) {\n    \/\/ \u51e6\u7406\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-30\">PHP Enum\u3068\u5f93\u6765\u624b\u6cd5\u306e\u6bd4\u8f03<\/h3>\n\n\n\n<p>\u5b9f\u969b\u306e\u30b3\u30fc\u30c9\u3067\u6bd4\u8f03\u3057\u3066\u307f\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ PHP 8.1\u4ee5\u524d\uff1a\u30af\u30e9\u30b9\u5b9a\u6570\u3067\u306e\u5b9f\u88c5\nclass OldPaymentStatus {\n    public const PENDING = 'pending';\n    public const COMPLETED = 'completed';\n    public const FAILED = 'failed';\n    \n    public static function getAll(): array {\n        return [self::PENDING, self::COMPLETED, self::FAILED];\n    }\n    \n    public static function isValid(string $status): bool {\n        return in_array($status, self::getAll());\n    }\n}\n\n\/\/ PHP 8.1\u4ee5\u964d\uff1aEnum\u3067\u306e\u5b9f\u88c5\nenum PaymentStatus: string {\n    case PENDING = 'pending';\n    case COMPLETED = 'completed';\n    case FAILED = 'failed';\n    \n    public function getLabel(): string {\n        return match($this) {\n            self::PENDING =&gt; '\u51e6\u7406\u4e2d',\n            self::COMPLETED =&gt; '\u5b8c\u4e86',\n            self::FAILED =&gt; '\u5931\u6557'\n        };\n    }\n}\n\n\/\/ \u5f93\u6765\u306e\u4f7f\u7528\u6cd5\n$oldStatus = OldPaymentStatus::PENDING;\nif ($oldStatus === OldPaymentStatus::PENDING) {\n    \/\/ \u6587\u5b57\u5217\u540c\u58eb\u306e\u6bd4\u8f03\uff08\u578b\u306e\u4fdd\u8a3c\u306a\u3057\uff09\n}\n\n\/\/ Enum\u306e\u4f7f\u7528\u6cd5\n$status = PaymentStatus::PENDING;\nif ($status === PaymentStatus::PENDING) {\n    \/\/ \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u540c\u58eb\u306e\u6bd4\u8f03\uff08\u578b\u306e\u4fdd\u8a3c\u3042\u308a\uff09\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-31\">PHP Enum\u306e\u4e3b\u306a\u30e1\u30ea\u30c3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u771f\u306e\u578b\u5b89\u5168\u6027<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5f15\u6570\u3084\u623b\u308a\u5024\u306b\u5177\u4f53\u7684\u306aEnum\u578b\u3092\u6307\u5b9a\u53ef\u80fd<\/li>\n\n\n\n<li>\u4e0d\u6b63\u306a\u5024\u306e\u4ee3\u5165\u3084\u6bd4\u8f03\u3092\u5b8c\u5168\u306b\u9632\u6b62<\/li>\n\n\n\n<li>PHPStan\u3084Psalm\u306a\u3069\u306e\u9759\u7684\u89e3\u6790\u30c4\u30fc\u30eb\u3068\u306e\u89aa\u548c\u6027\u5411\u4e0a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>IDE\u30b5\u30dd\u30fc\u30c8\u306e\u5145\u5b9f<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30b3\u30fc\u30c9\u88dc\u5b8c\u3067\u5229\u7528\u53ef\u80fd\u306a\u3059\u3079\u3066\u306e\u30b1\u30fc\u30b9\u3092\u8868\u793a<\/li>\n\n\n\n<li>\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u6642\u306e\u4e00\u62ec\u5909\u66f4\u304c\u5bb9\u6613<\/li>\n\n\n\n<li>\u4f7f\u7528\u7b87\u6240\u306e\u8ffd\u8de1\u304c\u7c21\u5358<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u30ed\u30b8\u30c3\u30af\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u306b\u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u3066\u30ed\u30b8\u30c3\u30af\u3092\u96c6\u7d04<\/li>\n\n\n\n<li>\u8868\u793a\u7528\u306e\u6587\u5b57\u5217\u3084\u632f\u308b\u821e\u3044\u3092Enum\u5185\u306b\u9589\u3058\u8fbc\u3081<\/li>\n\n\n\n<li>\u95a2\u9023\u3059\u308b\u30ed\u30b8\u30c3\u30af\u306e\u6563\u5728\u3092\u9632\u6b62<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b3\u30fc\u30c9\u306e\u660e\u78ba\u3055\u3068\u81ea\u5df1\u6587\u66f8\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u578b\u304b\u3089\u3069\u306e\u3088\u3046\u306a\u5024\u304c\u671f\u5f85\u3055\u308c\u308b\u304b\u660e\u78ba<\/li>\n\n\n\n<li>\u610f\u56f3\u304c\u660e\u78ba\u306b\u306a\u308a\u3001\u30b3\u30e1\u30f3\u30c8\u306e\u5fc5\u8981\u6027\u304c\u4f4e\u6e1b<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u3068\u4fdd\u5b88\u6027\u304c\u5411\u4e0a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u7c21\u7d20\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>from\/tryFrom\u30e1\u30bd\u30c3\u30c9\u306b\u3088\u308b\u5165\u529b\u5024\u306e\u691c\u8a3c<\/li>\n\n\n\n<li>\u4e0d\u6b63\u5024\u306e\u65e9\u671f\u691c\u51fa\u304c\u5bb9\u6613<\/li>\n\n\n\n<li>\u6761\u4ef6\u5206\u5c90\u306e\u6f0f\u308c\u3092\u9632\u6b62<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-32\">PHP Enum\u306e\u5236\u9650\u4e8b\u9805\u3068\u6ce8\u610f\u70b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>PHP 8.1\u4ee5\u4e0a\u306e\u8981\u4ef6<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u53e4\u3044PHP\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u30b5\u30dd\u30fc\u30c8\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u4f7f\u7528\u4e0d\u53ef<\/li>\n\n\n\n<li>\u6bb5\u968e\u7684\u79fb\u884c\u306e\u96e3\u3057\u3055<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u306e\u5236\u9650<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u76f4\u63a5\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u4fdd\u5b58\u6642\u306b\u5024\u3078\u306e\u5909\u63db\u304c\u5fc5\u8981<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u3078\u306e\u4fdd\u5b58\u306b\u5de5\u592b\u304c\u5fc5\u8981<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3078\u306e\u5f71\u97ff<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5358\u7d14\u306a\u6587\u5b57\u5217\u5b9a\u6570\u3068\u6bd4\u8f03\u3059\u308b\u3068\u82e5\u5e72\u306e\u30aa\u30fc\u30d0\u30fc\u30d8\u30c3\u30c9<\/li>\n\n\n\n<li>\u5927\u91cf\u306eEnum\u64cd\u4f5c\u304c\u5fc5\u8981\u306a\u5834\u9762\u3067\u306f\u8003\u616e\u304c\u5fc5\u8981<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30ea\u30d5\u30ec\u30af\u30b7\u30e7\u30f3\u306e\u5236\u9650<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u52d5\u7684\u306aEnum\u751f\u6210\u304c\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li>\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u3084\u30d7\u30ed\u30d1\u30c6\u30a3\u306b\u5236\u7d04\u3042\u308a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u65e2\u5b58\u30b3\u30fc\u30c9\u304b\u3089\u306e\u79fb\u884c\u30b3\u30b9\u30c8<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5e83\u7bc4\u56f2\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u308b\u5b9a\u6570\u306e\u79fb\u884c\u306b\u306f\u52b4\u529b\u304c\u5fc5\u8981<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3084API\u3068\u306e\u9023\u643a\u90e8\u5206\u306e\u4fee\u6b63\u304c\u5fc5\u8981<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u306e\u30e1\u30ea\u30c3\u30c8\u306f\u5236\u9650\u4e8b\u9805\u3092\u5927\u304d\u304f\u4e0a\u56de\u308b\u3053\u3068\u304c\u591a\u304f\u3001\u65b0\u898f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3084PHP 8.1\u4ee5\u4e0a\u3092\u4f7f\u7528\u3059\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u7a4d\u6975\u7684\u306b\u63a1\u7528\u3059\u3079\u304d\u6a5f\u80fd\u3067\u3059\u3002\u65e2\u5b58\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u3001\u91cd\u8981\u5ea6\u306e\u9ad8\u3044\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u304b\u3089\u6bb5\u968e\u7684\u306b\u79fb\u884c\u3059\u308b\u3053\u3068\u3067\u3001\u52b9\u679c\u7684\u306bEnum\u306e\u6069\u6075\u3092\u53d7\u3051\u3089\u308c\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-33\">\u5f93\u6765\u306e\u5b9a\u6570\u3068\u6bd4\u8f03\uff1aPHP Enum\u306e\u30e1\u30ea\u30c3\u30c8\u3068\u9650\u754c<\/h2>\n\n\n\n<p>PHP Enum\u306e\u4fa1\u5024\u3092\u6b63\u3057\u304f\u7406\u89e3\u3059\u308b\u305f\u3081\u306b\u306f\u3001\u5f93\u6765\u306ePHP\u3067\u306e\u5b9a\u6570\u8868\u73fe\u3068\u6bd4\u8f03\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002\u9577\u5e74\u306ePHP\u958b\u767a\u3067\u306f\u3001\u5217\u6319\u578b\u306e\u4ee3\u66ff\u3068\u3057\u3066\u69d8\u3005\u306a\u65b9\u6cd5\u304c\u4f7f\u308f\u308c\u3066\u304d\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-34\">\u5f93\u6765\u306ePHP\u3067\u306e\u5b9a\u6570\u8868\u73fe\u65b9\u6cd5<\/h3>\n\n\n\n<p>PHP 8.1\u4ee5\u524d\u3067\u306f\u3001\u5217\u6319\u578b\u306e\u5024\u3092\u8868\u73fe\u3059\u308b\u305f\u3081\u306b\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u65b9\u6cd5\u304c\u4f7f\u308f\u308c\u3066\u3044\u307e\u3057\u305f\uff1a<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-35\">1. \u30b0\u30ed\u30fc\u30d0\u30eb\u5b9a\u6570\uff08define\uff09<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30b0\u30ed\u30fc\u30d0\u30eb\u5b9a\u6570\u306b\u3088\u308b\u5b9f\u88c5\ndefine('STATUS_DRAFT', 'draft');\ndefine('STATUS_PUBLISHED', 'published');\ndefine('STATUS_ARCHIVED', 'archived');\n\n\/\/ \u4f7f\u7528\u4f8b\nfunction updateStatus($status) {\n    if ($status === STATUS_PUBLISHED) {\n        \/\/ \u51e6\u7406\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-36\">2. \u30af\u30e9\u30b9\u5b9a\u6570<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30af\u30e9\u30b9\u5b9a\u6570\u306b\u3088\u308b\u5b9f\u88c5\nclass ArticleStatus {\n    public const DRAFT = 'draft';\n    public const PUBLISHED = 'published';\n    public const ARCHIVED = 'archived';\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u7528\u306e\u88dc\u52a9\u30e1\u30bd\u30c3\u30c9\n    public static function isValid(string $status): bool {\n        return in_array($status, [\n            self::DRAFT,\n            self::PUBLISHED,\n            self::ARCHIVED\n        ]);\n    }\n    \n    \/\/ \u30e9\u30d9\u30eb\u53d6\u5f97\u7528\u306e\u30d8\u30eb\u30d1\u30fc\u30e1\u30bd\u30c3\u30c9\n    public static function getLabel(string $status): string {\n        return match($status) {\n            self::DRAFT =&gt; '\u4e0b\u66f8\u304d',\n            self::PUBLISHED =&gt; '\u516c\u958b\u6e08\u307f',\n            self::ARCHIVED =&gt; '\u30a2\u30fc\u30ab\u30a4\u30d6\u6e08\u307f',\n            default =&gt; '\u4e0d\u660e'\n        };\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nif (ArticleStatus::isValid($status)) {\n    echo ArticleStatus::getLabel($status);\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-37\">3. \u7591\u4f3cEnum\u7684\u306a\u30af\u30e9\u30b9<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6307\u5411\u3067\u7591\u4f3cEnum\u3092\u5b9f\u88c5\nclass Status {\n    private string $value;\n    \n    private function __construct(string $value) {\n        $this-&gt;value = $value;\n    }\n    \n    public static function DRAFT(): self {\n        return new self('draft');\n    }\n    \n    public static function PUBLISHED(): self {\n        return new self('published');\n    }\n    \n    public static function ARCHIVED(): self {\n        return new self('archived');\n    }\n    \n    public function getValue(): string {\n        return $this-&gt;value;\n    }\n    \n    public function equals(self $other): bool {\n        return $this-&gt;value === $other-&gt;value;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$status = Status::PUBLISHED();\nif ($status-&gt;equals(Status::PUBLISHED())) {\n    \/\/ \u51e6\u7406\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-38\">PHP Enum\u3068\u5f93\u6765\u624b\u6cd5\u306e\u6bd4\u8f03<\/h3>\n\n\n\n<p>\u5b9f\u969b\u306e\u30b3\u30fc\u30c9\u3067\u6bd4\u8f03\u3057\u3066\u307f\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ PHP 8.1\u4ee5\u524d\uff1a\u30af\u30e9\u30b9\u5b9a\u6570\u3067\u306e\u5b9f\u88c5\nclass OldPaymentStatus {\n    public const PENDING = 'pending';\n    public const COMPLETED = 'completed';\n    public const FAILED = 'failed';\n    \n    public static function getAll(): array {\n        return [self::PENDING, self::COMPLETED, self::FAILED];\n    }\n    \n    public static function isValid(string $status): bool {\n        return in_array($status, self::getAll());\n    }\n}\n\n\/\/ PHP 8.1\u4ee5\u964d\uff1aEnum\u3067\u306e\u5b9f\u88c5\nenum PaymentStatus: string {\n    case PENDING = 'pending';\n    case COMPLETED = 'completed';\n    case FAILED = 'failed';\n    \n    public function getLabel(): string {\n        return match($this) {\n            self::PENDING =&gt; '\u51e6\u7406\u4e2d',\n            self::COMPLETED =&gt; '\u5b8c\u4e86',\n            self::FAILED =&gt; '\u5931\u6557'\n        };\n    }\n}\n\n\/\/ \u5f93\u6765\u306e\u4f7f\u7528\u6cd5\n$oldStatus = OldPaymentStatus::PENDING;\nif ($oldStatus === OldPaymentStatus::PENDING) {\n    \/\/ \u6587\u5b57\u5217\u540c\u58eb\u306e\u6bd4\u8f03\uff08\u578b\u306e\u4fdd\u8a3c\u306a\u3057\uff09\n}\n\n\/\/ Enum\u306e\u4f7f\u7528\u6cd5\n$status = PaymentStatus::PENDING;\nif ($status === PaymentStatus::PENDING) {\n    \/\/ \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u540c\u58eb\u306e\u6bd4\u8f03\uff08\u578b\u306e\u4fdd\u8a3c\u3042\u308a\uff09\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-39\">PHP Enum\u306e\u4e3b\u306a\u30e1\u30ea\u30c3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u771f\u306e\u578b\u5b89\u5168\u6027<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5f15\u6570\u3084\u623b\u308a\u5024\u306b\u5177\u4f53\u7684\u306aEnum\u578b\u3092\u6307\u5b9a\u53ef\u80fd<\/li>\n\n\n\n<li>\u4e0d\u6b63\u306a\u5024\u306e\u4ee3\u5165\u3084\u6bd4\u8f03\u3092\u5b8c\u5168\u306b\u9632\u6b62<\/li>\n\n\n\n<li>PHPStan\u3084Psalm\u306a\u3069\u306e\u9759\u7684\u89e3\u6790\u30c4\u30fc\u30eb\u3068\u306e\u89aa\u548c\u6027\u5411\u4e0a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>IDE\u30b5\u30dd\u30fc\u30c8\u306e\u5145\u5b9f<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30b3\u30fc\u30c9\u88dc\u5b8c\u3067\u5229\u7528\u53ef\u80fd\u306a\u3059\u3079\u3066\u306e\u30b1\u30fc\u30b9\u3092\u8868\u793a<\/li>\n\n\n\n<li>\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u6642\u306e\u4e00\u62ec\u5909\u66f4\u304c\u5bb9\u6613<\/li>\n\n\n\n<li>\u4f7f\u7528\u7b87\u6240\u306e\u8ffd\u8de1\u304c\u7c21\u5358<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u30ed\u30b8\u30c3\u30af\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u306b\u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u3066\u30ed\u30b8\u30c3\u30af\u3092\u96c6\u7d04<\/li>\n\n\n\n<li>\u8868\u793a\u7528\u306e\u6587\u5b57\u5217\u3084\u632f\u308b\u821e\u3044\u3092Enum\u5185\u306b\u9589\u3058\u8fbc\u3081<\/li>\n\n\n\n<li>\u95a2\u9023\u3059\u308b\u30ed\u30b8\u30c3\u30af\u306e\u6563\u5728\u3092\u9632\u6b62<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b3\u30fc\u30c9\u306e\u660e\u78ba\u3055\u3068\u81ea\u5df1\u6587\u66f8\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u578b\u304b\u3089\u3069\u306e\u3088\u3046\u306a\u5024\u304c\u671f\u5f85\u3055\u308c\u308b\u304b\u660e\u78ba<\/li>\n\n\n\n<li>\u610f\u56f3\u304c\u660e\u78ba\u306b\u306a\u308a\u3001\u30b3\u30e1\u30f3\u30c8\u306e\u5fc5\u8981\u6027\u304c\u4f4e\u6e1b<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u3068\u4fdd\u5b88\u6027\u304c\u5411\u4e0a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u7c21\u7d20\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>from\/tryFrom\u30e1\u30bd\u30c3\u30c9\u306b\u3088\u308b\u5165\u529b\u5024\u306e\u691c\u8a3c<\/li>\n\n\n\n<li>\u4e0d\u6b63\u5024\u306e\u65e9\u671f\u691c\u51fa\u304c\u5bb9\u6613<\/li>\n\n\n\n<li>\u6761\u4ef6\u5206\u5c90\u306e\u6f0f\u308c\u3092\u9632\u6b62<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-40\">PHP Enum\u306e\u5236\u9650\u4e8b\u9805\u3068\u6ce8\u610f\u70b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>PHP 8.1\u4ee5\u4e0a\u306e\u8981\u4ef6<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u53e4\u3044PHP\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u30b5\u30dd\u30fc\u30c8\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u4f7f\u7528\u4e0d\u53ef<\/li>\n\n\n\n<li>\u6bb5\u968e\u7684\u79fb\u884c\u306e\u96e3\u3057\u3055<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u306e\u5236\u9650<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u76f4\u63a5\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u4fdd\u5b58\u6642\u306b\u5024\u3078\u306e\u5909\u63db\u304c\u5fc5\u8981<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u3078\u306e\u4fdd\u5b58\u306b\u5de5\u592b\u304c\u5fc5\u8981<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3078\u306e\u5f71\u97ff<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5358\u7d14\u306a\u6587\u5b57\u5217\u5b9a\u6570\u3068\u6bd4\u8f03\u3059\u308b\u3068\u82e5\u5e72\u306e\u30aa\u30fc\u30d0\u30fc\u30d8\u30c3\u30c9<\/li>\n\n\n\n<li>\u5927\u91cf\u306eEnum\u64cd\u4f5c\u304c\u5fc5\u8981\u306a\u5834\u9762\u3067\u306f\u8003\u616e\u304c\u5fc5\u8981<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30ea\u30d5\u30ec\u30af\u30b7\u30e7\u30f3\u306e\u5236\u9650<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u52d5\u7684\u306aEnum\u751f\u6210\u304c\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li>\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u3084\u30d7\u30ed\u30d1\u30c6\u30a3\u306b\u5236\u7d04\u3042\u308a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u65e2\u5b58\u30b3\u30fc\u30c9\u304b\u3089\u306e\u79fb\u884c\u30b3\u30b9\u30c8<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5e83\u7bc4\u56f2\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u308b\u5b9a\u6570\u306e\u79fb\u884c\u306b\u306f\u52b4\u529b\u304c\u5fc5\u8981<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3084API\u3068\u306e\u9023\u643a\u90e8\u5206\u306e\u4fee\u6b63\u304c\u5fc5\u8981<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u306e\u30e1\u30ea\u30c3\u30c8\u306f\u5236\u9650\u4e8b\u9805\u3092\u5927\u304d\u304f\u4e0a\u56de\u308b\u3053\u3068\u304c\u591a\u304f\u3001\u65b0\u898f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3084PHP 8.1\u4ee5\u4e0a\u3092\u4f7f\u7528\u3059\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u7a4d\u6975\u7684\u306b\u63a1\u7528\u3059\u3079\u304d\u6a5f\u80fd\u3067\u3059\u3002\u65e2\u5b58\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u3001\u91cd\u8981\u5ea6\u306e\u9ad8\u3044\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u304b\u3089\u6bb5\u968e\u7684\u306b\u79fb\u884c\u3059\u308b\u3053\u3068\u3067\u3001\u52b9\u679c\u7684\u306bEnum\u306e\u6069\u6075\u3092\u53d7\u3051\u3089\u308c\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-41\">\u578b\u5b89\u5168\u6027\u306e\u5411\u4e0a\u3068IDE\u30b5\u30dd\u30fc\u30c8\u306e\u5145\u5b9f<\/h3>\n\n\n\n<p>PHP Enum\u306e\u6700\u3082\u91cd\u8981\u306a\u30e1\u30ea\u30c3\u30c8\u306e\u4e00\u3064\u306f\u3001\u5f37\u529b\u306a\u578b\u5b89\u5168\u6027\u306e\u5411\u4e0a\u3068\u305d\u308c\u306b\u4f34\u3046IDE\u30b5\u30dd\u30fc\u30c8\u306e\u5145\u5b9f\u3067\u3059\u3002\u3053\u306e\u4e21\u8005\u304c\u76f8\u307e\u3063\u3066\u3001\u958b\u767a\u4f53\u9a13\u304c\u5287\u7684\u306b\u5411\u4e0a\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-42\">\u578b\u5b89\u5168\u6027\u306e\u5411\u4e0a<\/h4>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u5f93\u6765\u306e\u6587\u5b57\u5217\u3084\u6574\u6570\u306b\u3088\u308b\u5b9a\u6570\u8868\u73fe\u3068\u6bd4\u8f03\u3057\u3066\u3001\u578b\u30ec\u30d9\u30eb\u3067\u306e\u5b89\u5168\u6027\u304c\u5927\u5e45\u306b\u5411\u4e0a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u5f93\u6765\u306e\u65b9\u5f0f\uff08\u578b\u5b89\u5168\u6027\u306a\u3057\uff09\nfunction processOrder(string $status) {\n    \/\/ $status\u306b\u306f\u4efb\u610f\u306e\u6587\u5b57\u5217\u304c\u5165\u308b\u53ef\u80fd\u6027\u3042\u308a\n    if ($status === OrderStatus::SHIPPED) {\n        \/\/ ...\n    }\n}\n\n\/\/ Enum\u3092\u4f7f\u7528\uff08\u578b\u5b89\u5168\u6027\u3042\u308a\uff09\nfunction processOrder(OrderStatus $status) {\n    \/\/ $status\u306b\u306fOrderStatus\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3057\u304b\u5165\u3089\u306a\u3044\n    if ($status === OrderStatus::SHIPPED) {\n        \/\/ ...\n    }\n}\n<\/pre>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3059\u308b\u4e3b\u306a\u578b\u5b89\u5168\u6027\u306e\u30e1\u30ea\u30c3\u30c8\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4e0d\u6b63\u306a\u5024\u306e\u6df7\u5165\u9632\u6b62<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u95a2\u6570\u306e\u5f15\u6570\u3068\u3057\u3066\u6e21\u305b\u308b\u306e\u306fEnum\u578b\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u307f<\/li>\n\n\n\n<li>\u30bf\u30a4\u30d7\u30df\u30b9\u3084\u30e9\u30f3\u30bf\u30a4\u30e0\u30a8\u30e9\u30fc\u306e\u30ea\u30b9\u30af\u304c\u5927\u5e45\u306b\u4f4e\u6e1b<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u7db2\u7f85\u7684\u306a\u6761\u4ef6\u5206\u5c90\u306e\u4fdd\u8a3c<\/strong>\n<ul class=\"wp-block-list\">\n<li>match\u3084switch\u6587\u3067\u5168\u3066\u306e\u30b1\u30fc\u30b9\u3092\u7db2\u7f85\u3057\u3066\u3044\u308b\u304b\u691c\u8a3c\u53ef\u80fd<\/li>\n\n\n\n<li>\u65b0\u3057\u3044\u30b1\u30fc\u30b9\u304c\u8ffd\u52a0\u3055\u308c\u305f\u969b\u306e\u5909\u66f4\u6f0f\u308c\u3092\u691c\u51fa<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u5024\u306e\u5909\u63db\u3068\u691c\u8a3c\u306e\u81ea\u52d5\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>from\/tryFrom\u30e1\u30bd\u30c3\u30c9\u306b\u3088\u308b\u5b89\u5168\u306a\u5909\u63db<\/li>\n\n\n\n<li>\u4e0d\u6b63\u306a\u5024\u306e\u30a8\u30e9\u30fc\u51e6\u7406\u304c\u7c21\u7565\u5316<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-43\">IDE\u30b5\u30dd\u30fc\u30c8\u306e\u5145\u5b9f<\/h4>\n\n\n\n<p>PhpStorm\u3001VSCode + Intelephense\u3001NetBeans\u306a\u3069\u306e\u4e3b\u8981IDE\u306f\u3001PHP 8.1\u306eEnum\u578b\u3092\u5b8c\u5168\u306b\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u304a\u308a\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u958b\u767a\u4f53\u9a13\u306e\u5411\u4e0a\u304c\u898b\u3089\u308c\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30a4\u30f3\u30c6\u30ea\u30b8\u30a7\u30f3\u30c8\u306a\u30b3\u30fc\u30c9\u88dc\u5b8c<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u30b1\u30fc\u30b9\u306e\u540d\u524d\u3092\u6b63\u78ba\u306b\u88dc\u5b8c<\/li>\n\n\n\n<li>\u30e1\u30bd\u30c3\u30c9\u3084\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u63d0\u6848<\/li>\n\n\n\n<li>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306e\u30a4\u30f3\u30e9\u30a4\u30f3\u8868\u793a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306e\u30b5\u30dd\u30fc\u30c8<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u30b1\u30fc\u30b9\u540d\u306e\u4e00\u62ec\u5909\u66f4<\/li>\n\n\n\n<li>\u4f7f\u7528\u7b87\u6240\u306e\u81ea\u52d5\u691c\u51fa\u3068\u66f4\u65b0<\/li>\n\n\n\n<li>\u672a\u4f7f\u7528\u306e\u30b1\u30fc\u30b9\u306e\u8b66\u544a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b3\u30fc\u30c9\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u306e\u5411\u4e0a<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30b1\u30fc\u30b9\u5b9a\u7fa9\u3078\u306e\u30b8\u30e3\u30f3\u30d7<\/li>\n\n\n\n<li>\u4f7f\u7528\u7b87\u6240\u306e\u4e00\u89a7\u8868\u793a<\/li>\n\n\n\n<li>\u7d99\u627f\u95a2\u4fc2\u3084\u5b9f\u88c5\u306e\u53ef\u8996\u5316<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u30a8\u30e9\u30fc\u691c\u51fa<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5b58\u5728\u3057\u306a\u3044\u30b1\u30fc\u30b9\u306e\u53c2\u7167\u3092\u5373\u5ea7\u306b\u8b66\u544a<\/li>\n\n\n\n<li>\u578b\u306e\u4e0d\u4e00\u81f4\u3092\u8996\u899a\u7684\u306b\u8868\u793a<\/li>\n\n\n\n<li>Null\u5b89\u5168\u6027\u306e\u691c\u8a3c<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>\u4ee5\u4e0b\u306f\u3001PhpStorm\u3067\u306eEnum\u4f7f\u7528\u6642\u306eIDE\u6a5f\u80fd\u306e\u4f8b\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Enum\u5b9a\u7fa9\nenum PaymentMethod: string {\n    case CREDIT_CARD = 'credit_card';\n    case PAYPAL = 'paypal';\n    case BANK_TRANSFER = 'bank_transfer';\n    \n    public function getDisplayName(): string {\n        return match($this) {\n            self::CREDIT_CARD =&gt; '\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9',\n            self::PAYPAL =&gt; 'PayPal',\n            self::BANK_TRANSFER =&gt; '\u9280\u884c\u632f\u8fbc'\n        };\n    }\n    \n    public function getIcon(): string {\n        return match($this) {\n            self::CREDIT_CARD =&gt; 'credit-card-icon',\n            self::PAYPAL =&gt; 'paypal-icon',\n            self::BANK_TRANSFER =&gt; 'bank-icon'\n        };\n    }\n}\n\n\/\/ IDE\u88dc\u5b8c\u3068\u30a8\u30e9\u30fc\u691c\u51fa\u306e\u4f8b\nfunction processPayment(Order $order, PaymentMethod $method) {\n    \/\/ $method. \u3068\u5165\u529b\u3059\u308b\u3068\u3001getDisplayName()\u3068getIcon()\u304c\u88dc\u5b8c\u5019\u88dc\u3068\u3057\u3066\u8868\u793a\u3055\u308c\u308b\n    $displayName = $method-&gt;getDisplayName();\n    \n    \/\/ PaymentMethod::CR \u3068\u5165\u529b\u3059\u308b\u3068 CREDIT_CARD \u304c\u88dc\u5b8c\u3055\u308c\u308b\n    if ($method === PaymentMethod::CREDIT_CARD) {\n        \/\/ \u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9\u7279\u6709\u306e\u51e6\u7406\n    }\n    \n    \/\/ \u5b58\u5728\u3057\u306a\u3044\u30b1\u30fc\u30b9\u3092\u53c2\u7167\u3059\u308b\u3068IDE\u304c\u5373\u5ea7\u306b\u8b66\u544a\n    \/\/ if ($method === PaymentMethod::BITCOIN) { \/\/ \u30a8\u30e9\u30fc\u8868\u793a\n    \n    \/\/ match\u5f0f\u3067\u5168\u3066\u306e\u30b1\u30fc\u30b9\u3092\u7db2\u7f85\u3057\u3066\u3044\u306a\u3044\u3068IDE\u304c\u8b66\u544a\n    $fee = match($method) {\n        PaymentMethod::CREDIT_CARD =&gt; 3.5,\n        PaymentMethod::PAYPAL =&gt; 2.9,\n        \/\/ BANK_TRANSFER\u304c\u6f0f\u308c\u3066\u3044\u308b\u305f\u3081\u8b66\u544a\n    };\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-44\">\u9759\u7684\u89e3\u6790\u30c4\u30fc\u30eb\u3068\u306e\u9023\u643a<\/h4>\n\n\n\n<p>PHP Enum\u306f\u3001PHPStan\u3084Psalm\u306a\u3069\u306e\u9759\u7684\u89e3\u6790\u30c4\u30fc\u30eb\u3068\u3082\u5f37\u529b\u306b\u9023\u643a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>PHPStan Level 8+<\/strong> \u3067\u306e\u53b3\u683c\u306a\u578b\u30c1\u30a7\u30c3\u30af\n<ul class=\"wp-block-list\">\n<li>Enum\u306e\u7db2\u7f85\u6027\u30c1\u30a7\u30c3\u30af<\/li>\n\n\n\n<li>\u4e0d\u53ef\u80fd\u306a\u578b\u306e\u7d44\u307f\u5408\u308f\u305b\u306e\u691c\u51fa<\/li>\n\n\n\n<li>\u672a\u5b9a\u7fa9\u30b1\u30fc\u30b9\u306e\u53c2\u7167\u691c\u51fa<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Psalm<\/strong> \u3067\u306e\u62e1\u5f35\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n<ul class=\"wp-block-list\">\n<li>Enum\u306e\u4f7f\u7528\u30d1\u30bf\u30fc\u30f3\u306e\u691c\u8a3c<\/li>\n\n\n\n<li>\u6f5c\u5728\u7684\u306a\u578b\u306e\u554f\u984c\u306e\u767a\u898b<\/li>\n\n\n\n<li>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u751f\u6210\u306e\u5f37\u5316<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>PHP Enum\u306b\u3088\u308b\u578b\u5b89\u5168\u6027\u306e\u5411\u4e0a\u3068IDE\u30b5\u30dd\u30fc\u30c8\u306e\u5145\u5b9f\u306f\u3001\u5358\u306a\u308b\u958b\u767a\u4f53\u9a13\u306e\u5411\u4e0a\u3060\u3051\u3067\u306a\u304f\u3001\u30d0\u30b0\u306e\u65e9\u671f\u767a\u898b\u3068\u4e88\u9632\u3001\u30c1\u30fc\u30e0\u958b\u767a\u306e\u52b9\u7387\u5316\u3001\u30b3\u30fc\u30c9\u306e\u81ea\u5df1\u6587\u66f8\u5316\u306b\u3082\u5927\u304d\u304f\u8ca2\u732e\u3057\u307e\u3059\u3002\u7279\u306b\u5927\u898f\u6a21\u306a\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3084\u8907\u6570\u4eba\u3067\u306e\u958b\u767a\u306b\u304a\u3044\u3066\u3001\u305d\u306e\u6069\u6075\u306f\u9855\u8457\u3067\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-45\">Enum\u3092\u4f7f\u7528\u3059\u308b\u969b\u306e\u5236\u9650\u4e8b\u9805\u3068\u6ce8\u610f\u70b9<\/h3>\n\n\n\n<p>PHP Enum\u306f\u5f37\u529b\u306a\u6a5f\u80fd\u3067\u3059\u304c\u3001\u3044\u304f\u3064\u304b\u306e\u91cd\u8981\u306a\u5236\u9650\u4e8b\u9805\u304c\u3042\u308a\u307e\u3059\u3002\u5b9f\u969b\u306e\u958b\u767a\u3067\u554f\u984c\u306b\u76f4\u9762\u3059\u308b\u524d\u306b\u3001\u3053\u308c\u3089\u306e\u5236\u7d04\u3092\u7406\u89e3\u3057\u3001\u9069\u5207\u306a\u5bfe\u5fdc\u7b56\u3092\u77e5\u3063\u3066\u304a\u304f\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-46\">1. \u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u306e\u5236\u9650<\/h4>\n\n\n\n<p>PHP Enum\u306e\u6700\u3082\u5927\u304d\u306a\u5236\u9650\u306e\u4e00\u3064\u306f\u3001\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u304c\u3067\u304d\u306a\u3044\u3053\u3068\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u8a66\u884c\n$status = OrderStatus::PENDING;\n$serialized = serialize($status); \/\/ \u30a8\u30e9\u30fc: Uncaught Error: Serialization of backed enum is not allowed\n<\/pre>\n\n\n\n<p>\u3053\u306e\u5236\u9650\u306f\u3001Enum\u306e\u4e00\u8cab\u6027\u3068\u4e0d\u5909\u6027\u3092\u4fdd\u8a3c\u3059\u308b\u305f\u3081\u306e\u3082\u306e\u3067\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u5834\u9762\u3067\u554f\u984c\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u3078\u306eEnum\u4fdd\u5b58<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\uff08Redis\/Memcached\u306a\u3069\uff09\u3078\u306e\u4fdd\u5b58<\/li>\n\n\n\n<li>\u30b8\u30e7\u30d6\u30ad\u30e5\u30fc\u3078\u306e\u53d7\u3051\u6e21\u3057<\/li>\n<\/ul>\n\n\n\n<p><strong>\u5bfe\u5fdc\u7b56:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Backed Enum\u306e\u5834\u5408\uff1a\u5024\u3092\u4fdd\u5b58\nfunction storeEnum(BackedEnum $enum): string|int {\n    return $enum-&gt;value;\n}\n\nfunction retrieveEnum(string|int $value, string $enumClass): ?object {\n    return $enumClass::tryFrom($value);\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$storedValue = storeEnum(OrderStatus::PENDING); \/\/ 'pending'\u3092\u4fdd\u5b58\n$enum = retrieveEnum($storedValue, OrderStatus::class); \/\/ OrderStatus::PENDING\u3092\u5fa9\u5143\n\n\/\/ Pure Enum\u306e\u5834\u5408\uff1a\u540d\u524d\u3092\u4fdd\u5b58\nfunction storePureEnum(\\UnitEnum $enum): string {\n    return $enum-&gt;name;\n}\n\nfunction retrievePureEnum(string $name, string $enumClass): ?object {\n    foreach ($enumClass::cases() as $case) {\n        if ($case-&gt;name === $name) {\n            return $case;\n        }\n    }\n    return null;\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-47\">2. \u30d7\u30ed\u30d1\u30c6\u30a3\u3068\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u306e\u5236\u9650<\/h4>\n\n\n\n<p>Enum\u306f\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u5b9a\u7fa9\u3068\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u306e\u4f7f\u7528\u306b\u5236\u9650\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u5b9a\u7fa9\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li>\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u306e\u30a2\u30af\u30bb\u30b9\u4fee\u98fe\u5b50\u3092\u5909\u66f4\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li>\u72ec\u81ea\u306e\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u5f15\u6570\u3092\u8ffd\u52a0\u3067\u304d\u306a\u3044<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum Color\n{\n    case RED;\n    case GREEN;\n    case BLUE;\n    \n    \/\/ \u4ee5\u4e0b\u306f\u30a8\u30e9\u30fc: \u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u30d7\u30ed\u30d1\u30c6\u30a3\n    \/\/ private string $hex;\n    \n    \/\/ \u4ee5\u4e0b\u306f\u30a8\u30e9\u30fc: \u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u306e\u30a2\u30af\u30bb\u30b9\u4fee\u98fe\u5b50\u5909\u66f4\n    \/\/ public function __construct() { ... }\n}\n<\/pre>\n\n\n\n<p><strong>\u5bfe\u5fdc\u7b56:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum Color\n{\n    case RED;\n    case GREEN;\n    case BLUE;\n    \n    \/\/ \u9759\u7684\u30d7\u30ed\u30d1\u30c6\u30a3\u306f\u8a31\u53ef\u3055\u308c\u308b\n    private static array $hexValues = [\n        self::RED-&gt;name =&gt; '#FF0000',\n        self::GREEN-&gt;name =&gt; '#00FF00',\n        self::BLUE-&gt;name =&gt; '#0000FF'\n    ];\n    \n    \/\/ \u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u4ee3\u308f\u308a\u306b\u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u7528\n    public function getHexValue(): string\n    {\n        return self::$hexValues[$this-&gt;name];\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-48\">3. \u7d99\u627f\u3068\u62e1\u5f35\u306e\u5236\u9650<\/h4>\n\n\n\n<p>Enum\u306f\u7d99\u627f\u3084\u30af\u30e9\u30b9\u62e1\u5f35\u306b\u95a2\u3057\u3066\u91cd\u8981\u306a\u5236\u9650\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enum\u306f\u4ed6\u306e\u30af\u30e9\u30b9\u3084Enum\u3092\u7d99\u627f\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li>Enum\u306f\u7d99\u627f\u3055\u308c\u308b\u3053\u3068\u304c\u3067\u304d\u306a\u3044<\/li>\n\n\n\n<li>\u62bd\u8c61Enum\u306f\u4f5c\u6210\u3067\u304d\u306a\u3044<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u4ee5\u4e0b\u306f\u3059\u3079\u3066\u4e0d\u53ef\u80fd\n\/\/ enum AdvancedColor extends Color { ... }\n\/\/ enum DetailedStatus extends AbstractStatus { ... }\n\/\/ abstract enum AbstractStatus { ... }\n<\/pre>\n\n\n\n<p><strong>\u5bfe\u5fdc\u7b56:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u7d99\u627f\u306e\u4ee3\u308f\u308a\u306b\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3068\u8907\u5408\u3092\u4f7f\u7528\ninterface ColorInterface\n{\n    public function getHexValue(): string;\n    public function getRgbValue(): array;\n}\n\nenum Color implements ColorInterface\n{\n    case RED;\n    case GREEN;\n    case BLUE;\n    \n    public function getHexValue(): string\n    {\n        return match($this) {\n            self::RED =&gt; '#FF0000',\n            self::GREEN =&gt; '#00FF00',\n            self::BLUE =&gt; '#0000FF',\n        };\n    }\n    \n    public function getRgbValue(): array\n    {\n        return match($this) {\n            self::RED =&gt; [255, 0, 0],\n            self::GREEN =&gt; [0, 255, 0],\n            self::BLUE =&gt; [0, 0, 255],\n        };\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-49\">4. \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u306e\u9023\u643a\u5236\u9650<\/h4>\n\n\n\n<p>Enum\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u9023\u643a\u3059\u308b\u969b\u306b\u306f\u3001\u3044\u304f\u3064\u304b\u306e\u6ce8\u610f\u70b9\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Backed Enum\u306e\u5024\u3092\u30ab\u30e9\u30e0\u306b\u4fdd\u5b58\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b<\/li>\n\n\n\n<li>ORM\u30c4\u30fc\u30eb\u306b\u3088\u3063\u3066Enum\u5bfe\u5fdc\u72b6\u6cc1\u304c\u7570\u306a\u308b<\/li>\n\n\n\n<li>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30b9\u30ad\u30fc\u30de\u306e\u9069\u5207\u306a\u8a2d\u5b9a\u304c\u5fc5\u8981<\/li>\n<\/ul>\n\n\n\n<p><strong>\u5bfe\u5fdc\u7b56:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Eloquent (Laravel) \u306e\u4f8b\nclass Order extends Model\n{\n    protected $casts = [\n        'status' =&gt; OrderStatus::class,\n    ];\n}\n\n\/\/ Doctrine \u306e\u4f8b\n\/**\n * @Entity\n *\/\nclass Order\n{\n    \/**\n     * @Column(type=\"string\", enumType=OrderStatus::class)\n     *\/\n    private OrderStatus $status;\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-50\">5. \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3078\u306e\u5f71\u97ff<\/h4>\n\n\n\n<p>Enum\u306f\u5358\u7d14\u306a\u5b9a\u6570\u3088\u308a\u3082\u30aa\u30fc\u30d0\u30fc\u30d8\u30c3\u30c9\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u306e\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf<\/li>\n\n\n\n<li>\u30e1\u30bd\u30c3\u30c9\u547c\u3073\u51fa\u3057\u306e\u30b3\u30b9\u30c8<\/li>\n\n\n\n<li>\u5927\u91cf\u306eEnum\u64cd\u4f5c\u6642\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u5f71\u97ff<\/li>\n<\/ul>\n\n\n\n<p>\u975e\u5e38\u306b\u9ad8\u983b\u5ea6\u306e\u64cd\u4f5c\u3084\u6975\u3081\u3066\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30af\u30ea\u30c6\u30a3\u30ab\u30eb\u306a\u90e8\u5206\u3067\u306f\u3001\u3053\u306e\u70b9\u3092\u8003\u616e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-51\">6. PHP 8.1\u8981\u4ef6\u306e\u4e92\u63db\u6027\u554f\u984c<\/h4>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3059\u308b\u306b\u306fPHP 8.1\u4ee5\u4e0a\u304c\u5fc5\u8981\u306a\u305f\u3081\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u4e92\u63db\u6027\u306e\u554f\u984c\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30ec\u30ac\u30b7\u30fc\u30b7\u30b9\u30c6\u30e0\u3068\u306e\u7d71\u5408\u304c\u96e3\u3057\u3044<\/li>\n\n\n\n<li>\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u74b0\u5883\u306e\u5236\u7d04<\/li>\n\n\n\n<li>\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u4e92\u63db\u6027\u8981\u4ef6<\/li>\n<\/ul>\n\n\n\n<p><strong>\u5bfe\u5fdc\u7b56:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30dd\u30ea\u30d5\u30a3\u30eb\u7684\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\uff08\u5b8c\u5168\u306a\u4ee3\u66ff\u3067\u306f\u306a\u3044\uff09\nif (PHP_VERSION_ID &lt; 80100) {\n    class OrderStatus\n    {\n        public const PENDING = 'pending';\n        public const PROCESSING = 'processing';\n        public const COMPLETED = 'completed';\n        \n        private function __construct() {}\n        \n        public static function from(string $value): self\n        {\n            if (!in_array($value, [self::PENDING, self::PROCESSING, self::COMPLETED])) {\n                throw new \\ValueError(\"Invalid value\");\n            }\n            \n            $instance = new self();\n            $instance-&gt;value = $value;\n            return $instance;\n        }\n    }\n} else {\n    enum OrderStatus: string\n    {\n        case PENDING = 'pending';\n        case PROCESSING = 'processing';\n        case COMPLETED = 'completed';\n    }\n}\n<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5236\u9650\u4e8b\u9805\u3092\u7406\u89e3\u3057\u305f\u4e0a\u3067\u3001\u9069\u5207\u306a\u5834\u9762\u3067Enum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002\u591a\u304f\u306e\u5834\u5408\u3001\u3053\u308c\u3089\u306e\u5236\u9650\u306f\u56de\u907f\u53ef\u80fd\u3067\u3042\u308a\u3001Enum\u306e\u30e1\u30ea\u30c3\u30c8\u304c\u3053\u308c\u3089\u306e\u5236\u7d04\u3092\u5341\u5206\u306b\u4e0a\u56de\u308b\u3053\u3068\u304c\u591a\u3044\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-52\">PHP Enum\u306e\u5b9f\u8df5\u7684\u6d3b\u7528\u6cd5\uff1a5\u3064\u306e\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3<\/h2>\n\n\n\n<p>PHP Enum\u306e\u57fa\u672c\u7684\u306a\u69cb\u6587\u3068\u7279\u6027\u3092\u7406\u89e3\u3057\u305f\u3068\u3053\u308d\u3067\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u3069\u306e\u3088\u3046\u306b\u6d3b\u7528\u3067\u304d\u308b\u304b\u3092\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002\u3053\u3053\u3067\u306f\u3001PHP\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u304a\u3051\u308bEnum\u306e5\u3064\u306e\u5b9f\u8df5\u7684\u306a\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-53\">\u30d1\u30bf\u30fc\u30f3\u6982\u8981<\/h3>\n\n\n\n<p>PHP Enum\u306f\u69d8\u3005\u306a\u5834\u9762\u3067\u6d3b\u7528\u3067\u304d\u307e\u3059\u304c\u3001\u7279\u306b\u4ee5\u4e0b\u306e5\u3064\u306e\u30d1\u30bf\u30fc\u30f3\u304c\u52b9\u679c\u7684\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u3068\u30d5\u30ed\u30fc\u5236\u5fa1<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30d3\u30b8\u30cd\u30b9\u30d7\u30ed\u30bb\u30b9\u306e\u72b6\u614b\u9077\u79fb\u3092Enum\u578b\u3067\u8868\u73fe<\/li>\n\n\n\n<li>\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3084\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u7ba1\u7406\u3068\u72b6\u614b\u9077\u79fb\u306e\u5236\u7d04<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u30c7\u30fc\u30bf\u6574\u5408\u6027\u306e\u78ba\u4fdd<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5165\u529b\u5024\u306e\u691c\u8a3c\u3068\u578b\u5f37\u5236<\/li>\n\n\n\n<li>\u30c9\u30e1\u30a4\u30f3\u5236\u7d04\u3068\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u306e\u5b89\u5168\u306a\u9023\u643a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30dd\u30ea\u30b7\u30fc\u3068\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u6a29\u9650\u3068\u30ed\u30fc\u30eb\u306e\u4f53\u7cfb\u7684\u306a\u7ba1\u7406<\/li>\n\n\n\n<li>\u6761\u4ef6\u5206\u5c90\u306e\u7c21\u7d20\u5316\u3068\u53ef\u8aad\u6027\u5411\u4e0a<\/li>\n\n\n\n<li>\u30a2\u30af\u30bb\u30b9\u5236\u5fa1\u306e\u4e00\u5143\u7ba1\u7406<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u306e\u5fe0\u5b9f\u306a\u8868\u73fe<\/li>\n\n\n\n<li>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u306eEnum\u6d3b\u7528<\/li>\n\n\n\n<li>\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>API\u30ec\u30b9\u30dd\u30f3\u30b9\u3068\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u4e00\u8cab\u6027\u306e\u3042\u308bAPI\u5fdc\u7b54\u306e\u69cb\u7bc9<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3068\u4f8b\u5916\u306e\u4f53\u7cfb\u7684\u7ba1\u7406<\/li>\n\n\n\n<li>\u591a\u8a00\u8a9e\u5bfe\u5fdc\u3068\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u56fd\u969b\u5316<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-54\">\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u306e\u9078\u629e\u57fa\u6e96<\/h3>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30d1\u30bf\u30fc\u30f3\u306f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u7279\u6027\u3084\u8981\u4ef6\u306b\u5fdc\u3058\u3066\u9078\u629e\u30fb\u7d44\u307f\u5408\u308f\u305b\u304c\u53ef\u80fd\u3067\u3059\uff1a<\/p>\n\n\n<div id=\"id-eb35e0cf-c948-4a05-93e8-66330f080195\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u30d1\u30bf\u30fc\u30f3<\/th><th>\u6700\u9069\u306a\u4f7f\u7528\u5834\u9762<\/th><th>\u4e3b\u306a\u5229\u70b9<\/th><\/tr><\/thead><tbody><tr><td>\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406<\/td><td>\u8907\u96d1\u306a\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u304c\u3042\u308b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3<\/td><td>\u30d7\u30ed\u30bb\u30b9\u306e\u53ef\u8996\u5316\u3001\u4e0d\u6b63\u306a\u72b6\u614b\u9077\u79fb\u306e\u9632\u6b62<\/td><\/tr><tr><td>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/td><td>\u30e6\u30fc\u30b6\u30fc\u5165\u529b\u3084\u5916\u90e8\u30c7\u30fc\u30bf\u3092\u6271\u3046\u30b7\u30b9\u30c6\u30e0<\/td><td>\u4e00\u8cab\u3057\u305f\u30c7\u30fc\u30bf\u691c\u8a3c\u3001\u30c9\u30e1\u30a4\u30f3\u5236\u7d04\u306e\u660e\u78ba\u5316<\/td><\/tr><tr><td>\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3<\/td><td>\u8907\u6570\u6a29\u9650\u30ec\u30d9\u30eb\u3092\u6301\u3064\u30b7\u30b9\u30c6\u30e0<\/td><td>\u30a2\u30af\u30bb\u30b9\u5236\u5fa1\u306e\u7c21\u7d20\u5316\u3001\u6a29\u9650\u8a2d\u8a08\u306e\u67d4\u8edf\u6027<\/td><\/tr><tr><td>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8<\/td><td>\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08\u63a1\u7528\u30d7\u30ed\u30b8\u30a7\u30af\u30c8<\/td><td>\u8c4a\u304b\u306a\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u3001\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306e\u96c6\u7d04<\/td><\/tr><tr><td>API\u30ec\u30b9\u30dd\u30f3\u30b9<\/td><td>\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u3084Web API<\/td><td>\u4e00\u8cab\u3057\u305f\u30ec\u30b9\u30dd\u30f3\u30b9\u5f62\u5f0f\u3001\u56fd\u969b\u5316\u5bfe\u5fdc<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"i-55\">\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u306e\u7d44\u307f\u5408\u308f\u305b<\/h3>\n\n\n\n<p>\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u30d1\u30bf\u30fc\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u3066\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u4e00\u822c\u7684\u3067\u3059\u3002\u4f8b\u3048\u3070\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>E\u30b3\u30de\u30fc\u30b9\u30b5\u30a4\u30c8\uff1a\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406 + \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3 + \u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8<\/li>\n\n\n\n<li>CRM\u30b7\u30b9\u30c6\u30e0\uff1a\u30dd\u30ea\u30b7\u30fc\u7ba1\u7406 + \u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406 + API\u30ec\u30b9\u30dd\u30f3\u30b9<\/li>\n\n\n\n<li>\u91d1\u878d\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\uff1a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3 + \u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8 + \u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30d1\u30bf\u30fc\u30f3\u306f\u72ec\u7acb\u3057\u3066\u4f7f\u3048\u308b\u3060\u3051\u3067\u306a\u304f\u3001\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3055\u3089\u306b\u5f37\u529b\u306b\u306a\u308a\u307e\u3059\u3002\u5404\u30d1\u30bf\u30fc\u30f3\u306e\u8a73\u7d30\u3068\u5177\u4f53\u7684\u306a\u5b9f\u88c5\u4f8b\u3092\u4ee5\u964d\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u8a73\u3057\u304f\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<p>\u5404\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u306b\u306f\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u305d\u306e\u307e\u307e\u4f7f\u3048\u308b\u5b9f\u7528\u7684\u306a\u30b3\u30fc\u30c9\u4f8b\u3068\u3001\u5b9f\u88c5\u6642\u306e\u6ce8\u610f\u70b9\u3092\u542b\u3081\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002\u3053\u308c\u3089\u306e\u30d1\u30bf\u30fc\u30f3\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001PHP\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u54c1\u8cea\u3068\u4fdd\u5b88\u6027\u3092\u5927\u304d\u304f\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-56\">\u5b9f\u8df5\u4f8b1\uff1a\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u3068\u30d5\u30ed\u30fc\u5236\u5fa1<\/h2>\n\n\n\n<p>\u591a\u304f\u306e\u30d3\u30b8\u30cd\u30b9\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304c\u7570\u306a\u308b\u72b6\u614b\u9593\u3092\u9077\u79fb\u3059\u308b\u30d7\u30ed\u30bb\u30b9\u3092\u7ba1\u7406\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002E\u30b3\u30de\u30fc\u30b9\u306e\u6ce8\u6587\u51e6\u7406\u3001\u30b3\u30f3\u30c6\u30f3\u30c4\u627f\u8a8d\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3001\u30bf\u30b9\u30af\u7ba1\u7406\u306a\u3069\u3001\u72b6\u614b\u9077\u79fb\u306f\u69d8\u3005\u306a\u5834\u9762\u3067\u767b\u5834\u3057\u307e\u3059\u3002PHP Enum\u306f\u3053\u308c\u3089\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u3068\u30d5\u30ed\u30fc\u5236\u5fa1\u3092\u683c\u6bb5\u306b\u6539\u5584\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-57\">\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u306e\u5f93\u6765\u306e\u8ab2\u984c<\/h3>\n\n\n\n<p>\u5f93\u6765\u306e\u6587\u5b57\u5217\u30d9\u30fc\u30b9\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u306b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u554f\u984c\u304c\u3042\u308a\u307e\u3057\u305f\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u72b6\u614b\u306e\u4e0d\u4e00\u81f4\uff08\u30bf\u30a4\u30d7\u30df\u30b9\u3084\u7121\u52b9\u306a\u5024\uff09<\/li>\n\n\n\n<li>\u72b6\u614b\u9077\u79fb\u30eb\u30fc\u30eb\u306e\u5206\u6563\u3068\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u56f0\u96e3<\/li>\n\n\n\n<li>\u72b6\u614b\u306b\u95a2\u9023\u3059\u308b\u632f\u308b\u821e\u3044\u306e\u6563\u5728<\/li>\n\n\n\n<li>\u4e0d\u6b63\u306a\u9077\u79fb\u306e\u691c\u51fa\u306e\u96e3\u3057\u3055<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-58\">Enum\u306b\u3088\u308b\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u306e\u30e1\u30ea\u30c3\u30c8<\/h3>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3053\u308c\u3089\u306e\u554f\u984c\u3092\u89e3\u6c7a\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u578b\u5b89\u5168\u6027\u306b\u3088\u308b\u7121\u52b9\u306a\u72b6\u614b\u306e\u6392\u9664<\/li>\n\n\n\n<li>\u72b6\u614b\u9077\u79fb\u30eb\u30fc\u30eb\u306e\u96c6\u7d04<\/li>\n\n\n\n<li>\u95a2\u9023\u3059\u308b\u632f\u308b\u821e\u3044\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u3068\u4fdd\u5b88\u6027\u306e\u5411\u4e0a<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-59\">\u5b9f\u88c5\u4f8b\uff1a\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406<\/h3>\n\n\n\n<p>\u4ee5\u4e0b\u306f\u3001E\u30b3\u30de\u30fc\u30b9\u306e\u6ce8\u6587\u51e6\u7406\u3067Enum\u3092\u4f7f\u7528\u3057\u305f\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u306e\u5b9f\u88c5\u4f8b\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum OrderStatus\n{\n    case CART;\n    case CHECKOUT;\n    case PAYMENT_PENDING;\n    case PAYMENT_RECEIVED;\n    case PROCESSING;\n    case SHIPPED;\n    case DELIVERED;\n    case CANCELLED;\n    case REFUNDED;\n\n    \/**\n     * \u6b21\u306e\u6709\u52b9\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u53d6\u5f97\n     *\/\n    public function nextPossibleStatuses(): array\n    {\n        return match($this) {\n            self::CART =&gt; [self::CHECKOUT, self::CANCELLED],\n            self::CHECKOUT =&gt; [self::PAYMENT_PENDING, self::CANCELLED],\n            self::PAYMENT_PENDING =&gt; [self::PAYMENT_RECEIVED, self::CANCELLED],\n            self::PAYMENT_RECEIVED =&gt; [self::PROCESSING, self::REFUNDED],\n            self::PROCESSING =&gt; [self::SHIPPED, self::REFUNDED],\n            self::SHIPPED =&gt; [self::DELIVERED, self::REFUNDED],\n            self::DELIVERED =&gt; [self::REFUNDED],\n            self::CANCELLED, self::REFUNDED =&gt; [],\n        };\n    }\n\n    \/**\n     * \u7279\u5b9a\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3078\u306e\u9077\u79fb\u304c\u53ef\u80fd\u304b\u3092\u30c1\u30a7\u30c3\u30af\n     *\/\n    public function canTransitionTo(self $newStatus): bool\n    {\n        return in_array($newStatus, $this-&gt;nextPossibleStatuses());\n    }\n\n    \/**\n     * \u30b9\u30c6\u30fc\u30bf\u30b9\u306b\u95a2\u9023\u3059\u308b\u30e6\u30fc\u30b6\u30fc\u8868\u793a\u7528\u306e\u30e9\u30d9\u30eb\u3092\u53d6\u5f97\n     *\/\n    public function getLabel(): string\n    {\n        return match($this) {\n            self::CART =&gt; '\u30ab\u30fc\u30c8',\n            self::CHECKOUT =&gt; '\u30c1\u30a7\u30c3\u30af\u30a2\u30a6\u30c8',\n            self::PAYMENT_PENDING =&gt; '\u652f\u6255\u3044\u5f85\u3061',\n            self::PAYMENT_RECEIVED =&gt; '\u5165\u91d1\u78ba\u8a8d\u6e08\u307f',\n            self::PROCESSING =&gt; '\u51e6\u7406\u4e2d',\n            self::SHIPPED =&gt; '\u767a\u9001\u6e08\u307f',\n            self::DELIVERED =&gt; '\u914d\u9054\u5b8c\u4e86',\n            self::CANCELLED =&gt; '\u30ad\u30e3\u30f3\u30bb\u30eb',\n            self::REFUNDED =&gt; '\u8fd4\u91d1\u6e08\u307f',\n        };\n    }\n\n    \/**\n     * \u30b9\u30c6\u30fc\u30bf\u30b9\u304c\u6700\u7d42\u72b6\u614b\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\n     *\/\n    public function isFinal(): bool\n    {\n        return in_array($this, [self::DELIVERED, self::CANCELLED, self::REFUNDED]);\n    }\n\n    \/**\n     * \u30b9\u30c6\u30fc\u30bf\u30b9\u304c\u6709\u52b9\u306a\u30a2\u30af\u30b7\u30e7\u30f3\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\n     *\/\n    public function canPerformAction(string $action): bool\n    {\n        return match($this) {\n            self::CART =&gt; in_array($action, ['update', 'checkout', 'cancel']),\n            self::CHECKOUT =&gt; in_array($action, ['pay', 'cancel']),\n            self::PAYMENT_PENDING =&gt; in_array($action, ['confirm_payment', 'cancel']),\n            self::PAYMENT_RECEIVED =&gt; in_array($action, ['process', 'refund']),\n            self::PROCESSING =&gt; in_array($action, ['ship', 'refund']),\n            self::SHIPPED =&gt; in_array($action, ['confirm_delivery', 'refund']),\n            self::DELIVERED =&gt; in_array($action, ['refund']),\n            self::CANCELLED, self::REFUNDED =&gt; false,\n        };\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-60\">\u5b9f\u969b\u306e\u4f7f\u7528\u4f8b<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Order\n{\n    private OrderStatus $status;\n\n    public function __construct()\n    {\n        $this-&gt;status = OrderStatus::CART;\n    }\n\n    public function getStatus(): OrderStatus\n    {\n        return $this-&gt;status;\n    }\n\n    public function transitionTo(OrderStatus $newStatus): void\n    {\n        if (!$this-&gt;status-&gt;canTransitionTo($newStatus)) {\n            throw new InvalidStatusTransitionException(\n                \"Cannot transition from {$this-&gt;status-&gt;name} to {$newStatus-&gt;name}\"\n            );\n        }\n\n        $this-&gt;status = $newStatus;\n        $this-&gt;logStatusChange($newStatus);\n    }\n\n    private function logStatusChange(OrderStatus $newStatus): void\n    {\n        \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u306e\u30ed\u30b0\u3092\u8a18\u9332\n    }\n\n    public function performAction(string $action): void\n    {\n        if (!$this-&gt;status-&gt;canPerformAction($action)) {\n            throw new InvalidActionException(\n                \"Cannot perform {$action} in status {$this-&gt;status-&gt;name}\"\n            );\n        }\n\n        \/\/ \u30a2\u30af\u30b7\u30e7\u30f3\u306e\u5b9f\u884c\u30ed\u30b8\u30c3\u30af\n        match($action) {\n            'checkout' =&gt; $this-&gt;transitionTo(OrderStatus::CHECKOUT),\n            'pay' =&gt; $this-&gt;transitionTo(OrderStatus::PAYMENT_PENDING),\n            'confirm_payment' =&gt; $this-&gt;transitionTo(OrderStatus::PAYMENT_RECEIVED),\n            \/\/ \u4ed6\u306e\u30a2\u30af\u30b7\u30e7\u30f3\n            default =&gt; throw new UnknownActionException(\"Unknown action: {$action}\")\n        };\n    }\n}\n\n\/\/ \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u4f7f\u7528\u4f8b\npublic function processOrder(int $orderId, string $action)\n{\n    $order = $this-&gt;orderRepository-&gt;find($orderId);\n\n    try {\n        $order-&gt;performAction($action);\n        $this-&gt;orderRepository-&gt;save($order);\n        return ['success' =&gt; true];\n    } catch (InvalidActionException $e) {\n        return ['error' =&gt; $e-&gt;getMessage()];\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u306e\u30d1\u30bf\u30fc\u30f3\u306f\u591a\u304f\u306e\u5229\u70b9\u3092\u63d0\u4f9b\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u578b\u5b89\u5168\u6027<\/strong> \u2013 \u7121\u52b9\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u304c\u6df7\u5165\u3059\u308b\u53ef\u80fd\u6027\u3092\u6392\u9664<\/li>\n\n\n\n<li><strong>\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306e\u96c6\u7d04<\/strong> \u2013 \u9077\u79fb\u30eb\u30fc\u30eb\u3068\u30b9\u30c6\u30fc\u30bf\u30b9\u30ed\u30b8\u30c3\u30af\u304c\u4e00\u7b87\u6240\u306b\u96c6\u7d04<\/li>\n\n\n\n<li><strong>\u81ea\u5df1\u6587\u66f8\u5316\u30b3\u30fc\u30c9<\/strong> \u2013 \u30b3\u30fc\u30c9\u3060\u3051\u3067\u30d5\u30ed\u30fc\u5168\u4f53\u304c\u660e\u78ba\u306b\u7406\u89e3\u3067\u304d\u308b<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027<\/strong> \u2013 \u30b9\u30c6\u30fc\u30bf\u30b9\u9077\u79fb\u3092\u72ec\u7acb\u3057\u3066\u30c6\u30b9\u30c8\u53ef\u80fd<\/li>\n\n\n\n<li><strong>\u62e1\u5f35\u6027<\/strong> \u2013 \u65b0\u3057\u3044\u30b9\u30c6\u30fc\u30bf\u30b9\u3084\u9077\u79fb\u30eb\u30fc\u30eb\u306e\u8ffd\u52a0\u304c\u5bb9\u6613<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-61\">\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u69cb\u7bc9<\/h3>\n\n\n\n<p>\u3088\u308a\u8907\u96d1\u306a\u30d5\u30ed\u30fc\u5236\u5fa1\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u3001Enum\u3092\u30d9\u30fc\u30b9\u3068\u3057\u305f\u672c\u683c\u7684\u306a\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002\u4ee5\u4e0b\u306f\u3001\u305d\u306e\u30a2\u30d7\u30ed\u30fc\u30c1\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\ninterface StateMachineInterface\n{\n    public function getCurrentState(): UnitEnum;\n    public function canTransitionTo(UnitEnum $state): bool;\n    public function transitionTo(UnitEnum $state): void;\n}\n\n\/\/ \u6c4e\u7528\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u5b9f\u88c5\nclass StateMachine implements StateMachineInterface\n{\n    private UnitEnum $currentState;\n    private array $transitionCallbacks = [];\n\n    public function __construct(UnitEnum $initialState)\n    {\n        $this-&gt;currentState = $initialState;\n    }\n\n    public function getCurrentState(): UnitEnum\n    {\n        return $this-&gt;currentState;\n    }\n\n    public function canTransitionTo(UnitEnum $state): bool\n    {\n        \/\/ \u30b9\u30c6\u30fc\u30c8\u56fa\u6709\u306ecanTransitionTo\u30e1\u30bd\u30c3\u30c9\u304c\u3042\u308c\u3070\u4f7f\u7528\n        if (method_exists($this-&gt;currentState, 'canTransitionTo')) {\n            return $this-&gt;currentState-&gt;canTransitionTo($state);\n        }\n\n        \/\/ \u307e\u305f\u306f\u660e\u793a\u7684\u306a\u9077\u79fb\u30eb\u30fc\u30eb\u3092\u5b9a\u7fa9\n        return true; \/\/ \u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u306f\u5168\u3066\u306e\u9077\u79fb\u3092\u8a31\u53ef\n    }\n\n    public function transitionTo(UnitEnum $state): void\n    {\n        if (!$this-&gt;canTransitionTo($state)) {\n            throw new InvalidTransitionException(\n                \"Cannot transition from {$this-&gt;currentState-&gt;name} to {$state-&gt;name}\"\n            );\n        }\n\n        $oldState = $this-&gt;currentState;\n        $this-&gt;currentState = $state;\n\n        \/\/ \u9077\u79fb\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u3092\u5b9f\u884c\n        if (isset($this-&gt;transitionCallbacks[$oldState-&gt;name][$state-&gt;name])) {\n            $callback = $this-&gt;transitionCallbacks[$oldState-&gt;name][$state-&gt;name];\n            $callback($oldState, $state);\n        }\n    }\n\n    public function onTransition(UnitEnum $from, UnitEnum $to, callable $callback): void\n    {\n        $this-&gt;transitionCallbacks[$from-&gt;name][$to-&gt;name] = $callback;\n    }\n}\n\n\/\/ \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u627f\u8a8d\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u306e\u4f8b\nenum DocumentStatus\n{\n    case DRAFT;\n    case UNDER_REVIEW;\n    case APPROVED;\n    case REJECTED;\n    case PUBLISHED;\n\n    public function canTransitionTo(self $newStatus): bool\n    {\n        return match($this) {\n            self::DRAFT =&gt; in_array($newStatus, [self::UNDER_REVIEW]),\n            self::UNDER_REVIEW =&gt; in_array($newStatus, [self::APPROVED, self::REJECTED]),\n            self::APPROVED =&gt; in_array($newStatus, [self::PUBLISHED, self::UNDER_REVIEW]),\n            self::REJECTED =&gt; in_array($newStatus, [self::DRAFT]),\n            self::PUBLISHED =&gt; false,\n        };\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nclass Document\n{\n    private StateMachine $stateMachine;\n    private string $content;\n\n    public function __construct()\n    {\n        $this-&gt;stateMachine = new StateMachine(DocumentStatus::DRAFT);\n\n        \/\/ \u72b6\u614b\u9077\u79fb\u6642\u306e\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u3092\u8a2d\u5b9a\n        $this-&gt;stateMachine-&gt;onTransition(\n            DocumentStatus::APPROVED, \n            DocumentStatus::PUBLISHED,\n            function($from, $to) {\n                $this-&gt;notifySubscribers();\n            }\n        );\n    }\n\n    public function getStatus(): DocumentStatus\n    {\n        return $this-&gt;stateMachine-&gt;getCurrentState();\n    }\n\n    public function submitForReview(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentStatus::UNDER_REVIEW);\n    }\n\n    public function approve(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentStatus::APPROVED);\n    }\n\n    public function reject(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentStatus::REJECTED);\n    }\n\n    public function publish(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentStatus::PUBLISHED);\n    }\n\n    private function notifySubscribers(): void\n    {\n        \/\/ \u8cfc\u8aad\u8005\u306b\u901a\u77e5\u3092\u9001\u4fe1\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-62\">\u5b9f\u88c5\u4e0a\u306e\u6ce8\u610f\u70b9\u3068\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u72b6\u614b\u3068\u632f\u308b\u821e\u3044\u3092\u4e00\u7b87\u6240\u306b\u96c6\u7d04\u3059\u308b<\/strong> \u2013 \u30b9\u30c6\u30fc\u30bf\u30b9\u306b\u95a2\u9023\u3059\u308b\u30ed\u30b8\u30c3\u30af\u306fEnum\u5185\u306b\u542b\u3081\u308b<\/li>\n\n\n\n<li><strong>\u9077\u79fb\u30eb\u30fc\u30eb\u3092\u660e\u793a\u7684\u306b\u5b9a\u7fa9\u3059\u308b<\/strong> \u2013 \u8a31\u53ef\u3055\u308c\u308b\u9077\u79fb\u3092\u660e\u78ba\u306b\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5316<\/li>\n\n\n\n<li><strong>\u30ac\u30fc\u30c9\u6761\u4ef6\u3092\u8ffd\u52a0\u3059\u308b<\/strong> \u2013 \u5358\u306a\u308b\u30b9\u30c6\u30fc\u30bf\u30b9\u3060\u3051\u3067\u306a\u304f\u3001\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u4f9d\u5b58\u306e\u9077\u79fb\u6761\u4ef6\u3082\u8003\u616e<\/li>\n\n\n\n<li><strong>\u526f\u4f5c\u7528\u3092\u5206\u96e2\u3059\u308b<\/strong> \u2013 \u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u6642\u306e\u30b5\u30a4\u30c9\u30a8\u30d5\u30a7\u30af\u30c8\u306f\u5225\u9014\u7ba1\u7406\uff08\u30a4\u30d9\u30f3\u30c8\u30ea\u30b9\u30ca\u30fc\u306a\u3069\uff09<\/li>\n\n\n\n<li><strong>\u5c65\u6b74\u3092\u8a18\u9332\u3059\u308b<\/strong> \u2013 \u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u306e\u5c65\u6b74\u3092\u4fdd\u6301\u3057\u3066\u76e3\u67fb\u3084\u30c7\u30d0\u30c3\u30b0\u306b\u6d3b\u7528<\/li>\n<\/ol>\n\n\n\n<p>\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u3068\u30d5\u30ed\u30fc\u5236\u5fa1\u306e\u30d1\u30bf\u30fc\u30f3\u306f\u3001\u30d7\u30ed\u30bb\u30b9\u6307\u5411\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u7279\u306b\u5f37\u529b\u3067\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u5177\u4f53\u7684\u306a\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u5b9f\u88c5\u4f8b\u3068\u5171\u306b\u3001\u3088\u308a\u8a73\u7d30\u306a\u6d3b\u7528\u6cd5\u3092\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-63\">\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u3092Enum\u3067\u8868\u73fe\u3059\u308b\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<p>EC\uff08\u96fb\u5b50\u5546\u53d6\u5f15\uff09\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u6700\u3082\u91cd\u8981\u306a\u30d3\u30b8\u30cd\u30b9\u30d7\u30ed\u30bb\u30b9\u306e\u4e00\u3064\u304c\u6ce8\u6587\u51e6\u7406\u3067\u3059\u3002\u6ce8\u6587\u306f\u69d8\u3005\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u7d4c\u3066\u51e6\u7406\u3055\u308c\u308b\u305f\u3081\u3001\u3053\u308c\u3092Enum\u578b\u3067\u52b9\u679c\u7684\u306b\u8868\u73fe\u3067\u304d\u307e\u3059\u3002\u3053\u3053\u3067\u306f\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u3059\u3050\u306b\u4f7f\u3048\u308b\u5b8c\u5168\u306a\u5b9f\u88c5\u4f8b\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-64\">\u5305\u62ec\u7684\u306a\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9Enum<\/h4>\n\n\n\n<p>\u4ee5\u4e0b\u306f\u3001\u4e00\u822c\u7684\u306aEC\u30b5\u30a4\u30c8\u306e\u6ce8\u6587\u51e6\u7406\u30d5\u30ed\u30fc\u3092\u30ab\u30d0\u30fc\u3059\u308b\u5305\u62ec\u7684\u306aEnum\u5b9f\u88c5\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum OrderStatus: string\n{\n    \/\/ \u6ce8\u6587\u524d\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\n    case CART = 'cart';                     \/\/ \u30ab\u30fc\u30c8\u5185\n    case CHECKOUT_STARTED = 'checkout';     \/\/ \u6c7a\u6e08\u30d7\u30ed\u30bb\u30b9\u958b\u59cb\n    \n    \/\/ \u652f\u6255\u3044\u95a2\u9023\u30b9\u30c6\u30fc\u30bf\u30b9\n    case AWAITING_PAYMENT = 'awaiting_payment';      \/\/ \u652f\u6255\u3044\u5f85\u3061\n    case PAYMENT_PROCESSING = 'payment_processing';  \/\/ \u652f\u6255\u3044\u51e6\u7406\u4e2d\n    case PAYMENT_FAILED = 'payment_failed';          \/\/ \u652f\u6255\u3044\u5931\u6557\n    case PAYMENT_VERIFIED = 'payment_verified';      \/\/ \u652f\u6255\u3044\u78ba\u8a8d\u6e08\u307f\n    case PAID = 'paid';                              \/\/ \u5165\u91d1\u5b8c\u4e86\n    \n    \/\/ \u51e6\u7406\u30b9\u30c6\u30fc\u30bf\u30b9\n    case PROCESSING = 'processing';         \/\/ \u6ce8\u6587\u51e6\u7406\u4e2d\n    case ON_HOLD = 'on_hold';               \/\/ \u4fdd\u7559\u4e2d\uff08\u5728\u5eab\u78ba\u8a8d\u7b49\uff09\n    case READY_TO_SHIP = 'ready_to_ship';   \/\/ \u51fa\u8377\u6e96\u5099\u5b8c\u4e86\n    \n    \/\/ \u914d\u9001\u30b9\u30c6\u30fc\u30bf\u30b9\n    case PARTIALLY_SHIPPED = 'partially_shipped';  \/\/ \u4e00\u90e8\u51fa\u8377\u6e08\u307f\n    case SHIPPED = 'shipped';                      \/\/ \u51fa\u8377\u6e08\u307f\n    case OUT_FOR_DELIVERY = 'out_for_delivery';    \/\/ \u914d\u9054\u4e2d\n    case DELIVERED = 'delivered';                  \/\/ \u914d\u9054\u5b8c\u4e86\n    \n    \/\/ \u5b8c\u4e86\u30fb\u30ad\u30e3\u30f3\u30bb\u30eb\u30b9\u30c6\u30fc\u30bf\u30b9\n    case COMPLETED = 'completed';           \/\/ \u5b8c\u4e86\uff08\u914d\u9054\u78ba\u8a8d\u6e08\u307f\uff09\n    case CANCELLED = 'cancelled';           \/\/ \u30ad\u30e3\u30f3\u30bb\u30eb\n    case REFUNDED = 'refunded';             \/\/ \u8fd4\u91d1\u6e08\u307f\n    case PARTIALLY_REFUNDED = 'partially_refunded'; \/\/ \u4e00\u90e8\u8fd4\u91d1\n    \n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u60c5\u5831\u3092\u53d6\u5f97\n    public function getInfo(): array\n    {\n        return match($this) {\n            self::CART =&gt; [\n                'label' =&gt; '\u30ab\u30fc\u30c8',\n                'description' =&gt; '\u5546\u54c1\u304c\u30ab\u30fc\u30c8\u306b\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u3059',\n                'color' =&gt; 'gray',\n                'public' =&gt; false, \/\/ \u304a\u5ba2\u69d8\u306b\u306f\u8868\u793a\u3057\u306a\u3044\u5185\u90e8\u30b9\u30c6\u30fc\u30bf\u30b9\n                'admin_action' =&gt; null,\n            ],\n            self::CHECKOUT_STARTED =&gt; [\n                'label' =&gt; '\u30c1\u30a7\u30c3\u30af\u30a2\u30a6\u30c8\u4e2d',\n                'description' =&gt; '\u6c7a\u6e08\u51e6\u7406\u304c\u958b\u59cb\u3055\u308c\u307e\u3057\u305f',\n                'color' =&gt; 'gray',\n                'public' =&gt; false,\n                'admin_action' =&gt; null,\n            ],\n            self::AWAITING_PAYMENT =&gt; [\n                'label' =&gt; '\u652f\u6255\u3044\u5f85\u3061',\n                'description' =&gt; '\u304a\u652f\u6255\u3044\u3092\u304a\u5f85\u3061\u3057\u3066\u3044\u307e\u3059',\n                'color' =&gt; 'yellow',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u30ad\u30e3\u30f3\u30bb\u30eb\u53ef\u80fd',\n            ],\n            self::PAYMENT_PROCESSING =&gt; [\n                'label' =&gt; '\u6c7a\u6e08\u51e6\u7406\u4e2d',\n                'description' =&gt; '\u6c7a\u6e08\u60c5\u5831\u3092\u51e6\u7406\u4e2d\u3067\u3059',\n                'color' =&gt; 'yellow',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u624b\u52d5\u78ba\u8a8d\u53ef\u80fd',\n            ],\n            self::PAYMENT_FAILED =&gt; [\n                'label' =&gt; '\u652f\u6255\u3044\u5931\u6557',\n                'description' =&gt; '\u6c7a\u6e08\u51e6\u7406\u306b\u5931\u6557\u3057\u307e\u3057\u305f',\n                'color' =&gt; 'red',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u518d\u8a66\u884c\u6848\u5185',\n            ],\n            self::PAYMENT_VERIFIED =&gt; [\n                'label' =&gt; '\u652f\u6255\u3044\u78ba\u8a8d\u6e08\u307f',\n                'description' =&gt; '\u304a\u652f\u6255\u3044\u304c\u78ba\u8a8d\u3055\u308c\u307e\u3057\u305f',\n                'color' =&gt; 'green',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u51e6\u7406\u958b\u59cb\u53ef\u80fd',\n            ],\n            self::PAID =&gt; [\n                'label' =&gt; '\u5165\u91d1\u5b8c\u4e86',\n                'description' =&gt; '\u5165\u91d1\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f',\n                'color' =&gt; 'green',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u51e6\u7406\u958b\u59cb\u53ef\u80fd',\n            ],\n            self::PROCESSING =&gt; [\n                'label' =&gt; '\u51e6\u7406\u4e2d',\n                'description' =&gt; '\u3054\u6ce8\u6587\u3092\u51e6\u7406\u4e2d\u3067\u3059',\n                'color' =&gt; 'blue',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u51fa\u8377\u6307\u793a\u53ef\u80fd',\n            ],\n            self::ON_HOLD =&gt; [\n                'label' =&gt; '\u4fdd\u7559\u4e2d',\n                'description' =&gt; '\u78ba\u8a8d\u4f5c\u696d\u306e\u305f\u3081\u4fdd\u7559\u4e2d\u3067\u3059',\n                'color' =&gt; 'orange',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u78ba\u8a8d\u5fc5\u8981',\n            ],\n            self::READY_TO_SHIP =&gt; [\n                'label' =&gt; '\u51fa\u8377\u6e96\u5099\u5b8c\u4e86',\n                'description' =&gt; '\u51fa\u8377\u306e\u6e96\u5099\u304c\u6574\u3044\u307e\u3057\u305f',\n                'color' =&gt; 'blue',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u51fa\u8377\u51e6\u7406',\n            ],\n            self::PARTIALLY_SHIPPED =&gt; [\n                'label' =&gt; '\u4e00\u90e8\u51fa\u8377\u6e08\u307f',\n                'description' =&gt; '\u5546\u54c1\u306e\u4e00\u90e8\u304c\u51fa\u8377\u3055\u308c\u307e\u3057\u305f',\n                'color' =&gt; 'blue',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u6b8b\u308a\u51fa\u8377\u51e6\u7406',\n            ],\n            self::SHIPPED =&gt; [\n                'label' =&gt; '\u51fa\u8377\u6e08\u307f',\n                'description' =&gt; '\u5546\u54c1\u304c\u767a\u9001\u3055\u308c\u307e\u3057\u305f',\n                'color' =&gt; 'blue',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u914d\u9001\u72b6\u6cc1\u78ba\u8a8d',\n            ],\n            self::OUT_FOR_DELIVERY =&gt; [\n                'label' =&gt; '\u914d\u9054\u4e2d',\n                'description' =&gt; '\u914d\u9054\u4e2d\u3067\u3059',\n                'color' =&gt; 'purple',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u914d\u9001\u72b6\u6cc1\u78ba\u8a8d',\n            ],\n            self::DELIVERED =&gt; [\n                'label' =&gt; '\u914d\u9054\u5b8c\u4e86',\n                'description' =&gt; '\u5546\u54c1\u304c\u914d\u9054\u3055\u308c\u307e\u3057\u305f',\n                'color' =&gt; 'green',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u5b8c\u4e86\u78ba\u8a8d',\n            ],\n            self::COMPLETED =&gt; [\n                'label' =&gt; '\u5b8c\u4e86',\n                'description' =&gt; '\u6ce8\u6587\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f',\n                'color' =&gt; 'green',\n                'public' =&gt; true,\n                'admin_action' =&gt; null,\n            ],\n            self::CANCELLED =&gt; [\n                'label' =&gt; '\u30ad\u30e3\u30f3\u30bb\u30eb',\n                'description' =&gt; '\u6ce8\u6587\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f',\n                'color' =&gt; 'red',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u8fd4\u91d1\u51e6\u7406\uff08\u5fc5\u8981\u6642\uff09',\n            ],\n            self::REFUNDED =&gt; [\n                'label' =&gt; '\u8fd4\u91d1\u6e08\u307f',\n                'description' =&gt; '\u5168\u984d\u8fd4\u91d1\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f',\n                'color' =&gt; 'red',\n                'public' =&gt; true,\n                'admin_action' =&gt; null,\n            ],\n            self::PARTIALLY_REFUNDED =&gt; [\n                'label' =&gt; '\u4e00\u90e8\u8fd4\u91d1\u6e08\u307f',\n                'description' =&gt; '\u4e00\u90e8\u306e\u8fd4\u91d1\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f',\n                'color' =&gt; 'orange',\n                'public' =&gt; true,\n                'admin_action' =&gt; '\u6b8b\u984d\u8fd4\u91d1\uff08\u5fc5\u8981\u6642\uff09',\n            ],\n        };\n    }\n    \n    \/\/ \u30e9\u30d9\u30eb\u306e\u307f\u3092\u53d6\u5f97\u3059\u308b\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8\n    public function getLabel(): string\n    {\n        return $this-&gt;getInfo()['label'];\n    }\n    \n    \/\/ \u8aac\u660e\u3092\u53d6\u5f97\u3059\u308b\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8\n    public function getDescription(): string\n    {\n        return $this-&gt;getInfo()['description'];\n    }\n    \n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u8272\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\n    public function getColor(): string\n    {\n        return $this-&gt;getInfo()['color'];\n    }\n    \n    \/\/ \u9867\u5ba2\u306b\u8868\u793a\u3057\u3066\u826f\u3044\u30b9\u30c6\u30fc\u30bf\u30b9\u304b\u3069\u3046\u304b\n    public function isPublic(): bool\n    {\n        return $this-&gt;getInfo()['public'];\n    }\n    \n    \/\/ \u6b21\u306b\u53ef\u80fd\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u914d\u5217\u3092\u53d6\u5f97\n    public function getNextPossibleStatuses(): array\n    {\n        return match($this) {\n            self::CART =&gt; [self::CHECKOUT_STARTED],\n            self::CHECKOUT_STARTED =&gt; [self::AWAITING_PAYMENT, self::PAYMENT_PROCESSING, self::CART],\n            self::AWAITING_PAYMENT =&gt; [self::PAYMENT_PROCESSING, self::PAYMENT_FAILED, self::PAYMENT_VERIFIED, self::CANCELLED],\n            self::PAYMENT_PROCESSING =&gt; [self::PAYMENT_FAILED, self::PAYMENT_VERIFIED, self::CANCELLED],\n            self::PAYMENT_FAILED =&gt; [self::AWAITING_PAYMENT, self::PAYMENT_PROCESSING, self::CANCELLED],\n            self::PAYMENT_VERIFIED, self::PAID =&gt; [self::PROCESSING, self::ON_HOLD, self::CANCELLED],\n            self::PROCESSING =&gt; [self::ON_HOLD, self::READY_TO_SHIP, self::CANCELLED],\n            self::ON_HOLD =&gt; [self::PROCESSING, self::READY_TO_SHIP, self::CANCELLED],\n            self::READY_TO_SHIP =&gt; [self::SHIPPED, self::PARTIALLY_SHIPPED, self::CANCELLED],\n            self::PARTIALLY_SHIPPED =&gt; [self::SHIPPED, self::CANCELLED],\n            self::SHIPPED =&gt; [self::OUT_FOR_DELIVERY, self::DELIVERED, self::CANCELLED],\n            self::OUT_FOR_DELIVERY =&gt; [self::DELIVERED, self::CANCELLED],\n            self::DELIVERED =&gt; [self::COMPLETED, self::REFUNDED, self::PARTIALLY_REFUNDED],\n            self::COMPLETED =&gt; [self::REFUNDED, self::PARTIALLY_REFUNDED],\n            self::CANCELLED =&gt; [self::REFUNDED],\n            self::REFUNDED, self::PARTIALLY_REFUNDED =&gt; [],\n        };\n    }\n    \n    \/\/ \u7279\u5b9a\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3078\u9077\u79fb\u53ef\u80fd\u304b\u3092\u78ba\u8a8d\n    public function canTransitionTo(self $newStatus): bool\n    {\n        return in_array($newStatus, $this-&gt;getNextPossibleStatuses());\n    }\n    \n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u304c\u6700\u7d42\u72b6\u614b\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\n    public function isFinal(): bool\n    {\n        return in_array($this, [\n            self::COMPLETED,\n            self::CANCELLED,\n            self::REFUNDED,\n            self::PARTIALLY_REFUNDED\n        ]);\n    }\n    \n    \/\/ \u652f\u6255\u3044\u95a2\u9023\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u304b\u3069\u3046\u304b\n    public function isPaymentRelated(): bool\n    {\n        return in_array($this, [\n            self::AWAITING_PAYMENT,\n            self::PAYMENT_PROCESSING,\n            self::PAYMENT_FAILED,\n            self::PAYMENT_VERIFIED,\n            self::PAID\n        ]);\n    }\n    \n    \/\/ \u914d\u9001\u95a2\u9023\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u304b\u3069\u3046\u304b\n    public function isShippingRelated(): bool\n    {\n        return in_array($this, [\n            self::READY_TO_SHIP,\n            self::PARTIALLY_SHIPPED,\n            self::SHIPPED,\n            self::OUT_FOR_DELIVERY,\n            self::DELIVERED\n        ]);\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-65\">Laravel\u3067\u306e\u5b9f\u88c5\u4f8b<\/h4>\n\n\n\n<p>Laravel\u3067\u3053\u306e\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u4f7f\u7528\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Order.php \u30e2\u30c7\u30eb\nclass Order extends Model\n{\n    protected $casts = [\n        'status' =&gt; OrderStatus::class,\n    ];\n    \n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u30e1\u30bd\u30c3\u30c9\n    public function updateStatus(OrderStatus $newStatus): void\n    {\n        if (!$this-&gt;status-&gt;canTransitionTo($newStatus)) {\n            throw new OrderStatusTransitionException(\n                \"Cannot transition from {$this-&gt;status-&gt;name} to {$newStatus-&gt;name}\"\n            );\n        }\n        \n        $oldStatus = $this-&gt;status;\n        $this-&gt;status = $newStatus;\n        $this-&gt;save();\n        \n        \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u30a4\u30d9\u30f3\u30c8\u3092\u767a\u706b\n        event(new OrderStatusChanged($this, $oldStatus, $newStatus));\n    }\n    \n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u5c65\u6b74\u306e\u53d6\u5f97\n    public function statusHistory()\n    {\n        return $this-&gt;hasMany(OrderStatusHistory::class);\n    }\n}\n\n\/\/ \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\npublic function up()\n{\n    Schema::create('orders', function (Blueprint $table) {\n        $table-&gt;id();\n        $table-&gt;string('status')-&gt;default(OrderStatus::CART-&gt;value);\n        \/\/ \u305d\u306e\u4ed6\u306e\u30ab\u30e9\u30e0\n        $table-&gt;timestamps();\n    });\n    \n    Schema::create('order_status_history', function (Blueprint $table) {\n        $table-&gt;id();\n        $table-&gt;foreignId('order_id')-&gt;constrained();\n        $table-&gt;string('from_status');\n        $table-&gt;string('to_status');\n        $table-&gt;string('comment')-&gt;nullable();\n        $table-&gt;foreignId('user_id')-&gt;nullable()-&gt;constrained();\n        $table-&gt;timestamps();\n    });\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-66\">\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u4f7f\u7528\u4f8b<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class OrderController extends Controller\n{\n    public function processOrder(Order $order)\n    {\n        \/\/ \u6a29\u9650\u30c1\u30a7\u30c3\u30af\n        $this-&gt;authorize('process', $order);\n        \n        try {\n            $order-&gt;updateStatus(OrderStatus::PROCESSING);\n            \n            return redirect()-&gt;back()-&gt;with(\n                'success', \n                '\u6ce8\u6587\u3092' . $order-&gt;status-&gt;getLabel() . '\u306b\u66f4\u65b0\u3057\u307e\u3057\u305f'\n            );\n        } catch (OrderStatusTransitionException $e) {\n            return redirect()-&gt;back()-&gt;with('error', $e-&gt;getMessage());\n        }\n    }\n    \n    public function getOrderHistory(Order $order)\n    {\n        $history = $order-&gt;statusHistory()-&gt;latest()-&gt;get()-&gt;map(function ($item) {\n            return [\n                'date' =&gt; $item-&gt;created_at-&gt;format('Y-m-d H:i'),\n                'from' =&gt; OrderStatus::from($item-&gt;from_status)-&gt;getLabel(),\n                'to' =&gt; OrderStatus::from($item-&gt;to_status)-&gt;getLabel(),\n                'by' =&gt; $item-&gt;user ? $item-&gt;user-&gt;name : '\u30b7\u30b9\u30c6\u30e0',\n                'comment' =&gt; $item-&gt;comment,\n            ];\n        });\n        \n        return view('orders.history', compact('order', 'history'));\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-67\">\u30a4\u30d9\u30f3\u30c8\u30ea\u30b9\u30ca\u30fc\u3067\u306e\u6d3b\u7528\u4f8b<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class OrderStatusChangeListener\n{\n    public function handle(OrderStatusChanged $event)\n    {\n        $order = $event-&gt;order;\n        $oldStatus = $event-&gt;oldStatus;\n        $newStatus = $event-&gt;newStatus;\n        \n        \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u5c65\u6b74\u306e\u8a18\u9332\n        $order-&gt;statusHistory()-&gt;create([\n            'from_status' =&gt; $oldStatus-&gt;value,\n            'to_status' =&gt; $newStatus-&gt;value,\n            'user_id' =&gt; auth()-&gt;id(),\n        ]);\n        \n        \/\/ \u30e1\u30fc\u30eb\u901a\u77e5\u306e\u9001\u4fe1\uff08\u7279\u5b9a\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u6642\u306e\u307f\uff09\n        if ($newStatus-&gt;isPublic()) {\n            Mail::to($order-&gt;customer-&gt;email)-&gt;send(\n                new OrderStatusUpdated($order)\n            );\n        }\n        \n        \/\/ \u5728\u5eab\u8abf\u6574\uff08\u7279\u5b9a\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u6642\uff09\n        if ($newStatus === OrderStatus::CANCELLED) {\n            $this-&gt;restoreInventory($order);\n        }\n        \n        \/\/ \u51fa\u8377\u6307\u793a\u66f8\u306e\u751f\u6210\n        if ($newStatus === OrderStatus::READY_TO_SHIP) {\n            $this-&gt;generateShippingInstructions($order);\n        }\n    }\n}\n<\/pre>\n\n\n\n<p>\u3053\u306e\u5b9f\u88c5\u4f8b\u306f\u3001\u5b9f\u969b\u306eEC\u30b5\u30a4\u30c8\u3067\u5fc5\u8981\u3068\u306a\u308b\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u64cd\u4f5c\u3092\u7db2\u7f85\u7684\u306b\u30ab\u30d0\u30fc\u3057\u3066\u3044\u307e\u3059\u3002\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u3068\u30b9\u30c6\u30fc\u30bf\u30b9\u9077\u79fb\u30eb\u30fc\u30eb\u3092\u4e00\u7b87\u6240\u306b\u96c6\u7d04\u3059\u308b\u3053\u3068\u3067\u3001\u30b3\u30fc\u30c9\u306e\u4fdd\u5b88\u6027\u3068\u62e1\u5f35\u6027\u304c\u5927\u304d\u304f\u5411\u4e0a\u3057\u307e\u3059\u3002\u307e\u305f\u3001Enum\u578b\u306e\u529b\u3092\u6d3b\u304b\u3057\u3066\u3001\u30b3\u30fc\u30c9\u5168\u4f53\u306e\u5805\u7262\u6027\u3068\u578b\u5b89\u5168\u6027\u3092\u78ba\u4fdd\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-68\">Enum\u3092\u4f7f\u3063\u305f\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u69cb\u7bc9\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\uff08\u72b6\u614b\u6a5f\u68b0\uff09\u306f\u3001\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304c\u3068\u308a\u3046\u308b\u72b6\u614b\u3068\u3001\u72b6\u614b\u9593\u306e\u9077\u79fb\u3092\u660e\u793a\u7684\u306b\u30e2\u30c7\u30eb\u5316\u3059\u308b\u30c7\u30b6\u30a4\u30f3\u30d1\u30bf\u30fc\u30f3\u3067\u3059\u3002PHP\u306eEnum\u578b\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u578b\u5b89\u5168\u3067\u5805\u7262\u306a\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-69\">\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u57fa\u672c\u6982\u5ff5<\/h4>\n\n\n\n<p>\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u6838\u3068\u306a\u308b\u8981\u7d20\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u72b6\u614b\uff08State\uff09<\/strong> \u2013 \u30b7\u30b9\u30c6\u30e0\u304c\u3068\u308a\u3046\u308b\u96e2\u6563\u7684\u306a\u72b6\u614b\u306e\u96c6\u5408<\/li>\n\n\n\n<li><strong>\u9077\u79fb\uff08Transition\uff09<\/strong> \u2013 \u3042\u308b\u72b6\u614b\u304b\u3089\u5225\u306e\u72b6\u614b\u3078\u306e\u79fb\u52d5<\/li>\n\n\n\n<li><strong>\u30a4\u30d9\u30f3\u30c8\uff08Event\uff09<\/strong> \u2013 \u9077\u79fb\u3092\u30c8\u30ea\u30ac\u30fc\u3059\u308b\u51fa\u6765\u4e8b<\/li>\n\n\n\n<li><strong>\u30ac\u30fc\u30c9\u6761\u4ef6\uff08Guard\uff09<\/strong> \u2013 \u9077\u79fb\u304c\u8a31\u53ef\u3055\u308c\u308b\u305f\u3081\u306e\u6761\u4ef6<\/li>\n\n\n\n<li><strong>\u30a2\u30af\u30b7\u30e7\u30f3\uff08Action\uff09<\/strong> \u2013 \u9077\u79fb\u6642\u306b\u5b9f\u884c\u3055\u308c\u308b\u51e6\u7406<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-70\">Enum\u3092\u4f7f\u3063\u305f\u8efd\u91cf\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3<\/h4>\n\n\n\n<p>\u30b7\u30f3\u30d7\u30eb\u306a\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306f\u3001Enum\u3060\u3051\u3067\u5b9f\u88c5\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum TaskState\n{\n    case TODO;\n    case IN_PROGRESS;\n    case REVIEW;\n    case DONE;\n    \n    \/\/ \u6b21\u306e\u72b6\u614b\u3078\u306e\u9077\u79fb\u30eb\u30fc\u30eb\n    public function canTransitionTo(self $nextState): bool\n    {\n        return match($this) {\n            self::TODO =&gt; $nextState === self::IN_PROGRESS,\n            self::IN_PROGRESS =&gt; in_array($nextState, [self::REVIEW, self::TODO]),\n            self::REVIEW =&gt; in_array($nextState, [self::DONE, self::IN_PROGRESS]),\n            self::DONE =&gt; false, \/\/ \u5b8c\u4e86\u306f\u6700\u7d42\u72b6\u614b\n        };\n    }\n    \n    \/\/ \u9077\u79fb\u6642\u306e\u30a2\u30af\u30b7\u30e7\u30f3\n    public function onEnter(): string\n    {\n        return match($this) {\n            self::TODO =&gt; '\u30bf\u30b9\u30af\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f',\n            self::IN_PROGRESS =&gt; '\u4f5c\u696d\u304c\u958b\u59cb\u3055\u308c\u307e\u3057\u305f',\n            self::REVIEW =&gt; '\u30ec\u30d3\u30e5\u30fc\u4f9d\u983c\u304c\u51fa\u3055\u308c\u307e\u3057\u305f',\n            self::DONE =&gt; '\u30bf\u30b9\u30af\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f',\n        };\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nclass Task\n{\n    private TaskState $state;\n    \n    public function __construct()\n    {\n        $this-&gt;state = TaskState::TODO;\n    }\n    \n    public function getState(): TaskState\n    {\n        return $this-&gt;state;\n    }\n    \n    public function changeState(TaskState $newState): string\n    {\n        if (!$this-&gt;state-&gt;canTransitionTo($newState)) {\n            throw new InvalidStateTransitionException(\n                \"Cannot transition from {$this-&gt;state-&gt;name} to {$newState-&gt;name}\"\n            );\n        }\n        \n        $this-&gt;state = $newState;\n        return $newState-&gt;onEnter();\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-71\">\u5b8c\u5168\u306a\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u5b9f\u88c5<\/h4>\n\n\n\n<p>\u3088\u308a\u8907\u96d1\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3067\u306f\u3001\u67d4\u8edf\u3067\u62e1\u5f35\u53ef\u80fd\u306a\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u5b9f\u88c5\u304c\u5fc5\u8981\u3067\u3059\u3002\u4ee5\u4e0b\u306f\u3001Enum\u578b\u3092\u4e2d\u5fc3\u3068\u3057\u305f\u5b8c\u5168\u306a\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u5b9f\u88c5\u4f8b\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ 1. \u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\ninterface StateMachineInterface\n{\n    public function getCurrentState(): UnitEnum;\n    public function canTransitionTo(UnitEnum $state): bool;\n    public function transitionTo(UnitEnum $state, array $context = []): void;\n    public function addTransitionListener(callable $listener): void;\n}\n\n\/\/ 2. \u9077\u79fb\u30a4\u30d9\u30f3\u30c8\u30af\u30e9\u30b9\nclass TransitionEvent\n{\n    public function __construct(\n        public readonly UnitEnum $fromState,\n        public readonly UnitEnum $toState,\n        public readonly array $context = []\n    ) {}\n}\n\n\/\/ 3. \u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u5b9f\u88c5\nclass StateMachine implements StateMachineInterface\n{\n    private UnitEnum $currentState;\n    private array $transitionListeners = [];\n    private array $guardConditions = [];\n    \n    public function __construct(UnitEnum $initialState)\n    {\n        $this-&gt;currentState = $initialState;\n    }\n    \n    public function getCurrentState(): UnitEnum\n    {\n        return $this-&gt;currentState;\n    }\n    \n    \/\/ \u30ab\u30b9\u30bf\u30e0\u30ac\u30fc\u30c9\u6761\u4ef6\u3092\u8ffd\u52a0\n    public function addGuardCondition(UnitEnum $fromState, UnitEnum $toState, callable $condition): void\n    {\n        $this-&gt;guardConditions[$fromState-&gt;name][$toState-&gt;name][] = $condition;\n    }\n    \n    \/\/ \u9077\u79fb\u30ea\u30b9\u30ca\u30fc\u3092\u8ffd\u52a0\n    public function addTransitionListener(callable $listener): void\n    {\n        $this-&gt;transitionListeners[] = $listener;\n    }\n    \n    \/\/ \u9077\u79fb\u304c\u53ef\u80fd\u304b\u3069\u3046\u304b\u3092\u30c1\u30a7\u30c3\u30af\n    public function canTransitionTo(UnitEnum $state): bool\n    {\n        \/\/ 1. Enum\u81ea\u4f53\u306ecanTransitionTo\u30e1\u30bd\u30c3\u30c9\u3092\u30c1\u30a7\u30c3\u30af\n        if (method_exists($this-&gt;currentState, 'canTransitionTo')) {\n            if (!$this-&gt;currentState-&gt;canTransitionTo($state)) {\n                return false;\n            }\n        }\n        \n        \/\/ 2. \u767b\u9332\u3055\u308c\u305f\u30ac\u30fc\u30c9\u6761\u4ef6\u3092\u30c1\u30a7\u30c3\u30af\n        if (isset($this-&gt;guardConditions[$this-&gt;currentState-&gt;name][$state-&gt;name])) {\n            foreach ($this-&gt;guardConditions[$this-&gt;currentState-&gt;name][$state-&gt;name] as $condition) {\n                if (!$condition($this-&gt;currentState, $state)) {\n                    return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \n    \/\/ \u72b6\u614b\u3092\u9077\u79fb\n    public function transitionTo(UnitEnum $state, array $context = []): void\n    {\n        if (!$this-&gt;canTransitionTo($state)) {\n            throw new InvalidStateTransitionException(\n                \"Cannot transition from {$this-&gt;currentState-&gt;name} to {$state-&gt;name}\"\n            );\n        }\n        \n        $oldState = $this-&gt;currentState;\n        $this-&gt;currentState = $state;\n        \n        \/\/ \u9077\u79fb\u30a4\u30d9\u30f3\u30c8\u3092\u4f5c\u6210\n        $event = new TransitionEvent($oldState, $state, $context);\n        \n        \/\/ \u767b\u9332\u3055\u308c\u305f\u30ea\u30b9\u30ca\u30fc\u3092\u547c\u3073\u51fa\u3057\n        foreach ($this-&gt;transitionListeners as $listener) {\n            $listener($event);\n        }\n        \n        \/\/ Enum\u306bonExit\u3084onEnter\u30e1\u30bd\u30c3\u30c9\u304c\u3042\u308c\u3070\u547c\u3073\u51fa\u3057\n        if (method_exists($oldState, 'onExit')) {\n            $oldState-&gt;onExit($state, $context);\n        }\n        \n        if (method_exists($state, 'onEnter')) {\n            $state-&gt;onEnter($oldState, $context);\n        }\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-72\">\u5b9f\u8df5\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\uff1a\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u627f\u8a8d\u30ef\u30fc\u30af\u30d5\u30ed\u30fc<\/h4>\n\n\n\n<p>\u3053\u306e\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306e\u5b9f\u8df5\u7684\u306a\u4f7f\u7528\u4f8b\u3068\u3057\u3066\u3001\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u627f\u8a8d\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3092\u5b9f\u88c5\u3057\u3066\u307f\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u72b6\u614b\u306e\u5b9a\u7fa9\nenum DocumentState\n{\n    case DRAFT;\n    case SUBMITTED;\n    case UNDER_REVIEW;\n    case CHANGES_REQUESTED;\n    case APPROVED;\n    case PUBLISHED;\n    case ARCHIVED;\n    \n    \/\/ \u8a31\u53ef\u3055\u308c\u308b\u9077\u79fb\u3092\u5b9a\u7fa9\n    public function canTransitionTo(self $state): bool\n    {\n        return match($this) {\n            self::DRAFT =&gt; in_array($state, [self::SUBMITTED]),\n            self::SUBMITTED =&gt; in_array($state, [self::UNDER_REVIEW, self::DRAFT]),\n            self::UNDER_REVIEW =&gt; in_array($state, [self::CHANGES_REQUESTED, self::APPROVED]),\n            self::CHANGES_REQUESTED =&gt; in_array($state, [self::DRAFT, self::SUBMITTED]),\n            self::APPROVED =&gt; in_array($state, [self::PUBLISHED, self::UNDER_REVIEW]),\n            self::PUBLISHED =&gt; in_array($state, [self::ARCHIVED]),\n            self::ARCHIVED =&gt; false,\n        };\n    }\n    \n    \/\/ \u72b6\u614b\u8868\u793a\u7528\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\n    public function getMetadata(): array\n    {\n        return match($this) {\n            self::DRAFT =&gt; [\n                'label' =&gt; '\u4e0b\u66f8\u304d',\n                'color' =&gt; 'gray',\n                'icon' =&gt; 'draft-icon',\n            ],\n            self::SUBMITTED =&gt; [\n                'label' =&gt; '\u63d0\u51fa\u6e08\u307f',\n                'color' =&gt; 'blue',\n                'icon' =&gt; 'submit-icon',\n            ],\n            self::UNDER_REVIEW =&gt; [\n                'label' =&gt; '\u30ec\u30d3\u30e5\u30fc\u4e2d',\n                'color' =&gt; 'orange',\n                'icon' =&gt; 'review-icon',\n            ],\n            self::CHANGES_REQUESTED =&gt; [\n                'label' =&gt; '\u4fee\u6b63\u4f9d\u983c',\n                'color' =&gt; 'red',\n                'icon' =&gt; 'changes-icon',\n            ],\n            self::APPROVED =&gt; [\n                'label' =&gt; '\u627f\u8a8d\u6e08\u307f',\n                'color' =&gt; 'green',\n                'icon' =&gt; 'approved-icon',\n            ],\n            self::PUBLISHED =&gt; [\n                'label' =&gt; '\u516c\u958b\u4e2d',\n                'color' =&gt; 'green',\n                'icon' =&gt; 'published-icon',\n            ],\n            self::ARCHIVED =&gt; [\n                'label' =&gt; '\u30a2\u30fc\u30ab\u30a4\u30d6\u6e08\u307f',\n                'color' =&gt; 'gray',\n                'icon' =&gt; 'archive-icon',\n            ],\n        };\n    }\n}\n\n\/\/ \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30af\u30e9\u30b9\nclass Document\n{\n    private string $title;\n    private string $content;\n    private User $author;\n    private StateMachine $stateMachine;\n    private array $reviewComments = [];\n    \n    public function __construct(string $title, User $author)\n    {\n        $this-&gt;title = $title;\n        $this-&gt;author = $author;\n        \n        \/\/ \u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u3092\u521d\u671f\u5316\n        $this-&gt;stateMachine = new StateMachine(DocumentState::DRAFT);\n        \n        \/\/ \u9077\u79fb\u30ea\u30b9\u30ca\u30fc\u3092\u8ffd\u52a0\uff08\u30ed\u30b0\u8a18\u9332\u7528\uff09\n        $this-&gt;stateMachine-&gt;addTransitionListener(function(TransitionEvent $event) {\n            $this-&gt;logStateChange($event-&gt;fromState, $event-&gt;toState, $event-&gt;context);\n        });\n        \n        \/\/ \u7279\u5b9a\u306e\u9077\u79fb\u306b\u306e\u307f\u9069\u7528\u3055\u308c\u308b\u30ac\u30fc\u30c9\u6761\u4ef6\u3092\u8ffd\u52a0\n        $this-&gt;stateMachine-&gt;addGuardCondition(\n            DocumentState::SUBMITTED,\n            DocumentState::UNDER_REVIEW,\n            function($from, $to, $context = []) {\n                \/\/ \u30ec\u30d3\u30e5\u30a2\u30fc\u304c\u5272\u308a\u5f53\u3066\u3089\u308c\u3066\u3044\u308b\u304b\u30c1\u30a7\u30c3\u30af\n                return isset($this-&gt;reviewers) &amp;&amp; count($this-&gt;reviewers) &gt; 0;\n            }\n        );\n        \n        \/\/ \u516c\u958b\u6642\u306e\u901a\u77e5\u7528\u30ea\u30b9\u30ca\u30fc\n        $this-&gt;stateMachine-&gt;addTransitionListener(function(TransitionEvent $event) {\n            if ($event-&gt;toState === DocumentState::PUBLISHED) {\n                $this-&gt;notifySubscribers();\n            }\n        });\n    }\n    \n    \/\/ \u72b6\u614b\u3092\u53d6\u5f97\n    public function getState(): DocumentState\n    {\n        return $this-&gt;stateMachine-&gt;getCurrentState();\n    }\n    \n    \/\/ \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u63d0\u51fa\n    public function submit(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentState::SUBMITTED);\n    }\n    \n    \/\/ \u30ec\u30d3\u30e5\u30fc\u958b\u59cb\n    public function startReview(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentState::UNDER_REVIEW);\n    }\n    \n    \/\/ \u4fee\u6b63\u4f9d\u983c\n    public function requestChanges(string $comment): void\n    {\n        $this-&gt;reviewComments[] = $comment;\n        $this-&gt;stateMachine-&gt;transitionTo(\n            DocumentState::CHANGES_REQUESTED,\n            ['comment' =&gt; $comment]\n        );\n    }\n    \n    \/\/ \u627f\u8a8d\n    public function approve(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentState::APPROVED);\n    }\n    \n    \/\/ \u516c\u958b\n    public function publish(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentState::PUBLISHED);\n    }\n    \n    \/\/ \u30a2\u30fc\u30ab\u30a4\u30d6\n    public function archive(): void\n    {\n        $this-&gt;stateMachine-&gt;transitionTo(DocumentState::ARCHIVED);\n    }\n    \n    \/\/ \u72b6\u614b\u5909\u66f4\u30ed\u30b0\u306e\u8a18\u9332\n    private function logStateChange(DocumentState $from, DocumentState $to, array $context): void\n    {\n        \/\/ \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3084\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u306b\u8a18\u9332\u3059\u308b\u51e6\u7406\n    }\n    \n    \/\/ \u8cfc\u8aad\u8005\u306b\u901a\u77e5\n    private function notifySubscribers(): void\n    {\n        \/\/ \u901a\u77e5\u51e6\u7406\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-73\">\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u69cb\u7bc9\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u72b6\u614b\u3092Enum\u3067\u5b9a\u7fa9\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5404\u72b6\u614b\u3092\u660e\u78ba\u306b\u547d\u540d\u3057\u3001\u30bf\u30a4\u30d7\u30bb\u30fc\u30d5\u306b\u4f7f\u7528<\/li>\n\n\n\n<li>\u72b6\u614b\u306b\u95a2\u9023\u3059\u308b\u30e1\u30bf\u30c7\u30fc\u30bf\u3084\u30e1\u30bd\u30c3\u30c9\u3092Enum\u306b\u96c6\u7d04<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u9077\u79fb\u30eb\u30fc\u30eb\u3092\u660e\u793a\u7684\u306b\u5b9a\u7fa9\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li><code>canTransitionTo<\/code>\u30e1\u30bd\u30c3\u30c9\u3067\u8a31\u53ef\u3055\u308c\u308b\u9077\u79fb\u3092\u660e\u78ba\u306b<\/li>\n\n\n\n<li>\u8907\u96d1\u306a\u30eb\u30fc\u30eb\u306f\u30ac\u30fc\u30c9\u6761\u4ef6\u3068\u3057\u3066\u5206\u96e2<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u60c5\u5831\u3092\u9077\u79fb\u306b\u542b\u3081\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u9077\u79fb\u306e\u7406\u7531\u3084\u4ed8\u968f\u30c7\u30fc\u30bf\u3092\u5f15\u304d\u6e21\u305b\u308b\u3088\u3046\u306b\u3059\u308b<\/li>\n\n\n\n<li>\u5c65\u6b74\u3084\u30ed\u30b0\u306b\u8a73\u7d30\u60c5\u5831\u3092\u542b\u3081\u3089\u308c\u308b<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30ea\u30b9\u30ca\u30fc\u30d1\u30bf\u30fc\u30f3\u3067\u30a4\u30d9\u30f3\u30c8\u99c6\u52d5\u306b\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u9077\u79fb\u524d\u5f8c\u306e\u51e6\u7406\u3092\u67d4\u8edf\u306b\u8ffd\u52a0\u30fb\u524a\u9664\u53ef\u80fd\u306b<\/li>\n\n\n\n<li>\u95a2\u5fc3\u306e\u5206\u96e2\u3092\u4fc3\u9032<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u8907\u5408\u72b6\u614b\u306e\u8868\u73fe<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30b5\u30d6\u30b9\u30c6\u30fc\u30c8\u3084\u4e26\u884c\u72b6\u614b\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u968e\u5c64\u7684\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u3092\u691c\u8a0e<\/li>\n\n\n\n<li>\u8907\u6570\u306e\u72b6\u614b\u8ef8\u3092\u6301\u3064\u5834\u5408\u306f\u3001\u305d\u308c\u305e\u308c\u3092Enum\u3067\u5b9a\u7fa9<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u3092\u4f7f\u3063\u305f\u30b9\u30c6\u30fc\u30c8\u30de\u30b7\u30f3\u306f\u3001\u30d3\u30b8\u30cd\u30b9\u30d7\u30ed\u30bb\u30b9\u306e\u6d41\u308c\u3092\u660e\u78ba\u306b\u8868\u73fe\u3057\u3001\u4e0d\u6b63\u306a\u72b6\u614b\u9077\u79fb\u3092\u9632\u6b62\u3059\u308b\u5f37\u529b\u306a\u30c4\u30fc\u30eb\u3067\u3059\u3002PHP\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u54c1\u8cea\u3068\u4fdd\u5b88\u6027\u3092\u5411\u4e0a\u3055\u305b\u308b\u305f\u3081\u306b\u3001\u7a4d\u6975\u7684\u306b\u6d3b\u7528\u3059\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-74\">\u5b9f\u8df5\u4f8b2\uff1a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u30c7\u30fc\u30bf\u6574\u5408\u6027\u306e\u78ba\u4fdd<\/h2>\n\n\n\n<p>\u30c7\u30fc\u30bf\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u6574\u5408\u6027\u306e\u78ba\u4fdd\u306f\u3001\u3042\u3089\u3086\u308b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u4fe1\u983c\u6027\u3092\u4fdd\u8a3c\u3059\u308b\u4e0a\u3067\u975e\u5e38\u306b\u91cd\u8981\u3067\u3059\u3002PHP\u306eEnum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30c9\u30e1\u30a4\u30f3\u56fa\u6709\u306e\u5236\u7d04\u3092\u578b\u3068\u3057\u3066\u8868\u73fe\u3057\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u3067\u4e00\u8cab\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-75\">\u5f93\u6765\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u624b\u6cd5\u306e\u8ab2\u984c<\/h3>\n\n\n\n<p>\u5f93\u6765\u306ePHP\u3067\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u624b\u6cd5\u306b\u306f\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u8ab2\u984c\u304c\u3042\u308a\u307e\u3057\u305f\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5024\u306e\u6709\u52b9\u6027\u30c1\u30a7\u30c3\u30af\u304c\u5206\u6563<\/strong> \u2013 \u540c\u3058\u30c1\u30a7\u30c3\u30af\u30ed\u30b8\u30c3\u30af\u304c\u30b3\u30fc\u30c9\u5185\u306e\u8907\u6570\u7b87\u6240\u306b\u6563\u5728<\/li>\n\n\n\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u77e5\u8b58\u306e\u6697\u9ed9\u5316<\/strong> \u2013 \u6709\u52b9\u306a\u5024\u306e\u5b9a\u7fa9\u304c\u30b3\u30e1\u30f3\u30c8\u3084\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306b\u4f9d\u5b58<\/li>\n\n\n\n<li><strong>\u6574\u5408\u6027\u306e\u4fdd\u8a3c\u306e\u96e3\u3057\u3055<\/strong> \u2013 \u5165\u529b\u3001\u51e6\u7406\u3001\u4fdd\u5b58\u306e\u5404\u5c64\u3067\u4e00\u8cab\u3057\u305f\u691c\u8a3c\u304c\u56f0\u96e3<\/li>\n\n\n\n<li><strong>\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u4e0d\u4e00\u81f4<\/strong> \u2013 \u540c\u3058\u30a8\u30e9\u30fc\u306b\u5bfe\u3057\u3066\u7570\u306a\u308b\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u308b\u53ef\u80fd\u6027<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-76\">Enum\u306b\u3088\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5229\u70b9<\/h3>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3053\u308c\u3089\u306e\u8ab2\u984c\u3092\u89e3\u6c7a\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u578b\u306b\u3088\u308b\u4fdd\u8a3c<\/strong> \u2013 \u6709\u52b9\u306a\u5024\u306e\u96c6\u5408\u3092\u578b\u3068\u3057\u3066\u5b9a\u7fa9<\/li>\n\n\n\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u77e5\u8b58\u306e\u660e\u793a\u5316<\/strong> \u2013 \u8a31\u5bb9\u3055\u308c\u308b\u5024\u3068\u305d\u306e\u610f\u5473\u304c\u30b3\u30fc\u30c9\u5185\u3067\u660e\u78ba<\/li>\n\n\n\n<li><strong>\u4e00\u8cab\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/strong> \u2013 \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u3067\u7d71\u4e00\u3055\u308c\u305f\u691c\u8a3c<\/li>\n\n\n\n<li><strong>\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u6a19\u6e96\u5316<\/strong> \u2013 \u4e00\u8cab\u6027\u306e\u3042\u308b\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u3068\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-77\">\u5b9f\u88c5\u4f8b\uff1a\u30d5\u30a9\u30fc\u30e0\u5165\u529b\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/h3>\n\n\n\n<p>\u30e6\u30fc\u30b6\u30fc\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u767b\u9332\u30d5\u30a9\u30fc\u30e0\u3092\u4f8b\u306b\u3001Enum\u3092\u4f7f\u3063\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3092\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30e6\u30fc\u30b6\u30fc\u30bf\u30a4\u30d7\u306e\u5b9a\u7fa9\nenum UserType: string\n{\n    case INDIVIDUAL = 'individual';\n    case BUSINESS = 'business';\n    case NONPROFIT = 'nonprofit';\n    \n    \/\/ \u8868\u793a\u7528\u30e9\u30d9\u30eb\n    public function getLabel(): string\n    {\n        return match($this) {\n            self::INDIVIDUAL =&gt; '\u500b\u4eba',\n            self::BUSINESS =&gt; '\u4f01\u696d',\n            self::NONPROFIT =&gt; '\u975e\u55b6\u5229\u56e3\u4f53',\n        };\n    }\n    \n    \/\/ \u5168\u30b1\u30fc\u30b9\u3092\u9078\u629e\u80a2\u3068\u3057\u3066\u53d6\u5f97\n    public static function getOptions(): array\n    {\n        $options = [];\n        foreach (self::cases() as $case) {\n            $options[$case-&gt;value] = $case-&gt;getLabel();\n        }\n        return $options;\n    }\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30e1\u30c3\u30bb\u30fc\u30b8\n    public static function getValidationMessage(): string\n    {\n        return '\u30e6\u30fc\u30b6\u30fc\u30bf\u30a4\u30d7\u306f ' . implode(', ', array_column(self::cases(), 'value')) . ' \u306e\u3044\u305a\u308c\u304b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002';\n    }\n}\n\n\/\/ \u4f1a\u54e1\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u5b9a\u7fa9\nenum MembershipStatus: string\n{\n    case PENDING = 'pending';\n    case ACTIVE = 'active';\n    case SUSPENDED = 'suspended';\n    case CANCELLED = 'cancelled';\n    \n    \/\/ \u6709\u52b9\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\n    public function isActive(): bool\n    {\n        return $this === self::ACTIVE;\n    }\n    \n    \/\/ \u7ba1\u7406\u8005\u304c\u5909\u66f4\u53ef\u80fd\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u4e00\u89a7\n    public static function getAdminEditableStatuses(): array\n    {\n        return [self::ACTIVE, self::SUSPENDED];\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u304c\u9078\u629e\u53ef\u80fd\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u4e00\u89a7\uff08\u89e3\u7d04\u6642\u306a\u3069\uff09\n    public static function getUserSelectableStatuses(): array\n    {\n        return [self::ACTIVE, self::CANCELLED];\n    }\n}\n\n\/\/ \u30d5\u30a9\u30fc\u30e0\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\uff08Laravel\u4f7f\u7528\u4f8b\uff09\nclass UserProfileRequest extends FormRequest\n{\n    public function rules(): array\n    {\n        return [\n            'name' =&gt; 'required|string|max:255',\n            'email' =&gt; 'required|email|unique:users',\n            'user_type' =&gt; [\n                'required',\n                Rule::in(array_column(UserType::cases(), 'value'))\n            ],\n            'membership_status' =&gt; [\n                'sometimes',\n                Rule::in(array_column(MembershipStatus::cases(), 'value'))\n            ]\n        ];\n    }\n    \n    public function messages(): array\n    {\n        return [\n            'user_type.in' =&gt; UserType::getValidationMessage(),\n        ];\n    }\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6e08\u307f\u30c7\u30fc\u30bf\u3092Enum\u578b\u306b\u5909\u63db\n    public function validatedEnums(): array\n    {\n        $validated = $this-&gt;validated();\n        \n        if (isset($validated['user_type'])) {\n            $validated['user_type'] = UserType::from($validated['user_type']);\n        }\n        \n        if (isset($validated['membership_status'])) {\n            $validated['membership_status'] = MembershipStatus::from($validated['membership_status']);\n        }\n        \n        return $validated;\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-78\">\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u4f7f\u7528\u4f8b<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class UserController extends Controller\n{\n    public function store(UserProfileRequest $request)\n    {\n        \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6e08\u307f\u30c7\u30fc\u30bf\u3092Enum\u578b\u3068\u3057\u3066\u53d6\u5f97\n        $validatedData = $request-&gt;validatedEnums();\n        \n        \/\/ Enum\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u5229\u7528\u53ef\u80fd\n        $userType = $validatedData['user_type'];\n        \n        \/\/ \u578b\u5b89\u5168\u306a\u6bd4\u8f03\n        if ($userType === UserType::BUSINESS) {\n            \/\/ \u4f01\u696d\u5411\u3051\u8ffd\u52a0\u51e6\u7406\n        }\n        \n        \/\/ \u8868\u793a\u7528\u30e9\u30d9\u30eb\u3092\u53d6\u5f97\n        $typeLabel = $userType-&gt;getLabel();\n        \n        \/\/ \u30e6\u30fc\u30b6\u30fc\u4f5c\u6210\n        $user = User::create([\n            'name' =&gt; $validatedData['name'],\n            'email' =&gt; $validatedData['email'],\n            'user_type' =&gt; $userType,  \/\/ DB\u30ad\u30e3\u30b9\u30c8\u7d4c\u7531\u3067\u4fdd\u5b58\n            'membership_status' =&gt; MembershipStatus::PENDING,\n        ]);\n        \n        return redirect()-&gt;route('users.show', $user)\n            -&gt;with('success', \"\u30e6\u30fc\u30b6\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u3002\u30bf\u30a4\u30d7\uff1a{$typeLabel}\");\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-79\">\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u975e\u4f9d\u5b58\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30af\u30e9\u30b9<\/h3>\n\n\n\n<p>Laravel\u306a\u3069\u306e\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3092\u4f7f\u7528\u3057\u306a\u3044\u5834\u5408\u3067\u3082\u3001Enum\u3092\u6d3b\u7528\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30af\u30e9\u30b9\u3092\u5b9f\u88c5\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Validator\n{\n    protected array $errors = [];\n    \n    \/\/ Enum\u578b\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n    public function validateEnum(string $value, string $enumClass, string $fieldName): bool\n    {\n        try {\n            $enumClass::from($value);\n            return true;\n        } catch (\\ValueError $e) {\n            $validValues = implode(', ', array_column($enumClass::cases(), 'value'));\n            $this-&gt;errors[$fieldName] = \"{$fieldName}\u306f {$validValues} \u306e\u3044\u305a\u308c\u304b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\";\n            return false;\n        }\n    }\n    \n    \/\/ \u30aa\u30d7\u30b7\u30e7\u30ca\u30eb\u306aEnum\u578b\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n    public function validateOptionalEnum(?string $value, string $enumClass, string $fieldName): bool\n    {\n        if ($value === null || $value === '') {\n            return true;\n        }\n        return $this-&gt;validateEnum($value, $enumClass, $fieldName);\n    }\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\u306e\u53d6\u5f97\n    public function getErrors(): array\n    {\n        return $this-&gt;errors;\n    }\n    \n    \/\/ \u6709\u52b9\u6027\u30c1\u30a7\u30c3\u30af\n    public function isValid(): bool\n    {\n        return empty($this-&gt;errors);\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$validator = new Validator();\n$isValid = $validator-&gt;validateEnum($_POST['user_type'], UserType::class, '\u30e6\u30fc\u30b6\u30fc\u30bf\u30a4\u30d7');\nif (!$validator-&gt;isValid()) {\n    $errors = $validator-&gt;getErrors();\n    \/\/ \u30a8\u30e9\u30fc\u8868\u793a\u51e6\u7406\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-80\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u306e\u6574\u5408\u6027\u78ba\u4fdd<\/h3>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u306e\u9593\u3067\u3082\u6574\u5408\u6027\u3092\u78ba\u4fdd\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Eloquent\u30e2\u30c7\u30eb\u3067\u306eEnum\u4f7f\u7528\uff08Laravel 8.x\u4ee5\u964d\uff09\nclass User extends Model\n{\n    protected $fillable = [\n        'name', 'email', 'user_type', 'membership_status'\n    ];\n    \n    \/\/ Enum\u30ad\u30e3\u30b9\u30c8\n    protected $casts = [\n        'user_type' =&gt; UserType::class,\n        'membership_status' =&gt; MembershipStatus::class,\n    ];\n    \n    \/\/ \u4f1a\u54e1\u304c\u6709\u52b9\u304b\u3069\u3046\u304b\u3092\u30c1\u30a7\u30c3\u30af\n    public function isActiveMember(): bool\n    {\n        return $this-&gt;membership_status-&gt;isActive();\n    }\n}\n\n\/\/ \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\npublic function up()\n{\n    Schema::create('users', function (Blueprint $table) {\n        $table-&gt;id();\n        $table-&gt;string('name');\n        $table-&gt;string('email')-&gt;unique();\n        $table-&gt;string('user_type');  \/\/ Enum\u306e\u6587\u5b57\u5217\u5024\u3092\u4fdd\u5b58\n        $table-&gt;string('membership_status')-&gt;default(MembershipStatus::PENDING-&gt;value);\n        $table-&gt;timestamps();\n    });\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-81\">API\u30ec\u30b9\u30dd\u30f3\u30b9\u3067\u306e\u6574\u5408\u6027\u78ba\u4fdd<\/h3>\n\n\n\n<p>API\u5fdc\u7b54\u3067\u3082Enum\u3092\u4e00\u8cab\u3057\u3066\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u6574\u5408\u6027\u3092\u9ad8\u3081\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class UserResource extends JsonResource\n{\n    public function toArray($request): array\n    {\n        return [\n            'id' =&gt; $this-&gt;id,\n            'name' =&gt; $this-&gt;name,\n            'email' =&gt; $this-&gt;email,\n            'user_type' =&gt; [\n                'code' =&gt; $this-&gt;user_type-&gt;value,\n                'label' =&gt; $this-&gt;user_type-&gt;getLabel(),\n            ],\n            'membership_status' =&gt; [\n                'code' =&gt; $this-&gt;membership_status-&gt;value,\n                'is_active' =&gt; $this-&gt;membership_status-&gt;isActive(),\n            ],\n            'created_at' =&gt; $this-&gt;created_at,\n            'updated_at' =&gt; $this-&gt;updated_at,\n        ];\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-82\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u5b9f\u88c5\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5165\u529b\u5024\u2192Enum\u5909\u63db\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li><code>tryFrom<\/code>\u30e1\u30bd\u30c3\u30c9\u3092\u6d3b\u7528\u3057\u3066\u5b89\u5168\u306b\u5909\u63db<\/li>\n\n\n\n<li>\u691c\u8a3c\u3068\u5909\u63db\u3092\u4e00\u7b87\u6240\u306b\u96c6\u7d04<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u53b3\u5bc6\u306a\u578b\u30c1\u30a7\u30c3\u30af\u306e\u6d3b\u7528<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u53ef\u80fd\u306a\u9650\u308a\u578b\u5ba3\u8a00\u3092\u4f7f\u7528<\/li>\n\n\n\n<li>PHPStan\u306a\u3069\u306e\u9759\u7684\u89e3\u6790\u30c4\u30fc\u30eb\u3068\u9023\u643a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u77e5\u8b58\u306e\u96c6\u7d04<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30eb\u3068\u30e1\u30c3\u30bb\u30fc\u30b8\u3092Enum\u306b\u542b\u3081\u308b<\/li>\n\n\n\n<li>\u95a2\u9023\u3059\u308b\u632f\u308b\u821e\u3044\u3082\u540c\u3058\u5834\u6240\u306b\u30ab\u30d7\u30bb\u30eb\u5316<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u6a19\u6e96\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u4e00\u8cab\u3057\u305f\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u30d5\u30a9\u30fc\u30de\u30c3\u30c8<\/li>\n\n\n\n<li>\u591a\u8a00\u8a9e\u5bfe\u5fdc\u306e\u8003\u616e<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u3092\u4f7f\u3063\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u6574\u5408\u6027\u78ba\u4fdd\u306f\u3001\u7279\u306b\u8907\u96d1\u306a\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3084\u4e8b\u696d\u62e1\u5927\u306b\u3088\u308b\u8981\u4ef6\u5909\u66f4\u304c\u983b\u7e41\u306a\u5834\u9762\u3067\u3001\u305d\u306e\u771f\u4fa1\u3092\u767a\u63ee\u3057\u307e\u3059\u3002\u578b\u5b89\u5168\u6027\u3092\u6d3b\u304b\u3059\u3053\u3068\u3067\u3001\u958b\u767a\u30c1\u30fc\u30e0\u5168\u4f53\u304c\u4e00\u8cab\u3057\u305f\u30eb\u30fc\u30eb\u3067\u958b\u767a\u3067\u304d\u3001\u30d0\u30b0\u306e\u65e9\u671f\u767a\u898b\u3068\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u5411\u4e0a\u304c\u5b9f\u73fe\u3067\u304d\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-83\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u9023\u643a\u6642\u306eEnum\u306e\u6271\u3044\u65b9<\/h3>\n\n\n\n<p>PHP\u306eEnum\u306f\u30e1\u30e2\u30ea\u4e0a\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3067\u3059\u304c\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u306f\u6587\u5b57\u5217\u3084\u6574\u6570\u3068\u3057\u3066\u4fdd\u5b58\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u3053\u306e\u9023\u643a\u3092\u52b9\u7387\u7684\u306b\u884c\u3046\u3053\u3068\u3067\u3001\u578b\u5b89\u5168\u6027\u3092\u7dad\u6301\u3057\u3064\u3064\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u6574\u5408\u6027\u3082\u78ba\u4fdd\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-84\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u8a08\u306e\u8003\u616e\u70b9<\/h4>\n\n\n\n<p>Enum\u3068\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9023\u643a\u3059\u308b\u969b\u306e\u57fa\u672c\u7684\u306a\u8003\u616e\u70b9\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ab\u30e9\u30e0\u578b\u306e\u9078\u629e<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u6587\u5b57\u5217\u578bEnum\uff1a<code>VARCHAR<\/code>\/<code>TEXT<\/code>\u3092\u4f7f\u7528<\/li>\n\n\n\n<li>\u6574\u6570\u578bEnum\uff1a<code>INTEGER<\/code>\/<code>SMALLINT<\/code>\u3092\u4f7f\u7528<\/li>\n\n\n\n<li>\u53ef\u8aad\u6027\u3068\u5c06\u6765\u306e\u62e1\u5f35\u6027\u306e\u30d0\u30e9\u30f3\u30b9\u3092\u8003\u616e<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u5236\u7d04\u306e\u8a2d\u5b9a<\/strong>\n<ul class=\"wp-block-list\">\n<li><code>CHECK<\/code>\u5236\u7d04\u307e\u305f\u306f<code>ENUM<\/code>\u578b\uff08MySQL\u306e\u5834\u5408\uff09\u3067\u6709\u52b9\u5024\u3092\u5236\u9650<\/li>\n\n\n\n<li>\u5916\u90e8\u30ad\u30fc\u5236\u7d04\u3068\u306e\u7d44\u307f\u5408\u308f\u305b<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u6226\u7565<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u983b\u7e41\u306b\u691c\u7d22\u30fb\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\u3055\u308c\u308bEnum\u5024\u30ab\u30e9\u30e0\u306b\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u8a2d\u5b9a<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-85\">\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u5225\u306eEnum\u5bfe\u5fdc<\/h4>\n\n\n\n<p><strong>Laravel (8.x\u4ee5\u964d)<\/strong><\/p>\n\n\n\n<p>Laravel\u306f<code>$casts<\/code>\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u901a\u3058\u3066\u3001Enum\u3068\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u9023\u643a\u3092\u30b7\u30fc\u30e0\u30ec\u30b9\u306b\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30e2\u30c7\u30eb\u3067\u306eEnum\u578b\u30ad\u30e3\u30b9\u30c8\nclass Product extends Model\n{\n    protected $fillable = ['name', 'category', 'status'];\n    \n    protected $casts = [\n        'category' =&gt; ProductCategory::class,\n        'status' =&gt; ProductStatus::class\n    ];\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$product = Product::find(1);\necho $product-&gt;category-&gt;getLabel(); \/\/ Enum\u306e\u30e1\u30bd\u30c3\u30c9\u3092\u76f4\u63a5\u547c\u3073\u51fa\u3057\n\n\/\/ \u30af\u30a8\u30ea\u30d3\u30eb\u30c0\u3067\u306e\u4f7f\u7528\n$electronicsProducts = Product::where('category', ProductCategory::ELECTRONICS)-&gt;get();\n\n\/\/ \u4f5c\u6210\u6642\nProduct::create([\n    'name' =&gt; '\u30b9\u30de\u30fc\u30c8\u30d5\u30a9\u30f3',\n    'category' =&gt; ProductCategory::ELECTRONICS,\n    'status' =&gt; ProductStatus::ACTIVE\n]);\n<\/pre>\n\n\n\n<p><strong>Doctrine ORM<\/strong><\/p>\n\n\n\n<p>Doctrine 2.6\u4ee5\u964d\u3067\u306f\u3001\u30ab\u30b9\u30bf\u30e0\u578b\u3092\u901a\u3058\u3066Enum\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Enum\u30bf\u30a4\u30d7\u306e\u5b9a\u7fa9\nuse Doctrine\\DBAL\\Types\\Type;\n\nclass ProductCategoryType extends Type\n{\n    public function getSQLDeclaration(array $column, AbstractPlatform $platform): string\n    {\n        return $platform-&gt;getVarcharTypeDeclarationSQL([\n            'length' =&gt; 50,\n            'fixed' =&gt; false,\n        ]);\n    }\n    \n    public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed\n    {\n        return $value instanceof ProductCategory ? $value-&gt;value : $value;\n    }\n    \n    public function convertToPHPValue($value, AbstractPlatform $platform): ?ProductCategory\n    {\n        return $value !== null ? ProductCategory::tryFrom($value) : null;\n    }\n    \n    public function getName(): string\n    {\n        return 'product_category';\n    }\n}\n\n\/\/ \u578b\u306e\u767b\u9332\nType::addType('product_category', ProductCategoryType::class);\n\n\/\/ \u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u3067\u306e\u4f7f\u7528\n\/**\n * @Entity\n *\/\nclass Product\n{\n    \/**\n     * @Column(type=\"product_category\")\n     *\/\n    private ProductCategory $category;\n    \n    \/\/ \u30b2\u30c3\u30bf\u30fc\u30fb\u30bb\u30c3\u30bf\u30fc\n}\n<\/pre>\n\n\n\n<p><strong>Symfony Forms<\/strong><\/p>\n\n\n\n<p>Symfony 6.0\u4ee5\u964d\u3067\u306f\u3001FormType\u3067Enum\u3092\u76f4\u63a5\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30d5\u30a9\u30fc\u30e0\u30bf\u30a4\u30d7\u5b9a\u7fa9\nuse Symfony\\Component\\Form\\AbstractType;\nuse Symfony\\Component\\Form\\Extension\\Core\\Type\\EnumType;\n\nclass ProductFormType extends AbstractType\n{\n    public function buildForm(FormBuilderInterface $builder, array $options): void\n    {\n        $builder\n            -&gt;add('name', TextType::class)\n            -&gt;add('category', EnumType::class, [\n                'class' =&gt; ProductCategory::class,\n                'choice_label' =&gt; function (ProductCategory $choice) {\n                    return $choice-&gt;getLabel();\n                }\n            ]);\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-86\">\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306b\u4f9d\u5b58\u3057\u306a\u3044\u5b9f\u88c5<\/h4>\n\n\n\n<p>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3092\u4f7f\u7528\u3057\u306a\u3044\u5834\u5408\u3084\u3001\u30ec\u30ac\u30b7\u30fc\u30b3\u30fc\u30c9\u3068\u306e\u7d71\u5408\u3067\u306f\u3001\u72ec\u81ea\u306e\u30de\u30c3\u30d4\u30f3\u30b0\u30ed\u30b8\u30c3\u30af\u3092\u5b9f\u88c5\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ PDO\u3092\u4f7f\u7528\u3057\u305f\u4f8b\nclass ProductRepository\n{\n    private PDO $pdo;\n    \n    public function __construct(PDO $pdo) \n    {\n        $this-&gt;pdo = $pdo;\n    }\n    \n    \/\/ \u30c7\u30fc\u30bf\u306e\u53d6\u5f97\u6642\u306bEnum\u306b\u5909\u63db\n    public function findById(int $id): ?Product\n    {\n        $stmt = $this-&gt;pdo-&gt;prepare('SELECT * FROM products WHERE id = ?');\n        $stmt-&gt;execute([$id]);\n        $data = $stmt-&gt;fetch(PDO::FETCH_ASSOC);\n        \n        if (!$data) {\n            return null;\n        }\n        \n        $product = new Product();\n        $product-&gt;setId($data['id']);\n        $product-&gt;setName($data['name']);\n        \n        \/\/ \u6587\u5b57\u5217\u304b\u3089Enum\u306b\u5909\u63db\n        if ($data['category']) {\n            $product-&gt;setCategory(ProductCategory::from($data['category']));\n        }\n        \n        return $product;\n    }\n    \n    \/\/ \u30c7\u30fc\u30bf\u306e\u4fdd\u5b58\u6642\u306bEnum\u304b\u3089\u5909\u63db\n    public function save(Product $product): void\n    {\n        $stmt = $this-&gt;pdo-&gt;prepare(\n            'INSERT INTO products (name, category) VALUES (?, ?) \n             ON DUPLICATE KEY UPDATE name = ?, category = ?'\n        );\n        \n        \/\/ Enum\u3092\u6587\u5b57\u5217\u306b\u5909\u63db\n        $categoryValue = $product-&gt;getCategory() ? $product-&gt;getCategory()-&gt;value : null;\n        \n        $stmt-&gt;execute([\n            $product-&gt;getName(),\n            $categoryValue,\n            $product-&gt;getName(),\n            $categoryValue\n        ]);\n        \n        if (!$product-&gt;getId()) {\n            $product-&gt;setId($this-&gt;pdo-&gt;lastInsertId());\n        }\n    }\n    \n    \/\/ Enum\u306b\u3088\u308b\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\n    public function findByCategory(ProductCategory $category): array\n    {\n        $stmt = $this-&gt;pdo-&gt;prepare('SELECT * FROM products WHERE category = ?');\n        $stmt-&gt;execute([$category-&gt;value]);\n        \n        $products = [];\n        while ($data = $stmt-&gt;fetch(PDO::FETCH_ASSOC)) {\n            $product = new Product();\n            $product-&gt;setId($data['id']);\n            $product-&gt;setName($data['name']);\n            $product-&gt;setCategory(ProductCategory::from($data['category']));\n            $products[] = $product;\n        }\n        \n        return $products;\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-87\">\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30b9\u30ad\u30fc\u30de\u8a2d\u8a08<\/h4>\n\n\n\n<p>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001Enum\u306e\u5024\u306b\u5bfe\u3057\u3066\u9069\u5207\u306a\u5236\u7d04\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Laravel\u3067\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u4f8b\npublic function up()\n{\n    Schema::create('products', function (Blueprint $table) {\n        $table-&gt;id();\n        $table-&gt;string('name');\n        $table-&gt;string('category');\n        $table-&gt;string('status');\n        $table-&gt;timestamps();\n        \n        \/\/ \u30c1\u30a7\u30c3\u30af\u5236\u7d04\uff08PostgreSQL\u306a\u3069\uff09\n        $validCategories = implode(\"','\", array_column(ProductCategory::cases(), 'value'));\n        $table-&gt;whereRaw(\"category IN ('$validCategories')\");\n    });\n}\n\n\/\/ MySQL\u306e\u5834\u5408\u306fENUM\u578b\u3082\u5229\u7528\u53ef\u80fd\n\/\/ $table-&gt;enum('category', array_column(ProductCategory::cases(), 'value'));\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-88\">\u30d0\u30fc\u30b8\u30e7\u30f3\u7ba1\u7406\u3068\u5909\u66f4\u3078\u306e\u5bfe\u5fdc<\/h4>\n\n\n\n<p>Enum\u306e\u5024\u304c\u5909\u66f4\u3055\u308c\u308b\u3053\u3068\u3092\u8003\u616e\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u8a08\u3082\u91cd\u8981\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u65b0\u3057\u3044Enum\u5024\u306e\u8ffd\u52a0<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u901a\u5e38\u306f\u554f\u984c\u306a\u304f\u8ffd\u52a0\u53ef\u80fd<\/li>\n\n\n\n<li>\u65e2\u5b58\u30c7\u30fc\u30bf\u3068\u306e\u6574\u5408\u6027\u30c1\u30a7\u30c3\u30af<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Enum\u5024\u306e\u540d\u524d\u5909\u66f4<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30c7\u30fc\u30bf\u79fb\u884c\u304c\u5fc5\u8981<\/li>\n\n\n\n<li>\u4e00\u6642\u7684\u306a\u4e21\u5bfe\u5fdc\u671f\u9593\u306e\u8a2d\u8a08<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Enum\u5024\u306e\u524a\u9664<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u65e2\u5b58\u30c7\u30fc\u30bf\u306e\u53d6\u308a\u6271\u3044\u30dd\u30ea\u30b7\u30fc\u306e\u6c7a\u5b9a<\/li>\n\n\n\n<li>\u4ee3\u66ff\u5024\u3078\u306e\u79fb\u884c\u8a08\u753b<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Enum\u5024\u306e\u5909\u66f4\u7ba1\u7406\u4f8b\uff08Laravel\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\uff09\npublic function up()\n{\n    \/\/ \u53e4\u3044\u30ab\u30c6\u30b4\u30ea\u30fc\u5024\u3092\u65b0\u3057\u3044\u5024\u306b\u66f4\u65b0\n    DB::table('products')\n        -&gt;where('category', 'old_electronics')\n        -&gt;update(['category' =&gt; 'electronics']);\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-89\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u9023\u643a\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4e00\u8cab\u3057\u305f\u30de\u30c3\u30d4\u30f3\u30b0\u6226\u7565<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u3067\u7d71\u4e00\u3057\u305f\u30de\u30c3\u30d4\u30f3\u30b0\u65b9\u6cd5\u3092\u4f7f\u7528<\/li>\n\n\n\n<li>\u30ea\u30dd\u30b8\u30c8\u30ea\u30d1\u30bf\u30fc\u30f3\u306a\u3069\u3067\u30c7\u30fc\u30bf\u5909\u63db\u30ed\u30b8\u30c3\u30af\u3092\u96c6\u7d04<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>NULL\u5024\u306e\u9069\u5207\u306a\u51e6\u7406<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5fc5\u9808\u30d5\u30a3\u30fc\u30eb\u30c9\u3068\u4efb\u610f\u30d5\u30a3\u30fc\u30eb\u30c9\u306e\u533a\u5225<\/li>\n\n\n\n<li><code>tryFrom<\/code>\u30e1\u30bd\u30c3\u30c9\u3092\u6d3b\u7528\u3057\u305f\u5b89\u5168\u306a\u5909\u63db<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u5236\u7d04\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u691c\u8a3c\u306e\u4e21\u65b9\u3092\u6d3b\u7528<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u4e8c\u91cd\u306e\u9632\u5fa1\u7dda\u3068\u3057\u3066\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30ec\u30d9\u30eb\u306e\u6574\u5408\u6027\u4fdd\u8a3c<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u983b\u7e41\u306b\u4f7f\u7528\u3059\u308bEnum\u5024\u30ab\u30e9\u30e0\u306b\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u8a2d\u5b9a<\/li>\n\n\n\n<li>N+1\u30af\u30a8\u30ea\u554f\u984c\u306e\u56de\u907f<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u3068\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u9069\u5207\u306a\u9023\u643a\u306b\u3088\u308a\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u3067\u30c9\u30e1\u30a4\u30f3\u30ed\u30b8\u30c3\u30af\u306e\u4e00\u8cab\u6027\u3092\u4fdd\u3061\u3001\u30c7\u30fc\u30bf\u6574\u5408\u6027\u3092\u78ba\u4fdd\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u30b5\u30dd\u30fc\u30c8\u3092\u6d3b\u7528\u3057\u3064\u3064\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u8a08\u306b\u3082\u914d\u616e\u3059\u308b\u3053\u3068\u3067\u3001\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u306e\u9ad8\u3044\u30b7\u30b9\u30c6\u30e0\u3092\u69cb\u7bc9\u3067\u304d\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-90\">\u5b9f\u8df5\u4f8b3\uff1a\u30dd\u30ea\u30b7\u30fc\u3068\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406<\/h2>\n\n\n\n<p>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u304a\u3051\u308b\u6a29\u9650\u7ba1\u7406\u306f\u3001\u8907\u96d1\u3067\u8aa4\u308a\u304c\u8a31\u3055\u308c\u306a\u3044\u91cd\u8981\u306a\u8981\u7d20\u3067\u3059\u3002PHP\u306eEnum\u578b\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u578b\u5b89\u5168\u304b\u3064\u4fdd\u5b88\u6027\u306e\u9ad8\u3044\u6a29\u9650\u30b7\u30b9\u30c6\u30e0\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-91\">\u6a29\u9650\u7ba1\u7406\u306e\u5f93\u6765\u306e\u8ab2\u984c<\/h3>\n\n\n\n<p>\u5f93\u6765\u306e\u6a29\u9650\u7ba1\u7406\u306b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u8ab2\u984c\u304c\u3042\u308a\u307e\u3057\u305f\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6587\u5b57\u5217\u30d9\u30fc\u30b9\u306e\u6a29\u9650\u30c1\u30a7\u30c3\u30af<\/strong> \u2013 \u30bf\u30a4\u30d7\u30df\u30b9\u306b\u3088\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30db\u30fc\u30eb<\/li>\n\n\n\n<li><strong>\u6761\u4ef6\u5206\u5c90\u306e\u8907\u96d1\u5316<\/strong> \u2013 \u6a29\u9650\u30ed\u30b8\u30c3\u30af\u306e\u6563\u5728\u3068\u91cd\u8907<\/li>\n\n\n\n<li><strong>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c6\u30fc\u30b7\u30e7\u30f3\u3068\u30b3\u30fc\u30c9\u306e\u4e56\u96e2<\/strong> \u2013 \u6a29\u9650\u5b9a\u7fa9\u306e\u96c6\u7d04\u5834\u6240\u306e\u6b20\u5982<\/li>\n\n\n\n<li><strong>\u62e1\u5f35\u6027\u306e\u5236\u9650<\/strong> \u2013 \u65b0\u3057\u3044\u6a29\u9650\u8ffd\u52a0\u6642\u306e\u5909\u66f4\u7b87\u6240\u306e\u591a\u3055<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-92\">Enum\u306b\u3088\u308b\u6a29\u9650\u7ba1\u7406\u306e\u30a2\u30d7\u30ed\u30fc\u30c1<\/h3>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3057\u305f\u6a29\u9650\u7ba1\u7406\u306b\u306f\u4e3b\u306b\u4ee5\u4e0b\u306e\u30a2\u30d7\u30ed\u30fc\u30c1\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ed\u30fc\u30ebEnum<\/strong> \u2013 \u30e6\u30fc\u30b6\u30fc\u30ed\u30fc\u30eb\u3092\u8868\u73fe<\/li>\n\n\n\n<li><strong>\u6a29\u9650Enum<\/strong> \u2013 \u500b\u5225\u306e\u6a29\u9650\u3092\u8868\u73fe<\/li>\n\n\n\n<li><strong>\u30d3\u30c3\u30c8\u30d5\u30e9\u30b0Enum<\/strong> \u2013 \u8907\u6570\u6a29\u9650\u306e\u7d44\u307f\u5408\u308f\u305b\u3092\u52b9\u7387\u7684\u306b\u8868\u73fe<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-93\">\u5b9f\u88c5\u4f8b\uff1a\u30ed\u30fc\u30eb\u30d9\u30fc\u30b9\u306e\u6a29\u9650\u7ba1\u7406<\/h3>\n\n\n\n<p>\u6700\u3082\u30b7\u30f3\u30d7\u30eb\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u3068\u3057\u3066\u3001\u30e6\u30fc\u30b6\u30fc\u30ed\u30fc\u30eb\u3092Enum\u3067\u5b9a\u7fa9\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum UserRole: string\n{\n    case ADMIN = 'admin';             \/\/ \u7ba1\u7406\u8005\n    case EDITOR = 'editor';           \/\/ \u7de8\u96c6\u8005\n    case AUTHOR = 'author';           \/\/ \u8457\u8005\n    case SUBSCRIBER = 'subscriber';   \/\/ \u8cfc\u8aad\u8005\n    \n    \/\/ \u30ed\u30fc\u30eb\u306e\u968e\u5c64\u30ec\u30d9\u30eb\u3092\u53d6\u5f97\n    public function getLevel(): int\n    {\n        return match($this) {\n            self::ADMIN =&gt; 100,\n            self::EDITOR =&gt; 75,\n            self::AUTHOR =&gt; 50,\n            self::SUBSCRIBER =&gt; 25,\n        };\n    }\n    \n    \/\/ \u3042\u308b\u30ed\u30fc\u30eb\u304c\u5225\u306e\u30ed\u30fc\u30eb\u4ee5\u4e0a\u306e\u6a29\u9650\u3092\u6301\u3064\u304b\u3069\u3046\u304b\n    public function hasAtLeastRole(self $role): bool\n    {\n        return $this-&gt;getLevel() &gt;= $role-&gt;getLevel();\n    }\n    \n    \/\/ \u7279\u5b9a\u306e\u64cd\u4f5c\u304c\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\u304b\u3069\u3046\u304b\n    public function canPerformAction(string $action): bool\n    {\n        return match($action) {\n            'manage_users' =&gt; $this === self::ADMIN,\n            'edit_settings' =&gt; $this-&gt;hasAtLeastRole(self::ADMIN),\n            'publish_content' =&gt; $this-&gt;hasAtLeastRole(self::EDITOR),\n            'edit_own_content' =&gt; $this-&gt;hasAtLeastRole(self::AUTHOR),\n            'comment' =&gt; $this-&gt;hasAtLeastRole(self::SUBSCRIBER),\n            'view_content' =&gt; true,\n            default =&gt; false,\n        };\n    }\n    \n    \/\/ \u8868\u793a\u540d\u3092\u53d6\u5f97\n    public function getDisplayName(): string\n    {\n        return match($this) {\n            self::ADMIN =&gt; '\u7ba1\u7406\u8005',\n            self::EDITOR =&gt; '\u7de8\u96c6\u8005',\n            self::AUTHOR =&gt; '\u8457\u8005',\n            self::SUBSCRIBER =&gt; '\u8cfc\u8aad\u8005',\n        };\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nclass User\n{\n    private int $id;\n    private string $name;\n    private string $email;\n    private UserRole $role;\n    \n    \/\/ \u30b2\u30c3\u30bf\u30fc\u3068\u30bb\u30c3\u30bf\u30fc\n    \n    public function hasPermission(string $action): bool\n    {\n        return $this-&gt;role-&gt;canPerformAction($action);\n    }\n}\n\n\/\/ \u30a2\u30af\u30bb\u30b9\u5236\u5fa1\u306e\u5b9f\u88c5\nif ($user-&gt;hasPermission('publish_content')) {\n    \/\/ \u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u516c\u958b\u3059\u308b\u51e6\u7406\n} else {\n    throw new AuthorizationException('\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u516c\u958b\u3059\u308b\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093');\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-94\">\u5b9f\u88c5\u4f8b\uff1a\u7d30\u7c92\u5ea6\u306e\u6a29\u9650Enum<\/h3>\n\n\n\n<p>\u3088\u308a\u67d4\u8edf\u306a\u6a29\u9650\u30b7\u30b9\u30c6\u30e0\u306e\u305f\u3081\u306b\u3001\u500b\u5225\u306e\u6a29\u9650\u3092Enum\u3067\u5b9a\u7fa9\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum Permission: string\n{\n    \/\/ \u30e6\u30fc\u30b6\u30fc\u7ba1\u7406\u6a29\u9650\n    case MANAGE_USERS = 'manage_users';\n    case VIEW_USERS = 'view_users';\n    case CREATE_USER = 'create_user';\n    case EDIT_USER = 'edit_user';\n    case DELETE_USER = 'delete_user';\n    \n    \/\/ \u30b3\u30f3\u30c6\u30f3\u30c4\u7ba1\u7406\u6a29\u9650\n    case MANAGE_CONTENT = 'manage_content';\n    case VIEW_CONTENT = 'view_content';\n    case CREATE_CONTENT = 'create_content';\n    case EDIT_OWN_CONTENT = 'edit_own_content';\n    case EDIT_ANY_CONTENT = 'edit_any_content';\n    case PUBLISH_CONTENT = 'publish_content';\n    case DELETE_OWN_CONTENT = 'delete_own_content';\n    case DELETE_ANY_CONTENT = 'delete_any_content';\n    \n    \/\/ \u30b7\u30b9\u30c6\u30e0\u7ba1\u7406\u6a29\u9650\n    case MANAGE_SETTINGS = 'manage_settings';\n    case VIEW_LOGS = 'view_logs';\n    \n    \/\/ \u6a29\u9650\u306e\u8aac\u660e\u3092\u53d6\u5f97\n    public function getDescription(): string\n    {\n        return match($this) {\n            self::MANAGE_USERS =&gt; '\u30e6\u30fc\u30b6\u30fc\u7ba1\u7406\uff08\u5168\u3066\uff09',\n            self::VIEW_USERS =&gt; '\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u306e\u95b2\u89a7',\n            self::CREATE_USER =&gt; '\u30e6\u30fc\u30b6\u30fc\u306e\u4f5c\u6210',\n            self::EDIT_USER =&gt; '\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u306e\u7de8\u96c6',\n            self::DELETE_USER =&gt; '\u30e6\u30fc\u30b6\u30fc\u306e\u524a\u9664',\n            self::MANAGE_CONTENT =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u7ba1\u7406\uff08\u5168\u3066\uff09',\n            self::VIEW_CONTENT =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u95b2\u89a7',\n            self::CREATE_CONTENT =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u4f5c\u6210',\n            self::EDIT_OWN_CONTENT =&gt; '\u81ea\u5206\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u7de8\u96c6',\n            self::EDIT_ANY_CONTENT =&gt; '\u5168\u3066\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u7de8\u96c6',\n            self::PUBLISH_CONTENT =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u516c\u958b',\n            self::DELETE_OWN_CONTENT =&gt; '\u81ea\u5206\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u524a\u9664',\n            self::DELETE_ANY_CONTENT =&gt; '\u5168\u3066\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u524a\u9664',\n            self::MANAGE_SETTINGS =&gt; '\u30b7\u30b9\u30c6\u30e0\u8a2d\u5b9a\u306e\u7ba1\u7406',\n            self::VIEW_LOGS =&gt; '\u30b7\u30b9\u30c6\u30e0\u30ed\u30b0\u306e\u95b2\u89a7',\n        };\n    }\n    \n    \/\/ \u89aa\u6a29\u9650\u3092\u30c1\u30a7\u30c3\u30af\uff08\u5305\u542b\u95a2\u4fc2\uff09\n    public function impliesPermission(self $permission): bool\n    {\n        \/\/ \u7279\u5b9a\u306e\u6a29\u9650\u304c\u4ed6\u306e\u6a29\u9650\u3092\u5305\u542b\u3059\u308b\u95a2\u4fc2\u3092\u5b9a\u7fa9\n        if ($this === self::MANAGE_USERS) {\n            return in_array($permission, [\n                self::VIEW_USERS, self::CREATE_USER, self::EDIT_USER, self::DELETE_USER\n            ]);\n        }\n        \n        if ($this === self::MANAGE_CONTENT) {\n            return in_array($permission, [\n                self::VIEW_CONTENT, self::CREATE_CONTENT, \n                self::EDIT_OWN_CONTENT, self::EDIT_ANY_CONTENT,\n                self::PUBLISH_CONTENT, \n                self::DELETE_OWN_CONTENT, self::DELETE_ANY_CONTENT\n            ]);\n        }\n        \n        if ($this === self::EDIT_ANY_CONTENT) {\n            return $permission === self::EDIT_OWN_CONTENT;\n        }\n        \n        if ($this === self::DELETE_ANY_CONTENT) {\n            return $permission === self::DELETE_OWN_CONTENT;\n        }\n        \n        \/\/ \u540c\u3058\u6a29\u9650\u306e\u5834\u5408\u3082\u542b\u610f\u95a2\u4fc2\u3042\u308a\n        return $this === $permission;\n    }\n}\n\n\/\/ \u30ed\u30fc\u30eb\u3068\u6a29\u9650\u306e\u30de\u30c3\u30d4\u30f3\u30b0\nclass Role\n{\n    private string $name;\n    private array $permissions = [];\n    \n    public function __construct(string $name, array $permissions = [])\n    {\n        $this-&gt;name = $name;\n        $this-&gt;permissions = $permissions;\n    }\n    \n    public function hasPermission(Permission $permission): bool\n    {\n        foreach ($this-&gt;permissions as $rolePermission) {\n            if ($rolePermission-&gt;impliesPermission($permission)) {\n                return true;\n            }\n        }\n        \n        return false;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$adminRole = new Role('\u7ba1\u7406\u8005', [\n    Permission::MANAGE_USERS,\n    Permission::MANAGE_CONTENT,\n    Permission::MANAGE_SETTINGS,\n    Permission::VIEW_LOGS\n]);\n\n$editorRole = new Role('\u7de8\u96c6\u8005', [\n    Permission::VIEW_USERS,\n    Permission::VIEW_CONTENT,\n    Permission::CREATE_CONTENT,\n    Permission::EDIT_ANY_CONTENT,\n    Permission::PUBLISH_CONTENT\n]);\n\n$authorRole = new Role('\u8457\u8005', [\n    Permission::VIEW_CONTENT,\n    Permission::CREATE_CONTENT,\n    Permission::EDIT_OWN_CONTENT,\n    Permission::DELETE_OWN_CONTENT\n]);\n\n\/\/ \u6a29\u9650\u30c1\u30a7\u30c3\u30af\nif ($editorRole-&gt;hasPermission(Permission::PUBLISH_CONTENT)) {\n    \/\/ \u7de8\u96c6\u8005\u306f\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u516c\u958b\u3067\u304d\u308b\n}\n\nif (!$authorRole-&gt;hasPermission(Permission::PUBLISH_CONTENT)) {\n    \/\/ \u8457\u8005\u306f\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u516c\u958b\u3067\u304d\u306a\u3044\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-95\">\u5b9f\u88c5\u4f8b\uff1a\u30d3\u30c3\u30c8\u30d5\u30e9\u30b0\u3092\u4f7f\u3063\u305f\u52b9\u7387\u7684\u306a\u6a29\u9650\u7ba1\u7406<\/h3>\n\n\n\n<p>\u591a\u6570\u306e\u6a29\u9650\u3092\u52b9\u7387\u7684\u306b\u6271\u3046\u305f\u3081\u306b\u3001\u6574\u6570\u5024\u3092\u4f7f\u3063\u305f\u30d3\u30c3\u30c8\u30d5\u30e9\u30b0\u30d1\u30bf\u30fc\u30f3\u304c\u6709\u52b9\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum PermissionFlag: int\n{\n    case NONE = 0;              \/\/ 0000 0000\n    case VIEW = 1;              \/\/ 0000 0001\n    case CREATE = 2;            \/\/ 0000 0010\n    case EDIT = 4;              \/\/ 0000 0100\n    case DELETE = 8;            \/\/ 0000 1000\n    case PUBLISH = 16;          \/\/ 0001 0000\n    case MANAGE = 32;           \/\/ 0010 0000\n    case ADMIN = 64;            \/\/ 0100 0000\n    \n    \/\/ \u4fbf\u5229\u306a\u7d44\u307f\u5408\u308f\u305b\n    case BASIC = 3;             \/\/ VIEW | CREATE\n    case EDITOR = 7;            \/\/ VIEW | CREATE | EDIT\n    case MODERATOR = 31;        \/\/ VIEW | CREATE | EDIT | DELETE | PUBLISH\n    case SUPER_ADMIN = 127;     \/\/ \u5168\u3066\u306e\u6a29\u9650\n    \n    \/\/ \u7279\u5b9a\u306e\u6a29\u9650\u304c\u3042\u308b\u304b\u30c1\u30a7\u30c3\u30af\n    public function hasFlag(self $flag): bool\n    {\n        \/\/ \u30d3\u30c3\u30c8\u6f14\u7b97\u3067\u30d5\u30e9\u30b0\u306e\u5b58\u5728\u3092\u30c1\u30a7\u30c3\u30af\n        return ($this-&gt;value &amp; $flag-&gt;value) === $flag-&gt;value;\n    }\n    \n    \/\/ \u8907\u6570\u306e\u30d5\u30e9\u30b0\u3092\u7d44\u307f\u5408\u308f\u305b\u305f\u65b0\u3057\u3044PermissionFlag\u3092\u53d6\u5f97\n    public function add(self $flag): self\n    {\n        $newValue = $this-&gt;value | $flag-&gt;value;\n        return self::from($newValue);\n    }\n    \n    \/\/ \u7279\u5b9a\u306e\u30d5\u30e9\u30b0\u3092\u9664\u53bb\u3057\u305f\u65b0\u3057\u3044PermissionFlag\u3092\u53d6\u5f97\n    public function remove(self $flag): self\n    {\n        $newValue = $this-&gt;value &amp; ~$flag-&gt;value;\n        return self::from($newValue);\n    }\n}\n\n\/\/ \u30ea\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u3092\u5b9a\u7fa9\nenum ResourceType: string\n{\n    case USER = 'user';\n    case ARTICLE = 'article';\n    case COMMENT = 'comment';\n    case SETTING = 'setting';\n}\n\n\/\/ \u30e6\u30fc\u30b6\u30fc\u30af\u30e9\u30b9\u3067\u306e\u5b9f\u88c5\nclass User\n{\n    private array $permissions = [];\n    \n    public function __construct()\n    {\n        \/\/ \u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u3059\u3079\u3066\u306e\u30ea\u30bd\u30fc\u30b9\u306bNONE\u6a29\u9650\u3092\u8a2d\u5b9a\n        foreach (ResourceType::cases() as $resourceType) {\n            $this-&gt;permissions[$resourceType-&gt;value] = PermissionFlag::NONE;\n        }\n    }\n    \n    \/\/ \u30ea\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u306b\u5bfe\u3059\u308b\u6a29\u9650\u3092\u8a2d\u5b9a\n    public function setPermission(ResourceType $resourceType, PermissionFlag $permission): void\n    {\n        $this-&gt;permissions[$resourceType-&gt;value] = $permission;\n    }\n    \n    \/\/ \u30ea\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u306b\u5bfe\u3059\u308b\u6a29\u9650\u3092\u53d6\u5f97\n    public function getPermission(ResourceType $resourceType): PermissionFlag\n    {\n        return $this-&gt;permissions[$resourceType-&gt;value] ?? PermissionFlag::NONE;\n    }\n    \n    \/\/ \u30ea\u30bd\u30fc\u30b9\u306b\u5bfe\u3059\u308b\u7279\u5b9a\u306e\u64cd\u4f5c\u304c\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\u304b\u30c1\u30a7\u30c3\u30af\n    public function can(ResourceType $resourceType, PermissionFlag $permission): bool\n    {\n        $resourcePermission = $this-&gt;getPermission($resourceType);\n        return $resourcePermission-&gt;hasFlag($permission);\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$user = new User();\n$user-&gt;setPermission(ResourceType::ARTICLE, PermissionFlag::EDITOR);\n$user-&gt;setPermission(ResourceType::COMMENT, PermissionFlag::MODERATOR);\n\n\/\/ \u6a29\u9650\u30c1\u30a7\u30c3\u30af\nif ($user-&gt;can(ResourceType::ARTICLE, PermissionFlag::EDIT)) {\n    \/\/ \u8a18\u4e8b\u306e\u7de8\u96c6\u304c\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\n}\n\nif (!$user-&gt;can(ResourceType::ARTICLE, PermissionFlag::PUBLISH)) {\n    \/\/ \u8a18\u4e8b\u306e\u516c\u958b\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u306a\u3044\n}\n\nif ($user-&gt;can(ResourceType::COMMENT, PermissionFlag::DELETE)) {\n    \/\/ \u30b3\u30e1\u30f3\u30c8\u306e\u524a\u9664\u304c\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-96\">\u6761\u4ef6\u4ed8\u304d\u6a29\u9650\u30dd\u30ea\u30b7\u30fc\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p>\u7279\u5b9a\u306e\u6761\u4ef6\u306b\u57fa\u3065\u304f\u6a29\u9650\u30c1\u30a7\u30c3\u30af\u3092\u5b9f\u88c5\u3059\u308b\u5834\u5408\u306f\u3001Enum\u3068\u7d44\u307f\u5408\u308f\u305b\u305f\u30dd\u30ea\u30b7\u30fc\u30af\u30e9\u30b9\u304c\u52b9\u679c\u7684\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u62bd\u8c61\u30dd\u30ea\u30b7\u30fc\u30af\u30e9\u30b9\nabstract class Policy\n{\n    abstract public function can(User $user, string $action, object $resource): bool;\n}\n\n\/\/ \u8a18\u4e8b\u306b\u5bfe\u3059\u308b\u30dd\u30ea\u30b7\u30fc\nclass ArticlePolicy extends Policy\n{\n    public function can(User $user, string $action, object $resource): bool\n    {\n        \/\/ \u8a18\u4e8b\u30ea\u30bd\u30fc\u30b9\u306e\u578b\u30c1\u30a7\u30c3\u30af\n        if (!$resource instanceof Article) {\n            return false;\n        }\n        \n        return match($action) {\n            'view' =&gt; true,  \/\/ \u8ab0\u3067\u3082\u95b2\u89a7\u53ef\u80fd\n            'create' =&gt; $user-&gt;hasPermission(Permission::CREATE_CONTENT),\n            'edit' =&gt; $this-&gt;canEdit($user, $resource),\n            'delete' =&gt; $this-&gt;canDelete($user, $resource),\n            'publish' =&gt; $user-&gt;hasPermission(Permission::PUBLISH_CONTENT),\n            default =&gt; false,\n        };\n    }\n    \n    private function canEdit(User $user, Article $article): bool\n    {\n        \/\/ \u81ea\u5206\u306e\u8a18\u4e8b\u304b\u3001\u307e\u305f\u306f\u5168\u3066\u306e\u8a18\u4e8b\u3092\u7de8\u96c6\u3067\u304d\u308b\u6a29\u9650\u304c\u3042\u308b\u304b\n        return $article-&gt;getAuthorId() === $user-&gt;getId() &amp;&amp; $user-&gt;hasPermission(Permission::EDIT_OWN_CONTENT)\n            || $user-&gt;hasPermission(Permission::EDIT_ANY_CONTENT);\n    }\n    \n    private function canDelete(User $user, Article $article): bool\n    {\n        \/\/ \u81ea\u5206\u306e\u8a18\u4e8b\u304b\u3001\u307e\u305f\u306f\u5168\u3066\u306e\u8a18\u4e8b\u3092\u524a\u9664\u3067\u304d\u308b\u6a29\u9650\u304c\u3042\u308b\u304b\n        return $article-&gt;getAuthorId() === $user-&gt;getId() &amp;&amp; $user-&gt;hasPermission(Permission::DELETE_OWN_CONTENT)\n            || $user-&gt;hasPermission(Permission::DELETE_ANY_CONTENT);\n    }\n}\n\n\/\/ \u30dd\u30ea\u30b7\u30fc\u306e\u4f7f\u7528\u4f8b\n$articlePolicy = new ArticlePolicy();\n$canEdit = $articlePolicy-&gt;can($currentUser, 'edit', $article);\n\nif ($canEdit) {\n    \/\/ \u7de8\u96c6\u51e6\u7406\n} else {\n    throw new AuthorizationException('\u3053\u306e\u8a18\u4e8b\u3092\u7de8\u96c6\u3059\u308b\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093');\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-97\">\u6a29\u9650\u30b7\u30b9\u30c6\u30e0\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6a29\u9650\u306e\u7c92\u5ea6\u3092\u9069\u5207\u306b\u8a2d\u8a08\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u7d30\u304b\u3059\u304e\u308b\u3068\u7ba1\u7406\u304c\u8907\u96d1\u306b\u306a\u308a\u3001\u5927\u304d\u3059\u304e\u308b\u3068\u67d4\u8edf\u6027\u304c\u5931\u308f\u308c\u308b<\/li>\n\n\n\n<li>\u30c9\u30e1\u30a4\u30f3\u306b\u5fdc\u3058\u305f\u9069\u5207\u306a\u62bd\u8c61\u5316\u30ec\u30d9\u30eb\u3092\u9078\u629e<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u968e\u5c64\u7684\u306a\u6a29\u9650\u30e2\u30c7\u30eb\u3092\u6d3b\u7528\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u4e0a\u4f4d\u6a29\u9650\u304c\u4e0b\u4f4d\u6a29\u9650\u3092\u5305\u542b\u3059\u308b\u95a2\u4fc2\u3092\u660e\u78ba\u306b\u5b9a\u7fa9<\/li>\n\n\n\n<li>\u6a29\u9650\u30c1\u30a7\u30c3\u30af\u3092\u52b9\u7387\u5316<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u983b\u7e41\u306a\u6a29\u9650\u30c1\u30a7\u30c3\u30af\u306f\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u691c\u8a0e<\/li>\n\n\n\n<li>\u30d3\u30c3\u30c8\u30d5\u30e9\u30b0\u3092\u6d3b\u7528\u3057\u3066\u52b9\u7387\u5316<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027\u3092\u78ba\u4fdd\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u6a29\u9650\u30ed\u30b8\u30c3\u30af\u306e\u5358\u4f53\u30c6\u30b9\u30c8\u3092\u5145\u5b9f\u3055\u305b\u308b<\/li>\n\n\n\n<li>\u30e2\u30c3\u30af\u30e6\u30fc\u30b6\u30fc\u3067\u69d8\u3005\u306a\u30b7\u30ca\u30ea\u30aa\u3092\u30c6\u30b9\u30c8<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u3092\u6d3b\u7528\u3057\u305f\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306f\u3001\u578b\u5b89\u5168\u6027\u3068\u30b3\u30fc\u30c9\u306e\u660e\u78ba\u3055\u3092\u4e21\u7acb\u3057\u3001\u8907\u96d1\u306a\u6a29\u9650\u30ed\u30b8\u30c3\u30af\u3092\u6574\u7406\u3059\u308b\u5f37\u529b\u306a\u30c4\u30fc\u30eb\u3067\u3059\u3002\u9069\u5207\u306b\u8a2d\u8a08\u3059\u308b\u3053\u3068\u3067\u3001\u62e1\u5f35\u6027\u304c\u9ad8\u304f\u3001\u4fdd\u5b88\u3057\u3084\u3059\u3044\u6a29\u9650\u30b7\u30b9\u30c6\u30e0\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-98\">\u6a29\u9650\u7ba1\u7406\u3092Enum\u3067\u5b9f\u88c5\u3059\u308b\u4f8b<\/h3>\n\n\n\n<p>\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u3092Enum\u3067\u5b9f\u88c5\u3059\u308b\u5177\u4f53\u7684\u306a\u4f8b\u3092\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002\u3053\u3053\u3067\u306f\u3001\u30b3\u30f3\u30c6\u30f3\u30c4\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\uff08CMS\uff09\u3092\u60f3\u5b9a\u3057\u305f\u3001\u5b9f\u8df5\u7684\u306a\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u3092\u69cb\u7bc9\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-99\">\u6a29\u9650\u3068\u30e6\u30fc\u30b6\u30fc\u30ed\u30fc\u30eb\u306e\u30e2\u30c7\u30ea\u30f3\u30b0<\/h4>\n\n\n\n<p>\u307e\u305a\u3001\u57fa\u672c\u7684\u306a\u6a29\u9650\u3068\u30ed\u30fc\u30eb\u3092Enum\u578b\u3067\u5b9a\u7fa9\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u500b\u5225\u306e\u6a29\u9650\u3092\u5b9a\u7fa9\u3059\u308bEnum\nenum Permission: string\n{\n    \/\/ \u30b3\u30f3\u30c6\u30f3\u30c4\u95a2\u9023\u306e\u6a29\u9650\n    case VIEW_CONTENT = 'view_content';\n    case CREATE_CONTENT = 'create_content';\n    case EDIT_OWN_CONTENT = 'edit_own_content';\n    case EDIT_ANY_CONTENT = 'edit_any_content';\n    case DELETE_OWN_CONTENT = 'delete_own_content';\n    case DELETE_ANY_CONTENT = 'delete_any_content';\n    case PUBLISH_CONTENT = 'publish_content';\n    \n    \/\/ \u30e1\u30c7\u30a3\u30a2\u95a2\u9023\u306e\u6a29\u9650\n    case UPLOAD_MEDIA = 'upload_media';\n    case MANAGE_MEDIA = 'manage_media';\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u7ba1\u7406\u95a2\u9023\u306e\u6a29\u9650\n    case VIEW_USERS = 'view_users';\n    case MANAGE_USERS = 'manage_users';\n    \n    \/\/ \u30b7\u30b9\u30c6\u30e0\u95a2\u9023\u306e\u6a29\u9650\n    case MANAGE_SETTINGS = 'manage_settings';\n    case VIEW_STATISTICS = 'view_statistics';\n    \n    \/\/ \u8868\u793a\u7528\u30e9\u30d9\u30eb\u3092\u53d6\u5f97\n    public function getLabel(): string\n    {\n        return match($this) {\n            self::VIEW_CONTENT =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u95b2\u89a7',\n            self::CREATE_CONTENT =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u4f5c\u6210',\n            self::EDIT_OWN_CONTENT =&gt; '\u81ea\u5206\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u7de8\u96c6',\n            self::EDIT_ANY_CONTENT =&gt; '\u4efb\u610f\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u7de8\u96c6',\n            self::DELETE_OWN_CONTENT =&gt; '\u81ea\u5206\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u524a\u9664',\n            self::DELETE_ANY_CONTENT =&gt; '\u4efb\u610f\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u524a\u9664',\n            self::PUBLISH_CONTENT =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u516c\u958b',\n            self::UPLOAD_MEDIA =&gt; '\u30e1\u30c7\u30a3\u30a2\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9',\n            self::MANAGE_MEDIA =&gt; '\u30e1\u30c7\u30a3\u30a2\u7ba1\u7406',\n            self::VIEW_USERS =&gt; '\u30e6\u30fc\u30b6\u30fc\u95b2\u89a7',\n            self::MANAGE_USERS =&gt; '\u30e6\u30fc\u30b6\u30fc\u7ba1\u7406',\n            self::MANAGE_SETTINGS =&gt; '\u30b7\u30b9\u30c6\u30e0\u8a2d\u5b9a\u7ba1\u7406',\n            self::VIEW_STATISTICS =&gt; '\u7d71\u8a08\u60c5\u5831\u95b2\u89a7',\n        };\n    }\n}\n\n\/\/ \u30e6\u30fc\u30b6\u30fc\u30ed\u30fc\u30eb\u3092\u5b9a\u7fa9\u3059\u308bEnum\nenum UserRole: string\n{\n    case ADMIN = 'admin';\n    case EDITOR = 'editor';\n    case AUTHOR = 'author';\n    case CONTRIBUTOR = 'contributor';\n    case SUBSCRIBER = 'subscriber';\n    \n    \/\/ \u30ed\u30fc\u30eb\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u308b\u6a29\u9650\u306e\u914d\u5217\u3092\u53d6\u5f97\n    public function getPermissions(): array\n    {\n        return match($this) {\n            self::ADMIN =&gt; [\n                Permission::VIEW_CONTENT,\n                Permission::CREATE_CONTENT,\n                Permission::EDIT_ANY_CONTENT,\n                Permission::DELETE_ANY_CONTENT,\n                Permission::PUBLISH_CONTENT,\n                Permission::UPLOAD_MEDIA,\n                Permission::MANAGE_MEDIA,\n                Permission::VIEW_USERS,\n                Permission::MANAGE_USERS,\n                Permission::MANAGE_SETTINGS,\n                Permission::VIEW_STATISTICS,\n            ],\n            self::EDITOR =&gt; [\n                Permission::VIEW_CONTENT,\n                Permission::CREATE_CONTENT,\n                Permission::EDIT_ANY_CONTENT,\n                Permission::DELETE_ANY_CONTENT,\n                Permission::PUBLISH_CONTENT,\n                Permission::UPLOAD_MEDIA,\n                Permission::MANAGE_MEDIA,\n                Permission::VIEW_USERS,\n                Permission::VIEW_STATISTICS,\n            ],\n            self::AUTHOR =&gt; [\n                Permission::VIEW_CONTENT,\n                Permission::CREATE_CONTENT,\n                Permission::EDIT_OWN_CONTENT,\n                Permission::DELETE_OWN_CONTENT,\n                Permission::UPLOAD_MEDIA,\n                Permission::VIEW_STATISTICS,\n            ],\n            self::CONTRIBUTOR =&gt; [\n                Permission::VIEW_CONTENT,\n                Permission::CREATE_CONTENT,\n                Permission::EDIT_OWN_CONTENT,\n                Permission::UPLOAD_MEDIA,\n            ],\n            self::SUBSCRIBER =&gt; [\n                Permission::VIEW_CONTENT,\n            ],\n        };\n    }\n    \n    \/\/ \u8868\u793a\u7528\u30e9\u30d9\u30eb\u3092\u53d6\u5f97\n    public function getLabel(): string\n    {\n        return match($this) {\n            self::ADMIN =&gt; '\u7ba1\u7406\u8005',\n            self::EDITOR =&gt; '\u7de8\u96c6\u8005',\n            self::AUTHOR =&gt; '\u8457\u8005',\n            self::CONTRIBUTOR =&gt; '\u5bc4\u7a3f\u8005',\n            self::SUBSCRIBER =&gt; '\u8cfc\u8aad\u8005',\n        };\n    }\n    \n    \/\/ \u7279\u5b9a\u306e\u6a29\u9650\u3092\u6301\u3063\u3066\u3044\u308b\u304b\u30c1\u30a7\u30c3\u30af\n    public function hasPermission(Permission $permission): bool\n    {\n        return in_array($permission, $this-&gt;getPermissions());\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-100\">\u30e6\u30fc\u30b6\u30fc\u6a29\u9650\u30de\u30cd\u30fc\u30b8\u30e3\u30fc\u306e\u5b9f\u88c5<\/h4>\n\n\n\n<p>\u6b21\u306b\u3001\u8907\u6570\u306e\u30ed\u30fc\u30eb\u3092\u6301\u3064\u30e6\u30fc\u30b6\u30fc\u3092\u30b5\u30dd\u30fc\u30c8\u3059\u308b\u305f\u3081\u306e\u6a29\u9650\u30de\u30cd\u30fc\u30b8\u30e3\u30fc\u3092\u5b9f\u88c5\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class PermissionManager\n{\n    private array $userRoles = [];\n    private array $customPermissions = [];\n    private array $permissionCache = [];\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u306b\u30ed\u30fc\u30eb\u3092\u5272\u308a\u5f53\u3066\n    public function assignRoleToUser(int $userId, UserRole $role): void\n    {\n        if (!isset($this-&gt;userRoles[$userId])) {\n            $this-&gt;userRoles[$userId] = [];\n        }\n        \n        $this-&gt;userRoles[$userId][] = $role;\n        \n        \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u30af\u30ea\u30a2\n        unset($this-&gt;permissionCache[$userId]);\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u306b\u30ab\u30b9\u30bf\u30e0\u6a29\u9650\u3092\u5272\u308a\u5f53\u3066\n    public function assignPermissionToUser(int $userId, Permission $permission, bool $granted = true): void\n    {\n        if (!isset($this-&gt;customPermissions[$userId])) {\n            $this-&gt;customPermissions[$userId] = [];\n        }\n        \n        $this-&gt;customPermissions[$userId][$permission-&gt;value] = $granted;\n        \n        \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u30af\u30ea\u30a2\n        unset($this-&gt;permissionCache[$userId]);\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u304c\u7279\u5b9a\u306e\u6a29\u9650\u3092\u6301\u3063\u3066\u3044\u308b\u304b\u30c1\u30a7\u30c3\u30af\n    public function userHasPermission(int $userId, Permission $permission): bool\n    {\n        \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u304b\u3089\u7d50\u679c\u3092\u53d6\u5f97\n        if (isset($this-&gt;permissionCache[$userId][$permission-&gt;value])) {\n            return $this-&gt;permissionCache[$userId][$permission-&gt;value];\n        }\n        \n        \/\/ \u30ab\u30b9\u30bf\u30e0\u6a29\u9650\u3092\u30c1\u30a7\u30c3\u30af\uff08\u660e\u793a\u7684\u306a\u62d2\u5426\u304c\u512a\u5148\uff09\n        if (isset($this-&gt;customPermissions[$userId][$permission-&gt;value]) &amp;&amp; \n            $this-&gt;customPermissions[$userId][$permission-&gt;value] === false) {\n            $result = false;\n            $this-&gt;cachePermissionResult($userId, $permission, $result);\n            return $result;\n        }\n        \n        \/\/ \u30ab\u30b9\u30bf\u30e0\u6a29\u9650\u3067\u4ed8\u4e0e\u3055\u308c\u3066\u3044\u308b\u304b\u30c1\u30a7\u30c3\u30af\n        if (isset($this-&gt;customPermissions[$userId][$permission-&gt;value]) &amp;&amp; \n            $this-&gt;customPermissions[$userId][$permission-&gt;value] === true) {\n            $result = true;\n            $this-&gt;cachePermissionResult($userId, $permission, $result);\n            return $result;\n        }\n        \n        \/\/ \u30ed\u30fc\u30eb\u306b\u57fa\u3065\u3044\u3066\u6a29\u9650\u3092\u30c1\u30a7\u30c3\u30af\n        if (isset($this-&gt;userRoles[$userId])) {\n            foreach ($this-&gt;userRoles[$userId] as $role) {\n                if ($role-&gt;hasPermission($permission)) {\n                    $result = true;\n                    $this-&gt;cachePermissionResult($userId, $permission, $result);\n                    return $result;\n                }\n            }\n        }\n        \n        $result = false;\n        $this-&gt;cachePermissionResult($userId, $permission, $result);\n        return $result;\n    }\n    \n    \/\/ \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u5411\u4e0a\u306e\u305f\u3081\u306b\u7d50\u679c\u3092\u30ad\u30e3\u30c3\u30b7\u30e5\n    private function cachePermissionResult(int $userId, Permission $permission, bool $result): void\n    {\n        if (!isset($this-&gt;permissionCache[$userId])) {\n            $this-&gt;permissionCache[$userId] = [];\n        }\n        \n        $this-&gt;permissionCache[$userId][$permission-&gt;value] = $result;\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-101\">\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u4f9d\u5b58\u306e\u6a29\u9650\u30c1\u30a7\u30c3\u30af<\/h4>\n\n\n\n<p>\u3088\u308a\u8907\u96d1\u306a\u30b1\u30fc\u30b9\u3067\u306f\u3001\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\uff08\u30ea\u30bd\u30fc\u30b9\u306e\u6240\u6709\u6a29\u306a\u3069\uff09\u306b\u5fdc\u3058\u305f\u6a29\u9650\u30c1\u30a7\u30c3\u30af\u304c\u5fc5\u8981\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class ContentAuthorization\n{\n    private PermissionManager $permissionManager;\n    \n    public function __construct(PermissionManager $permissionManager)\n    {\n        $this-&gt;permissionManager = $permissionManager;\n    }\n    \n    \/\/ \u30b3\u30f3\u30c6\u30f3\u30c4\u306b\u5bfe\u3059\u308b\u64cd\u4f5c\u304c\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\u304b\u30c1\u30a7\u30c3\u30af\n    public function canPerformOnContent(int $userId, string $action, Content $content): bool\n    {\n        return match($action) {\n            'view' =&gt; $this-&gt;canViewContent($userId, $content),\n            'edit' =&gt; $this-&gt;canEditContent($userId, $content),\n            'delete' =&gt; $this-&gt;canDeleteContent($userId, $content),\n            'publish' =&gt; $this-&gt;canPublishContent($userId, $content),\n            default =&gt; false,\n        };\n    }\n    \n    private function canViewContent(int $userId, Content $content): bool\n    {\n        \/\/ \u516c\u958b\u6e08\u307f\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u95b2\u89a7\u53ef\u80fd\n        if ($content-&gt;isPublished()) {\n            return $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::VIEW_CONTENT);\n        }\n        \n        \/\/ \u672a\u516c\u958b\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u7de8\u96c6\u6a29\u9650\u304c\u3042\u308c\u3070\u95b2\u89a7\u53ef\u80fd\n        return $this-&gt;canEditContent($userId, $content);\n    }\n    \n    private function canEditContent(int $userId, Content $content): bool\n    {\n        \/\/ \u4efb\u610f\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u7de8\u96c6\u6a29\u9650\n        if ($this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::EDIT_ANY_CONTENT)) {\n            return true;\n        }\n        \n        \/\/ \u81ea\u5206\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u7de8\u96c6\u6a29\u9650\n        return $content-&gt;getAuthorId() === $userId &amp;&amp; \n               $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::EDIT_OWN_CONTENT);\n    }\n    \n    private function canDeleteContent(int $userId, Content $content): bool\n    {\n        \/\/ \u4efb\u610f\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u524a\u9664\u6a29\u9650\n        if ($this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::DELETE_ANY_CONTENT)) {\n            return true;\n        }\n        \n        \/\/ \u81ea\u5206\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u524a\u9664\u6a29\u9650\n        return $content-&gt;getAuthorId() === $userId &amp;&amp; \n               $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::DELETE_OWN_CONTENT);\n    }\n    \n    private function canPublishContent(int $userId, Content $content): bool\n    {\n        return $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::PUBLISH_CONTENT);\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-102\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u306e\u9023\u643a<\/h4>\n\n\n\n<p>\u6a29\u9650\u60c5\u5831\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u4fdd\u5b58\u3059\u308b\u5834\u5408\u306e\u5b9f\u88c5\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class PermissionRepository\n{\n    private PDO $pdo;\n    \n    public function __construct(PDO $pdo)\n    {\n        $this-&gt;pdo = $pdo;\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u306e\u30ed\u30fc\u30eb\u3092\u4fdd\u5b58\n    public function saveUserRole(int $userId, UserRole $role): void\n    {\n        $stmt = $this-&gt;pdo-&gt;prepare(\n            'INSERT INTO user_roles (user_id, role) VALUES (?, ?) \n             ON DUPLICATE KEY UPDATE role = ?'\n        );\n        \n        $stmt-&gt;execute([$userId, $role-&gt;value, $role-&gt;value]);\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u306e\u30ab\u30b9\u30bf\u30e0\u6a29\u9650\u3092\u4fdd\u5b58\n    public function saveUserPermission(int $userId, Permission $permission, bool $granted): void\n    {\n        $stmt = $this-&gt;pdo-&gt;prepare(\n            'INSERT INTO user_permissions (user_id, permission, granted) VALUES (?, ?, ?) \n             ON DUPLICATE KEY UPDATE granted = ?'\n        );\n        \n        $stmt-&gt;execute([$userId, $permission-&gt;value, $granted ? 1 : 0, $granted ? 1 : 0]);\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u306e\u30ed\u30fc\u30eb\u3092\u8aad\u307f\u8fbc\u307f\n    public function loadUserRoles(int $userId): array\n    {\n        $stmt = $this-&gt;pdo-&gt;prepare('SELECT role FROM user_roles WHERE user_id = ?');\n        $stmt-&gt;execute([$userId]);\n        \n        $roles = [];\n        while ($row = $stmt-&gt;fetch(PDO::FETCH_ASSOC)) {\n            try {\n                $roles[] = UserRole::from($row['role']);\n            } catch (\\ValueError $e) {\n                \/\/ \u7121\u52b9\u306a\u30ed\u30fc\u30eb\u5024\u306f\u30b9\u30ad\u30c3\u30d7\n                error_log(\"Invalid role value: {$row['role']}\");\n            }\n        }\n        \n        return $roles;\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u306e\u30ab\u30b9\u30bf\u30e0\u6a29\u9650\u3092\u8aad\u307f\u8fbc\u307f\n    public function loadUserPermissions(int $userId): array\n    {\n        $stmt = $this-&gt;pdo-&gt;prepare('SELECT permission, granted FROM user_permissions WHERE user_id = ?');\n        $stmt-&gt;execute([$userId]);\n        \n        $permissions = [];\n        while ($row = $stmt-&gt;fetch(PDO::FETCH_ASSOC)) {\n            try {\n                $permission = Permission::from($row['permission']);\n                $permissions[$permission-&gt;value] = (bool)$row['granted'];\n            } catch (\\ValueError $e) {\n                \/\/ \u7121\u52b9\u306a\u6a29\u9650\u5024\u306f\u30b9\u30ad\u30c3\u30d7\n                error_log(\"Invalid permission value: {$row['permission']}\");\n            }\n        }\n        \n        return $permissions;\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-103\">\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306e\u4f7f\u7528\u4f8b<\/h4>\n\n\n\n<p>\u5b9f\u969b\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u3053\u306e\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u3092\u4f7f\u7528\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306e\u4f7f\u7528\u4f8b\nclass ApplicationService\n{\n    private PermissionManager $permissionManager;\n    private ContentAuthorization $contentAuth;\n    private PermissionRepository $permissionRepo;\n    \n    public function __construct(\n        PermissionManager $permissionManager,\n        ContentAuthorization $contentAuth,\n        PermissionRepository $permissionRepo\n    ) {\n        $this-&gt;permissionManager = $permissionManager;\n        $this-&gt;contentAuth = $contentAuth;\n        $this-&gt;permissionRepo = $permissionRepo;\n    }\n    \n    \/\/ \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u8d77\u52d5\u6642\u306b\u30e6\u30fc\u30b6\u30fc\u6a29\u9650\u3092\u8aad\u307f\u8fbc\u307f\n    public function initializeUserPermissions(int $userId): void\n    {\n        \/\/ \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u30ed\u30fc\u30eb\u3068\u30ab\u30b9\u30bf\u30e0\u6a29\u9650\u3092\u8aad\u307f\u8fbc\u307f\n        $roles = $this-&gt;permissionRepo-&gt;loadUserRoles($userId);\n        $customPermissions = $this-&gt;permissionRepo-&gt;loadUserPermissions($userId);\n        \n        \/\/ \u6a29\u9650\u30de\u30cd\u30fc\u30b8\u30e3\u30fc\u306b\u8a2d\u5b9a\n        foreach ($roles as $role) {\n            $this-&gt;permissionManager-&gt;assignRoleToUser($userId, $role);\n        }\n        \n        foreach ($customPermissions as $permissionName =&gt; $granted) {\n            $permission = Permission::from($permissionName);\n            $this-&gt;permissionManager-&gt;assignPermissionToUser($userId, $permission, $granted);\n        }\n    }\n    \n    \/\/ \u30b3\u30f3\u30c6\u30f3\u30c4\u7de8\u96c6\u30da\u30fc\u30b8\u3078\u306e\u30a2\u30af\u30bb\u30b9\u5236\u5fa1\n    public function handleEditContentRequest(int $userId, int $contentId): Response\n    {\n        $content = $this-&gt;contentRepository-&gt;findById($contentId);\n        \n        if (!$content) {\n            return new Response('Content not found', 404);\n        }\n        \n        if (!$this-&gt;contentAuth-&gt;canPerformOnContent($userId, 'edit', $content)) {\n            return new Response('Permission denied', 403);\n        }\n        \n        \/\/ \u6a29\u9650\u30c1\u30a7\u30c3\u30af\u306b\u901a\u904e\u3057\u305f\u5834\u5408\u3001\u7de8\u96c6\u30da\u30fc\u30b8\u3092\u8868\u793a\n        return new Response(\n            $this-&gt;renderEditForm($content)\n        );\n    }\n    \n    \/\/ \u7ba1\u7406\u753b\u9762\u30e1\u30cb\u30e5\u30fc\u306e\u6a29\u9650\u306b\u57fa\u3065\u304f\u8868\u793a\u5236\u5fa1\n    public function buildAdminMenu(int $userId): array\n    {\n        $menu = [];\n        \n        \/\/ \u57fa\u672c\u7684\u306a\u30e1\u30cb\u30e5\u30fc\u9805\u76ee\n        $menu[] = [\n            'title' =&gt; '\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9',\n            'url' =&gt; '\/admin\/dashboard',\n            'visible' =&gt; true \/\/ \u5e38\u306b\u8868\u793a\n        ];\n        \n        \/\/ \u30b3\u30f3\u30c6\u30f3\u30c4\u7ba1\u7406\u30e1\u30cb\u30e5\u30fc\n        $menu[] = [\n            'title' =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u7ba1\u7406',\n            'url' =&gt; '\/admin\/content',\n            'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::VIEW_CONTENT),\n            'children' =&gt; [\n                [\n                    'title' =&gt; '\u65b0\u898f\u4f5c\u6210',\n                    'url' =&gt; '\/admin\/content\/create',\n                    'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::CREATE_CONTENT)\n                ],\n                [\n                    'title' =&gt; '\u30b3\u30f3\u30c6\u30f3\u30c4\u4e00\u89a7',\n                    'url' =&gt; '\/admin\/content\/list',\n                    'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::VIEW_CONTENT)\n                ]\n            ]\n        ];\n        \n        \/\/ \u30e1\u30c7\u30a3\u30a2\u7ba1\u7406\u30e1\u30cb\u30e5\u30fc\n        $menu[] = [\n            'title' =&gt; '\u30e1\u30c7\u30a3\u30a2\u7ba1\u7406',\n            'url' =&gt; '\/admin\/media',\n            'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::UPLOAD_MEDIA),\n            'children' =&gt; [\n                [\n                    'title' =&gt; '\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9',\n                    'url' =&gt; '\/admin\/media\/upload',\n                    'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::UPLOAD_MEDIA)\n                ],\n                [\n                    'title' =&gt; '\u30e1\u30c7\u30a3\u30a2\u30e9\u30a4\u30d6\u30e9\u30ea',\n                    'url' =&gt; '\/admin\/media\/library',\n                    'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::MANAGE_MEDIA)\n                ]\n            ]\n        ];\n        \n        \/\/ \u30e6\u30fc\u30b6\u30fc\u7ba1\u7406\u30e1\u30cb\u30e5\u30fc\uff08\u7ba1\u7406\u8005\u306e\u307f\uff09\n        $menu[] = [\n            'title' =&gt; '\u30e6\u30fc\u30b6\u30fc\u7ba1\u7406',\n            'url' =&gt; '\/admin\/users',\n            'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::VIEW_USERS),\n            'children' =&gt; [\n                [\n                    'title' =&gt; '\u30e6\u30fc\u30b6\u30fc\u4e00\u89a7',\n                    'url' =&gt; '\/admin\/users\/list',\n                    'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::VIEW_USERS)\n                ],\n                [\n                    'title' =&gt; '\u65b0\u898f\u30e6\u30fc\u30b6\u30fc\u8ffd\u52a0',\n                    'url' =&gt; '\/admin\/users\/create',\n                    'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::MANAGE_USERS)\n                ],\n                [\n                    'title' =&gt; '\u6a29\u9650\u8a2d\u5b9a',\n                    'url' =&gt; '\/admin\/users\/permissions',\n                    'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::MANAGE_USERS)\n                ]\n            ]\n        ];\n        \n        \/\/ \u30b7\u30b9\u30c6\u30e0\u8a2d\u5b9a\u30e1\u30cb\u30e5\u30fc\uff08\u7ba1\u7406\u8005\u306e\u307f\uff09\n        $menu[] = [\n            'title' =&gt; '\u30b7\u30b9\u30c6\u30e0\u8a2d\u5b9a',\n            'url' =&gt; '\/admin\/settings',\n            'visible' =&gt; $this-&gt;permissionManager-&gt;userHasPermission($userId, Permission::MANAGE_SETTINGS)\n        ];\n        \n        return array_filter($menu, fn($item) =&gt; $item['visible']);\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-104\">\u6a29\u9650\u30b7\u30b9\u30c6\u30e0\u306e\u69cb\u7bc9\u306b\u95a2\u3059\u308b\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b7\u30f3\u30d7\u30eb\u3055\u3068\u62e1\u5f35\u6027\u306e\u30d0\u30e9\u30f3\u30b9<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u521d\u671f\u8a2d\u8a08\u306f\u5fc5\u8981\u6700\u4f4e\u9650\u306b\u3057\u3001\u5f8c\u304b\u3089\u306e\u62e1\u5f35\u3092\u5bb9\u6613\u306b\u3059\u308b<\/li>\n\n\n\n<li>\u30af\u30e9\u30b9\u5b9a\u6570\u3067\u306f\u306a\u304fEnum\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u578b\u5b89\u5168\u6027\u3092\u78ba\u4fdd<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u6a29\u9650\u30c1\u30a7\u30c3\u30af\u306f\u9ad8\u983b\u5ea6\u3067\u884c\u308f\u308c\u308b\u305f\u3081\u3001\u30ad\u30e3\u30c3\u30b7\u30f3\u30b0\u3092\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30d3\u30c3\u30c8\u30d5\u30e9\u30b0\u3092\u4f7f\u3063\u305f\u52b9\u7387\u7684\u306a\u6a29\u9650\u8868\u73fe\uff08\u591a\u6570\u306e\u6a29\u9650\u304c\u3042\u308b\u5834\u5408\uff09<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u3068\u691c\u8a3c<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u69d8\u3005\u306a\u30e6\u30fc\u30b6\u30fc\u30ed\u30fc\u30eb\u3068\u72b6\u6cc1\u3092\u60f3\u5b9a\u3057\u305f\u5358\u4f53\u30c6\u30b9\u30c8\u306e\u4f5c\u6210<\/li>\n\n\n\n<li>\u30a8\u30c3\u30b8\u30b1\u30fc\u30b9\u3067\u306e\u6319\u52d5\u3092\u691c\u8a3c<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u610f\u8b58<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u300c\u62d2\u5426\u300d\u3057\u3001\u660e\u793a\u7684\u306b\u8a31\u53ef\u3059\u308b\u8a2d\u8a08<\/li>\n\n\n\n<li>\u6a29\u9650\u5909\u66f4\u306b\u306f\u76e3\u67fb\u30ed\u30b0\u3092\u6b8b\u3059\u4ed5\u7d44\u307f<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u306e\u5404\u30b1\u30fc\u30b9\u306b\u30b3\u30e1\u30f3\u30c8\u3092\u5145\u5b9f\u3055\u305b\u3001\u81ea\u5df1\u6587\u66f8\u5316\u30b3\u30fc\u30c9\u306b<\/li>\n\n\n\n<li>\u6a29\u9650\u30de\u30c3\u30d7\u306e\u8996\u899a\u5316\u3068\u5171\u6709<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u3092\u6d3b\u7528\u3057\u305f\u6a29\u9650\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306f\u3001\u578b\u5b89\u5168\u6027\u3068\u660e\u78ba\u306a\u30b3\u30fc\u30c9\u69cb\u9020\u306b\u3088\u3063\u3066\u3001\u8907\u96d1\u306a\u6a29\u9650\u30ed\u30b8\u30c3\u30af\u3092\u7ba1\u7406\u53ef\u80fd\u306b\u3057\u307e\u3059\u3002\u5805\u7262\u3067\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u306e\u9ad8\u3044\u6a29\u9650\u30b7\u30b9\u30c6\u30e0\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u9577\u671f\u7684\u306a\u9032\u5316\u3068\u54c1\u8cea\u5411\u4e0a\u306b\u5927\u304d\u304f\u8ca2\u732e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-105\">\u8907\u96d1\u306a\u6761\u4ef6\u5206\u5c90\u3092Enum\u3067\u30af\u30ea\u30fc\u30f3\u306b\u66f8\u304f\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u8907\u96d1\u306a\u6761\u4ef6\u5206\u5c90\u306f\u3001\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u3001\u4fdd\u5b88\u6027\u3001\u30c6\u30b9\u30c8\u5bb9\u6613\u6027\u3092\u4f4e\u4e0b\u3055\u305b\u308b\u4e3b\u8981\u306a\u8981\u56e0\u306e\u4e00\u3064\u3067\u3059\u3002PHP Enum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u8907\u96d1\u306a\u6761\u4ef6\u30ed\u30b8\u30c3\u30af\u3092\u30af\u30ea\u30fc\u30f3\u3067\u578b\u5b89\u5168\u3001\u304b\u3064\u62e1\u5f35\u3057\u3084\u3059\u3044\u5f62\u3067\u5b9f\u88c5\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-106\">\u6761\u4ef6\u5206\u5c90\u306e\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3<\/h4>\n\n\n\n<p>\u307e\u305a\u3001\u8907\u96d1\u306a\u6761\u4ef6\u5206\u5c90\u306e\u5178\u578b\u7684\u306a\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3092\u898b\u3066\u307f\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u5f93\u6765\u306e\u8907\u96d1\u306a\u6761\u4ef6\u5206\u5c90\uff08\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\uff09\nfunction calculateShippingCost($country, $weight, $method, $isPriority)\n{\n    \/\/ \u56fd\u306b\u57fa\u3065\u304f\u57fa\u672c\u6599\u91d1\n    if ($country === 'JP') {\n        $baseCost = 1000;\n    } elseif ($country === 'US') {\n        $baseCost = 2500;\n    } elseif (in_array($country, ['GB', 'FR', 'DE', 'IT', 'ES'])) {\n        $baseCost = 3000;\n    } else {\n        $baseCost = 4000;\n    }\n    \n    \/\/ \u914d\u9001\u65b9\u6cd5\u306b\u3088\u308b\u4fc2\u6570\n    if ($method === 'air') {\n        $methodFactor = 1.5;\n    } elseif ($method === 'sea') {\n        $methodFactor = 0.8;\n    } elseif ($method === 'land') {\n        if (in_array($country, ['JP', 'CN', 'KR', 'TW'])) {\n            \/\/ \u30a2\u30b8\u30a2\u5730\u57df\u306e\u9678\u9001\n            $methodFactor = 0.7;\n        } else {\n            $methodFactor = 1.0;\n        }\n    } else {\n        $methodFactor = 1.0;\n    }\n    \n    \/\/ \u91cd\u91cf\u306b\u3088\u308b\u8ffd\u52a0\u6599\u91d1\n    if ($weight &lt;= 1) {\n        $weightCost = 0;\n    } elseif ($weight &lt;= 5) {\n        $weightCost = 500;\n    } elseif ($weight &lt;= 10) {\n        $weightCost = 1000;\n    } elseif ($weight &lt;= 20) {\n        $weightCost = 2000;\n    } else {\n        $weightCost = 3000 + ($weight - 20) * 100;\n    }\n    \n    \/\/ \u512a\u5148\u914d\u9001\u306e\u8ffd\u52a0\u6599\u91d1\n    if ($isPriority) {\n        if ($method === 'air') {\n            $priorityFee = 2000;\n        } elseif ($method === 'sea') {\n            $priorityFee = 3000;\n        } else {\n            $priorityFee = 1500;\n        }\n    } else {\n        $priorityFee = 0;\n    }\n    \n    return $baseCost * $methodFactor + $weightCost + $priorityFee;\n}\n<\/pre>\n\n\n\n<p>\u3053\u306e\u30b3\u30fc\u30c9\u306b\u306f\u4ee5\u4e0b\u306e\u554f\u984c\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u53ef\u8aad\u6027\u306e\u4f4e\u3055<\/strong> \u2013 \u5165\u308c\u5b50\u306e\u6761\u4ef6\u5206\u5c90\u304c\u7406\u89e3\u3092\u56f0\u96e3\u306b\u3057\u3066\u3044\u308b<\/li>\n\n\n\n<li><strong>\u62e1\u5f35\u6027\u306e\u6b20\u5982<\/strong> \u2013 \u65b0\u3057\u3044\u6761\u4ef6\u306e\u8ffd\u52a0\u304c\u8907\u6570\u7b87\u6240\u3067\u306e\u5909\u66f4\u3092\u8981\u6c42\u3059\u308b<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u306e\u96e3\u3057\u3055<\/strong> \u2013 \u5168\u3066\u306e\u6761\u4ef6\u306e\u7d44\u307f\u5408\u308f\u305b\u3092\u30c6\u30b9\u30c8\u3059\u308b\u306e\u304c\u56f0\u96e3<\/li>\n\n\n\n<li><strong>\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u5206\u6563<\/strong> \u2013 \u95a2\u9023\u3059\u308b\u8ad6\u7406\u304c\u5206\u6563\u3057\u3066\u3044\u308b<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-107\">Enum\u3092\u4f7f\u3063\u305f\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0<\/h4>\n\n\n\n<p>\u3053\u308c\u3092Enum\u3092\u4f7f\u3063\u3066\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u56fd\/\u5730\u57df\u3092Enum\u3067\u8868\u73fe\nenum ShippingRegion: string\n{\n    case JAPAN = 'JP';\n    case USA = 'US';\n    case EU = 'EU';     \/\/ EU\u3092\u30b0\u30eb\u30fc\u30d7\u5316\n    case OTHER = 'OTHER';\n    \n    \/\/ \u56fd\u30b3\u30fc\u30c9\u304b\u3089Region\u3092\u53d6\u5f97\n    public static function fromCountryCode(string $countryCode): self\n    {\n        if ($countryCode === 'JP') {\n            return self::JAPAN;\n        } elseif ($countryCode === 'US') {\n            return self::USA;\n        } elseif (in_array($countryCode, ['GB', 'FR', 'DE', 'IT', 'ES'])) {\n            return self::EU;\n        } else {\n            return self::OTHER;\n        }\n    }\n    \n    \/\/ \u57fa\u672c\u6599\u91d1\u3092\u53d6\u5f97\n    public function getBaseCost(): int\n    {\n        return match($this) {\n            self::JAPAN =&gt; 1000,\n            self::USA =&gt; 2500,\n            self::EU =&gt; 3000,\n            self::OTHER =&gt; 4000,\n        };\n    }\n    \n    \/\/ \u30a2\u30b8\u30a2\u5730\u57df\u304b\u3069\u3046\u304b\u3092\u5224\u5b9a\n    public function isAsiaRegion(): bool\n    {\n        return $this === self::JAPAN;\n    }\n}\n\n\/\/ \u914d\u9001\u65b9\u6cd5\u3092Enum\u3067\u8868\u73fe\nenum ShippingMethod: string\n{\n    case AIR = 'air';\n    case SEA = 'sea';\n    case LAND = 'land';\n    \n    \/\/ \u5730\u57df\u3054\u3068\u306e\u4fc2\u6570\u3092\u53d6\u5f97\n    public function getMethodFactor(ShippingRegion $region): float\n    {\n        return match($this) {\n            self::AIR =&gt; 1.5,\n            self::SEA =&gt; 0.8,\n            self::LAND =&gt; $region-&gt;isAsiaRegion() ? 0.7 : 1.0\n        };\n    }\n    \n    \/\/ \u512a\u5148\u914d\u9001\u306e\u8ffd\u52a0\u6599\u91d1\u3092\u53d6\u5f97\n    public function getPriorityFee(): int\n    {\n        return match($this) {\n            self::AIR =&gt; 2000,\n            self::SEA =&gt; 3000,\n            self::LAND =&gt; 1500\n        };\n    }\n}\n\n\/\/ \u91cd\u91cf\u30ab\u30c6\u30b4\u30ea\u3092Enum\u3067\u8868\u73fe\nenum WeightCategory\n{\n    case LIGHT;       \/\/ 0-1kg\n    case MEDIUM;      \/\/ 1-5kg\n    case HEAVY;       \/\/ 5-10kg\n    case VERY_HEAVY;  \/\/ 10-20kg\n    case OVERSIZE;    \/\/ 20kg\u4ee5\u4e0a\n    \n    \/\/ \u91cd\u91cf\u304b\u3089\u9069\u5207\u306a\u30ab\u30c6\u30b4\u30ea\u3092\u53d6\u5f97\n    public static function fromWeight(float $weight): self\n    {\n        if ($weight &lt;= 1) {\n            return self::LIGHT;\n        } elseif ($weight &lt;= 5) {\n            return self::MEDIUM;\n        } elseif ($weight &lt;= 10) {\n            return self::HEAVY;\n        } elseif ($weight &lt;= 20) {\n            return self::VERY_HEAVY;\n        } else {\n            return self::OVERSIZE;\n        }\n    }\n    \n    \/\/ \u91cd\u91cf\u8ffd\u52a0\u6599\u91d1\u3092\u8a08\u7b97\n    public function calculateWeightCost(float $weight): int\n    {\n        return match($this) {\n            self::LIGHT =&gt; 0,\n            self::MEDIUM =&gt; 500,\n            self::HEAVY =&gt; 1000,\n            self::VERY_HEAVY =&gt; 2000,\n            self::OVERSIZE =&gt; 3000 + (int)(($weight - 20) * 100)\n        };\n    }\n}\n\n\/\/ \u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u5f8c\u306e\u6599\u91d1\u8a08\u7b97\u95a2\u6570\nfunction calculateShippingCost(string $country, float $weight, string $methodString, bool $isPriority): int\n{\n    \/\/ \u5165\u529b\u5024\u3092Enum\u578b\u306b\u5909\u63db\n    $region = ShippingRegion::fromCountryCode($country);\n    $method = ShippingMethod::from($methodString);\n    $weightCategory = WeightCategory::fromWeight($weight);\n    \n    \/\/ \u57fa\u672c\u6599\u91d1\u3092\u8a08\u7b97\n    $baseCost = $region-&gt;getBaseCost();\n    \n    \/\/ \u914d\u9001\u65b9\u6cd5\u306b\u3088\u308b\u4fc2\u6570\u3092\u9069\u7528\n    $adjustedBaseCost = (int)($baseCost * $method-&gt;getMethodFactor($region));\n    \n    \/\/ \u91cd\u91cf\u306b\u3088\u308b\u8ffd\u52a0\u6599\u91d1\n    $weightCost = $weightCategory-&gt;calculateWeightCost($weight);\n    \n    \/\/ \u512a\u5148\u914d\u9001\u306e\u8ffd\u52a0\u6599\u91d1\n    $priorityFee = $isPriority ? $method-&gt;getPriorityFee() : 0;\n    \n    return $adjustedBaseCost + $weightCost + $priorityFee;\n}\n<\/pre>\n\n\n\n<p>\u3053\u306e\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306b\u306f\u4ee5\u4e0b\u306e\u30e1\u30ea\u30c3\u30c8\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u53ef\u8aad\u6027\u306e\u5411\u4e0a<\/strong> \u2013 \u5404\u30ed\u30b8\u30c3\u30af\u304c\u8ad6\u7406\u7684\u306a\u5358\u4f4d\u306b\u5206\u96e2\u3055\u308c\u3066\u3044\u308b<\/li>\n\n\n\n<li><strong>\u578b\u5b89\u5168\u6027<\/strong> \u2013 Enum\u306e\u4f7f\u7528\u306b\u3088\u308a\u578b\u5b89\u5168\u6027\u304c\u4fdd\u8a3c\u3055\u308c\u308b<\/li>\n\n\n\n<li><strong>\u62e1\u5f35\u6027<\/strong> \u2013 \u65b0\u3057\u3044\u5730\u57df\u3084\u914d\u9001\u65b9\u6cd5\u306e\u8ffd\u52a0\u304c\u5bb9\u6613<\/li>\n\n\n\n<li><strong>\u4fdd\u5b88\u6027<\/strong> \u2013 \u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306e\u5909\u66f4\u304c\u8a72\u5f53\u3059\u308b\u7b87\u6240\u306e\u307f\u306b\u5f71\u97ff<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027<\/strong> \u2013 \u5404Enum\u3092\u500b\u5225\u306b\u30c6\u30b9\u30c8\u53ef\u80fd<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-108\">\u8907\u96d1\u306a\u6761\u4ef6\u5206\u5c90\u306e\u6574\u7406\u30d1\u30bf\u30fc\u30f3<\/h4>\n\n\n\n<p>Enum\u3092\u4f7f\u3063\u3066\u6761\u4ef6\u5206\u5c90\u3092\u6574\u7406\u3059\u308b\u4e00\u822c\u7684\u306a\u30d1\u30bf\u30fc\u30f3\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5024\u306e\u5206\u985e\u3068\u30b0\u30eb\u30fc\u30d7\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u95a2\u9023\u3059\u308b\u5024\u3092Enum\u5185\u306b\u5b9a\u7fa9<\/li>\n\n\n\n<li>\u5024\u306e\u5909\u63db\u30ed\u30b8\u30c3\u30af\u3092static\u30e1\u30bd\u30c3\u30c9\u3068\u3057\u3066\u5b9f\u88c5<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b1\u30fc\u30b9\u306b\u5fdc\u3058\u305f\u632f\u308b\u821e\u3044\u306e\u5b9a\u7fa9<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5404Enum\u30b1\u30fc\u30b9\u306b\u5bfe\u3059\u308b\u51e6\u7406\u3092Enum\u306e\u30e1\u30bd\u30c3\u30c9\u3068\u3057\u3066\u5b9f\u88c5<\/li>\n\n\n\n<li>match\u5f0f\u3092\u4f7f\u7528\u3057\u3066\u7c21\u6f54\u306b\u8a18\u8ff0<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u60c5\u5831\u306e\u53d7\u3051\u6e21\u3057<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u30e1\u30bd\u30c3\u30c9\u306b\u8ffd\u52a0\u60c5\u5831\u3092\u6e21\u3059<\/li>\n\n\n\n<li>Enum\u30e1\u30bd\u30c3\u30c9\u9593\u306e\u9023\u643a\u3092\u660e\u793a\u7684\u306b\u8a2d\u8a08<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u578b\u5909\u63db\u306e\u5206\u96e2<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5165\u529b\u5024\u306e\u691c\u8a3c\u3068\u5909\u63db\u3092\u660e\u78ba\u306b\u5206\u3051\u308b<\/li>\n\n\n\n<li>\u7121\u52b9\u306a\u5165\u529b\u306b\u5bfe\u3059\u308b\u4f8b\u5916\u51e6\u7406\u3092\u7d71\u4e00<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-109\">\u305d\u306e\u4ed6\u306e\u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af<\/h4>\n\n\n\n<p>\u8907\u96d1\u306a\u6761\u4ef6\u306b\u5bfe\u51e6\u3059\u308b\u3055\u3089\u306a\u308b\u30c6\u30af\u30cb\u30c3\u30af\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u8907\u6570\u306e\u8981\u7d20\u3092\u7d44\u307f\u5408\u308f\u305b\u305f\u6761\u4ef6\u5224\u5b9a\nenum OrderStatus: string\n{\n    case PENDING = 'pending';\n    case PAID = 'paid';\n    case SHIPPED = 'shipped';\n    case DELIVERED = 'delivered';\n    case CANCELLED = 'cancelled';\n    \n    \/\/ \u8907\u5408\u7684\u306a\u6761\u4ef6\u5224\u5b9a\u306e\u4f8b\n    public function canEdit(UserRole $userRole, bool $isOwner): bool\n    {\n        \/\/ \u30e6\u30fc\u30b6\u30fc\u30ed\u30fc\u30eb\u3068\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u306b\u57fa\u3065\u304f\u7de8\u96c6\u53ef\u5426\u5224\u5b9a\n        return match([$this, $userRole, $isOwner]) {\n            \/\/ \u7ba1\u7406\u8005\u306f\u5e38\u306b\u7de8\u96c6\u53ef\u80fd\n            [self::PENDING, UserRole::ADMIN, true] =&gt; true,\n            [self::PENDING, UserRole::ADMIN, false] =&gt; true,\n            [self::PAID, UserRole::ADMIN, true] =&gt; true,\n            [self::PAID, UserRole::ADMIN, false] =&gt; true,\n            [self::SHIPPED, UserRole::ADMIN, true] =&gt; true,\n            [self::SHIPPED, UserRole::ADMIN, false] =&gt; true,\n            \n            \/\/ \u6ce8\u6587\u6240\u6709\u8005\u306f\u7279\u5b9a\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u307f\u7de8\u96c6\u53ef\u80fd\n            [self::PENDING, UserRole::CUSTOMER, true] =&gt; true,\n            [self::PAID, UserRole::CUSTOMER, true] =&gt; true,\n            \n            \/\/ \u305d\u308c\u4ee5\u5916\u306e\u30d1\u30bf\u30fc\u30f3\u306f\u7de8\u96c6\u4e0d\u53ef\n            default =&gt; false,\n        };\n        \n        \/\/ \u307e\u305f\u306f\u6700\u9069\u5316\u3057\u3066:\n        return match(true) {\n            $userRole === UserRole::ADMIN =&gt; true,\n            $isOwner &amp;&amp; in_array($this, [self::PENDING, self::PAID]) =&gt; true,\n            default =&gt; false\n        };\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-110\">\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306e\u30b9\u30c6\u30c3\u30d7\u30d0\u30a4\u30b9\u30c6\u30c3\u30d7\u30ac\u30a4\u30c9<\/h4>\n\n\n\n<p>\u65e2\u5b58\u306e\u8907\u96d1\u306a\u6761\u4ef6\u5206\u5c90\u3092Enum\u306b\u79fb\u884c\u3059\u308b\u624b\u9806\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u95a2\u9023\u3059\u308b\u6761\u4ef6\u3092\u30b0\u30eb\u30fc\u30d7\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u6761\u4ef6\u306e\u610f\u5473\u3084\u76ee\u7684\u306b\u57fa\u3065\u3044\u3066\u30b0\u30eb\u30fc\u30d7\u3092\u7279\u5b9a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Enum\u306e\u5b9a\u7fa9<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5404\u30b0\u30eb\u30fc\u30d7\u306b\u5bfe\u5fdc\u3059\u308bEnum\u30af\u30e9\u30b9\u3092\u8a2d\u8a08<\/li>\n\n\n\n<li>\u9069\u5207\u306a\u578b\uff08Pure\/Backed\uff09\u3092\u9078\u629e<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u5165\u529b\u5024\u304b\u3089Enum\u3078\u306e\u5909\u63db\u30ed\u30b8\u30c3\u30af\u5b9f\u88c5<\/strong>\n<ul class=\"wp-block-list\">\n<li>from\/tryFrom\u30e1\u30bd\u30c3\u30c9\u3084\u30ab\u30b9\u30bf\u30e0\u30d5\u30a1\u30af\u30c8\u30ea\u30e1\u30bd\u30c3\u30c9\u3092\u5b9f\u88c5<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u6761\u4ef6\u30ed\u30b8\u30c3\u30af\u306eEnum\u30e1\u30bd\u30c3\u30c9\u3078\u306e\u79fb\u884c<\/strong>\n<ul class=\"wp-block-list\">\n<li>match\u5f0f\u3092\u4f7f\u7528\u3057\u3066\u65e2\u5b58\u306e\u6761\u4ef6\u5206\u5c90\u3092\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0<\/li>\n\n\n\n<li>\u6761\u4ef6\u306e\u7d44\u307f\u5408\u308f\u305b\u3092\u52b9\u7387\u7684\u306b\u8868\u73fe<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30e1\u30a4\u30f3\u51e6\u7406\u306e\u66f8\u304d\u63db\u3048<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u30d9\u30fc\u30b9\u306e\u65b0\u3057\u3044\u30ed\u30b8\u30c3\u30af\u3092\u4f7f\u3046\u3088\u3046\u306b\u30e1\u30a4\u30f3\u51e6\u7406\u3092\u66f4\u65b0<\/li>\n\n\n\n<li>\u578b\u5b89\u5168\u306a\u5f15\u6570\u3068\u623b\u308a\u5024\u3092\u8a2d\u8a08<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3057\u305f\u6761\u4ef6\u5206\u5c90\u306e\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306f\u3001\u30b3\u30fc\u30c9\u306e\u8cea\u3092\u5927\u5e45\u306b\u5411\u4e0a\u3055\u305b\u308b\u52b9\u679c\u7684\u306a\u624b\u6cd5\u3067\u3059\u3002\u7279\u306b\u8907\u96d1\u306a\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u304c\u95a2\u308f\u308b\u5834\u5408\u3001Enum\u306b\u3088\u308b\u660e\u793a\u7684\u306a\u8868\u73fe\u3068\u578b\u5b89\u5168\u6027\u306f\u3001\u30d0\u30b0\u306e\u524a\u6e1b\u3068\u30b3\u30fc\u30c9\u306e\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u5411\u4e0a\u306b\u5927\u304d\u304f\u8ca2\u732e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-111\">\u5b9f\u8df5\u4f8b4\uff1a\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08<\/h2>\n\n\n\n<p>\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08\uff08DDD\uff09\u306f\u3001\u8907\u96d1\u306a\u30d3\u30b8\u30cd\u30b9\u30c9\u30e1\u30a4\u30f3\u3092\u52b9\u679c\u7684\u306b\u30e2\u30c7\u30ea\u30f3\u30b0\u3059\u308b\u305f\u3081\u306e\u65b9\u6cd5\u8ad6\u3067\u3059\u3002PHP Enum\u306f\u3001DDD\u306e\u4e2d\u5fc3\u7684\u306a\u6982\u5ff5\u3067\u3042\u308b\u300c\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u300d\u3092\u5b9f\u88c5\u3059\u308b\u5f37\u529b\u306a\u624b\u6bb5\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-112\">\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u306f<\/h3>\n\n\n\n<p>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u3001DDD\u306b\u304a\u3044\u3066\u4ee5\u4e0b\u306e\u7279\u6027\u3092\u6301\u3064\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u540c\u4e00\u6027\u304c\u306a\u3044<\/strong> \u2013 \u5185\u5bb9\u304c\u540c\u3058\u3067\u3042\u308c\u3070\u7b49\u4fa1\u3068\u307f\u306a\u3055\u308c\u308b<\/li>\n\n\n\n<li><strong>\u4e0d\u5909\u6027<\/strong> \u2013 \u4f5c\u6210\u5f8c\u306b\u5185\u5bb9\u304c\u5909\u66f4\u3055\u308c\u306a\u3044<\/li>\n\n\n\n<li><strong>\u81ea\u5df1\u5b8c\u7d50\u6027<\/strong> \u2013 \u30c9\u30e1\u30a4\u30f3\u306e\u6982\u5ff5\u3092\u5b8c\u5168\u306b\u8868\u73fe\u3059\u308b<\/li>\n\n\n\n<li><strong>\u526f\u4f5c\u7528\u304c\u306a\u3044<\/strong> \u2013 \u64cd\u4f5c\u304c\u72b6\u614b\u3092\u5909\u66f4\u3057\u306a\u3044<\/li>\n<\/ol>\n\n\n\n<p>PHP\u306eEnum\u306f\u3001\u305d\u306e\u6027\u8cea\u4e0a\u3053\u308c\u3089\u306e\u7279\u6027\u3092\u81ea\u7136\u306b\u6e80\u305f\u3057\u3001\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u5b9f\u88c5\u306b\u7406\u60f3\u7684\u3067\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-113\">Enum\u3092\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u6d3b\u7528\u3059\u308b<\/h3>\n\n\n\n<p>Enum\u306f\u5358\u7d14\u306a\u5217\u6319\u578b\u4ee5\u4e0a\u306e\u5f79\u5272\u3092\u679c\u305f\u3057\u307e\u3059\u3002\u30c9\u30e1\u30a4\u30f3\u6982\u5ff5\u3092\u30ab\u30d7\u30bb\u30eb\u5316\u3057\u3001\u95a2\u9023\u3059\u308b\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u3092\u96c6\u7d04\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u901a\u8ca8\u3092\u8868\u3059\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u306eEnum\nenum Currency: string\n{\n    case JPY = 'JPY';\n    case USD = 'USD';\n    case EUR = 'EUR';\n    case GBP = 'GBP';\n    \n    \/\/ \u901a\u8ca8\u8a18\u53f7\u3092\u53d6\u5f97\n    public function getSymbol(): string\n    {\n        return match($this) {\n            self::JPY =&gt; '\u00a5',\n            self::USD =&gt; '$',\n            self::EUR =&gt; '\u20ac',\n            self::GBP =&gt; '\u00a3',\n        };\n    }\n    \n    \/\/ \u5c0f\u6570\u70b9\u4ee5\u4e0b\u306e\u6841\u6570\u3092\u53d6\u5f97\uff08\u901a\u8ca8\u3054\u3068\u306e\u8868\u793a\u30eb\u30fc\u30eb\uff09\n    public function getDecimalPlaces(): int\n    {\n        return match($this) {\n            self::JPY =&gt; 0,   \/\/ \u65e5\u672c\u5186\u306f\u5c0f\u6570\u70b9\u4ee5\u4e0b\u306a\u3057\n            default =&gt; 2,     \/\/ \u305d\u306e\u4ed6\u306e\u901a\u8ca8\u306f2\u6841\n        };\n    }\n    \n    \/\/ \u91d1\u984d\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u65b9\u6cd5\n    public function format(float $amount): string\n    {\n        $decimals = $this-&gt;getDecimalPlaces();\n        $formattedAmount = number_format($amount, $decimals);\n        \n        return match($this) {\n            self::JPY, self::USD =&gt; $this-&gt;getSymbol() . $formattedAmount,\n            self::EUR, self::GBP =&gt; $formattedAmount . $this-&gt;getSymbol(),\n        };\n    }\n}\n\n\/\/ Money\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068Enum\u306e\u7d44\u307f\u5408\u308f\u305b\nclass Money\n{\n    private float $amount;\n    private Currency $currency;\n    \n    \/\/ \u4e0d\u5909\u6027\u3092\u4fdd\u8a3c\u3059\u308b\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\n    public function __construct(float $amount, Currency $currency)\n    {\n        $this-&gt;amount = $amount;\n        $this-&gt;currency = $currency;\n    }\n    \n    \/\/ \u7b49\u4fa1\u6027\u306e\u5b9f\u88c5\n    public function equals(self $other): bool\n    {\n        return $this-&gt;amount === $other-&gt;amount &amp;&amp; \n               $this-&gt;currency === $other-&gt;currency;\n    }\n    \n    \/\/ \u52a0\u7b97\u64cd\u4f5c\uff08\u65b0\u3057\u3044\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8fd4\u3059\uff09\n    public function add(self $other): self\n    {\n        if ($this-&gt;currency !== $other-&gt;currency) {\n            throw new \\InvalidArgumentException('\u901a\u8ca8\u5358\u4f4d\u304c\u7570\u306a\u308bMoney\u540c\u58eb\u306f\u8a08\u7b97\u3067\u304d\u307e\u305b\u3093');\n        }\n        \n        return new self($this-&gt;amount + $other-&gt;amount, $this-&gt;currency);\n    }\n    \n    \/\/ \u4e57\u7b97\u64cd\u4f5c\uff08\u65b0\u3057\u3044\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8fd4\u3059\uff09\n    public function multiply(float $multiplier): self\n    {\n        return new self($this-&gt;amount * $multiplier, $this-&gt;currency);\n    }\n    \n    \/\/ \u8868\u793a\u7528\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\n    public function format(): string\n    {\n        return $this-&gt;currency-&gt;format($this-&gt;amount);\n    }\n    \n    \/\/ \u30b2\u30c3\u30bf\u30fc\n    public function getAmount(): float\n    {\n        return $this-&gt;amount;\n    }\n    \n    public function getCurrency(): Currency\n    {\n        return $this-&gt;currency;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$jpy1000 = new Money(1000, Currency::JPY);\n$jpy2000 = new Money(2000, Currency::JPY);\n$sum = $jpy1000-&gt;add($jpy2000);\n\necho $sum-&gt;format();  \/\/ \"\u00a53,000\"\n\n$usd100 = new Money(100, Currency::USD);\necho $usd100-&gt;format();  \/\/ \"$100.00\"\n<\/pre>\n\n\n\n<p>\u3053\u306e\u30b3\u30fc\u30c9\u306f\u3001\u901a\u8ca8\u3068\u3044\u3046\u6982\u5ff5\u3092Enum\u3067\u8868\u73fe\u3057\u3001\u305d\u308c\u3092Money\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u91d1\u984d\u8a08\u7b97\u3068\u8868\u793a\u306b\u95a2\u3059\u308b\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3092\u30ab\u30d7\u30bb\u30eb\u5316\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-114\">\u3088\u308a\u8907\u96d1\u306a\u30c9\u30e1\u30a4\u30f3\u6982\u5ff5\u306e\u8868\u73fe<\/h3>\n\n\n\n<p>Enum\u3092\u4f7f\u7528\u3057\u3066\u3088\u308a\u8907\u96d1\u306a\u30c9\u30e1\u30a4\u30f3\u6982\u5ff5\u3092\u8868\u73fe\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u5546\u54c1\u306e\u8a55\u4fa1\u3092\u8868\u3059Enum\nenum ProductRating: int\n{\n    case ONE_STAR = 1;\n    case TWO_STARS = 2;\n    case THREE_STARS = 3;\n    case FOUR_STARS = 4;\n    case FIVE_STARS = 5;\n    \n    \/\/ \u661f\u8a55\u4fa1\u306e\u6587\u5b57\u8868\u73fe\n    public function getStars(): string\n    {\n        return str_repeat('\u2605', $this-&gt;value);\n    }\n    \n    \/\/ \u8a55\u4fa1\u30ab\u30c6\u30b4\u30ea\n    public function getCategory(): string\n    {\n        return match($this) {\n            self::ONE_STAR, self::TWO_STARS =&gt; '\u4f4e\u8a55\u4fa1',\n            self::THREE_STARS =&gt; '\u666e\u901a',\n            self::FOUR_STARS, self::FIVE_STARS =&gt; '\u9ad8\u8a55\u4fa1',\n        };\n    }\n    \n    \/\/ \u63a8\u5968\u30ec\u30d9\u30eb\n    public function isRecommended(): bool\n    {\n        return $this-&gt;value &gt;= 4;\n    }\n    \n    \/\/ \u6587\u5b57\u5217\u304b\u3089\u306e\u5909\u63db\uff08\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u4ed8\u304d\uff09\n    public static function fromString(string $rating): self\n    {\n        $intRating = (int) $rating;\n        \n        if ($intRating &lt; 1 || $intRating &gt; 5) {\n            throw new \\InvalidArgumentException('\u8a55\u4fa1\u306f1\u304b\u30895\u306e\u9593\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093');\n        }\n        \n        return self::from($intRating);\n    }\n}\n\n\/\/ \u30ec\u30d3\u30e5\u30fc\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\nclass Review\n{\n    private ProductRating $rating;\n    private ?string $comment;\n    private \\DateTimeImmutable $createdAt;\n    \n    public function __construct(ProductRating $rating, ?string $comment = null)\n    {\n        $this-&gt;rating = $rating;\n        $this-&gt;comment = $comment;\n        $this-&gt;createdAt = new \\DateTimeImmutable();\n    }\n    \n    public function getRating(): ProductRating\n    {\n        return $this-&gt;rating;\n    }\n    \n    public function getComment(): ?string\n    {\n        return $this-&gt;comment;\n    }\n    \n    public function getCreatedAt(): \\DateTimeImmutable\n    {\n        return $this-&gt;createdAt;\n    }\n    \n    \/\/ \u30ec\u30d3\u30e5\u30fc\u306e\u8868\u793a\u5f62\u5f0f\n    public function getFormattedRating(): string\n    {\n        return $this-&gt;rating-&gt;getStars() . ' (' . $this-&gt;rating-&gt;value . '\/5)';\n    }\n    \n    \/\/ \u9ad8\u8a55\u4fa1\u30ec\u30d3\u30e5\u30fc\u304b\u3069\u3046\u304b\n    public function isPositive(): bool\n    {\n        return $this-&gt;rating-&gt;isRecommended();\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$fiveStarReview = new Review(ProductRating::FIVE_STARS, '\u7d20\u6674\u3089\u3057\u3044\u5546\u54c1\u3067\u3059\uff01');\necho $fiveStarReview-&gt;getFormattedRating();  \/\/ \"\u2605\u2605\u2605\u2605\u2605 (5\/5)\"\n\nif ($fiveStarReview-&gt;isPositive()) {\n    echo \"\u3053\u308c\u306f\u63a8\u5968\u30ec\u30d3\u30e5\u30fc\u3067\u3059\";\n}\n<\/pre>\n\n\n\n<p>\u3053\u306eProductRating\u306eEnum\u306f\u3001\u5358\u306a\u308b\u6570\u5024\u3067\u306f\u306a\u304f\u3001\u8a55\u4fa1\u3068\u3044\u3046\u8c4a\u304b\u306a\u30c9\u30e1\u30a4\u30f3\u6982\u5ff5\u3092\u8868\u73fe\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-115\">DDD\u306b\u304a\u3051\u308b\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/h3>\n\n\n\n<p>Enum\u3092\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u4f7f\u7528\u3059\u308b\u6700\u5927\u306e\u5229\u70b9\u306f\u3001\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3092\u30ab\u30d7\u30bb\u30eb\u5316\u3067\u304d\u308b\u3053\u3068\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u8868\u3059Enum\nenum OrderStatus: string\n{\n    case DRAFT = 'draft';\n    case PENDING = 'pending';\n    case PROCESSING = 'processing';\n    case SHIPPED = 'shipped';\n    case DELIVERED = 'delivered';\n    case CANCELLED = 'cancelled';\n    \n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u306b\u5fdc\u3058\u305f\u6b21\u306e\u30a2\u30af\u30b7\u30e7\u30f3\u540d\u3092\u53d6\u5f97\n    public function getNextActionName(): string\n    {\n        return match($this) {\n            self::DRAFT =&gt; '\u6ce8\u6587\u78ba\u5b9a',\n            self::PENDING =&gt; '\u51e6\u7406\u958b\u59cb',\n            self::PROCESSING =&gt; '\u51fa\u8377\u624b\u7d9a\u304d',\n            self::SHIPPED =&gt; '\u914d\u9054\u5b8c\u4e86\u78ba\u8a8d',\n            self::DELIVERED =&gt; '\u30ec\u30d3\u30e5\u30fc\u4f9d\u983c',\n            self::CANCELLED =&gt; '\u518d\u6ce8\u6587',\n        };\n    }\n    \n    \/\/ \u6ce8\u6587\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u53ef\u80fd\u304b\u3069\u3046\u304b\n    public function isCancellable(): bool\n    {\n        return in_array($this, [self::DRAFT, self::PENDING, self::PROCESSING]);\n    }\n    \n    \/\/ \u6ce8\u6587\u304c\u5909\u66f4\u53ef\u80fd\u304b\u3069\u3046\u304b\n    public function isModifiable(): bool\n    {\n        return in_array($this, [self::DRAFT, self::PENDING]);\n    }\n    \n    \/\/ \u9867\u5ba2\u304c\u8ffd\u8de1\u53ef\u80fd\u304b\u3069\u3046\u304b\n    public function isTrackable(): bool\n    {\n        return in_array($this, [self::SHIPPED, self::DELIVERED]);\n    }\n    \n    \/\/ \u3053\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3067\u53ef\u80fd\u306a\u64cd\u4f5c\u306e\u30ea\u30b9\u30c8\u3092\u53d6\u5f97\n    public function getAllowedOperations(): array\n    {\n        $operations = [];\n        \n        if ($this-&gt;isCancellable()) {\n            $operations[] = 'cancel';\n        }\n        \n        if ($this-&gt;isModifiable()) {\n            $operations[] = 'modify';\n        }\n        \n        if ($this-&gt;isTrackable()) {\n            $operations[] = 'track';\n        }\n        \n        return match($this) {\n            self::DRAFT =&gt; array_merge($operations, ['confirm']),\n            self::PENDING =&gt; array_merge($operations, ['process']),\n            self::PROCESSING =&gt; array_merge($operations, ['ship']),\n            self::SHIPPED =&gt; array_merge($operations, ['deliver']),\n            self::DELIVERED =&gt; array_merge($operations, ['review']),\n            self::CANCELLED =&gt; array_merge($operations, ['reorder']),\n        };\n    }\n}\n\n\/\/ \u6ce8\u6587\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u3067\u306e\u4f7f\u7528\u4f8b\nclass Order\n{\n    private int $id;\n    private OrderStatus $status;\n    private Customer $customer;\n    private array $items = [];\n    \n    \/\/ \u30b2\u30c3\u30bf\u30fc\u30fb\u30bb\u30c3\u30bf\u30fc\u7701\u7565\n    \n    \/\/ \u6ce8\u6587\u306e\u30ad\u30e3\u30f3\u30bb\u30eb\u64cd\u4f5c\n    public function cancel(): void\n    {\n        if (!$this-&gt;status-&gt;isCancellable()) {\n            throw new \\DomainException('\u3053\u306e\u6ce8\u6587\u306f\u30ad\u30e3\u30f3\u30bb\u30eb\u3067\u304d\u307e\u305b\u3093');\n        }\n        \n        $this-&gt;status = OrderStatus::CANCELLED;\n        \/\/ \u30ad\u30e3\u30f3\u30bb\u30eb\u51e6\u7406\u306e\u5b9f\u88c5...\n    }\n    \n    \/\/ \u64cd\u4f5c\u304c\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\u304b\u30c1\u30a7\u30c3\u30af\n    public function canPerform(string $operation): bool\n    {\n        return in_array($operation, $this-&gt;status-&gt;getAllowedOperations());\n    }\n    \n    \/\/ \u6b21\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3078\u9032\u3081\u308b\n    public function proceedToNextStatus(): void\n    {\n        $this-&gt;status = match($this-&gt;status) {\n            OrderStatus::DRAFT =&gt; OrderStatus::PENDING,\n            OrderStatus::PENDING =&gt; OrderStatus::PROCESSING,\n            OrderStatus::PROCESSING =&gt; OrderStatus::SHIPPED,\n            OrderStatus::SHIPPED =&gt; OrderStatus::DELIVERED,\n            default =&gt; throw new \\DomainException('\u3053\u306e\u6ce8\u6587\u306f\u3053\u308c\u4ee5\u4e0a\u9032\u3081\u307e\u305b\u3093')\n        };\n    }\n}\n<\/pre>\n\n\n\n<p>\u3053\u306eOrderStatus\u306eEnum\u306f\u3001\u6ce8\u6587\u306e\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u5168\u4f53\u306b\u95a2\u3059\u308b\u30eb\u30fc\u30eb\u3092\u96c6\u7d04\u3057\u3001Order\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u306b\u660e\u78ba\u306a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u63d0\u4f9b\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-116\">\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u4f7f\u7528\u3059\u308b\u969b\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d5\u30a1\u30af\u30c8\u30ea\u30fc\u30e1\u30bd\u30c3\u30c9\u306e\u63d0\u4f9b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u6587\u5b57\u5217\u3084\u6570\u5024\u304b\u3089\u306e\u5b89\u5168\u306a\u5909\u63db\u3092\u884c\u3046static\u30e1\u30bd\u30c3\u30c9<\/li>\n\n\n\n<li>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30eb\u3092\u7d44\u307f\u8fbc\u3080<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u3092Enum\u306e\u30e1\u30bd\u30c3\u30c9\u306b\u96c6\u7d04<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u3068\u632f\u308b\u821e\u3044\u3092\u7d50\u5408<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30ea\u30c3\u30c1\u306a\u6bd4\u8f03\u64cd\u4f5c<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5358\u7d14\u306a\u7b49\u4fa1\u6bd4\u8f03\u3060\u3051\u3067\u306a\u304f\u3001\u610f\u5473\u306e\u3042\u308b\u6bd4\u8f03\u30e1\u30bd\u30c3\u30c9<\/li>\n\n\n\n<li><code>isGreaterThan()<\/code>, <code>isBetterThan()<\/code> \u306a\u3069\u306e\u8868\u73fe\u529b\u8c4a\u304b\u306a\u30e1\u30bd\u30c3\u30c9<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u4e0d\u5909\u6027\u306e\u6d3b\u7528<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u306e\u4e0d\u5909\u6027\u3092\u524d\u63d0\u3068\u3057\u305f\u8a2d\u8a08<\/li>\n\n\n\n<li>\u5909\u66f4\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u65b0\u3057\u3044\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u751f\u6210<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u578b\u5b89\u5168\u6027\u306e\u5fb9\u5e95<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30d7\u30ea\u30df\u30c6\u30a3\u30d6\u578b\uff08\u6587\u5b57\u5217\u3084\u6574\u6570\uff09\u3067\u306f\u306a\u304fEnum\u578b\u3092\u5f15\u6570\u306b\u8981\u6c42<\/li>\n\n\n\n<li>\u578b\u5ba3\u8a00\u306b\u3088\u308a\u4e0d\u6b63\u306a\u5024\u306e\u6df7\u5165\u3092\u9632\u6b62<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>PHP Enum\u3092\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30c9\u30e1\u30a4\u30f3\u306e\u6982\u5ff5\u3092\u30b3\u30fc\u30c9\u3068\u3057\u3066\u660e\u78ba\u306b\u8868\u73fe\u3057\u3001\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u3092\u30ab\u30d7\u30bb\u30eb\u5316\u3057\u305f\u5f37\u529b\u306a\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u4fdd\u5b88\u6027\u3068\u62e1\u5f35\u6027\u304c\u5927\u304d\u304f\u5411\u4e0a\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-117\">Enum\u3092\u6d3b\u7528\u3057\u305f\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<p>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u3001\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08\uff08DDD\uff09\u306e\u91cd\u8981\u306a\u69cb\u6210\u8981\u7d20\u3067\u3001\u6982\u5ff5\u7684\u306b\u306f\u300c\u5c5e\u6027\u3057\u304b\u6301\u305f\u306a\u3044\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u300d\u3067\u3059\u3002PHP\u306eEnum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u8868\u73fe\u529b\u8c4a\u304b\u3067\u578b\u5b89\u5168\u306a\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u5b9f\u88c5\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-118\">\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8<\/h4>\n\n\n\n<p>\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3092\u5358\u306a\u308b\u6587\u5b57\u5217\u3067\u306f\u306a\u304f\u3001\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u5b9f\u88c5\u3059\u308b\u4f8b\u3092\u898b\u3066\u307f\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u30c9\u30e1\u30a4\u30f3\u7a2e\u5225\u3092Enum\u3067\u8868\u73fe\nenum EmailDomainType\n{\n    case CORPORATE;   \/\/ \u4f01\u696d\u30c9\u30e1\u30a4\u30f3\n    case PERSONAL;    \/\/ \u500b\u4eba\u7528\u30e1\u30fc\u30eb\u30b5\u30fc\u30d3\u30b9\n    case ACADEMIC;    \/\/ \u6559\u80b2\u6a5f\u95a2\n    case GOVERNMENT;  \/\/ \u653f\u5e9c\u6a5f\u95a2\n    case OTHER;       \/\/ \u305d\u306e\u4ed6\n    \n    \/\/ \u30c9\u30e1\u30a4\u30f3\u306e\u7a2e\u985e\u3092\u5224\u5b9a\n    public static function fromDomain(string $domain): self\n    {\n        \/\/ \u4f01\u696d\u30e1\u30fc\u30eb\n        if (preg_match('\/\\.(co\\.jp|com|co|corp|inc)$\/', $domain)) {\n            return self::CORPORATE;\n        }\n        \n        \/\/ \u500b\u4eba\u7528\u30e1\u30fc\u30eb\u30b5\u30fc\u30d3\u30b9\n        if (in_array($domain, ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com'])) {\n            return self::PERSONAL;\n        }\n        \n        \/\/ \u5b66\u8853\u6a5f\u95a2\n        if (preg_match('\/\\.(edu|ac\\.jp|\\.edu\\.)\/', $domain)) {\n            return self::ACADEMIC;\n        }\n        \n        \/\/ \u653f\u5e9c\u6a5f\u95a2\n        if (preg_match('\/\\.(gov|go\\.jp)$\/', $domain)) {\n            return self::GOVERNMENT;\n        }\n        \n        return self::OTHER;\n    }\n    \n    \/\/ \u30c9\u30e1\u30a4\u30f3\u7a2e\u5225\u306e\u8aac\u660e\n    public function getDescription(): string\n    {\n        return match($this) {\n            self::CORPORATE =&gt; '\u4f01\u696d\u30c9\u30e1\u30a4\u30f3',\n            self::PERSONAL =&gt; '\u500b\u4eba\u7528\u30e1\u30fc\u30eb\u30b5\u30fc\u30d3\u30b9',\n            self::ACADEMIC =&gt; '\u6559\u80b2\u6a5f\u95a2',\n            self::GOVERNMENT =&gt; '\u653f\u5e9c\u6a5f\u95a2',\n            self::OTHER =&gt; '\u305d\u306e\u4ed6\u306e\u30c9\u30e1\u30a4\u30f3'\n        };\n    }\n    \n    \/\/ \u7279\u5b9a\u306e\u7a2e\u985e\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u304b\u3092\u30c1\u30a7\u30c3\u30af\n    public function isPersonal(): bool\n    {\n        return $this === self::PERSONAL;\n    }\n    \n    public function isCorporate(): bool\n    {\n        return $this === self::CORPORATE;\n    }\n}\n\n\/\/ Email\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\nclass Email\n{\n    private string $address;\n    private string $localPart;\n    private string $domain;\n    private EmailDomainType $domainType;\n    \n    \/\/ \u4e0d\u5909\u6027\u3092\u78ba\u4fdd\u3059\u308b\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\n    private function __construct(string $address)\n    {\n        $this-&gt;address = $address;\n        \n        \/\/ \u30ed\u30fc\u30ab\u30eb\u90e8\u3068\u30c9\u30e1\u30a4\u30f3\u90e8\u306b\u5206\u5272\n        list($this-&gt;localPart, $this-&gt;domain) = explode('@', $address, 2);\n        \n        \/\/ \u30c9\u30e1\u30a4\u30f3\u7a2e\u5225\u3092\u5224\u5b9a\n        $this-&gt;domainType = EmailDomainType::fromDomain($this-&gt;domain);\n    }\n    \n    \/\/ \u30d5\u30a1\u30af\u30c8\u30ea\u30fc\u30e1\u30bd\u30c3\u30c9\uff08\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u4ed8\u304d\uff09\n    public static function fromString(string $address): self\n    {\n        \/\/ \u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u5f62\u5f0f\u3092\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n        if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {\n            throw new \\InvalidArgumentException('\u4e0d\u6b63\u306a\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u5f62\u5f0f\u3067\u3059: ' . $address);\n        }\n        \n        return new self($address);\n    }\n    \n    \/\/ \u5b89\u5168\u306a\u4f5c\u6210\u30e1\u30bd\u30c3\u30c9\uff08\u7121\u52b9\u306a\u3089\u4f8b\u5916\u3067\u306f\u306a\u304fnull\u3092\u8fd4\u3059\uff09\n    public static function tryFromString(string $address): ?self\n    {\n        try {\n            return self::fromString($address);\n        } catch (\\InvalidArgumentException $e) {\n            return null;\n        }\n    }\n    \n    \/\/ \u30a2\u30c9\u30ec\u30b9\u6587\u5b57\u5217\u3092\u53d6\u5f97\n    public function toString(): string\n    {\n        return $this-&gt;address;\n    }\n    \n    \/\/ \u30ed\u30fc\u30ab\u30eb\u90e8\u3092\u53d6\u5f97\n    public function getLocalPart(): string\n    {\n        return $this-&gt;localPart;\n    }\n    \n    \/\/ \u30c9\u30e1\u30a4\u30f3\u90e8\u3092\u53d6\u5f97\n    public function getDomain(): string\n    {\n        return $this-&gt;domain;\n    }\n    \n    \/\/ \u30c9\u30e1\u30a4\u30f3\u7a2e\u5225\u3092\u53d6\u5f97\n    public function getDomainType(): EmailDomainType\n    {\n        return $this-&gt;domainType;\n    }\n    \n    \/\/ \u7b49\u4fa1\u6027\u306e\u5b9f\u88c5\n    public function equals(self $other): bool\n    {\n        return $this-&gt;address === $other-&gt;address;\n    }\n    \n    \/\/ \u30c9\u30e1\u30a4\u30f3\u7a2e\u5225\u306b\u57fa\u3065\u304f\u5224\u5b9a\u30e1\u30bd\u30c3\u30c9\n    public function isPersonalEmail(): bool\n    {\n        return $this-&gt;domainType-&gt;isPersonal();\n    }\n    \n    public function isCorporateEmail(): bool\n    {\n        return $this-&gt;domainType-&gt;isCorporate();\n    }\n    \n    \/\/ \u30c9\u30e1\u30a4\u30f3\u7a2e\u5225\u306b\u57fa\u3065\u304f\u8aac\u660e\n    public function getDomainDescription(): string\n    {\n        return $this-&gt;domainType-&gt;getDescription();\n    }\n    \n    \/\/ \u6587\u5b57\u5217\u30ad\u30e3\u30b9\u30c8\n    public function __toString(): string\n    {\n        return $this-&gt;address;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\ntry {\n    $email = Email::fromString('john.doe@example.com');\n    \n    echo $email-&gt;getDomain();  \/\/ \"example.com\"\n    echo $email-&gt;getDomainDescription();  \/\/ \"\u4f01\u696d\u30c9\u30e1\u30a4\u30f3\"\n    \n    if ($email-&gt;isCorporateEmail()) {\n        echo \"\u3053\u308c\u306f\u4f01\u696d\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3067\u3059\";\n    }\n} catch (\\InvalidArgumentException $e) {\n    echo $e-&gt;getMessage();\n}\n<\/pre>\n\n\n\n<p>\u3053\u306eEmail\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u3001EmailDomainType\u3068\u3044\u3046Enum\u3068\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u5358\u306a\u308b\u6587\u5b57\u5217\u691c\u8a3c\u3092\u8d85\u3048\u3066\u3001\u30c9\u30e1\u30a4\u30f3\u306e\u7a2e\u985e\u306b\u57fa\u3065\u3044\u305f\u5224\u65ad\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-119\">\u96fb\u8a71\u756a\u53f7\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8<\/h4>\n\n\n\n<p>\u96fb\u8a71\u756a\u53f7\u3082\u3001Enum\u3092\u6d3b\u7528\u3057\u305f\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u5b9f\u88c5\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u56fd\u30b3\u30fc\u30c9\u3092Enum\u3067\u8868\u73fe\nenum CountryCode: string\n{\n    case JAPAN = 'JP';\n    case USA = 'US';\n    case UK = 'GB';\n    case CHINA = 'CN';\n    case KOREA = 'KR';\n    \n    \/\/ \u56fd\u969b\u96fb\u8a71\u756a\u53f7\u306e\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u53d6\u5f97\n    public function getPrefix(): string\n    {\n        return match($this) {\n            self::JAPAN =&gt; '+81',\n            self::USA =&gt; '+1',\n            self::UK =&gt; '+44',\n            self::CHINA =&gt; '+86',\n            self::KOREA =&gt; '+82',\n        };\n    }\n    \n    \/\/ \u96fb\u8a71\u756a\u53f7\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u30d1\u30bf\u30fc\u30f3\u3092\u53d6\u5f97\n    public function getNumberPattern(): string\n    {\n        return match($this) {\n            self::JAPAN =&gt; '\/^0\\d{1,4}-\\d{1,4}-\\d{4}$\/',   \/\/ \u65e5\u672c\u306e\u5f62\u5f0f\n            self::USA =&gt; '\/^\\(\\d{3}\\) \\d{3}-\\d{4}$\/',      \/\/ \u7c73\u56fd\u306e\u5f62\u5f0f\n            default =&gt; '\/^\\+?[\\d\\s-]{8,15}$\/',             \/\/ \u6c4e\u7528\u30d1\u30bf\u30fc\u30f3\n        };\n    }\n    \n    \/\/ \u8868\u793a\u7528\u306e\u56fd\u540d\u3092\u53d6\u5f97\n    public function getCountryName(): string\n    {\n        return match($this) {\n            self::JAPAN =&gt; '\u65e5\u672c',\n            self::USA =&gt; '\u30a2\u30e1\u30ea\u30ab',\n            self::UK =&gt; '\u30a4\u30ae\u30ea\u30b9',\n            self::CHINA =&gt; '\u4e2d\u56fd',\n            self::KOREA =&gt; '\u97d3\u56fd',\n        };\n    }\n}\n\n\/\/ \u96fb\u8a71\u756a\u53f7\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\nclass PhoneNumber\n{\n    private string $number;\n    private CountryCode $countryCode;\n    \n    private function __construct(string $number, CountryCode $countryCode)\n    {\n        $this-&gt;number = $number;\n        $this-&gt;countryCode = $countryCode;\n    }\n    \n    \/\/ \u65e5\u672c\u306e\u96fb\u8a71\u756a\u53f7\u3092\u4f5c\u6210\n    public static function fromJapaneseNumber(string $number): self\n    {\n        $pattern = CountryCode::JAPAN-&gt;getNumberPattern();\n        \n        if (!preg_match($pattern, $number)) {\n            throw new \\InvalidArgumentException('\u4e0d\u6b63\u306a\u65e5\u672c\u306e\u96fb\u8a71\u756a\u53f7\u5f62\u5f0f\u3067\u3059: ' . $number);\n        }\n        \n        return new self($number, CountryCode::JAPAN);\n    }\n    \n    \/\/ \u7c73\u56fd\u306e\u96fb\u8a71\u756a\u53f7\u3092\u4f5c\u6210\n    public static function fromUSNumber(string $number): self\n    {\n        $pattern = CountryCode::USA-&gt;getNumberPattern();\n        \n        if (!preg_match($pattern, $number)) {\n            throw new \\InvalidArgumentException('\u4e0d\u6b63\u306a\u7c73\u56fd\u306e\u96fb\u8a71\u756a\u53f7\u5f62\u5f0f\u3067\u3059: ' . $number);\n        }\n        \n        return new self($number, CountryCode::USA);\n    }\n    \n    \/\/ \u56fd\u30b3\u30fc\u30c9\u3092\u6307\u5b9a\u3057\u3066\u4f5c\u6210\uff08\u6c4e\u7528\uff09\n    public static function fromNumberWithCountry(string $number, CountryCode $countryCode): self\n    {\n        \/\/ \u5404\u56fd\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u30c1\u30a7\u30c3\u30af\u306f\u7701\u7565\n        return new self($number, $countryCode);\n    }\n    \n    \/\/ \u56fd\u969b\u5f62\u5f0f\u3067\u53d6\u5f97\n    public function toInternational(): string\n    {\n        $prefix = $this-&gt;countryCode-&gt;getPrefix();\n        \n        \/\/ \u56fd\u3054\u3068\u306e\u5909\u63db\u30ed\u30b8\u30c3\u30af\uff08\u7c21\u7565\u5316\uff09\n        $internationalNumber = match($this-&gt;countryCode) {\n            CountryCode::JAPAN =&gt; preg_replace('\/^0\/', '', str_replace('-', '', $this-&gt;number)),\n            CountryCode::USA =&gt; preg_replace('\/^\\((\\d{3})\\) (\\d{3})-(\\d{4})$\/', '$1$2$3', $this-&gt;number),\n            default =&gt; str_replace(['-', ' '], '', $this-&gt;number),\n        };\n        \n        return $prefix . $internationalNumber;\n    }\n    \n    \/\/ \u56fd\u5185\u5f62\u5f0f\u3067\u53d6\u5f97\n    public function toDomestic(): string\n    {\n        return $this-&gt;number;\n    }\n    \n    \/\/ \u56fd\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\n    public function getCountryCode(): CountryCode\n    {\n        return $this-&gt;countryCode;\n    }\n    \n    \/\/ \u56fd\u540d\u3092\u53d6\u5f97\n    public function getCountryName(): string\n    {\n        return $this-&gt;countryCode-&gt;getCountryName();\n    }\n    \n    \/\/ \u7b49\u4fa1\u6027\u306e\u5b9f\u88c5\n    public function equals(self $other): bool\n    {\n        \/\/ \u56fd\u969b\u5f62\u5f0f\u3067\u6bd4\u8f03\u3059\u308b\u3053\u3068\u3067\u7570\u306a\u308b\u5f62\u5f0f\u3067\u3082\u540c\u3058\u756a\u53f7\u3068\u5224\u5b9a\n        return $this-&gt;toInternational() === $other-&gt;toInternational();\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$jpPhone = PhoneNumber::fromJapaneseNumber('03-1234-5678');\necho $jpPhone-&gt;toInternational();  \/\/ \"+81312345678\"\necho $jpPhone-&gt;getCountryName();   \/\/ \"\u65e5\u672c\"\n\n$usPhone = PhoneNumber::fromUSNumber('(123) 456-7890');\necho $usPhone-&gt;toInternational();  \/\/ \"+11234567890\"\n\n\/\/ \u540c\u3058\u96fb\u8a71\u756a\u53f7\u304b\u3069\u3046\u304b\u306e\u6bd4\u8f03\nif ($jpPhone-&gt;equals($usPhone)) {\n    echo \"\u540c\u3058\u96fb\u8a71\u756a\u53f7\u3067\u3059\";\n} else {\n    echo \"\u7570\u306a\u308b\u96fb\u8a71\u756a\u53f7\u3067\u3059\";\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-120\">ISBN\u306a\u3069\u306e\u6a19\u6e96\u5316\u3055\u308c\u305f\u8b58\u5225\u5b50<\/h4>\n\n\n\n<p>ISBN\uff08\u56fd\u969b\u6a19\u6e96\u56f3\u66f8\u756a\u53f7\uff09\u306e\u3088\u3046\u306a\u6a19\u6e96\u5316\u3055\u308c\u305f\u8b58\u5225\u5b50\u3082\u3001Enum\u3092\u6d3b\u7528\u3057\u305f\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u5b9f\u88c5\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ ISBN\u5f62\u5f0f\u3092Enum\u3067\u8868\u73fe\nenum ISBNFormat\n{\n    case ISBN10;    \/\/ 10\u6841\u5f62\u5f0f\n    case ISBN13;    \/\/ 13\u6841\u5f62\u5f0f\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30d1\u30bf\u30fc\u30f3\u3092\u53d6\u5f97\n    public function getValidationPattern(): string\n    {\n        return match($this) {\n            self::ISBN10 =&gt; '\/^[0-9]{9}[0-9X]$\/',\n            self::ISBN13 =&gt; '\/^97[89][0-9]{10}$\/',\n        };\n    }\n    \n    \/\/ \u8868\u793a\u7528\u306e\u30e9\u30d9\u30eb\u3092\u53d6\u5f97\n    public function getLabel(): string\n    {\n        return match($this) {\n            self::ISBN10 =&gt; 'ISBN-10',\n            self::ISBN13 =&gt; 'ISBN-13',\n        };\n    }\n    \n    \/\/ \u30c1\u30a7\u30c3\u30af\u30c7\u30a3\u30b8\u30c3\u30c8\u304c\u6709\u52b9\u304b\u3092\u691c\u8a3c\n    public function validateCheckDigit(string $isbn): bool\n    {\n        return match($this) {\n            self::ISBN10 =&gt; self::validateISBN10CheckDigit($isbn),\n            self::ISBN13 =&gt; self::validateISBN13CheckDigit($isbn),\n        };\n    }\n    \n    \/\/ ISBN-10\u306e\u30c1\u30a7\u30c3\u30af\u30c7\u30a3\u30b8\u30c3\u30c8\u691c\u8a3c\n    private static function validateISBN10CheckDigit(string $isbn): bool\n    {\n        $sum = 0;\n        $length = strlen($isbn);\n        \n        for ($i = 0; $i &lt; $length - 1; $i++) {\n            $sum += (int)$isbn[$i] * (10 - $i);\n        }\n        \n        $checkDigit = $isbn[$length - 1];\n        $checkDigit = ($checkDigit === 'X') ? 10 : (int)$checkDigit;\n        \n        $remainder = $sum % 11;\n        $calculatedCheck = (11 - $remainder) % 11;\n        \n        return $calculatedCheck === $checkDigit;\n    }\n    \n    \/\/ ISBN-13\u306e\u30c1\u30a7\u30c3\u30af\u30c7\u30a3\u30b8\u30c3\u30c8\u691c\u8a3c\n    private static function validateISBN13CheckDigit(string $isbn): bool\n    {\n        $sum = 0;\n        $length = strlen($isbn);\n        \n        for ($i = 0; $i &lt; $length - 1; $i++) {\n            $weight = ($i % 2 === 0) ? 1 : 3;\n            $sum += (int)$isbn[$i] * $weight;\n        }\n        \n        $remainder = $sum % 10;\n        $calculatedCheck = (10 - $remainder) % 10;\n        \n        return $calculatedCheck === (int)$isbn[$length - 1];\n    }\n}\n\n\/\/ ISBN\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\nclass ISBN\n{\n    private string $value;\n    private ISBNFormat $format;\n    \n    private function __construct(string $value, ISBNFormat $format)\n    {\n        $this-&gt;value = $value;\n        $this-&gt;format = $format;\n    }\n    \n    \/\/ \u6587\u5b57\u5217\u304b\u3089ISBN\u3092\u4f5c\u6210\n    public static function fromString(string $isbn): self\n    {\n        \/\/ \u30cf\u30a4\u30d5\u30f3\u3084\u7a7a\u767d\u3092\u524a\u9664\u3057\u3066\u6b63\u898f\u5316\n        $normalized = preg_replace('\/[- ]\/', '', $isbn);\n        \n        \/\/ \u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3092\u5224\u5b9a\n        $format = (strlen($normalized) === 10) \n            ? ISBNFormat::ISBN10 \n            : ((strlen($normalized) === 13) ? ISBNFormat::ISBN13 : null);\n        \n        if ($format === null) {\n            throw new \\InvalidArgumentException('\u7121\u52b9\u306aISBN\u5f62\u5f0f\u3067\u3059\u300210\u6841\u307e\u305f\u306f13\u6841\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002');\n        }\n        \n        \/\/ \u30d1\u30bf\u30fc\u30f3\u30c1\u30a7\u30c3\u30af\n        if (!preg_match($format-&gt;getValidationPattern(), $normalized)) {\n            throw new \\InvalidArgumentException('\u7121\u52b9\u306aISBN\u5f62\u5f0f\u3067\u3059: ' . $isbn);\n        }\n        \n        \/\/ \u30c1\u30a7\u30c3\u30af\u30c7\u30a3\u30b8\u30c3\u30c8\u306e\u691c\u8a3c\n        if (!$format-&gt;validateCheckDigit($normalized)) {\n            throw new \\InvalidArgumentException('\u7121\u52b9\u306aISBN\u30c1\u30a7\u30c3\u30af\u30c7\u30a3\u30b8\u30c3\u30c8\u3067\u3059: ' . $isbn);\n        }\n        \n        return new self($normalized, $format);\n    }\n    \n    \/\/ 10\u6841\u5f62\u5f0f\u304b\u308913\u6841\u5f62\u5f0f\u306b\u5909\u63db\n    public function toISBN13(): self\n    {\n        if ($this-&gt;format === ISBNFormat::ISBN13) {\n            return $this;\n        }\n        \n        \/\/ 10\u6841\u304b\u308913\u6841\u3078\u306e\u5909\u63db\u30ed\u30b8\u30c3\u30af\uff08\u7c21\u7565\u5316\uff09\n        $isbn13 = '978' . substr($this-&gt;value, 0, 9);\n        \n        \/\/ \u30c1\u30a7\u30c3\u30af\u30c7\u30a3\u30b8\u30c3\u30c8\u306e\u8a08\u7b97\n        $sum = 0;\n        for ($i = 0; $i &lt; 12; $i++) {\n            $weight = ($i % 2 === 0) ? 1 : 3;\n            $sum += (int)$isbn13[$i] * $weight;\n        }\n        \n        $remainder = $sum % 10;\n        $checkDigit = (10 - $remainder) % 10;\n        \n        $isbn13 .= $checkDigit;\n        \n        return new self($isbn13, ISBNFormat::ISBN13);\n    }\n    \n    \/\/ \u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u4ed8\u304d\u3067\u8868\u793a\n    public function format(string $separator = '-'): string\n    {\n        if ($this-&gt;format === ISBNFormat::ISBN10) {\n            return sprintf(\n                '%s%s%s%s%s',\n                substr($this-&gt;value, 0, 1),\n                $separator,\n                substr($this-&gt;value, 1, 3),\n                $separator,\n                substr($this-&gt;value, 4, 5),\n                $separator,\n                substr($this-&gt;value, 9, 1)\n            );\n        } else {\n            return sprintf(\n                '%s%s%s%s%s%s%s',\n                substr($this-&gt;value, 0, 3),\n                $separator,\n                substr($this-&gt;value, 3, 1),\n                $separator,\n                substr($this-&gt;value, 4, 6),\n                $separator,\n                substr($this-&gt;value, 10, 3)\n            );\n        }\n    }\n    \n    \/\/ \u5024\u3092\u53d6\u5f97\n    public function getValue(): string\n    {\n        return $this-&gt;value;\n    }\n    \n    \/\/ \u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3092\u53d6\u5f97\n    public function getFormat(): ISBNFormat\n    {\n        return $this-&gt;format;\n    }\n    \n    \/\/ \u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u30e9\u30d9\u30eb\u3092\u53d6\u5f97\n    public function getFormatLabel(): string\n    {\n        return $this-&gt;format-&gt;getLabel();\n    }\n    \n    \/\/ 10\u6841\u5f62\u5f0f\u304b\u3069\u3046\u304b\n    public function isISBN10(): bool\n    {\n        return $this-&gt;format === ISBNFormat::ISBN10;\n    }\n    \n    \/\/ 13\u6841\u5f62\u5f0f\u304b\u3069\u3046\u304b\n    public function isISBN13(): bool\n    {\n        return $this-&gt;format === ISBNFormat::ISBN13;\n    }\n    \n    \/\/ \u7b49\u4fa1\u6027\u306e\u5b9f\u88c5\n    public function equals(self $other): bool\n    {\n        \/\/ 13\u6841\u5f62\u5f0f\u306b\u63c3\u3048\u3066\u6bd4\u8f03\n        $this13 = $this-&gt;isISBN13() ? $this : $this-&gt;toISBN13();\n        $other13 = $other-&gt;isISBN13() ? $other : $other-&gt;toISBN13();\n        \n        return $this13-&gt;value === $other13-&gt;value;\n    }\n    \n    \/\/ \u6587\u5b57\u5217\u30ad\u30e3\u30b9\u30c8\n    public function __toString(): string\n    {\n        return $this-&gt;format-&gt;getLabel() . ': ' . $this-&gt;format();\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\ntry {\n    $isbn10 = ISBN::fromString('0-306-40615-2');\n    echo $isbn10;  \/\/ \"ISBN-10: 0-306-40615-2\"\n    \n    $isbn13 = $isbn10-&gt;toISBN13();\n    echo $isbn13;  \/\/ \"ISBN-13: 978-0-306-40615-7\"\n    \n    if ($isbn10-&gt;equals($isbn13)) {\n        echo \"\u540c\u3058\u66f8\u7c4d\u3092\u53c2\u7167\u3057\u3066\u3044\u307e\u3059\";\n    }\n} catch (\\InvalidArgumentException $e) {\n    echo $e-&gt;getMessage();\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-121\">\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068Enum\u306e\u9023\u643a\u30d1\u30bf\u30fc\u30f3<\/h4>\n\n\n\n<p>\u4e0a\u8a18\u306e\u4f8b\u304b\u3089\u3001\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068Enum\u578b\u3092\u9023\u643a\u3055\u305b\u308b\u4e3b\u306a\u30d1\u30bf\u30fc\u30f3\u304c\u898b\u3048\u3066\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Enum\u578b\u3067\u5206\u985e\u3084\u7a2e\u5225\u3092\u8868\u73fe<\/strong>\n<ul class=\"wp-block-list\">\n<li>Email\u306e\u30c9\u30e1\u30a4\u30f3\u30bf\u30a4\u30d7\u3084ISBN\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306a\u3069<\/li>\n\n\n\n<li>\u6709\u9650\u304b\u3064\u660e\u78ba\u306b\u533a\u5225\u3067\u304d\u308b\u7a2e\u5225\u3092\u8868\u73fe<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Enum\u306b\u632f\u308b\u821e\u3044\u3092\u6301\u305f\u305b\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5404\u7a2e\u5225\u306b\u56fa\u6709\u306e\u30ed\u30b8\u30c3\u30af\u3092Enum\u30e1\u30bd\u30c3\u30c9\u3068\u3057\u3066\u5b9f\u88c5<\/li>\n\n\n\n<li>\u4f8b\uff1a\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u30d1\u30bf\u30fc\u30f3\u306e\u63d0\u4f9b\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30eb\u306a\u3069<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304cEnum\u3092\u5185\u90e8\u7684\u306b\u4f7f\u7528<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304cEnum\u3092\u72b6\u614b\u3068\u3057\u3066\u4fdd\u6301<\/li>\n\n\n\n<li>Enum\u306e\u632f\u308b\u821e\u3044\u3092\u59d4\u8b72\u3057\u3066\u6d3b\u7528<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30d5\u30a1\u30af\u30c8\u30ea\u30fc\u30e1\u30bd\u30c3\u30c9\u3067\u5b89\u5168\u306a\u751f\u6210<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u306e\u9759\u7684\u30e1\u30bd\u30c3\u30c9\u3084\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u30d5\u30a1\u30af\u30c8\u30ea\u30fc\u30e1\u30bd\u30c3\u30c9\u306b\u3088\u308b\u5b89\u5168\u306a\u751f\u6210<\/li>\n\n\n\n<li>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30ed\u30b8\u30c3\u30af\u306e\u96c6\u7d04<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306a\u30d1\u30bf\u30fc\u30f3\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30d7\u30ea\u30df\u30c6\u30a3\u30d6\u306a\u578b\uff08\u6587\u5b57\u5217\u3084\u6570\u5024\uff09\u3067\u306f\u306a\u304f\u3001\u30c9\u30e1\u30a4\u30f3\u56fa\u6709\u306e\u6982\u5ff5\u3092\u578b\u3068\u3057\u3066\u8868\u73fe\u3057\u3001\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u3092\u30b3\u30fc\u30c9\u306b\u7d44\u307f\u8fbc\u3080\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068Enum\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u578b\u5b89\u5168\u6027\u3001\u30c9\u30e1\u30a4\u30f3\u77e5\u8b58\u306e\u8868\u73fe\u529b\u3001\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u304c\u5927\u304d\u304f\u5411\u4e0a\u3057\u307e\u3059\u3002\u7279\u306b\u3001DDD\u30a2\u30d7\u30ed\u30fc\u30c1\u3092\u63a1\u7528\u3059\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u3001\u3053\u306e\u30d1\u30bf\u30fc\u30f3\u304c\u975e\u5e38\u306b\u6709\u52b9\u3067\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-122\">\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3092Enum\u306b\u9589\u3058\u8fbc\u3081\u308b\u8a2d\u8a08\u30d1\u30bf\u30fc\u30f3<\/h3>\n\n\n\n<p>\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3068\u306f\u3001\u30d3\u30b8\u30cd\u30b9\u9818\u57df\u56fa\u6709\u306e\u5236\u7d04\u3084\u632f\u308b\u821e\u3044\u3092\u5b9a\u7fa9\u3059\u308b\u30eb\u30fc\u30eb\u306e\u3053\u3068\u3067\u3059\u3002\u3053\u308c\u3089\u306e\u30eb\u30fc\u30eb\u3092\u30b3\u30fc\u30c9\u3067\u8868\u73fe\u3059\u308b\u5834\u5408\u3001PHP\u306eEnum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u660e\u78ba\u3067\u4e00\u8cab\u6027\u306e\u3042\u308b\u5b9f\u88c5\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-123\">\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3068Enum<\/h4>\n\n\n\n<p>\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3092Enum\u306b\u9589\u3058\u8fbc\u3081\u308b\u3053\u3068\u306e\u4e3b\u306a\u30e1\u30ea\u30c3\u30c8\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u96c6\u4e2d\u7ba1\u7406<\/strong> \u2013 \u95a2\u9023\u3059\u308b\u30eb\u30fc\u30eb\u304c\u4e00\u7b87\u6240\u306b\u307e\u3068\u307e\u308a\u3001\u6563\u5728\u3092\u9632\u3050<\/li>\n\n\n\n<li><strong>\u81ea\u5df1\u6587\u66f8\u5316<\/strong> \u2013 \u30eb\u30fc\u30eb\u306e\u610f\u56f3\u304c\u30b3\u30fc\u30c9\u3068\u3057\u3066\u660e\u793a\u3055\u308c\u308b<\/li>\n\n\n\n<li><strong>\u578b\u5b89\u5168\u6027<\/strong> \u2013 \u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u30c1\u30a7\u30c3\u30af\u306b\u3088\u308a\u4e0d\u6b63\u306a\u5024\u306e\u6df7\u5165\u3092\u9632\u3050<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027<\/strong> \u2013 \u30eb\u30fc\u30eb\u3092\u72ec\u7acb\u3057\u3066\u30c6\u30b9\u30c8\u3067\u304d\u308b<\/li>\n\n\n\n<li><strong>\u5909\u66f4\u306e\u5c40\u6240\u5316<\/strong> \u2013 \u30eb\u30fc\u30eb\u5909\u66f4\u306e\u5f71\u97ff\u7bc4\u56f2\u3092\u6700\u5c0f\u9650\u306b\u6291\u3048\u3089\u308c\u308b<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-124\">\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f31: \u5272\u5f15\u30eb\u30fc\u30eb\u306e\u8868\u73fe<\/h4>\n\n\n\n<p>E\u30b3\u30de\u30fc\u30b9\u30b5\u30a4\u30c8\u306e\u5272\u5f15\u30eb\u30fc\u30eb\u3092Enum\u3067\u8868\u73fe\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u5272\u5f15\u30bf\u30a4\u30d7\u3092Enum\u3067\u8868\u73fe\nenum DiscountType\n{\n    case PERCENT;        \/\/ \u5272\u5408\u5272\u5f15\n    case FIXED_AMOUNT;   \/\/ \u56fa\u5b9a\u91d1\u984d\u5272\u5f15\n    case BUY_X_GET_Y;    \/\/ X\u500b\u8cb7\u3046\u3068Y\u500b\u7121\u6599\n    case BUNDLE;         \/\/ \u30bb\u30c3\u30c8\u5272\u5f15\n    \n    \/\/ \u5272\u5f15\u8a08\u7b97\u30ed\u30b8\u30c3\u30af\u3092Enum\u306b\u9589\u3058\u8fbc\u3081\u308b\n    public function calculateDiscount(float $originalPrice, array $parameters): float\n    {\n        return match($this) {\n            self::PERCENT =&gt; $this-&gt;calculatePercentDiscount($originalPrice, $parameters),\n            self::FIXED_AMOUNT =&gt; $this-&gt;calculateFixedDiscount($originalPrice, $parameters),\n            self::BUY_X_GET_Y =&gt; $this-&gt;calculateBuyXGetYDiscount($originalPrice, $parameters),\n            self::BUNDLE =&gt; $this-&gt;calculateBundleDiscount($originalPrice, $parameters),\n        };\n    }\n    \n    \/\/ \u5272\u5408\u5272\u5f15\u306e\u8a08\u7b97\n    private function calculatePercentDiscount(float $price, array $parameters): float\n    {\n        $percent = $parameters['percent'] ?? 0;\n        $maxDiscount = $parameters['max_discount'] ?? PHP_FLOAT_MAX;\n        \n        $discount = $price * ($percent \/ 100);\n        return min($discount, $maxDiscount);\n    }\n    \n    \/\/ \u56fa\u5b9a\u91d1\u984d\u5272\u5f15\u306e\u8a08\u7b97\n    private function calculateFixedDiscount(float $price, array $parameters): float\n    {\n        $amount = $parameters['amount'] ?? 0;\n        return min($amount, $price); \/\/ \u5546\u54c1\u4fa1\u683c\u3092\u8d85\u3048\u308b\u5272\u5f15\u306f\u3067\u304d\u306a\u3044\n    }\n    \n    \/\/ X\u500b\u8cb7\u3046\u3068Y\u500b\u7121\u6599\u306e\u5272\u5f15\u8a08\u7b97\n    private function calculateBuyXGetYDiscount(float $price, array $parameters): float\n    {\n        $quantity = $parameters['quantity'] ?? 1;\n        $buyCount = $parameters['buy_count'] ?? 1;\n        $getFreeCount = $parameters['get_free_count'] ?? 0;\n        \n        if ($quantity &lt; $buyCount) {\n            return 0; \/\/ \u6761\u4ef6\u3092\u6e80\u305f\u3055\u306a\u3044\u5834\u5408\u306f\u5272\u5f15\u306a\u3057\n        }\n        \n        $sets = floor($quantity \/ ($buyCount + $getFreeCount));\n        $freeItems = min($sets * $getFreeCount, $quantity - $buyCount);\n        \n        $unitPrice = $price \/ $quantity;\n        return $freeItems * $unitPrice;\n    }\n    \n    \/\/ \u30bb\u30c3\u30c8\u5272\u5f15\u306e\u8a08\u7b97\n    private function calculateBundleDiscount(float $price, array $parameters): float\n    {\n        $bundleDiscount = $parameters['bundle_discount'] ?? 0;\n        $requiredCategories = $parameters['required_categories'] ?? [];\n        $presentCategories = $parameters['present_categories'] ?? [];\n        \n        \/\/ \u3059\u3079\u3066\u306e\u5fc5\u8981\u30ab\u30c6\u30b4\u30ea\u304c\u63c3\u3063\u3066\u3044\u308b\u304b\u78ba\u8a8d\n        $allCategoriesPresent = empty(array_diff($requiredCategories, $presentCategories));\n        \n        return $allCategoriesPresent ? $bundleDiscount : 0;\n    }\n    \n    \/\/ \u5272\u5f15\u306e\u8aac\u660e\u3092\u53d6\u5f97\n    public function getDescription(array $parameters): string\n    {\n        return match($this) {\n            self::PERCENT =&gt; $parameters['percent'] . '%\u5272\u5f15',\n            self::FIXED_AMOUNT =&gt; number_format($parameters['amount']) . '\u5186\u5272\u5f15',\n            self::BUY_X_GET_Y =&gt; $parameters['buy_count'] . '\u500b\u8cb7\u3046\u3068' . $parameters['get_free_count'] . '\u500b\u7121\u6599',\n            self::BUNDLE =&gt; '\u30bb\u30c3\u30c8\u5272\u5f15',\n        };\n    }\n    \n    \/\/ \u5272\u5f15\u306e\u9069\u7528\u6761\u4ef6\u3092\u30c1\u30a7\u30c3\u30af\n    public function isApplicable(array $orderData, array $parameters): bool\n    {\n        return match($this) {\n            self::PERCENT, self::FIXED_AMOUNT =&gt; true, \/\/ \u57fa\u672c\u7684\u306b\u5e38\u306b\u9069\u7528\u53ef\u80fd\n            self::BUY_X_GET_Y =&gt; $orderData['quantity'] &gt;= ($parameters['buy_count'] ?? 1),\n            self::BUNDLE =&gt; $this-&gt;checkBundleRequirements($orderData, $parameters),\n        };\n    }\n    \n    \/\/ \u30bb\u30c3\u30c8\u5272\u5f15\u306e\u6761\u4ef6\u30c1\u30a7\u30c3\u30af\n    private function checkBundleRequirements(array $orderData, array $parameters): bool\n    {\n        $requiredCategories = $parameters['required_categories'] ?? [];\n        $orderCategories = $orderData['categories'] ?? [];\n        \n        return empty(array_diff($requiredCategories, $orderCategories));\n    }\n}\n\n\/\/ \u5272\u5f15\u30eb\u30fc\u30eb\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u30af\u30e9\u30b9\nclass Discount\n{\n    private DiscountType $type;\n    private array $parameters;\n    \n    public function __construct(DiscountType $type, array $parameters)\n    {\n        $this-&gt;type = $type;\n        $this-&gt;parameters = $parameters;\n    }\n    \n    \/\/ \u5272\u5f15\u91d1\u984d\u3092\u8a08\u7b97\n    public function apply(float $price, array $orderData = []): float\n    {\n        if (!$this-&gt;isApplicable($orderData)) {\n            return 0;\n        }\n        \n        return $this-&gt;type-&gt;calculateDiscount($price, $this-&gt;parameters);\n    }\n    \n    \/\/ \u9069\u7528\u6761\u4ef6\u3092\u30c1\u30a7\u30c3\u30af\n    public function isApplicable(array $orderData): bool\n    {\n        return $this-&gt;type-&gt;isApplicable($orderData, $this-&gt;parameters);\n    }\n    \n    \/\/ \u5272\u5f15\u306e\u8aac\u660e\u3092\u53d6\u5f97\n    public function getDescription(): string\n    {\n        return $this-&gt;type-&gt;getDescription($this-&gt;parameters);\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n\/\/ 20%\u5272\u5f15\uff08\u6700\u59272000\u5186\u307e\u3067\uff09\u3092\u4f5c\u6210\n$percentDiscount = new Discount(\n    DiscountType::PERCENT,\n    ['percent' =&gt; 20, 'max_discount' =&gt; 2000]\n);\n\n\/\/ 3\u500b\u8cb7\u3046\u30681\u500b\u7121\u6599\u306e\u5272\u5f15\n$buyXGetYDiscount = new Discount(\n    DiscountType::BUY_X_GET_Y,\n    ['buy_count' =&gt; 3, 'get_free_count' =&gt; 1]\n);\n\n\/\/ \u5272\u5f15\u306e\u9069\u7528\n$orderData = ['quantity' =&gt; 4, 'categories' =&gt; ['electronics', 'accessories']];\n$originalPrice = 10000;\n\n$discount1 = $percentDiscount-&gt;apply($originalPrice, $orderData);\n$discount2 = $buyXGetYDiscount-&gt;apply($originalPrice, $orderData);\n\necho \"\u5272\u5f151: \" . $percentDiscount-&gt;getDescription() . \" - \" . $discount1 . \"\u5186\\n\";\necho \"\u5272\u5f152: \" . $buyXGetYDiscount-&gt;getDescription() . \" - \" . $discount2 . \"\u5186\\n\";\n<\/pre>\n\n\n\n<p>\u3053\u306e\u30d1\u30bf\u30fc\u30f3\u3067\u306f\u3001DiscountType\u3068\u3044\u3046Enum\u306b\u5272\u5f15\u8a08\u7b97\u30ed\u30b8\u30c3\u30af\u3068\u30eb\u30fc\u30eb\u3092\u9589\u3058\u8fbc\u3081\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u65b0\u3057\u3044\u5272\u5f15\u30bf\u30a4\u30d7\u3092\u8ffd\u52a0\u3059\u308b\u969b\u3082\u3001Enum\u306b\u65b0\u3057\u3044\u30b1\u30fc\u30b9\u3068\u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\u3059\u308b\u3060\u3051\u3067\u6e08\u307f\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-125\">\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f32: \u8cc7\u683c\u5224\u5b9a\u30eb\u30fc\u30eb<\/h4>\n\n\n\n<p>\u30e6\u30fc\u30b6\u30fc\u306e\u8cc7\u683c\u3084\u6a29\u9650\u5224\u5b9a\u30eb\u30fc\u30eb\u3092Enum\u306b\u9589\u3058\u8fbc\u3081\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u4f1a\u54e1\u8cc7\u683c\u30ec\u30d9\u30eb\u3092Enum\u3067\u8868\u73fe\nenum MembershipTier\n{\n    case BRONZE;\n    case SILVER;\n    case GOLD;\n    case PLATINUM;\n    \n    \/\/ \u5fc5\u8981\u306a\u30dd\u30a4\u30f3\u30c8\u6570\u3092\u53d6\u5f97\n    public function getRequiredPoints(): int\n    {\n        return match($this) {\n            self::BRONZE =&gt; 0,\n            self::SILVER =&gt; 100,\n            self::GOLD =&gt; 500,\n            self::PLATINUM =&gt; 1000,\n        };\n    }\n    \n    \/\/ \u6240\u5b9a\u306e\u30dd\u30a4\u30f3\u30c8\u3067\u306e\u30e9\u30f3\u30af\u3092\u53d6\u5f97\n    public static function fromPoints(int $points): self\n    {\n        if ($points &gt;= self::PLATINUM-&gt;getRequiredPoints()) {\n            return self::PLATINUM;\n        } elseif ($points &gt;= self::GOLD-&gt;getRequiredPoints()) {\n            return self::GOLD;\n        } elseif ($points &gt;= self::SILVER-&gt;getRequiredPoints()) {\n            return self::SILVER;\n        } else {\n            return self::BRONZE;\n        }\n    }\n    \n    \/\/ \u30e9\u30f3\u30af\u30a2\u30c3\u30d7\u306b\u5fc5\u8981\u306a\u6b8b\u308a\u30dd\u30a4\u30f3\u30c8\u3092\u8a08\u7b97\n    public function pointsToNextTier(int $currentPoints): ?int\n    {\n        $nextTier = $this-&gt;getNextTier();\n        if ($nextTier === null) {\n            return null; \/\/ \u6700\u9ad8\u30e9\u30f3\u30af\u306e\u5834\u5408\u306fnull\n        }\n        \n        return max(0, $nextTier-&gt;getRequiredPoints() - $currentPoints);\n    }\n    \n    \/\/ \u6b21\u306e\u30e9\u30f3\u30af\u3092\u53d6\u5f97\n    public function getNextTier(): ?self\n    {\n        return match($this) {\n            self::BRONZE =&gt; self::SILVER,\n            self::SILVER =&gt; self::GOLD,\n            self::GOLD =&gt; self::PLATINUM,\n            self::PLATINUM =&gt; null, \/\/ \u6700\u9ad8\u30e9\u30f3\u30af\n        };\n    }\n    \n    \/\/ \u7279\u5178\u30ea\u30b9\u30c8\u3092\u53d6\u5f97\n    public function getBenefits(): array\n    {\n        $baseBenefits = ['\u57fa\u672c\u30b5\u30dd\u30fc\u30c8'];\n        \n        return match($this) {\n            self::BRONZE =&gt; $baseBenefits,\n            self::SILVER =&gt; [...$baseBenefits, '5%\u5272\u5f15', '\u512a\u5148\u30ab\u30b9\u30bf\u30de\u30fc\u30b5\u30dd\u30fc\u30c8'],\n            self::GOLD =&gt; [...self::SILVER-&gt;getBenefits(), '\u8a95\u751f\u65e5\u30ae\u30d5\u30c8', '\u9650\u5b9a\u30a4\u30d9\u30f3\u30c8'],\n            self::PLATINUM =&gt; [...self::GOLD-&gt;getBenefits(), '\u30b3\u30f3\u30b7\u30a7\u30eb\u30b8\u30e5\u30b5\u30fc\u30d3\u30b9', 'VIP\u30a4\u30d9\u30f3\u30c8', '\u7121\u6599\u914d\u9001'],\n        };\n    }\n    \n    \/\/ \u30dd\u30a4\u30f3\u30c8\u7372\u5f97\u500d\u7387\u3092\u53d6\u5f97\n    public function getPointMultiplier(): float\n    {\n        return match($this) {\n            self::BRONZE =&gt; 1.0,\n            self::SILVER =&gt; 1.2,\n            self::GOLD =&gt; 1.5,\n            self::PLATINUM =&gt; 2.0,\n        };\n    }\n    \n    \/\/ \u8868\u793a\u540d\u3092\u53d6\u5f97\n    public function getDisplayName(): string\n    {\n        return match($this) {\n            self::BRONZE =&gt; '\u30d6\u30ed\u30f3\u30ba\u4f1a\u54e1',\n            self::SILVER =&gt; '\u30b7\u30eb\u30d0\u30fc\u4f1a\u54e1',\n            self::GOLD =&gt; '\u30b4\u30fc\u30eb\u30c9\u4f1a\u54e1',\n            self::PLATINUM =&gt; '\u30d7\u30e9\u30c1\u30ca\u4f1a\u54e1',\n        };\n    }\n}\n\n\/\/ \u4f1a\u54e1\u30af\u30e9\u30b9\nclass Member\n{\n    private string $name;\n    private int $points;\n    private MembershipTier $tier;\n    \n    public function __construct(string $name, int $points)\n    {\n        $this-&gt;name = $name;\n        $this-&gt;points = $points;\n        $this-&gt;tier = MembershipTier::fromPoints($points);\n    }\n    \n    \/\/ \u30dd\u30a4\u30f3\u30c8\u8ffd\u52a0\n    public function addPoints(int $amount): void\n    {\n        $multiplier = $this-&gt;tier-&gt;getPointMultiplier();\n        $this-&gt;points += (int)($amount * $multiplier);\n        \n        \/\/ \u30dd\u30a4\u30f3\u30c8\u66f4\u65b0\u5f8c\u306b\u30e9\u30f3\u30af\u3092\u518d\u8a08\u7b97\n        $this-&gt;tier = MembershipTier::fromPoints($this-&gt;points);\n    }\n    \n    \/\/ \u73fe\u5728\u306e\u30e9\u30f3\u30af\u3067\u306e\u7279\u5178\u30ea\u30b9\u30c8\n    public function getBenefits(): array\n    {\n        return $this-&gt;tier-&gt;getBenefits();\n    }\n    \n    \/\/ \u6b21\u306e\u30e9\u30f3\u30af\u307e\u3067\u306e\u6b8b\u308a\u30dd\u30a4\u30f3\u30c8\n    public function getPointsToNextTier(): ?int\n    {\n        return $this-&gt;tier-&gt;pointsToNextTier($this-&gt;points);\n    }\n    \n    \/\/ \u4f1a\u54e1\u60c5\u5831\u306e\u8868\u793a\n    public function getMemberInfo(): array\n    {\n        $nextTierPoints = $this-&gt;getPointsToNextTier();\n        \n        return [\n            'name' =&gt; $this-&gt;name,\n            'points' =&gt; $this-&gt;points,\n            'tier' =&gt; $this-&gt;tier-&gt;getDisplayName(),\n            'benefits' =&gt; $this-&gt;getBenefits(),\n            'nextTier' =&gt; $this-&gt;tier-&gt;getNextTier()?-&gt;getDisplayName(),\n            'pointsToNextTier' =&gt; $nextTierPoints,\n        ];\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$member = new Member('\u5c71\u7530\u592a\u90ce', 300);\n$info = $member-&gt;getMemberInfo();\n\necho \"\u4f1a\u54e1\u540d: {$info['name']}\\n\";\necho \"\u4f1a\u54e1\u30e9\u30f3\u30af: {$info['tier']}\\n\";\necho \"\u30dd\u30a4\u30f3\u30c8: {$info['points']}\\n\";\necho \"\u7279\u5178: \" . implode(', ', $info['benefits']) . \"\\n\";\n\nif ($info['nextTier']) {\n    echo \"\u6b21\u306e\u30e9\u30f3\u30af {$info['nextTier']} \u307e\u3067\u3042\u3068{$info['pointsToNextTier']}\u30dd\u30a4\u30f3\u30c8\\n\";\n}\n\n\/\/ \u30dd\u30a4\u30f3\u30c8\u52a0\u7b97\n$member-&gt;addPoints(100);\n$newInfo = $member-&gt;getMemberInfo();\necho \"\u65b0\u3057\u3044\u30dd\u30a4\u30f3\u30c8: {$newInfo['points']}\\n\";\necho \"\u65b0\u3057\u3044\u30e9\u30f3\u30af: {$newInfo['tier']}\\n\";\n<\/pre>\n\n\n\n<p>\u3053\u306e\u30d1\u30bf\u30fc\u30f3\u3067\u306f\u3001MembershipTier\u3068\u3044\u3046Enum\u306b\u4f1a\u54e1\u8cc7\u683c\u306b\u95a2\u3059\u308b\u30eb\u30fc\u30eb\u3084\u632f\u308b\u821e\u3044\u3092\u9589\u3058\u8fbc\u3081\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u4f1a\u54e1\u8cc7\u683c\u306e\u30ed\u30b8\u30c3\u30af\u304c\u4e00\u7b87\u6240\u306b\u96c6\u4e2d\u3057\u3001\u5909\u66f4\u304c\u5bb9\u6613\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-126\">\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3092Enum\u306b\u9589\u3058\u8fbc\u3081\u308b\u969b\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4e00\u3064\u306eEnum\u306b\u4e00\u3064\u306e\u6982\u5ff5\u3092\u8868\u73fe\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5358\u4e00\u8cac\u4efb\u306e\u539f\u5247\u3092\u5b88\u308a\u3001\u95a2\u9023\u3059\u308b\u6982\u5ff5\u306e\u307f\u3092\u30b0\u30eb\u30fc\u30d7\u5316<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30e1\u30bd\u30c3\u30c9\u540d\u306f\u610f\u56f3\u3092\u660e\u78ba\u306b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30c9\u30e1\u30a4\u30f3\u306e\u8a00\u8449\u3092\u4f7f\u3044\u3001\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u3092\u81ea\u5df1\u6587\u66f8\u5316<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u9759\u7684\u30e1\u30bd\u30c3\u30c9\u3068\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u30e1\u30bd\u30c3\u30c9\u3092\u4f7f\u3044\u5206\u3051\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5909\u63db\u3084\u751f\u6210\u306b\u306f\u9759\u7684\u30e1\u30bd\u30c3\u30c9<\/li>\n\n\n\n<li>\u72b6\u614b\u306b\u4f9d\u5b58\u3059\u308b\u632f\u308b\u821e\u3044\u306b\u306f\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u30e1\u30bd\u30c3\u30c9<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30eb\u30fc\u30eb\u306e\u4f8b\u5916\u306b\u3082\u5bfe\u5fdc<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u7279\u6b8a\u306a\u30b1\u30fc\u30b9\u3082\u660e\u793a\u7684\u306b\u53d6\u308a\u6271\u3046<\/li>\n\n\n\n<li>\u672a\u77e5\u306e\u5024\u306b\u5bfe\u3059\u308b\u6319\u52d5\u3092\u660e\u78ba\u306b\u5b9a\u7fa9<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027\u3092\u610f\u8b58<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5404\u30eb\u30fc\u30eb\u3092\u72ec\u7acb\u3057\u3066\u30c6\u30b9\u30c8\u3067\u304d\u308b\u3088\u3046\u8a2d\u8a08<\/li>\n\n\n\n<li>\u8907\u96d1\u306a\u30b1\u30fc\u30b9\u3082\u500b\u5225\u306b\u30c6\u30b9\u30c8\u53ef\u80fd\u306b<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u306b\u30c9\u30e1\u30a4\u30f3\u30eb\u30fc\u30eb\u3092\u9589\u3058\u8fbc\u3081\u308b\u3053\u3068\u3067\u3001\u30eb\u30fc\u30eb\u306e\u5909\u66f4\u3084\u62e1\u5f35\u304c\u5bb9\u6613\u306b\u306a\u308a\u3001\u30b3\u30fc\u30c9\u306e\u4fdd\u5b88\u6027\u3068\u53ef\u8aad\u6027\u3092\u5927\u304d\u304f\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002DDD\u306e\u8003\u3048\u65b9\u306b\u6cbf\u3063\u305f\u3053\u306e\u30d1\u30bf\u30fc\u30f3\u306f\u3001\u7279\u306b\u8907\u96d1\u306a\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u3092\u6301\u3064\u30b7\u30b9\u30c6\u30e0\u3067\u52b9\u679c\u3092\u767a\u63ee\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-127\">\u5b9f\u8df5\u4f8b5\uff1aAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u3068\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/h2>\n\n\n\n<p>API\u306e\u8a2d\u8a08\u306b\u304a\u3044\u3066\u3001\u4e00\u8cab\u6027\u306e\u3042\u308b\u30ec\u30b9\u30dd\u30f3\u30b9\u5f62\u5f0f\u3068\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306f\u975e\u5e38\u306b\u91cd\u8981\u3067\u3059\u3002PHP\u306eEnum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u660e\u78ba\u3067\u30bf\u30a4\u30d7\u30bb\u30fc\u30d5\u306aAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u3068\u30a8\u30e9\u30fc\u7ba1\u7406\u304c\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-128\">API\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u6a19\u6e96\u5316<\/h3>\n\n\n\n<p>API\u30ec\u30b9\u30dd\u30f3\u30b9\u306f\u4e00\u8cab\u6027\u306e\u3042\u308b\u69cb\u9020\u3092\u6301\u3061\u3001\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u4e88\u6e2c\u3057\u3084\u3059\u3044\u5f62\u5f0f\u3067\u3042\u308b\u3079\u304d\u3067\u3059\u3002Enum\u3092\u4f7f\u3063\u3066\u3001\u3053\u306e\u3088\u3046\u306a\u6a19\u6e96\u5316\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ API\u30ec\u30b9\u30dd\u30f3\u30b9\u30b9\u30c6\u30fc\u30bf\u30b9\u3092Enum\u3067\u8868\u73fe\nenum ApiResponseStatus: string\n{\n    case SUCCESS = 'success';\n    case ERROR = 'error';\n    case VALIDATION_ERROR = 'validation_error';\n    case UNAUTHORIZED = 'unauthorized';\n    case FORBIDDEN = 'forbidden';\n    case NOT_FOUND = 'not_found';\n    case INTERNAL_ERROR = 'internal_error';\n    \n    \/\/ HTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\n    public function getHttpCode(): int\n    {\n        return match($this) {\n            self::SUCCESS =&gt; 200,\n            self::ERROR =&gt; 400,\n            self::VALIDATION_ERROR =&gt; 422,\n            self::UNAUTHORIZED =&gt; 401,\n            self::FORBIDDEN =&gt; 403,\n            self::NOT_FOUND =&gt; 404,\n            self::INTERNAL_ERROR =&gt; 500,\n        };\n    }\n    \n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u8aac\u660e\n    public function getDescription(): string\n    {\n        return match($this) {\n            self::SUCCESS =&gt; '\u30ea\u30af\u30a8\u30b9\u30c8\u306f\u6b63\u5e38\u306b\u51e6\u7406\u3055\u308c\u307e\u3057\u305f',\n            self::ERROR =&gt; '\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u51e6\u7406\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            self::VALIDATION_ERROR =&gt; '\u5165\u529b\u30c7\u30fc\u30bf\u304c\u7121\u52b9\u3067\u3059',\n            self::UNAUTHORIZED =&gt; '\u8a8d\u8a3c\u304c\u5fc5\u8981\u3067\u3059',\n            self::FORBIDDEN =&gt; '\u30a2\u30af\u30bb\u30b9\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093',\n            self::NOT_FOUND =&gt; '\u30ea\u30af\u30a8\u30b9\u30c8\u3055\u308c\u305f\u30ea\u30bd\u30fc\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093',\n            self::INTERNAL_ERROR =&gt; '\u30b5\u30fc\u30d0\u30fc\u5185\u90e8\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n        };\n    }\n    \n    \/\/ \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30a8\u30e9\u30fc\u304b\u3069\u3046\u304b\n    public function isClientError(): bool\n    {\n        return in_array($this, [\n            self::ERROR,\n            self::VALIDATION_ERROR,\n            self::UNAUTHORIZED,\n            self::FORBIDDEN,\n            self::NOT_FOUND\n        ]);\n    }\n    \n    \/\/ \u30b5\u30fc\u30d0\u30fc\u30a8\u30e9\u30fc\u304b\u3069\u3046\u304b\n    public function isServerError(): bool\n    {\n        return $this === self::INTERNAL_ERROR;\n    }\n    \n    \/\/ \u6210\u529f\u304b\u3069\u3046\u304b\n    public function isSuccess(): bool\n    {\n        return $this === self::SUCCESS;\n    }\n}\n\n\/\/ API\u30ec\u30b9\u30dd\u30f3\u30b9\u30af\u30e9\u30b9\nclass ApiResponse\n{\n    private ApiResponseStatus $status;\n    private mixed $data;\n    private ?array $errors;\n    private ?string $message;\n    \n    public function __construct(\n        ApiResponseStatus $status,\n        mixed $data = null,\n        ?array $errors = null,\n        ?string $message = null\n    ) {\n        $this-&gt;status = $status;\n        $this-&gt;data = $data;\n        $this-&gt;errors = $errors;\n        $this-&gt;message = $message ?? $status-&gt;getDescription();\n    }\n    \n    \/\/ \u6210\u529f\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u4f5c\u6210\n    public static function success(mixed $data = null, ?string $message = null): self\n    {\n        return new self(ApiResponseStatus::SUCCESS, $data, null, $message);\n    }\n    \n    \/\/ \u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u4f5c\u6210\n    public static function error(\n        ApiResponseStatus $status = ApiResponseStatus::ERROR,\n        ?array $errors = null,\n        ?string $message = null\n    ): self {\n        return new self($status, null, $errors, $message);\n    }\n    \n    \/\/ \u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u914d\u5217\u306b\u5909\u63db\n    public function toArray(): array\n    {\n        $response = [\n            'status' =&gt; $this-&gt;status-&gt;value,\n            'message' =&gt; $this-&gt;message,\n        ];\n        \n        if ($this-&gt;data !== null) {\n            $response['data'] = $this-&gt;data;\n        }\n        \n        if ($this-&gt;errors !== null) {\n            $response['errors'] = $this-&gt;errors;\n        }\n        \n        return $response;\n    }\n    \n    \/\/ JSON\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u9001\u4fe1\n    public function send(): void\n    {\n        http_response_code($this-&gt;status-&gt;getHttpCode());\n        header('Content-Type: application\/json');\n        echo json_encode($this-&gt;toArray());\n        exit;\n    }\n    \n    \/\/ \u30b2\u30c3\u30bf\u30fc\n    public function getStatus(): ApiResponseStatus\n    {\n        return $this-&gt;status;\n    }\n    \n    public function getData(): mixed\n    {\n        return $this-&gt;data;\n    }\n    \n    public function getErrors(): ?array\n    {\n        return $this-&gt;errors;\n    }\n    \n    public function getMessage(): string\n    {\n        return $this-&gt;message;\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-129\">\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u7ba1\u7406<\/h3>\n\n\n\n<p>\u3055\u3089\u306b\u8a73\u7d30\u306a\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3092Enum\u3067\u7ba1\u7406\u3059\u308b\u3053\u3068\u3067\u3001\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u30a8\u30e9\u30fc\u3092\u9069\u5207\u306b\u51e6\u7406\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u56fa\u6709\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3092Enum\u3067\u5b9a\u7fa9\nenum AppErrorCode: string\n{\n    \/\/ \u8a8d\u8a3c\u95a2\u9023\u30a8\u30e9\u30fc\n    case AUTH_INVALID_CREDENTIALS = 'auth.invalid_credentials';\n    case AUTH_TOKEN_EXPIRED = 'auth.token_expired';\n    case AUTH_INVALID_TOKEN = 'auth.invalid_token';\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u95a2\u9023\u30a8\u30e9\u30fc\n    case USER_NOT_FOUND = 'user.not_found';\n    case USER_EMAIL_DUPLICATE = 'user.email_duplicate';\n    case USER_INSUFFICIENT_PERMISSION = 'user.insufficient_permission';\n    \n    \/\/ \u5165\u529b\u691c\u8a3c\u30a8\u30e9\u30fc\n    case VALIDATION_REQUIRED_FIELD = 'validation.required_field';\n    case VALIDATION_INVALID_FORMAT = 'validation.invalid_format';\n    case VALIDATION_INVALID_VALUE = 'validation.invalid_value';\n    \n    \/\/ \u30ea\u30bd\u30fc\u30b9\u95a2\u9023\u30a8\u30e9\u30fc\n    case RESOURCE_NOT_FOUND = 'resource.not_found';\n    case RESOURCE_ALREADY_EXISTS = 'resource.already_exists';\n    case RESOURCE_LOCKED = 'resource.locked';\n    \n    \/\/ \u30b7\u30b9\u30c6\u30e0\u30a8\u30e9\u30fc\n    case SYSTEM_DATABASE_ERROR = 'system.database_error';\n    case SYSTEM_SERVICE_UNAVAILABLE = 'system.service_unavailable';\n    case SYSTEM_UNEXPECTED_ERROR = 'system.unexpected_error';\n    \n    \/\/ \u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306e\u30ab\u30c6\u30b4\u30ea\u3092\u53d6\u5f97\n    public function getCategory(): string\n    {\n        return explode('.', $this-&gt;value)[0];\n    }\n    \n    \/\/ HTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3078\u306e\u30de\u30c3\u30d4\u30f3\u30b0\n    public function getHttpStatus(): ApiResponseStatus\n    {\n        return match($this-&gt;getCategory()) {\n            'auth' =&gt; match($this) {\n                self::AUTH_INVALID_CREDENTIALS =&gt; ApiResponseStatus::UNAUTHORIZED,\n                self::AUTH_TOKEN_EXPIRED =&gt; ApiResponseStatus::UNAUTHORIZED,\n                self::AUTH_INVALID_TOKEN =&gt; ApiResponseStatus::UNAUTHORIZED,\n            },\n            'user' =&gt; match($this) {\n                self::USER_NOT_FOUND =&gt; ApiResponseStatus::NOT_FOUND,\n                self::USER_EMAIL_DUPLICATE =&gt; ApiResponseStatus::VALIDATION_ERROR,\n                self::USER_INSUFFICIENT_PERMISSION =&gt; ApiResponseStatus::FORBIDDEN,\n            },\n            'validation' =&gt; ApiResponseStatus::VALIDATION_ERROR,\n            'resource' =&gt; match($this) {\n                self::RESOURCE_NOT_FOUND =&gt; ApiResponseStatus::NOT_FOUND,\n                self::RESOURCE_ALREADY_EXISTS =&gt; ApiResponseStatus::VALIDATION_ERROR,\n                self::RESOURCE_LOCKED =&gt; ApiResponseStatus::FORBIDDEN,\n            },\n            'system' =&gt; ApiResponseStatus::INTERNAL_ERROR,\n            default =&gt; ApiResponseStatus::ERROR,\n        };\n    }\n    \n    \/\/ \u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u53d6\u5f97\uff08\u4f8b\u3068\u3057\u3066\u65e5\u672c\u8a9e\uff09\n    public function getJapaneseMessage(): string\n    {\n        return match($this) {\n            self::AUTH_INVALID_CREDENTIALS =&gt; '\u30e6\u30fc\u30b6\u30fc\u540d\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093',\n            self::AUTH_TOKEN_EXPIRED =&gt; '\u8a8d\u8a3c\u30c8\u30fc\u30af\u30f3\u306e\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u3066\u3044\u307e\u3059',\n            self::AUTH_INVALID_TOKEN =&gt; '\u7121\u52b9\u306a\u8a8d\u8a3c\u30c8\u30fc\u30af\u30f3\u3067\u3059',\n            \n            self::USER_NOT_FOUND =&gt; '\u6307\u5b9a\u3055\u308c\u305f\u30e6\u30fc\u30b6\u30fc\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093',\n            self::USER_EMAIL_DUPLICATE =&gt; '\u3053\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u65e2\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059',\n            self::USER_INSUFFICIENT_PERMISSION =&gt; '\u3053\u306e\u64cd\u4f5c\u3092\u884c\u3046\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093',\n            \n            self::VALIDATION_REQUIRED_FIELD =&gt; '\u5fc5\u9808\u9805\u76ee\u304c\u5165\u529b\u3055\u308c\u3066\u3044\u307e\u305b\u3093',\n            self::VALIDATION_INVALID_FORMAT =&gt; '\u5165\u529b\u5f62\u5f0f\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093',\n            self::VALIDATION_INVALID_VALUE =&gt; '\u7121\u52b9\u306a\u5024\u304c\u6307\u5b9a\u3055\u308c\u307e\u3057\u305f',\n            \n            self::RESOURCE_NOT_FOUND =&gt; '\u30ea\u30bd\u30fc\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093',\n            self::RESOURCE_ALREADY_EXISTS =&gt; '\u30ea\u30bd\u30fc\u30b9\u306f\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059',\n            self::RESOURCE_LOCKED =&gt; '\u30ea\u30bd\u30fc\u30b9\u306f\u73fe\u5728\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059',\n            \n            self::SYSTEM_DATABASE_ERROR =&gt; '\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            self::SYSTEM_SERVICE_UNAVAILABLE =&gt; '\u73fe\u5728\u30b5\u30fc\u30d3\u30b9\u3092\u3054\u5229\u7528\u3044\u305f\u3060\u3051\u307e\u305b\u3093',\n            self::SYSTEM_UNEXPECTED_ERROR =&gt; '\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n        };\n    }\n    \n    \/\/ \u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u53d6\u5f97\uff08\u4f8b\u3068\u3057\u3066\u82f1\u8a9e\uff09\n    public function getEnglishMessage(): string\n    {\n        return match($this) {\n            self::AUTH_INVALID_CREDENTIALS =&gt; 'Invalid username or password',\n            self::AUTH_TOKEN_EXPIRED =&gt; 'Authentication token has expired',\n            self::AUTH_INVALID_TOKEN =&gt; 'Invalid authentication token',\n            \n            \/\/ \u4ed6\u306e\u82f1\u8a9e\u30e1\u30c3\u30bb\u30fc\u30b8\u3082\u540c\u69d8\u306b\u5b9a\u7fa9\n            default =&gt; 'An error occurred',\n        };\n    }\n    \n    \/\/ \u30ed\u30b1\u30fc\u30eb\u306b\u5fdc\u3058\u305f\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u53d6\u5f97\n    public function getLocalizedMessage(string $locale = 'ja'): string\n    {\n        return match($locale) {\n            'ja' =&gt; $this-&gt;getJapaneseMessage(),\n            'en' =&gt; $this-&gt;getEnglishMessage(),\n            default =&gt; $this-&gt;getJapaneseMessage(), \/\/ \u30c7\u30d5\u30a9\u30eb\u30c8\u306f\u65e5\u672c\u8a9e\n        };\n    }\n}\n\n\/\/ API\u4f8b\u5916\u30af\u30e9\u30b9\nclass ApiException extends \\Exception\n{\n    private AppErrorCode $errorCode;\n    private ?array $additionalData;\n    \n    public function __construct(\n        AppErrorCode $errorCode,\n        ?string $message = null,\n        ?array $additionalData = null,\n        int $code = 0,\n        ?\\Throwable $previous = null\n    ) {\n        $this-&gt;errorCode = $errorCode;\n        $this-&gt;additionalData = $additionalData;\n        \n        parent::__construct(\n            $message ?? $errorCode-&gt;getJapaneseMessage(),\n            $code,\n            $previous\n        );\n    }\n    \n    public function getErrorCode(): AppErrorCode\n    {\n        return $this-&gt;errorCode;\n    }\n    \n    public function getAdditionalData(): ?array\n    {\n        return $this-&gt;additionalData;\n    }\n    \n    \/\/ API\u30ec\u30b9\u30dd\u30f3\u30b9\u306b\u5909\u63db\n    public function toApiResponse(string $locale = 'ja'): ApiResponse\n    {\n        $httpStatus = $this-&gt;errorCode-&gt;getHttpStatus();\n        $message = $this-&gt;getMessage() ?: $this-&gt;errorCode-&gt;getLocalizedMessage($locale);\n        \n        $errors = [\n            'code' =&gt; $this-&gt;errorCode-&gt;value,\n            'message' =&gt; $message,\n        ];\n        \n        if ($this-&gt;additionalData) {\n            $errors['details'] = $this-&gt;additionalData;\n        }\n        \n        return ApiResponse::error($httpStatus, [$errors], $httpStatus-&gt;getDescription());\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-130\">\u5b9f\u969b\u306e\u4f7f\u7528\u4f8b<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ API \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u4f7f\u7528\u4f8b\nclass UserController\n{\n    private UserRepository $userRepository;\n    \n    public function __construct(UserRepository $userRepository)\n    {\n        $this-&gt;userRepository = $userRepository;\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u767b\u9332API\n    public function register(): void\n    {\n        try {\n            \/\/ \u30ea\u30af\u30a8\u30b9\u30c8\u30c7\u30fc\u30bf\u306e\u53d6\u5f97\n            $requestData = json_decode(file_get_contents('php:\/\/input'), true);\n            \n            \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n            if (empty($requestData['email'])) {\n                throw new ApiException(\n                    AppErrorCode::VALIDATION_REQUIRED_FIELD,\n                    null,\n                    ['field' =&gt; 'email']\n                );\n            }\n            \n            \/\/ \u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u91cd\u8907\u30c1\u30a7\u30c3\u30af\n            if ($this-&gt;userRepository-&gt;emailExists($requestData['email'])) {\n                throw new ApiException(AppErrorCode::USER_EMAIL_DUPLICATE);\n            }\n            \n            \/\/ \u30e6\u30fc\u30b6\u30fc\u4f5c\u6210\n            $user = $this-&gt;userRepository-&gt;create($requestData);\n            \n            \/\/ \u6210\u529f\u30ec\u30b9\u30dd\u30f3\u30b9\n            ApiResponse::success(['user' =&gt; $user], '\u30e6\u30fc\u30b6\u30fc\u304c\u6b63\u5e38\u306b\u767b\u9332\u3055\u308c\u307e\u3057\u305f')-&gt;send();\n        } catch (ApiException $e) {\n            \/\/ API\u30a8\u30e9\u30fc\u306e\u51e6\u7406\n            $e-&gt;toApiResponse()-&gt;send();\n        } catch (\\Exception $e) {\n            \/\/ \u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc\u306e\u51e6\u7406\n            $systemError = new ApiException(\n                AppErrorCode::SYSTEM_UNEXPECTED_ERROR,\n                $e-&gt;getMessage()\n            );\n            $systemError-&gt;toApiResponse()-&gt;send();\n        }\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u53d6\u5f97API\n    public function getUser(int $id): void\n    {\n        try {\n            \/\/ \u30e6\u30fc\u30b6\u30fc\u691c\u7d22\n            $user = $this-&gt;userRepository-&gt;findById($id);\n            \n            if (!$user) {\n                throw new ApiException(AppErrorCode::USER_NOT_FOUND);\n            }\n            \n            \/\/ \u6210\u529f\u30ec\u30b9\u30dd\u30f3\u30b9\n            ApiResponse::success(['user' =&gt; $user])-&gt;send();\n        } catch (ApiException $e) {\n            $e-&gt;toApiResponse()-&gt;send();\n        } catch (\\Exception $e) {\n            $systemError = new ApiException(AppErrorCode::SYSTEM_UNEXPECTED_ERROR);\n            $systemError-&gt;toApiResponse()-&gt;send();\n        }\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-131\">\u30b0\u30ed\u30fc\u30d0\u30eb\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u3067\u4e00\u8cab\u3057\u305f\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u3092\u5b9f\u73fe\u3059\u308b\u305f\u3081\u306b\u3001\u30b0\u30ed\u30fc\u30d0\u30eb\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u5b9f\u88c5\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30b0\u30ed\u30fc\u30d0\u30eb\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30e9\u30fc\nfunction globalErrorHandler($errno, $errstr, $errfile, $errline): bool\n{\n    \/\/ \u30a8\u30e9\u30fc\u3092\u4f8b\u5916\u306b\u5909\u63db\n    throw new \\ErrorException($errstr, 0, $errno, $errfile, $errline);\n    return true;\n}\n\n\/\/ \u4f8b\u5916\u30cf\u30f3\u30c9\u30e9\u30fc\nfunction globalExceptionHandler(\\Throwable $exception): void\n{\n    \/\/ \u958b\u767a\u74b0\u5883\u3067\u306e\u8a73\u7d30\u60c5\u5831\n    $isDebug = ($_ENV['APP_ENV'] ?? '') === 'development';\n    \n    if ($exception instanceof ApiException) {\n        $response = $exception-&gt;toApiResponse();\n    } else {\n        $errorData = null;\n        \n        if ($isDebug) {\n            $errorData = [\n                'message' =&gt; $exception-&gt;getMessage(),\n                'file' =&gt; $exception-&gt;getFile(),\n                'line' =&gt; $exception-&gt;getLine(),\n                'trace' =&gt; $exception-&gt;getTraceAsString(),\n            ];\n        }\n        \n        $errorCode = AppErrorCode::SYSTEM_UNEXPECTED_ERROR;\n        $response = ApiResponse::error(\n            ApiResponseStatus::INTERNAL_ERROR,\n            [\n                [\n                    'code' =&gt; $errorCode-&gt;value,\n                    'message' =&gt; $errorCode-&gt;getJapaneseMessage(),\n                    'details' =&gt; $errorData\n                ]\n            ]\n        );\n    }\n    \n    \/\/ \u30a8\u30e9\u30fc\u3092\u30ed\u30b0\u306b\u8a18\u9332\n    error_log(\"Exception: {$exception-&gt;getMessage()} in {$exception-&gt;getFile()} on line {$exception-&gt;getLine()}\");\n    \n    \/\/ \u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u9001\u4fe1\n    $response-&gt;send();\n}\n\n\/\/ \u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u767b\u9332\nset_error_handler('globalErrorHandler');\nset_exception_handler('globalExceptionHandler');\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-132\">Enum\u3092\u6d3b\u7528\u3057\u305fAPI\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u30e1\u30ea\u30c3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4e00\u8cab\u6027<\/strong> \u2013 \u5168\u3066\u306e\u30a8\u30e9\u30fc\u304c\u540c\u3058\u5f62\u5f0f\u3067\u8fd4\u3055\u308c\u308b<\/li>\n\n\n\n<li><strong>\u30bf\u30a4\u30d7\u30bb\u30fc\u30d5<\/strong> \u2013 \u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306e\u30c1\u30a7\u30c3\u30af\u3067\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306e\u30bf\u30a4\u30d7\u30df\u30b9\u3092\u9632\u6b62<\/li>\n\n\n\n<li><strong>\u96c6\u4e2d\u7ba1\u7406<\/strong> \u2013 \u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3068\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u4e00\u7b87\u6240\u306b\u96c6\u7d04<\/li>\n\n\n\n<li><strong>\u56fd\u969b\u5316\u5bfe\u5fdc<\/strong> \u2013 \u8a00\u8a9e\u3054\u3068\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u7ba1\u7406\u3057\u3084\u3059\u3044<\/li>\n\n\n\n<li><strong>\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u89aa\u548c\u6027<\/strong> \u2013 \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u5074\u3067\u4e88\u6e2c\u30fb\u89e3\u6790\u3057\u3084\u3059\u3044<\/li>\n\n\n\n<li><strong>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5316<\/strong> \u2013 \u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u304c\u81ea\u5df1\u6587\u66f8\u5316\u3055\u308c\u308b<\/li>\n<\/ol>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30d1\u30bf\u30fc\u30f3\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u5805\u7262\u3067\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u306e\u9ad8\u3044API\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u304c\u5b9f\u73fe\u3067\u304d\u3001\u7d50\u679c\u3068\u3057\u3066\u958b\u767a\u8005\u3068\u30a8\u30f3\u30c9\u30e6\u30fc\u30b6\u30fc\u53cc\u65b9\u306e\u4f53\u9a13\u304c\u5411\u4e0a\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-133\">\u4e00\u8cab\u6027\u306e\u3042\u308bAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u3092Enum\u3067\u69cb\u7bc9\u3059\u308b<\/h3>\n\n\n\n<p>API\u3092\u8a2d\u8a08\u3059\u308b\u969b\u3001\u4e00\u8cab\u6027\u306e\u3042\u308b\u30ec\u30b9\u30dd\u30f3\u30b9\u69cb\u9020\u306f\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u958b\u767a\u8005\u306e\u4f7f\u3044\u52dd\u624b\u3092\u5927\u304d\u304f\u5de6\u53f3\u3057\u307e\u3059\u3002PHP\u306eEnum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u4e88\u6e2c\u53ef\u80fd\u3067\u578b\u5b89\u5168\u306aAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-134\">API\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u6a19\u6e96\u69cb\u9020<\/h4>\n\n\n\n<p>\u307e\u305a\u3001API\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u6a19\u6e96\u69cb\u9020\u3092\u5b9a\u7fa9\u3057\u3001\u305d\u308c\u3092Enum\u3067\u7ba1\u7406\u3059\u308b\u65b9\u6cd5\u3092\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ API\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u72b6\u614b\u3092Enum\u3067\u5b9a\u7fa9\nenum ApiStatus: string\n{\n    case OK = 'ok';\n    case ERROR = 'error';\n    case FAIL = 'fail';\n    \n    \/\/ \u8aac\u660e\u3092\u53d6\u5f97\n    public function getDescription(): string\n    {\n        return match($this) {\n            self::OK =&gt; '\u51e6\u7406\u306b\u6210\u529f\u3057\u307e\u3057\u305f',\n            self::ERROR =&gt; '\u30b5\u30fc\u30d0\u30fc\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            self::FAIL =&gt; '\u30ea\u30af\u30a8\u30b9\u30c8\u5185\u5bb9\u306b\u554f\u984c\u304c\u3042\u308a\u307e\u3059',\n        };\n    }\n    \n    \/\/ HTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\n    public function getHttpStatusCode(): int\n    {\n        return match($this) {\n            self::OK =&gt; 200,\n            self::ERROR =&gt; 500,\n            self::FAIL =&gt; 400,\n        };\n    }\n}\n\n\/\/ \u30ea\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u3092Enum\u3067\u5b9a\u7fa9\nenum ResourceType: string\n{\n    case USER = 'user';\n    case PRODUCT = 'product';\n    case ORDER = 'order';\n    case PAYMENT = 'payment';\n    \n    \/\/ \u30ea\u30bd\u30fc\u30b9\u56fa\u6709\u306e\u60c5\u5831\u3092\u53d6\u5f97\n    public function getInfo(): array\n    {\n        return match($this) {\n            self::USER =&gt; [\n                'collection' =&gt; 'users',\n                'identifier' =&gt; 'id',\n                'displayName' =&gt; '\u30e6\u30fc\u30b6\u30fc'\n            ],\n            self::PRODUCT =&gt; [\n                'collection' =&gt; 'products',\n                'identifier' =&gt; 'product_id',\n                'displayName' =&gt; '\u5546\u54c1'\n            ],\n            self::ORDER =&gt; [\n                'collection' =&gt; 'orders',\n                'identifier' =&gt; 'order_id',\n                'displayName' =&gt; '\u6ce8\u6587'\n            ],\n            self::PAYMENT =&gt; [\n                'collection' =&gt; 'payments',\n                'identifier' =&gt; 'payment_id',\n                'displayName' =&gt; '\u652f\u6255\u3044'\n            ],\n        };\n    }\n    \n    \/\/ \u8907\u6570\u5f62\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u540d\u3092\u53d6\u5f97\n    public function getCollectionName(): string\n    {\n        return $this-&gt;getInfo()['collection'];\n    }\n    \n    \/\/ \u8b58\u5225\u5b50\u30d5\u30a3\u30fc\u30eb\u30c9\u540d\u3092\u53d6\u5f97\n    public function getIdentifierField(): string\n    {\n        return $this-&gt;getInfo()['identifier'];\n    }\n    \n    \/\/ \u8868\u793a\u540d\u3092\u53d6\u5f97\n    public function getDisplayName(): string\n    {\n        return $this-&gt;getInfo()['displayName'];\n    }\n}\n\n\/\/ \u6a19\u6e96API\u30ec\u30b9\u30dd\u30f3\u30b9\u30af\u30e9\u30b9\nclass ApiResponse\n{\n    private ApiStatus $status;\n    private mixed $data;\n    private ?array $meta;\n    private ?array $error;\n    \n    public function __construct(\n        ApiStatus $status,\n        mixed $data = null,\n        ?array $meta = null,\n        ?array $error = null\n    ) {\n        $this-&gt;status = $status;\n        $this-&gt;data = $data;\n        $this-&gt;meta = $meta;\n        $this-&gt;error = $error;\n    }\n    \n    \/\/ \u6210\u529f\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u4f5c\u6210\n    public static function success(mixed $data, ?array $meta = null): self\n    {\n        return new self(ApiStatus::OK, $data, $meta);\n    }\n    \n    \/\/ \u30b5\u30fc\u30d0\u30fc\u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u4f5c\u6210\n    public static function error(string $message, string $code = 'server_error', ?array $details = null): self\n    {\n        return new self(\n            ApiStatus::ERROR,\n            null,\n            null,\n            [\n                'message' =&gt; $message,\n                'code' =&gt; $code,\n                'details' =&gt; $details\n            ]\n        );\n    }\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u4f5c\u6210\n    public static function validationFail(array $errors, string $message = '\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f'): self\n    {\n        return new self(\n            ApiStatus::FAIL,\n            null,\n            null,\n            [\n                'message' =&gt; $message,\n                'code' =&gt; 'validation_error',\n                'errors' =&gt; $errors\n            ]\n        );\n    }\n    \n    \/\/ \u30ec\u30b9\u30dd\u30f3\u30b9\u30c7\u30fc\u30bf\u3092JSON\u306b\u5909\u63db\n    public function toJson(): string\n    {\n        $response = [\n            'status' =&gt; $this-&gt;status-&gt;value,\n        ];\n        \n        if ($this-&gt;data !== null) {\n            $response['data'] = $this-&gt;data;\n        }\n        \n        if ($this-&gt;meta !== null) {\n            $response['meta'] = $this-&gt;meta;\n        }\n        \n        if ($this-&gt;error !== null) {\n            $response['error'] = $this-&gt;error;\n        }\n        \n        return json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);\n    }\n    \n    \/\/ \u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u9001\u4fe1\n    public function send(): void\n    {\n        http_response_code($this-&gt;status-&gt;getHttpStatusCode());\n        header('Content-Type: application\/json; charset=utf-8');\n        echo $this-&gt;toJson();\n        exit;\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-135\">\u30ea\u30bd\u30fc\u30b9\u30e2\u30c7\u30eb\u306e\u6a19\u6e96\u5316<\/h4>\n\n\n\n<p>\u6b21\u306b\u3001API\u3067\u6271\u3046\u30ea\u30bd\u30fc\u30b9\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u69cb\u9020\u3092\u6a19\u6e96\u5316\u3059\u308b\u4f8b\u3092\u793a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ API\u30ea\u30bd\u30fc\u30b9\u306e\u57fa\u5e95\u30af\u30e9\u30b9\nabstract class ApiResource\n{\n    protected mixed $model;\n    \n    public function __construct(mixed $model)\n    {\n        $this-&gt;model = $model;\n    }\n    \n    \/\/ \u30ea\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u3092\u53d6\u5f97\uff08\u30b5\u30d6\u30af\u30e9\u30b9\u3067\u5b9f\u88c5\uff09\n    abstract public function getResourceType(): ResourceType;\n    \n    \/\/ \u30ea\u30bd\u30fc\u30b9\u3092\u914d\u5217\u306b\u5909\u63db\uff08\u30b5\u30d6\u30af\u30e9\u30b9\u3067\u5b9f\u88c5\uff09\n    abstract public function toArray(): array;\n    \n    \/\/ \u30ea\u30bd\u30fc\u30b9\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\n    public static function collection(array $items): array\n    {\n        return array_map(fn($item) =&gt; (new static($item))-&gt;toArray(), $items);\n    }\n}\n\n\/\/ \u30e6\u30fc\u30b6\u30fc\u30ea\u30bd\u30fc\u30b9\u306e\u4f8b\nclass UserResource extends ApiResource\n{\n    public function getResourceType(): ResourceType\n    {\n        return ResourceType::USER;\n    }\n    \n    public function toArray(): array\n    {\n        \/\/ \u30e6\u30fc\u30b6\u30fc\u30e2\u30c7\u30eb\u3092API\u30ec\u30b9\u30dd\u30f3\u30b9\u7528\u306e\u914d\u5217\u306b\u5909\u63db\n        return [\n            'id' =&gt; $this-&gt;model-&gt;id,\n            'name' =&gt; $this-&gt;model-&gt;name,\n            'email' =&gt; $this-&gt;model-&gt;email,\n            'created_at' =&gt; $this-&gt;model-&gt;created_at-&gt;format('Y-m-d H:i:s'),\n            'type' =&gt; $this-&gt;getResourceType()-&gt;value,\n        ];\n    }\n}\n\n\/\/ \u5546\u54c1\u30ea\u30bd\u30fc\u30b9\u306e\u4f8b\nclass ProductResource extends ApiResource\n{\n    public function getResourceType(): ResourceType\n    {\n        return ResourceType::PRODUCT;\n    }\n    \n    public function toArray(): array\n    {\n        return [\n            'product_id' =&gt; $this-&gt;model-&gt;id,\n            'name' =&gt; $this-&gt;model-&gt;name,\n            'price' =&gt; $this-&gt;model-&gt;price,\n            'description' =&gt; $this-&gt;model-&gt;description,\n            'stock' =&gt; $this-&gt;model-&gt;stock,\n            'type' =&gt; $this-&gt;getResourceType()-&gt;value,\n        ];\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-136\">\u5b9f\u969b\u306eAPI\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u4f7f\u7528\u4f8b<\/h4>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30af\u30e9\u30b9\u3092\u4f7f\u7528\u3057\u3066\u3001\u7d71\u4e00\u3055\u308c\u305fAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u751f\u6210\u3059\u308b\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u4f8b\u3092\u793a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30e6\u30fc\u30b6\u30fcAPI\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\nclass UserApiController\n{\n    private UserRepository $userRepository;\n    \n    public function __construct(UserRepository $userRepository)\n    {\n        $this-&gt;userRepository = $userRepository;\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u4e00\u89a7\u3092\u53d6\u5f97\n    public function index(): void\n    {\n        try {\n            $users = $this-&gt;userRepository-&gt;findAll();\n            \n            \/\/ \u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u30e1\u30bf\u30c7\u30fc\u30bf\n            $meta = [\n                'total' =&gt; count($users),\n                'page' =&gt; 1,\n                'per_page' =&gt; 20,\n            ];\n            \n            \/\/ \u6210\u529f\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u9001\u4fe1\n            ApiResponse::success(\n                UserResource::collection($users),\n                $meta\n            )-&gt;send();\n        } catch (\\Exception $e) {\n            \/\/ \u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u9001\u4fe1\n            ApiResponse::error($e-&gt;getMessage())-&gt;send();\n        }\n    }\n    \n    \/\/ \u5358\u4e00\u30e6\u30fc\u30b6\u30fc\u3092\u53d6\u5f97\n    public function show(int $id): void\n    {\n        try {\n            $user = $this-&gt;userRepository-&gt;findById($id);\n            \n            if (!$user) {\n                ApiResponse::validationFail(\n                    ['id' =&gt; '\u30e6\u30fc\u30b6\u30fc\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093'],\n                    '\u30e6\u30fc\u30b6\u30fc\u304c\u5b58\u5728\u3057\u307e\u305b\u3093'\n                )-&gt;send();\n                return;\n            }\n            \n            \/\/ \u6210\u529f\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u9001\u4fe1\n            ApiResponse::success(\n                (new UserResource($user))-&gt;toArray()\n            )-&gt;send();\n        } catch (\\Exception $e) {\n            ApiResponse::error($e-&gt;getMessage())-&gt;send();\n        }\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u3092\u4f5c\u6210\n    public function store(): void\n    {\n        try {\n            \/\/ \u30ea\u30af\u30a8\u30b9\u30c8\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\n            $requestData = json_decode(file_get_contents('php:\/\/input'), true);\n            \n            \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n            $errors = $this-&gt;validateUserData($requestData);\n            if (!empty($errors)) {\n                ApiResponse::validationFail($errors)-&gt;send();\n                return;\n            }\n            \n            \/\/ \u30e6\u30fc\u30b6\u30fc\u3092\u4f5c\u6210\n            $user = $this-&gt;userRepository-&gt;create($requestData);\n            \n            \/\/ \u6210\u529f\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u9001\u4fe1\n            ApiResponse::success(\n                (new UserResource($user))-&gt;toArray()\n            )-&gt;send();\n        } catch (\\Exception $e) {\n            ApiResponse::error($e-&gt;getMessage())-&gt;send();\n        }\n    }\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u51e6\u7406\n    private function validateUserData(array $data): array\n    {\n        $errors = [];\n        \n        if (empty($data['name'])) {\n            $errors['name'] = '\u540d\u524d\u306f\u5fc5\u9808\u3067\u3059';\n        }\n        \n        if (empty($data['email'])) {\n            $errors['email'] = '\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u5fc5\u9808\u3067\u3059';\n        } elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {\n            $errors['email'] = '\u6709\u52b9\u306a\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044';\n        } elseif ($this-&gt;userRepository-&gt;emailExists($data['email'])) {\n            $errors['email'] = '\u3053\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u65e2\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059';\n        }\n        \n        if (empty($data['password'])) {\n            $errors['password'] = '\u30d1\u30b9\u30ef\u30fc\u30c9\u306f\u5fc5\u9808\u3067\u3059';\n        } elseif (strlen($data['password']) &lt; 8) {\n            $errors['password'] = '\u30d1\u30b9\u30ef\u30fc\u30c9\u306f8\u6587\u5b57\u4ee5\u4e0a\u306b\u3057\u3066\u304f\u3060\u3055\u3044';\n        }\n        \n        return $errors;\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-137\">API\u30a2\u30af\u30b7\u30e7\u30f3\u30bf\u30a4\u30d7\u306eEnum<\/h4>\n\n\n\n<p>API\u3067\u5b9f\u884c\u3067\u304d\u308b\u30a2\u30af\u30b7\u30e7\u30f3\u3092\u8868\u73fe\u3059\u308bEnum\u3082\u3001\u4e00\u8cab\u6027\u306e\u3042\u308b\u8a2d\u8a08\u306b\u5f79\u7acb\u3061\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ API\u30a2\u30af\u30b7\u30e7\u30f3\u30bf\u30a4\u30d7\nenum ApiActionType: string\n{\n    case LIST = 'list';       \/\/ \u30ea\u30bd\u30fc\u30b9\u4e00\u89a7\u53d6\u5f97\n    case GET = 'get';         \/\/ \u5358\u4e00\u30ea\u30bd\u30fc\u30b9\u53d6\u5f97\n    case CREATE = 'create';   \/\/ \u30ea\u30bd\u30fc\u30b9\u4f5c\u6210\n    case UPDATE = 'update';   \/\/ \u30ea\u30bd\u30fc\u30b9\u66f4\u65b0\n    case DELETE = 'delete';   \/\/ \u30ea\u30bd\u30fc\u30b9\u524a\u9664\n    case BULK = 'bulk';       \/\/ \u4e00\u62ec\u51e6\u7406\n    \n    \/\/ \u30a2\u30af\u30b7\u30e7\u30f3\u306e\u8aac\u660e\u3092\u53d6\u5f97\n    public function getDescription(): string\n    {\n        return match($this) {\n            self::LIST =&gt; '\u30ea\u30bd\u30fc\u30b9\u4e00\u89a7\u306e\u53d6\u5f97',\n            self::GET =&gt; '\u5358\u4e00\u30ea\u30bd\u30fc\u30b9\u306e\u53d6\u5f97',\n            self::CREATE =&gt; '\u30ea\u30bd\u30fc\u30b9\u306e\u65b0\u898f\u4f5c\u6210',\n            self::UPDATE =&gt; '\u30ea\u30bd\u30fc\u30b9\u306e\u66f4\u65b0',\n            self::DELETE =&gt; '\u30ea\u30bd\u30fc\u30b9\u306e\u524a\u9664',\n            self::BULK =&gt; '\u30ea\u30bd\u30fc\u30b9\u306e\u4e00\u62ec\u51e6\u7406',\n        };\n    }\n    \n    \/\/ \u5bfe\u5fdc\u3059\u308bHTTP\u30e1\u30bd\u30c3\u30c9\u3092\u53d6\u5f97\n    public function getHttpMethod(): string\n    {\n        return match($this) {\n            self::LIST, self::GET =&gt; 'GET',\n            self::CREATE =&gt; 'POST',\n            self::UPDATE =&gt; 'PUT',\n            self::DELETE =&gt; 'DELETE',\n            self::BULK =&gt; 'POST', \/\/ BULK\u306fPOST\u3067\u51e6\u7406\n        };\n    }\n    \n    \/\/ \u30a2\u30af\u30bb\u30b9\u6a29\u9650\u540d\u3092\u53d6\u5f97\n    public function getPermissionName(ResourceType $resourceType): string\n    {\n        $action = strtolower($this-&gt;value);\n        $resource = strtolower($resourceType-&gt;value);\n        \n        return \"{$action}_{$resource}\";\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-138\">API\u30ec\u30b9\u30dd\u30f3\u30b9\u30da\u30fc\u30b8\u30cd\u30fc\u30b7\u30e7\u30f3\u7528\u306eEnum<\/h4>\n\n\n\n<p>\u30da\u30fc\u30b8\u30cd\u30fc\u30b7\u30e7\u30f3\u306e\u30b9\u30bf\u30a4\u30eb\u3092\u7ba1\u7406\u3059\u308bEnum\u3082\u5b9f\u88c5\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30da\u30fc\u30b8\u30cd\u30fc\u30b7\u30e7\u30f3\u30bf\u30a4\u30d7\nenum PaginationType: string\n{\n    case OFFSET = 'offset';  \/\/ \u30aa\u30d5\u30bb\u30c3\u30c8\u30d9\u30fc\u30b9 (page, per_page)\n    case CURSOR = 'cursor';  \/\/ \u30ab\u30fc\u30bd\u30eb\u30d9\u30fc\u30b9 (after, before)\n    case NONE = 'none';      \/\/ \u30da\u30fc\u30b8\u30cd\u30fc\u30b7\u30e7\u30f3\u306a\u3057\n    \n    \/\/ \u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u751f\u6210\n    public function generateMeta(array $params, int $totalItems): array\n    {\n        return match($this) {\n            self::OFFSET =&gt; [\n                'total' =&gt; $totalItems,\n                'per_page' =&gt; $params['per_page'] ?? 20,\n                'current_page' =&gt; $params['page'] ?? 1,\n                'last_page' =&gt; ceil($totalItems \/ ($params['per_page'] ?? 20)),\n                'from' =&gt; (($params['page'] ?? 1) - 1) * ($params['per_page'] ?? 20) + 1,\n                'to' =&gt; min($totalItems, (($params['page'] ?? 1) * ($params['per_page'] ?? 20))),\n            ],\n            self::CURSOR =&gt; [\n                'total' =&gt; $totalItems,\n                'per_page' =&gt; $params['limit'] ?? 20,\n                'has_more' =&gt; ($params['offset'] ?? 0) + ($params['limit'] ?? 20) &lt; $totalItems,\n                'next_cursor' =&gt; $params['has_more'] ? $params['next_cursor'] : null,\n            ],\n            self::NONE =&gt; [\n                'total' =&gt; $totalItems,\n                'filtered' =&gt; count($params['filters'] ?? []) &gt; 0,\n            ],\n        };\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-139\">\u5b9f\u969b\u306eAPI\u30ea\u30af\u30a8\u30b9\u30c8\u30fb\u30ec\u30b9\u30dd\u30f3\u30b9\u4f8b<\/h4>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u8981\u7d20\u3092\u7d44\u307f\u5408\u308f\u305b\u3066\u3001\u5b9f\u969b\u306eAPI\u30ea\u30af\u30a8\u30b9\u30c8\u3068\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u4f8b\u3092\u793a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<p><strong>\u30ea\u30af\u30a8\u30b9\u30c8\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">GET \/api\/users\/123\n<\/pre>\n\n\n\n<p><strong>\u30ec\u30b9\u30dd\u30f3\u30b9\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n  \"status\": \"ok\",\n  \"data\": {\n    \"id\": 123,\n    \"name\": \"\u5c71\u7530\u592a\u90ce\",\n    \"email\": \"yamada@example.com\",\n    \"created_at\": \"2023-01-15 08:30:45\",\n    \"type\": \"user\"\n  }\n}\n<\/pre>\n\n\n\n<p><strong>\u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u4f8b\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n  \"status\": \"fail\",\n  \"error\": {\n    \"message\": \"\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\",\n    \"code\": \"validation_error\",\n    \"errors\": {\n      \"email\": \"\u3053\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u65e2\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\",\n      \"password\": \"\u30d1\u30b9\u30ef\u30fc\u30c9\u306f8\u6587\u5b57\u4ee5\u4e0a\u306b\u3057\u3066\u304f\u3060\u3055\u3044\"\n    }\n  }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-140\">\u4e00\u8cab\u6027\u306e\u3042\u308bAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u8a2d\u8a08\u306e\u30e1\u30ea\u30c3\u30c8<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4e88\u6e2c\u53ef\u80fd\u6027<\/strong> \u2013 \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u958b\u767a\u8005\u304c\u69cb\u9020\u3092\u4e88\u6e2c\u3057\u3084\u3059\u304f\u3001\u9023\u643a\u304c\u30b9\u30e0\u30fc\u30ba<\/li>\n\n\n\n<li><strong>\u52b9\u7387\u7684\u306a\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/strong> \u2013 \u7d71\u4e00\u3055\u308c\u305f\u30a8\u30e9\u30fc\u5f62\u5f0f\u306b\u3088\u308a\u3001\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u5074\u3067\u306e\u51e6\u7406\u304c\u7c21\u7d20\u5316<\/li>\n\n\n\n<li><strong>\u30b3\u30fc\u30c9\u518d\u5229\u7528<\/strong> \u2013 \u5171\u901a\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u69cb\u9020\u306b\u3088\u308a\u3001\u30b3\u30fc\u30c9\u306e\u91cd\u8907\u304c\u6e1b\u5c11<\/li>\n\n\n\n<li><strong>\u62e1\u5f35\u6027<\/strong> \u2013 \u65b0\u3057\u3044\u30ea\u30bd\u30fc\u30b9\u3084\u30a8\u30e9\u30fc\u30bf\u30a4\u30d7\u306e\u8ffd\u52a0\u304c\u5bb9\u6613<\/li>\n\n\n\n<li><strong>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u751f\u6210<\/strong> \u2013 Enum\u306b\u57fa\u3065\u3044\u305f\u81ea\u52d5\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u751f\u6210\u304c\u53ef\u80fd<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027<\/strong> \u2013 \u69cb\u9020\u304c\u4e88\u6e2c\u53ef\u80fd\u306a\u305f\u3081\u3001\u30c6\u30b9\u30c8\u306e\u4f5c\u6210\u304c\u5bb9\u6613<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-141\">\u5b9f\u88c5\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ec\u30b9\u30dd\u30f3\u30b9\u69cb\u9020\u3092\u30b7\u30f3\u30d7\u30eb\u306b\u4fdd\u3064<\/strong> \u2013 \u5fc5\u8981\u6700\u5c0f\u9650\u306e\u968e\u5c64\u3092\u7dad\u6301<\/li>\n\n\n\n<li><strong>\u4e00\u8cab\u3057\u305f\u30d5\u30a3\u30fc\u30eb\u30c9\u540d<\/strong> \u2013 \u5168\u3066\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u3067\u540c\u3058\u30d5\u30a3\u30fc\u30eb\u30c9\u540d\u898f\u5247\u3092\u4f7f\u7528<\/li>\n\n\n\n<li><strong>HTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u306e\u9069\u5207\u306a\u4f7f\u7528<\/strong> \u2013 \u30ec\u30b9\u30dd\u30f3\u30b9\u306e<code>status<\/code>\u30d5\u30a3\u30fc\u30eb\u30c9\u3068HTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3092\u4e00\u81f4\u3055\u305b\u308b<\/li>\n\n\n\n<li><strong>\u30d0\u30fc\u30b8\u30e7\u30cb\u30f3\u30b0\u306e\u8003\u616e<\/strong> \u2013 API\u306e\u9032\u5316\u306b\u5408\u308f\u305b\u3066\u62e1\u5f35\u53ef\u80fd\u306a\u8a2d\u8a08\u306b\u3059\u308b<\/li>\n\n\n\n<li><strong>\u56fd\u969b\u5316\u5bfe\u5fdc<\/strong> \u2013 \u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306a\u3069\u306f\u591a\u8a00\u8a9e\u5316\u3092\u8003\u616e\u3059\u308b<\/li>\n\n\n\n<li><strong>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3068\u306e\u9023\u643a<\/strong> \u2013 OpenAPI\u306a\u3069\u306e\u4ed5\u69d8\u3068\u6574\u5408\u3055\u305b\u308b<\/li>\n<\/ol>\n\n\n\n<p>Enum\u3092\u6d3b\u7528\u3057\u305f\u4e00\u8cab\u6027\u306e\u3042\u308bAPI\u30ec\u30b9\u30dd\u30f3\u30b9\u8a2d\u8a08\u306f\u3001\u958b\u767a\u52b9\u7387\u3068\u5229\u7528\u8005\u4f53\u9a13\u306e\u4e21\u65b9\u3092\u5411\u4e0a\u3055\u305b\u308b\u5f37\u529b\u306a\u624b\u6cd5\u3067\u3059\u3002\u578b\u5b89\u5168\u6027\u3068\u660e\u78ba\u306a\u69cb\u9020\u306b\u3088\u308a\u3001\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u306e\u9ad8\u3044API\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-142\">\u4f8b\u5916\u51e6\u7406\u3068\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3092Enum\u3067\u7ba1\u7406\u3059\u308b\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u52b9\u679c\u7684\u306a\u4f8b\u5916\u51e6\u7406\u3068\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u7ba1\u7406\u306f\u3001\u5805\u7262\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u306e\u57fa\u76e4\u3067\u3059\u3002PHP\u306eEnum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u578b\u5b89\u5168\u3067\u4e00\u8cab\u6027\u306e\u3042\u308b\u30a8\u30e9\u30fc\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-143\">\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306eEnum\u7ba1\u7406<\/h4>\n\n\n\n<p>\u5f93\u6765\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u7ba1\u7406\uff08\u30af\u30e9\u30b9\u5b9a\u6570\u3084\u914d\u5217\uff09\u3068\u6bd4\u8f03\u3057\u3066\u3001Enum\u3092\u4f7f\u7528\u3059\u308b\u4e3b\u306a\u30e1\u30ea\u30c3\u30c8\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u578b\u5b89\u5168\u6027<\/strong> \u2013 \u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u304c\u7279\u5b9a\u306e\u578b\u3068\u3057\u3066\u6271\u308f\u308c\u308b<\/li>\n\n\n\n<li><strong>IDE\u88dc\u5b8c<\/strong> \u2013 \u30b3\u30fc\u30c9\u5165\u529b\u6642\u306b\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306e\u5019\u88dc\u304c\u8868\u793a\u3055\u308c\u308b<\/li>\n\n\n\n<li><strong>\u96c6\u4e2d\u7ba1\u7406<\/strong> \u2013 \u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3068\u305d\u306e\u95a2\u9023\u60c5\u5831\u3092\u4e00\u7b87\u6240\u306b\u96c6\u7d04<\/li>\n\n\n\n<li><strong>\u81ea\u5df1\u6587\u66f8\u5316<\/strong> \u2013 \u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306e\u610f\u5473\u3084\u7528\u9014\u304c\u30b3\u30fc\u30c9\u3068\u3057\u3066\u660e\u793a\u3055\u308c\u308b<\/li>\n<\/ol>\n\n\n\n<p>\u4ee5\u4e0b\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u3067\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u7ba1\u7406\u306e\u4f8b\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3092Enum\u3067\u5b9a\u7fa9\nenum AppErrorCode: string\n{\n    \/\/ \u4e00\u822c\u30a8\u30e9\u30fc (10xxx)\n    case UNKNOWN_ERROR = 'E10001';\n    case INVALID_CONFIGURATION = 'E10002';\n    case RESOURCE_NOT_FOUND = 'E10003';\n    \n    \/\/ \u8a8d\u8a3c\u30fb\u8a8d\u53ef\u30a8\u30e9\u30fc (20xxx)\n    case AUTHENTICATION_FAILED = 'E20001';\n    case INVALID_CREDENTIALS = 'E20002';\n    case SESSION_EXPIRED = 'E20003';\n    case INSUFFICIENT_PERMISSIONS = 'E20004';\n    \n    \/\/ \u5165\u529b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc (30xxx)\n    case INVALID_INPUT = 'E30001';\n    case REQUIRED_FIELD_MISSING = 'E30002';\n    case INVALID_FORMAT = 'E30003';\n    case INVALID_VALUE_RANGE = 'E30004';\n    \n    \/\/ \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc (40xxx)\n    case DATABASE_CONNECTION_ERROR = 'E40001';\n    case QUERY_EXECUTION_ERROR = 'E40002';\n    case DUPLICATE_ENTRY = 'E40003';\n    case DATA_INTEGRITY_ERROR = 'E40004';\n    \n    \/\/ \u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u9023\u643a\u30a8\u30e9\u30fc (50xxx)\n    case API_CONNECTION_ERROR = 'E50001';\n    case API_RESPONSE_ERROR = 'E50002';\n    case API_TIMEOUT = 'E50003';\n    \n    \/\/ \u30d5\u30a1\u30a4\u30eb\u64cd\u4f5c\u30a8\u30e9\u30fc (60xxx)\n    case FILE_NOT_FOUND = 'E60001';\n    case FILE_PERMISSION_DENIED = 'E60002';\n    case FILE_UPLOAD_ERROR = 'E60003';\n    \n    \/\/ \u30a8\u30e9\u30fc\u306e\u30ab\u30c6\u30b4\u30ea\u3092\u53d6\u5f97\n    public function getCategory(): string\n    {\n        $code = substr($this-&gt;value, 1, 2);\n        return match($code) {\n            '10' =&gt; 'General',\n            '20' =&gt; 'Authentication',\n            '30' =&gt; 'Validation',\n            '40' =&gt; 'Database',\n            '50' =&gt; 'ExternalAPI',\n            '60' =&gt; 'FileSystem',\n            default =&gt; 'Unknown',\n        };\n    }\n    \n    \/\/ HTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\n    public function getHttpStatus(): int\n    {\n        return match($this) {\n            \/\/ \u4e00\u822c\u30a8\u30e9\u30fc\n            self::UNKNOWN_ERROR =&gt; 500,\n            self::INVALID_CONFIGURATION =&gt; 500,\n            self::RESOURCE_NOT_FOUND =&gt; 404,\n            \n            \/\/ \u8a8d\u8a3c\u30fb\u8a8d\u53ef\u30a8\u30e9\u30fc\n            self::AUTHENTICATION_FAILED, \n            self::INVALID_CREDENTIALS, \n            self::SESSION_EXPIRED =&gt; 401,\n            self::INSUFFICIENT_PERMISSIONS =&gt; 403,\n            \n            \/\/ \u5165\u529b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\n            self::INVALID_INPUT,\n            self::REQUIRED_FIELD_MISSING,\n            self::INVALID_FORMAT,\n            self::INVALID_VALUE_RANGE =&gt; 422,\n            \n            \/\/ \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\n            self::DATABASE_CONNECTION_ERROR,\n            self::QUERY_EXECUTION_ERROR,\n            self::DATA_INTEGRITY_ERROR =&gt; 500,\n            self::DUPLICATE_ENTRY =&gt; 409,\n            \n            \/\/ \u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u9023\u643a\u30a8\u30e9\u30fc\n            self::API_CONNECTION_ERROR,\n            self::API_RESPONSE_ERROR,\n            self::API_TIMEOUT =&gt; 502,\n            \n            \/\/ \u30d5\u30a1\u30a4\u30eb\u64cd\u4f5c\u30a8\u30e9\u30fc\n            self::FILE_NOT_FOUND =&gt; 404,\n            self::FILE_PERMISSION_DENIED =&gt; 403,\n            self::FILE_UPLOAD_ERROR =&gt; 422,\n        };\n    }\n    \n    \/\/ \u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u53d6\u5f97\n    public function getMessage(): string\n    {\n        return match($this) {\n            \/\/ \u4e00\u822c\u30a8\u30e9\u30fc\n            self::UNKNOWN_ERROR =&gt; '\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            self::INVALID_CONFIGURATION =&gt; '\u8a2d\u5b9a\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            self::RESOURCE_NOT_FOUND =&gt; '\u30ea\u30bd\u30fc\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093',\n            \n            \/\/ \u8a8d\u8a3c\u30fb\u8a8d\u53ef\u30a8\u30e9\u30fc\n            self::AUTHENTICATION_FAILED =&gt; '\u8a8d\u8a3c\u306b\u5931\u6557\u3057\u307e\u3057\u305f',\n            self::INVALID_CREDENTIALS =&gt; '\u30e6\u30fc\u30b6\u30fc\u540d\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093',\n            self::SESSION_EXPIRED =&gt; '\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u307e\u3057\u305f\u3002\u518d\u30ed\u30b0\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044',\n            self::INSUFFICIENT_PERMISSIONS =&gt; '\u3053\u306e\u64cd\u4f5c\u3092\u884c\u3046\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093',\n            \n            \/\/ \u5165\u529b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\n            self::INVALID_INPUT =&gt; '\u5165\u529b\u30c7\u30fc\u30bf\u304c\u7121\u52b9\u3067\u3059',\n            self::REQUIRED_FIELD_MISSING =&gt; '\u5fc5\u9808\u9805\u76ee\u304c\u5165\u529b\u3055\u308c\u3066\u3044\u307e\u305b\u3093',\n            self::INVALID_FORMAT =&gt; '\u5165\u529b\u5f62\u5f0f\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093',\n            self::INVALID_VALUE_RANGE =&gt; '\u5165\u529b\u5024\u304c\u8a31\u5bb9\u7bc4\u56f2\u5916\u3067\u3059',\n            \n            \/\/ \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\n            self::DATABASE_CONNECTION_ERROR =&gt; '\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            self::QUERY_EXECUTION_ERROR =&gt; '\u30af\u30a8\u30ea\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            self::DUPLICATE_ENTRY =&gt; '\u30c7\u30fc\u30bf\u304c\u91cd\u8907\u3057\u3066\u3044\u307e\u3059',\n            self::DATA_INTEGRITY_ERROR =&gt; '\u30c7\u30fc\u30bf\u6574\u5408\u6027\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            \n            \/\/ \u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u9023\u643a\u30a8\u30e9\u30fc\n            self::API_CONNECTION_ERROR =&gt; '\u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u3068\u306e\u63a5\u7d9a\u306b\u5931\u6557\u3057\u307e\u3057\u305f',\n            self::API_RESPONSE_ERROR =&gt; '\u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u304b\u3089\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u306b\u30a8\u30e9\u30fc\u304c\u3042\u308a\u307e\u3059',\n            self::API_TIMEOUT =&gt; '\u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u304b\u3089\u306e\u5fdc\u7b54\u304c\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u3057\u307e\u3057\u305f',\n            \n            \/\/ \u30d5\u30a1\u30a4\u30eb\u64cd\u4f5c\u30a8\u30e9\u30fc\n            self::FILE_NOT_FOUND =&gt; '\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093',\n            self::FILE_PERMISSION_DENIED =&gt; '\u30d5\u30a1\u30a4\u30eb\u306e\u30a2\u30af\u30bb\u30b9\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093',\n            self::FILE_UPLOAD_ERROR =&gt; '\u30d5\u30a1\u30a4\u30eb\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306b\u5931\u6557\u3057\u307e\u3057\u305f',\n        };\n    }\n    \n    \/\/ \u958b\u767a\u8005\u5411\u3051\u306e\u8a73\u7d30\u30e1\u30c3\u30bb\u30fc\u30b8\uff08\u30c7\u30d0\u30c3\u30b0\u7528\uff09\n    public function getDeveloperMessage(): string\n    {\n        return match($this) {\n            self::UNKNOWN_ERROR =&gt; 'An unhandled exception occurred in the application',\n            self::INVALID_CONFIGURATION =&gt; 'Application configuration is invalid or missing required values',\n            \/\/ \u4ed6\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3082\u540c\u69d8\u306b\u5b9a\u7fa9\n            default =&gt; 'See logs for detailed error information',\n        };\n    }\n    \n    \/\/ \u30ed\u30b0\u30ec\u30d9\u30eb\u3092\u53d6\u5f97\n    public function getLogLevel(): string\n    {\n        return match($this-&gt;getCategory()) {\n            'General' =&gt; 'ERROR',\n            'Authentication' =&gt; 'WARNING',\n            'Validation' =&gt; 'NOTICE',\n            'Database' =&gt; 'ERROR',\n            'ExternalAPI' =&gt; 'ERROR',\n            'FileSystem' =&gt; 'WARNING',\n            default =&gt; 'ERROR',\n        };\n    }\n    \n    \/\/ \u30e6\u30fc\u30b6\u30fc\u3078\u306e\u63a8\u5968\u30a2\u30af\u30b7\u30e7\u30f3\u3092\u53d6\u5f97\n    public function getSuggestedAction(): ?string\n    {\n        return match($this) {\n            self::SESSION_EXPIRED =&gt; '\u518d\u5ea6\u30ed\u30b0\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044',\n            self::INVALID_CREDENTIALS =&gt; '\u30e6\u30fc\u30b6\u30fc\u540d\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044',\n            self::REQUIRED_FIELD_MISSING, \n            self::INVALID_FORMAT,\n            self::INVALID_VALUE_RANGE =&gt; '\u5165\u529b\u5185\u5bb9\u3092\u78ba\u8a8d\u3057\u3066\u518d\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044',\n            self::API_TIMEOUT =&gt; '\u3057\u3070\u3089\u304f\u7d4c\u3063\u3066\u304b\u3089\u518d\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044',\n            default =&gt; null,\n        };\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-144\">Enum\u3092\u6d3b\u7528\u3057\u305f\u30ab\u30b9\u30bf\u30e0\u4f8b\u5916<\/h4>\n\n\n\n<p>\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9Enum\u3068\u9023\u643a\u3059\u308b\u30ab\u30b9\u30bf\u30e0\u4f8b\u5916\u30af\u30e9\u30b9\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u578b\u5b89\u5168\u306a\u30a8\u30e9\u30fc\u51e6\u7406\u30b7\u30b9\u30c6\u30e0\u304c\u69cb\u7bc9\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3092\u6301\u3064\u57fa\u5e95\u4f8b\u5916\u30af\u30e9\u30b9\nabstract class AppException extends \\Exception\n{\n    protected AppErrorCode $errorCode;\n    protected ?array $context;\n    \n    public function __construct(\n        AppErrorCode $errorCode,\n        ?string $message = null,\n        ?array $context = null,\n        int $code = 0,\n        ?\\Throwable $previous = null\n    ) {\n        $this-&gt;errorCode = $errorCode;\n        $this-&gt;context = $context;\n        \n        parent::__construct(\n            $message ?? $errorCode-&gt;getMessage(),\n            $code,\n            $previous\n        );\n    }\n    \n    public function getErrorCode(): AppErrorCode\n    {\n        return $this-&gt;errorCode;\n    }\n    \n    public function getContext(): ?array\n    {\n        return $this-&gt;context;\n    }\n    \n    \/\/ API\u30ec\u30b9\u30dd\u30f3\u30b9\u7528\u306e\u30a8\u30e9\u30fc\u60c5\u5831\u3092\u53d6\u5f97\n    public function getApiErrorResponse(): array\n    {\n        $response = [\n            'code' =&gt; $this-&gt;errorCode-&gt;value,\n            'message' =&gt; $this-&gt;getMessage(),\n        ];\n        \n        $suggestedAction = $this-&gt;errorCode-&gt;getSuggestedAction();\n        if ($suggestedAction) {\n            $response['suggested_action'] = $suggestedAction;\n        }\n        \n        return $response;\n    }\n    \n    \/\/ \u30ed\u30b0\u8a18\u9332\u7528\u306e\u30a8\u30e9\u30fc\u60c5\u5831\u3092\u53d6\u5f97\n    public function getLogContext(): array\n    {\n        $logContext = [\n            'error_code' =&gt; $this-&gt;errorCode-&gt;value,\n            'error_category' =&gt; $this-&gt;errorCode-&gt;getCategory(),\n        ];\n        \n        if ($this-&gt;context) {\n            $logContext['context'] = $this-&gt;context;\n        }\n        \n        return $logContext;\n    }\n}\n\n\/\/ \u5177\u4f53\u7684\u306a\u4f8b\u5916\u30af\u30e9\u30b9\uff08\u8a8d\u8a3c\u30a8\u30e9\u30fc\uff09\nclass AuthenticationException extends AppException\n{\n    public function __construct(\n        AppErrorCode $errorCode = AppErrorCode::AUTHENTICATION_FAILED,\n        ?string $message = null,\n        ?array $context = null,\n        int $code = 0,\n        ?\\Throwable $previous = null\n    ) {\n        parent::__construct($errorCode, $message, $context, $code, $previous);\n    }\n}\n\n\/\/ \u5177\u4f53\u7684\u306a\u4f8b\u5916\u30af\u30e9\u30b9\uff08\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\uff09\nclass ValidationException extends AppException\n{\n    private array $validationErrors;\n    \n    public function __construct(\n        array $validationErrors,\n        AppErrorCode $errorCode = AppErrorCode::INVALID_INPUT,\n        ?string $message = null,\n        ?array $context = null,\n        int $code = 0,\n        ?\\Throwable $previous = null\n    ) {\n        $this-&gt;validationErrors = $validationErrors;\n        parent::__construct($errorCode, $message, $context, $code, $previous);\n    }\n    \n    public function getValidationErrors(): array\n    {\n        return $this-&gt;validationErrors;\n    }\n    \n    \/\/ API\u30ec\u30b9\u30dd\u30f3\u30b9\u7528\u306e\u30a8\u30e9\u30fc\u60c5\u5831\u3092\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\n    public function getApiErrorResponse(): array\n    {\n        $response = parent::getApiErrorResponse();\n        $response['errors'] = $this-&gt;validationErrors;\n        return $response;\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-145\">\u4f8b\u5916\u30cf\u30f3\u30c9\u30e9\u30fc\u3067\u306e\u4f7f\u7528\u4f8b<\/h4>\n\n\n\n<p>Enum\u30d9\u30fc\u30b9\u306e\u4f8b\u5916\u3092\u52b9\u679c\u7684\u306b\u6271\u3046\u30b0\u30ed\u30fc\u30d0\u30eb\u4f8b\u5916\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30b0\u30ed\u30fc\u30d0\u30eb\u4f8b\u5916\u30cf\u30f3\u30c9\u30e9\u30fc\nfunction globalExceptionHandler(\\Throwable $exception): void\n{\n    \/\/ \u74b0\u5883\u8a2d\u5b9a\n    $isDebug = ($_ENV['APP_ENV'] ?? '') === 'development';\n    $logger = new Logger(); \/\/ \u5b9f\u969b\u306e\u30ed\u30ac\u30fc\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\n    \n    \/\/ API\u30ec\u30b9\u30dd\u30f3\u30b9\u6e96\u5099\n    $httpStatus = 500;\n    $responseData = [\n        'status' =&gt; 'error',\n        'error' =&gt; [\n            'code' =&gt; 'E10001', \/\/ \u30c7\u30d5\u30a9\u30eb\u30c8\u306f\u672a\u77e5\u306e\u30a8\u30e9\u30fc\n            'message' =&gt; '\u30b5\u30fc\u30d0\u30fc\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f'\n        ]\n    ];\n    \n    \/\/ \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4f8b\u5916\u306e\u5834\u5408\n    if ($exception instanceof AppException) {\n        $errorCode = $exception-&gt;getErrorCode();\n        $httpStatus = $errorCode-&gt;getHttpStatus();\n        $responseData['error'] = $exception-&gt;getApiErrorResponse();\n        \n        \/\/ \u30ed\u30b0\u8a18\u9332\n        $logLevel = $errorCode-&gt;getLogLevel();\n        $logger-&gt;log($logLevel, $exception-&gt;getMessage(), $exception-&gt;getLogContext());\n    } else {\n        \/\/ \u672a\u51e6\u7406\u306e\u4f8b\u5916\u306e\u5834\u5408\n        if ($isDebug) {\n            $responseData['error']['details'] = [\n                'message' =&gt; $exception-&gt;getMessage(),\n                'file' =&gt; $exception-&gt;getFile(),\n                'line' =&gt; $exception-&gt;getLine(),\n                'trace' =&gt; $exception-&gt;getTraceAsString()\n            ];\n        }\n        \n        \/\/ \u30ed\u30b0\u8a18\u9332\n        $logger-&gt;error($exception-&gt;getMessage(), [\n            'file' =&gt; $exception-&gt;getFile(),\n            'line' =&gt; $exception-&gt;getLine(),\n            'exception' =&gt; get_class($exception)\n        ]);\n    }\n    \n    \/\/ \u30ec\u30b9\u30dd\u30f3\u30b9\u9001\u4fe1\n    http_response_code($httpStatus);\n    header('Content-Type: application\/json');\n    echo json_encode($responseData);\n    exit;\n}\n\n\/\/ \u30cf\u30f3\u30c9\u30e9\u30fc\u767b\u9332\nset_exception_handler('globalExceptionHandler');\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-146\">\u5b9f\u969b\u306e\u4f7f\u7528\u4f8b<\/h4>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3092\u4f7f\u7528\u3057\u305f\u30b3\u30fc\u30c9\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u30ed\u30b8\u30c3\u30af\u306e\u4f8b\nfunction authenticateUser(string $username, string $password): User\n{\n    $user = UserRepository::findByUsername($username);\n    \n    if (!$user) {\n        throw new AuthenticationException(\n            AppErrorCode::INVALID_CREDENTIALS,\n            null,\n            ['username' =&gt; $username]\n        );\n    }\n    \n    if (!password_verify($password, $user-&gt;getPasswordHash())) {\n        \/\/ \u5931\u6557\u56de\u6570\u306e\u30ab\u30a6\u30f3\u30c8\n        LoginAttemptTracker::recordFailedAttempt($username);\n        \n        throw new AuthenticationException(\n            AppErrorCode::INVALID_CREDENTIALS,\n            null,\n            ['username' =&gt; $username]\n        );\n    }\n    \n    if ($user-&gt;isLocked()) {\n        throw new AuthenticationException(\n            AppErrorCode::AUTHENTICATION_FAILED,\n            '\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059',\n            ['username' =&gt; $username, 'locked_until' =&gt; $user-&gt;getLockedUntil()]\n        );\n    }\n    \n    return $user;\n}\n\n\/\/ \u30e6\u30fc\u30b6\u30fc\u5165\u529b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u4f8b\nfunction validateUserInput(array $data): array\n{\n    $errors = [];\n    \n    if (empty($data['name'])) {\n        $errors['name'] = '\u540d\u524d\u306f\u5fc5\u9808\u3067\u3059';\n    }\n    \n    if (empty($data['email'])) {\n        $errors['email'] = '\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u5fc5\u9808\u3067\u3059';\n    } elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {\n        $errors['email'] = '\u6709\u52b9\u306a\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044';\n    }\n    \n    if (!empty($errors)) {\n        throw new ValidationException(\n            $errors,\n            AppErrorCode::INVALID_INPUT,\n            '\u30d5\u30a9\u30fc\u30e0\u306e\u5165\u529b\u5185\u5bb9\u306b\u554f\u984c\u304c\u3042\u308a\u307e\u3059'\n        );\n    }\n    \n    return $data;\n}\n\n\/\/ \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u4f7f\u7528\u4f8b\ntry {\n    $input = json_decode(file_get_contents('php:\/\/input'), true);\n    $validatedData = validateUserInput($input);\n    $user = authenticateUser($validatedData['username'], $validatedData['password']);\n    \n    \/\/ \u6210\u529f\u30ec\u30b9\u30dd\u30f3\u30b9\n    echo json_encode(['status' =&gt; 'success', 'data' =&gt; $user-&gt;toArray()]);\n} catch (AppException $e) {\n    \/\/ \u4f8b\u5916\u306f globalExceptionHandler \u306b\u3088\u3063\u3066\u51e6\u7406\u3055\u308c\u308b\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-147\">Enum\u306b\u3088\u308b\u30a8\u30e9\u30fc\u7ba1\u7406\u306e\u30e1\u30ea\u30c3\u30c8<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u578b\u5b89\u5168\u6027<\/strong> \u2013 \u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306f\u5217\u6319\u578b\u3068\u3057\u3066\u5b9a\u7fa9\u3055\u308c\u3001\u30bf\u30a4\u30d7\u30df\u30b9\u3092\u9632\u6b62<\/li>\n\n\n\n<li><strong>\u4e00\u8cab\u6027<\/strong> \u2013 \u30a8\u30e9\u30fc\u51e6\u7406\u3068\u30ec\u30dd\u30fc\u30c8\u304c\u7d71\u4e00\u3055\u308c\u305f\u5f62\u5f0f\u3067\u884c\u308f\u308c\u308b<\/li>\n\n\n\n<li><strong>\u81ea\u5df1\u6587\u66f8\u5316<\/strong> \u2013 \u30b3\u30fc\u30c9\u30d9\u30fc\u30b9\u306b\u30a8\u30e9\u30fc\u60c5\u5831\u3068\u51e6\u7406\u65b9\u6cd5\u304c\u660e\u793a\u3055\u308c\u3066\u3044\u308b<\/li>\n\n\n\n<li><strong>\u4fdd\u5b88\u6027<\/strong> \u2013 \u65b0\u3057\u3044\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306e\u8ffd\u52a0\u304c\u5bb9\u6613<\/li>\n\n\n\n<li><strong>\u62e1\u5f35\u6027<\/strong> \u2013 \u65b0\u3057\u3044\u30ab\u30c6\u30b4\u30ea\u3084\u51e6\u7406\u65b9\u6cd5\u3092\u8ffd\u52a0\u3057\u3084\u3059\u3044<\/li>\n\n\n\n<li><strong>IDE\u88dc\u5b8c<\/strong> \u2013 \u958b\u767a\u6642\u306b\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306e\u88dc\u5b8c\u3068\u691c\u8a3c\u304c\u53ef\u80fd<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-148\">\u56fd\u969b\u5316\uff08\u591a\u8a00\u8a9e\u5bfe\u5fdc\uff09<\/h4>\n\n\n\n<p>\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u56fd\u969b\u5316\u3082\u3001Enum\u3092\u4f7f\u7528\u3057\u3066\u52b9\u7387\u7684\u306b\u7ba1\u7406\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u591a\u8a00\u8a9e\u5bfe\u5fdc\u306e\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\nenum ErrorMessageLanguage\n{\n    case ENGLISH;\n    case JAPANESE;\n    case SPANISH;\n    case FRENCH;\n    \n    \/\/ \u8a00\u8a9e\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\n    public function getCode(): string\n    {\n        return match($this) {\n            self::ENGLISH =&gt; 'en',\n            self::JAPANESE =&gt; 'ja',\n            self::SPANISH =&gt; 'es',\n            self::FRENCH =&gt; 'fr',\n        };\n    }\n}\n\n\/\/ AppErrorCode\u30af\u30e9\u30b9\u306b\u591a\u8a00\u8a9e\u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\nenum AppErrorCode: string\n{\n    \/\/ \u65e2\u5b58\u306e\u30b1\u30fc\u30b9\u5b9a\u7fa9...\n    \n    \/\/ \u6307\u5b9a\u3055\u308c\u305f\u8a00\u8a9e\u3067\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u53d6\u5f97\n    public function getLocalizedMessage(ErrorMessageLanguage $language): string\n    {\n        return match($language) {\n            ErrorMessageLanguage::ENGLISH =&gt; $this-&gt;getEnglishMessage(),\n            ErrorMessageLanguage::JAPANESE =&gt; $this-&gt;getJapaneseMessage(),\n            ErrorMessageLanguage::SPANISH =&gt; $this-&gt;getSpanishMessage(),\n            ErrorMessageLanguage::FRENCH =&gt; $this-&gt;getFrenchMessage(),\n        };\n    }\n    \n    \/\/ \u82f1\u8a9e\u30e1\u30c3\u30bb\u30fc\u30b8\n    private function getEnglishMessage(): string\n    {\n        return match($this) {\n            self::UNKNOWN_ERROR =&gt; 'An unexpected error occurred',\n            self::INVALID_CREDENTIALS =&gt; 'Invalid username or password',\n            \/\/ \u4ed6\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3082\u540c\u69d8\u306b\u5b9a\u7fa9...\n            default =&gt; 'An error occurred',\n        };\n    }\n    \n    \/\/ \u65e5\u672c\u8a9e\u30e1\u30c3\u30bb\u30fc\u30b8\n    private function getJapaneseMessage(): string\n    {\n        return match($this) {\n            self::UNKNOWN_ERROR =&gt; '\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n            self::INVALID_CREDENTIALS =&gt; '\u30e6\u30fc\u30b6\u30fc\u540d\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093',\n            \/\/ \u4ed6\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3082\u540c\u69d8\u306b\u5b9a\u7fa9...\n            default =&gt; '\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f',\n        };\n    }\n    \n    \/\/ \u30b9\u30da\u30a4\u30f3\u8a9e\u30e1\u30c3\u30bb\u30fc\u30b8\n    private function getSpanishMessage(): string\n    {\n        return match($this) {\n            self::UNKNOWN_ERROR =&gt; 'Se produjo un error inesperado',\n            self::INVALID_CREDENTIALS =&gt; 'Nombre de usuario o contrase\u00f1a inv\u00e1lidos',\n            \/\/ \u4ed6\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3082\u540c\u69d8\u306b\u5b9a\u7fa9...\n            default =&gt; 'Se produjo un error',\n        };\n    }\n    \n    \/\/ \u30d5\u30e9\u30f3\u30b9\u8a9e\u30e1\u30c3\u30bb\u30fc\u30b8\n    private function getFrenchMessage(): string\n    {\n        return match($this) {\n            self::UNKNOWN_ERROR =&gt; 'Une erreur inattendue s\\'est produite',\n            self::INVALID_CREDENTIALS =&gt; 'Nom d\\'utilisateur ou mot de passe invalide',\n            \/\/ \u4ed6\u306e\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3082\u540c\u69d8\u306b\u5b9a\u7fa9...\n            default =&gt; 'Une erreur s\\'est produite',\n        };\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-149\">\u5b9f\u88c5\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306e\u547d\u540d\u898f\u5247\u3092\u78ba\u7acb\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u4e00\u8cab\u6027\u306e\u3042\u308b\u5f62\u5f0f\uff08\u4f8b\uff1a<code>E10001<\/code>\uff09<\/li>\n\n\n\n<li>\u30ab\u30c6\u30b4\u30ea\u3054\u3068\u306b\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u6c7a\u5b9a<\/li>\n\n\n\n<li>\u6570\u5b57\u3084\u30bb\u30de\u30f3\u30c6\u30a3\u30c3\u30af\u306a\u547d\u540d\u898f\u5247\u3092\u4f7f\u7528<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30a8\u30e9\u30fc\u306e\u8a73\u7d30\u30ec\u30d9\u30eb\u3092\u9069\u5207\u306b\u8a2d\u5b9a\u3059\u308b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30e6\u30fc\u30b6\u30fc\u5411\u3051\u30e1\u30c3\u30bb\u30fc\u30b8\uff08\u4e00\u822c\u7684\u3067\u7406\u89e3\u3057\u3084\u3059\u3044\uff09<\/li>\n\n\n\n<li>\u958b\u767a\u8005\u5411\u3051\u30e1\u30c3\u30bb\u30fc\u30b8\uff08\u6280\u8853\u7684\u3067\u8a73\u7d30\uff09<\/li>\n\n\n\n<li>\u30ed\u30b0\u5411\u3051\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\uff08\u30c7\u30d0\u30c3\u30b0\u306b\u5fc5\u8981\u306a\u60c5\u5831\uff09<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u91cd\u5927\u5ea6\u3068\u8cac\u4efb\u306e\u660e\u78ba\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30a8\u30e9\u30fc\u3068\u30b5\u30fc\u30d0\u30fc\u30a8\u30e9\u30fc\u3092\u533a\u5225<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u30ab\u30c6\u30b4\u30ea\u306e\u660e\u78ba\u306a\u5b9a\u7fa9<\/li>\n\n\n\n<li>\u9069\u5207\u306aHTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3068\u306e\u5bfe\u5fdc<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>API\u4ed5\u69d8\u66f8\u3078\u306e\u53cd\u6620<\/li>\n\n\n\n<li>Enum\u304b\u3089\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u81ea\u52d5\u751f\u6210<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u5bfe\u5fdc\u30ac\u30a4\u30c9\u306e\u4f5c\u6210<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3078\u306e\u914d\u616e<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u74b0\u5883\u306b\u5fdc\u3058\u305f\u30a8\u30e9\u30fc\u8a73\u7d30\u306e\u5236\u5fa1<\/li>\n\n\n\n<li>\u30bb\u30f3\u30b7\u30c6\u30a3\u30d6\u60c5\u5831\u306e\u6f0f\u6d29\u9632\u6b62<\/li>\n\n\n\n<li>\u653b\u6483\u8005\u306b\u6709\u7528\u306a\u60c5\u5831\u306e\u5236\u9650<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u306b\u3088\u308b\u4f8b\u5916\u51e6\u7406\u3068\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u7ba1\u7406\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u54c1\u8cea\u3068\u4fdd\u5b88\u6027\u3092\u5927\u304d\u304f\u5411\u4e0a\u3055\u305b\u308b\u5f37\u529b\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u3067\u3059\u3002\u578b\u5b89\u5168\u6027\u3001\u4e00\u8cab\u6027\u3001\u81ea\u5df1\u6587\u66f8\u5316\u3068\u3044\u3063\u305f\u7279\u6027\u306b\u3088\u308a\u3001\u30a8\u30e9\u30fc\u51e6\u7406\u306e\u30df\u30b9\u3092\u6e1b\u3089\u3057\u3001\u958b\u767a\u8005\u4f53\u9a13\u3068\u30a8\u30f3\u30c9\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u306e\u4e21\u65b9\u3092\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-150\">Laravel\u3067\u306eEnum\u5bfe\u5fdc\u3068\u6d3b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<p>Laravel 9.0\u4ee5\u964d\u3067\u306f\u3001PHP 8.1\u306eEnum\u578b\u306b\u5bfe\u3059\u308b\u5305\u62ec\u7684\u306a\u30b5\u30dd\u30fc\u30c8\u304c\u5c0e\u5165\u3055\u308c\u307e\u3057\u305f\u3002\u3053\u308c\u306b\u3088\u308a\u3001Eloquent\u30e2\u30c7\u30eb\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306a\u3069\u69d8\u3005\u306a\u5834\u9762\u3067Enum\u3092\u6d3b\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-151\">Eloquent\u30e2\u30c7\u30eb\u3067\u306e\u30ad\u30e3\u30b9\u30c8<\/h4>\n\n\n\n<p>Laravel Eloquent\u306e\u5f37\u529b\u306a\u6a5f\u80fd\u306e\u4e00\u3064\u304c\u5c5e\u6027\u30ad\u30e3\u30b9\u30c8\u3067\u3042\u308a\u3001\u3053\u308c\u304cEnum\u3068\u30b7\u30fc\u30e0\u30ec\u30b9\u306b\u9023\u643a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Enums\/SubscriptionStatus.php\nenum SubscriptionStatus: string\n{\n    case ACTIVE = 'active';\n    case TRIAL = 'trial';\n    case CANCELLED = 'cancelled';\n    case PENDING = 'pending';\n    case EXPIRED = 'expired';\n    \n    \/\/ \u8ffd\u52a0\u6a5f\u80fd: \u30a2\u30af\u30c6\u30a3\u30d6\u72b6\u614b\u304b\u3069\u3046\u304b\u3092\u5224\u5b9a\n    public function isActive(): bool\n    {\n        return in_array($this, [self::ACTIVE, self::TRIAL]);\n    }\n    \n    \/\/ \u8868\u793a\u7528\u30e9\u30d9\u30eb\u3092\u53d6\u5f97\n    public function label(): string\n    {\n        return match($this) {\n            self::ACTIVE =&gt; '\u30a2\u30af\u30c6\u30a3\u30d6',\n            self::TRIAL =&gt; '\u30c8\u30e9\u30a4\u30a2\u30eb\u4e2d',\n            self::CANCELLED =&gt; '\u30ad\u30e3\u30f3\u30bb\u30eb\u6e08\u307f',\n            self::PENDING =&gt; '\u4fdd\u7559\u4e2d',\n            self::EXPIRED =&gt; '\u671f\u9650\u5207\u308c',\n        };\n    }\n    \n    \/\/ \u8272\u8868\u793a\u7528\u30af\u30e9\u30b9\u3092\u53d6\u5f97\n    public function colorClass(): string\n    {\n        return match($this) {\n            self::ACTIVE =&gt; 'text-green-500',\n            self::TRIAL =&gt; 'text-blue-500',\n            self::CANCELLED =&gt; 'text-red-500',\n            self::PENDING =&gt; 'text-yellow-500',\n            self::EXPIRED =&gt; 'text-gray-500',\n        };\n    }\n}\n\n\/\/ app\/Models\/Subscription.php\nclass Subscription extends Model\n{\n    protected $fillable = [\n        'user_id',\n        'plan_id',\n        'status',\n        'start_date',\n        'end_date',\n    ];\n    \n    \/\/ \u6587\u5b57\u5217\u304b\u3089SubscriptionStatus Enum\u3078\u306e\u81ea\u52d5\u30ad\u30e3\u30b9\u30c8\n    protected $casts = [\n        'status' =&gt; SubscriptionStatus::class,\n        'start_date' =&gt; 'datetime',\n        'end_date' =&gt; 'datetime',\n    ];\n    \n    \/\/ \u30ea\u30ec\u30fc\u30b7\u30e7\u30f3\u30b7\u30c3\u30d7\n    public function user()\n    {\n        return $this-&gt;belongsTo(User::class);\n    }\n    \n    public function plan()\n    {\n        return $this-&gt;belongsTo(Plan::class);\n    }\n    \n    \/\/ Enum\u306e\u6a5f\u80fd\u3092\u6d3b\u7528\u3057\u305f\u30b9\u30b3\u30fc\u30d7\n    public function scopeActive($query)\n    {\n        return $query-&gt;whereIn('status', [\n            SubscriptionStatus::ACTIVE-&gt;value,\n            SubscriptionStatus::TRIAL-&gt;value\n        ]);\n    }\n    \n    \/\/ \u30d8\u30eb\u30d1\u30fc\u30e1\u30bd\u30c3\u30c9\n    public function cancel(): void\n    {\n        $this-&gt;status = SubscriptionStatus::CANCELLED;\n        $this-&gt;save();\n    }\n    \n    \/\/ Enum\u3092\u5229\u7528\u3057\u305f\u6761\u4ef6\u5224\u5b9a\n    public function canReactivate(): bool\n    {\n        return $this-&gt;status === SubscriptionStatus::CANCELLED &amp;&amp; \n               $this-&gt;end_date-&gt;isFuture();\n    }\n}\n<\/pre>\n\n\n\n<p>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u53d6\u5f97\u3059\u308b\u969b\u3001<code>status<\/code>\u30ab\u30e9\u30e0\u306e\u5024\u306f\u81ea\u52d5\u7684\u306b<code>SubscriptionStatus<\/code>Enum\u306b\u5909\u63db\u3055\u308c\u307e\u3059\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u578b\u5b89\u5168\u6027\u304c\u78ba\u4fdd\u3055\u308c\u3001Enum\u306e\u30e1\u30bd\u30c3\u30c9\u3084\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u76f4\u63a5\u5229\u7528\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$subscription = Subscription::find(1);\n\n\/\/ Enum\u306e\u6bd4\u8f03\nif ($subscription-&gt;status === SubscriptionStatus::ACTIVE) {\n    \/\/ \u30a2\u30af\u30c6\u30a3\u30d6\u306a\u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3\u306e\u51e6\u7406\n}\n\n\/\/ Enum\u306e\u30e1\u30bd\u30c3\u30c9\u547c\u3073\u51fa\u3057\nif ($subscription-&gt;status-&gt;isActive()) {\n    \/\/ \u30a2\u30af\u30c6\u30a3\u30d6\u306a\u51e6\u7406\n}\n\n\/\/ \u30e9\u30d9\u30eb\u8868\u793a\necho $subscription-&gt;status-&gt;label(); \/\/ \u300c\u30a2\u30af\u30c6\u30a3\u30d6\u300d\u306a\u3069\n\n\/\/ \u6761\u4ef6\u306b\u57fa\u3065\u304f\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\n$activeSubscriptions = Subscription::active()-&gt;get();\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-152\">\u30d5\u30a9\u30fc\u30e0\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/h4>\n\n\n\n<p>Laravel 9\u4ee5\u964d\u3067\u306f\u3001FormRequest\u3067Enum\u3092\u4f7f\u7528\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u304c\u7c21\u5358\u306b\u5b9f\u88c5\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Requests\/SubscriptionRequest.php\nclass SubscriptionRequest extends FormRequest\n{\n    public function rules()\n    {\n        return [\n            'user_id' =&gt; 'required|exists:users,id',\n            'plan_id' =&gt; 'required|exists:plans,id',\n            \/\/ Enum\u3092\u4f7f\u7528\u3057\u305f\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n            'status' =&gt; ['required', Rule::enum(SubscriptionStatus::class)],\n            'start_date' =&gt; 'required|date',\n            'end_date' =&gt; 'required|date|after:start_date',\n        ];\n    }\n}\n<\/pre>\n\n\n\n<p><code>Rule::enum<\/code>\u30e1\u30bd\u30c3\u30c9\u306f\u3001\u5165\u529b\u5024\u304c\u6307\u5b9a\u3055\u308c\u305fEnum\u306e\u6709\u52b9\u306a\u5024\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u7121\u52b9\u306a\u5024\u306e\u53d7\u3051\u5165\u308c\u3092\u9632\u6b62\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-153\">\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30eb<\/h4>\n\n\n\n<p>\u3088\u308a\u7d30\u304b\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u8981\u4ef6\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u30ab\u30b9\u30bf\u30e0\u30eb\u30fc\u30eb\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Rules\/ActiveSubscriptionStatus.php\nclass ActiveSubscriptionStatus implements Rule\n{\n    public function passes($attribute, $value)\n    {\n        try {\n            $status = SubscriptionStatus::from($value);\n            return $status-&gt;isActive();\n        } catch (\\ValueError $e) {\n            return false;\n        }\n    }\n    \n    public function message()\n    {\n        return '\u30b9\u30c6\u30fc\u30bf\u30b9\u306f\u30a2\u30af\u30c6\u30a3\u30d6\u306a\u72b6\u614b\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002';\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n'status' =&gt; ['required', new ActiveSubscriptionStatus],\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-154\">\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3067\u306eEnum<\/h4>\n\n\n\n<p>Laravel\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3067\u3082Enum\u5024\u3092\u4f7f\u7528\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ database\/migrations\/create_subscriptions_table.php\npublic function up()\n{\n    Schema::create('subscriptions', function (Blueprint $table) {\n        $table-&gt;id();\n        $table-&gt;foreignId('user_id')-&gt;constrained();\n        $table-&gt;foreignId('plan_id')-&gt;constrained();\n        \/\/ Enum\u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u5024\u3092\u6307\u5b9a\n        $table-&gt;string('status')-&gt;default(SubscriptionStatus::PENDING-&gt;value);\n        $table-&gt;timestamp('start_date');\n        $table-&gt;timestamp('end_date');\n        $table-&gt;timestamps();\n        \n        \/\/ MySQL\u56fa\u6709\u306eENUM\u578b\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\uff08\u30aa\u30d7\u30b7\u30e7\u30f3\uff09\n        \/\/ $table-&gt;enum('status', array_column(SubscriptionStatus::cases(), 'value'))\n        \/\/     -&gt;default(SubscriptionStatus::PENDING-&gt;value);\n    });\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-155\">Blade\u30d3\u30e5\u30fc\u3067\u306e\u6d3b\u7528<\/h4>\n\n\n\n<p>Blade\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u5185\u3067Enum\u3092\u52b9\u679c\u7684\u306b\u4f7f\u7528\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{{-- resources\/views\/subscriptions\/show.blade.php --}}\n&lt;div class=\"subscription-card\"&gt;\n    &lt;h2&gt;\u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3\u8a73\u7d30&lt;\/h2&gt;\n    \n    &lt;div class=\"status-badge {{ $subscription-&gt;status-&gt;colorClass() }}\"&gt;\n        {{ $subscription-&gt;status-&gt;label() }}\n    &lt;\/div&gt;\n    \n    &lt;div class=\"details\"&gt;\n        &lt;p&gt;\u30d7\u30e9\u30f3: {{ $subscription-&gt;plan-&gt;name }}&lt;\/p&gt;\n        &lt;p&gt;\u958b\u59cb\u65e5: {{ $subscription-&gt;start_date-&gt;format('Y\u5e74m\u6708d\u65e5') }}&lt;\/p&gt;\n        &lt;p&gt;\u7d42\u4e86\u65e5: {{ $subscription-&gt;end_date-&gt;format('Y\u5e74m\u6708d\u65e5') }}&lt;\/p&gt;\n    &lt;\/div&gt;\n    \n    &lt;div class=\"actions\"&gt;\n        @if($subscription-&gt;status === \\App\\Enums\\SubscriptionStatus::ACTIVE)\n            &lt;form action=\"{{ route('subscriptions.cancel', $subscription) }}\" method=\"POST\"&gt;\n                @csrf\n                @method('PATCH')\n                &lt;button type=\"submit\" class=\"btn btn-danger\"&gt;\u30ad\u30e3\u30f3\u30bb\u30eb&lt;\/button&gt;\n            &lt;\/form&gt;\n        @elseif($subscription-&gt;canReactivate())\n            &lt;form action=\"{{ route('subscriptions.reactivate', $subscription) }}\" method=\"POST\"&gt;\n                @csrf\n                @method('PATCH')\n                &lt;button type=\"submit\" class=\"btn btn-success\"&gt;\u518d\u30a2\u30af\u30c6\u30a3\u30d6\u5316&lt;\/button&gt;\n            &lt;\/form&gt;\n        @endif\n    &lt;\/div&gt;\n&lt;\/div&gt;\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-156\">\u30bb\u30ec\u30af\u30c8\u30dc\u30c3\u30af\u30b9\u306e\u4f5c\u6210<\/h4>\n\n\n\n<p>\u30d5\u30a9\u30fc\u30e0\u3067Enum\u3092\u4f7f\u7528\u3057\u305f\u30bb\u30ec\u30af\u30c8\u30dc\u30c3\u30af\u30b9\u3092\u751f\u6210\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{{-- resources\/views\/subscriptions\/edit.blade.php --}}\n&lt;div class=\"form-group\"&gt;\n    &lt;label for=\"status\"&gt;\u30b9\u30c6\u30fc\u30bf\u30b9&lt;\/label&gt;\n    &lt;select name=\"status\" id=\"status\" class=\"form-control\"&gt;\n        @foreach(\\App\\Enums\\SubscriptionStatus::cases() as $status)\n            &lt;option \n                value=\"{{ $status-&gt;value }}\" \n                {{ $subscription-&gt;status === $status ? 'selected' : '' }}\n            &gt;\n                {{ $status-&gt;label() }}\n            &lt;\/option&gt;\n        @endforeach\n    &lt;\/select&gt;\n&lt;\/div&gt;\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-157\">\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u6d3b\u7528<\/h4>\n\n\n\n<p>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306eEnum\u6d3b\u7528\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/SubscriptionController.php\npublic function update(SubscriptionRequest $request, Subscription $subscription)\n{\n    $validated = $request-&gt;validated();\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6e08\u307f\u30c7\u30fc\u30bf\u304b\u3089\u76f4\u63a5Enum\u3092\u53d6\u5f97\n    $status = SubscriptionStatus::from($validated['status']);\n    \n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u306e\u5c65\u6b74\u3092\u8a18\u9332\n    if ($subscription-&gt;status !== $status) {\n        SubscriptionStatusHistory::create([\n            'subscription_id' =&gt; $subscription-&gt;id,\n            'from_status' =&gt; $subscription-&gt;status-&gt;value,\n            'to_status' =&gt; $status-&gt;value,\n            'changed_by' =&gt; auth()-&gt;id(),\n        ]);\n    }\n    \n    $subscription-&gt;update($validated);\n    \n    return redirect()-&gt;route('subscriptions.show', $subscription)\n        -&gt;with('success', '\u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3\u304c\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f');\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-158\">Enum\u30d8\u30eb\u30d1\u30fc\u30c8\u30ec\u30a4\u30c8<\/h4>\n\n\n\n<p>Laravel\u3067\u518d\u5229\u7528\u53ef\u80fd\u306aEnum\u30d8\u30eb\u30d1\u30fc\u30c8\u30ec\u30a4\u30c8\u3092\u4f5c\u6210\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Traits\/EnumHelpers.php\ntrait EnumHelpers\n{\n    \/\/ \u5168\u30b1\u30fc\u30b9\u306e\u5024\u3092\u53d6\u5f97\n    public static function values(): array\n    {\n        return array_column(self::cases(), 'value');\n    }\n    \n    \/\/ select\u30dc\u30c3\u30af\u30b9\u7528\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u751f\u6210\n    public static function options(): array\n    {\n        $options = [];\n        foreach (self::cases() as $case) {\n            $options[$case-&gt;value] = method_exists($case, 'label') \n                ? $case-&gt;label() \n                : $case-&gt;name;\n        }\n        return $options;\n    }\n    \n    \/\/ \u30e9\u30f3\u30c0\u30e0\u306a\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\uff08\u30c6\u30b9\u30c8\u7528\uff09\n    public static function random(): static\n    {\n        $cases = self::cases();\n        return $cases[array_rand($cases)];\n    }\n    \n    \/\/ \u7279\u5b9a\u306e\u30b1\u30fc\u30b9\u304c\u542b\u307e\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\n    public static function contains(self $needle): bool\n    {\n        foreach (self::cases() as $case) {\n            if ($case === $needle) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nenum SubscriptionStatus: string\n{\n    use EnumHelpers;\n    \n    \/\/ \u30b1\u30fc\u30b9\u306e\u5b9a\u7fa9...\n}\n\n\/\/ \u30bb\u30ec\u30af\u30c8\u30dc\u30c3\u30af\u30b9\u7528\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u751f\u6210\n$statusOptions = SubscriptionStatus::options();\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-159\">Enum\u7528\u30de\u30af\u30ed\u306e\u5b9a\u7fa9<\/h4>\n\n\n\n<p>Laravel\u306e\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0\u3067\u3001Enum\u7528\u306e\u30de\u30af\u30ed\u3092\u5b9a\u7fa9\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Providers\/AppServiceProvider.php\npublic function boot()\n{\n    \/\/ Blueprint\u62e1\u5f35: Enum\u7528\u30ab\u30e9\u30e0\u8ffd\u52a0\u30e1\u30bd\u30c3\u30c9\n    Blueprint::macro('enumString', function (string $column, string $enumClass) {\n        \/** @var Blueprint $this *\/\n        return $this-&gt;string($column)-&gt;default($enumClass::cases()[0]-&gt;value);\n    });\n    \n    \/\/ \u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u62e1\u5f35: Enum\u5024\u3067\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\n    Collection::macro('whereEnum', function (string $key, $enumValue) {\n        \/** @var Collection $this *\/\n        if ($enumValue instanceof \\UnitEnum) {\n            $value = $enumValue instanceof \\BackedEnum ? $enumValue-&gt;value : $enumValue-&gt;name;\n        } else {\n            $value = $enumValue;\n        }\n        \n        return $this-&gt;where($key, $value);\n    });\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nSchema::create('subscriptions', function (Blueprint $table) {\n    $table-&gt;id();\n    $table-&gt;enumString('status', SubscriptionStatus::class);\n    \/\/ ...\n});\n\n$activeSubscriptions = $subscriptions-&gt;whereEnum('status', SubscriptionStatus::ACTIVE);\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-160\">Livewire\/Alpine.js\u3068\u306e\u9023\u643a<\/h4>\n\n\n\n<p>Livewire\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u306eEnum\u6d3b\u7528\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Livewire\/SubscriptionManager.php\nclass SubscriptionManager extends Component\n{\n    public Subscription $subscription;\n    public string $status;\n    \n    public function mount(Subscription $subscription)\n    {\n        $this-&gt;subscription = $subscription;\n        $this-&gt;status = $subscription-&gt;status-&gt;value;\n    }\n    \n    public function updateStatus()\n    {\n        $this-&gt;validate([\n            'status' =&gt; ['required', Rule::enum(SubscriptionStatus::class)],\n        ]);\n        \n        $this-&gt;subscription-&gt;status = SubscriptionStatus::from($this-&gt;status);\n        $this-&gt;subscription-&gt;save();\n        \n        $this-&gt;emit('statusUpdated');\n    }\n    \n    public function render()\n    {\n        return view('livewire.subscription-manager', [\n            'statusOptions' =&gt; SubscriptionStatus::options(),\n        ]);\n    }\n}\n<\/pre>\n\n\n\n<p>Laravel\u3067\u306eEnum\u6d3b\u7528\u306f\u3001\u30b3\u30fc\u30c9\u306e\u578b\u5b89\u5168\u6027\u3001\u4fdd\u5b88\u6027\u3001\u53ef\u8aad\u6027\u3092\u5927\u304d\u304f\u5411\u4e0a\u3055\u305b\u307e\u3059\u3002\u7279\u306b\u30c9\u30e1\u30a4\u30f3\u30ed\u30b8\u30c3\u30af\u304c\u8907\u96d1\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001Eloquent\u30e2\u30c7\u30eb\u3068\u306e\u7dca\u5bc6\u306a\u7d71\u5408\u306b\u3088\u3063\u3066\u3001\u3088\u308a\u5805\u7262\u3067\u8868\u73fe\u529b\u8c4a\u304b\u306a\u30b3\u30fc\u30c9\u304c\u66f8\u3051\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-161\">Symfony\u3067\u306eEnum\u6d3b\u7528\u3068FormType\u9023\u643a<\/h3>\n\n\n\n<p>Symfony 6.0\u4ee5\u964d\u3067\u306f\u3001PHP 8.1\u306eEnum\u578b\u306b\u5bfe\u3059\u308b\u5305\u62ec\u7684\u306a\u30b5\u30dd\u30fc\u30c8\u304c\u5c0e\u5165\u3055\u308c\u307e\u3057\u305f\u3002\u7279\u306b\u30d5\u30a9\u30fc\u30e0\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3001Doctrine ORM\u3068\u306e\u9023\u643a\u306b\u304a\u3044\u3066\u3001Enum\u3092\u30b7\u30fc\u30e0\u30ec\u30b9\u306b\u7d71\u5408\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-162\">Symfony\u306eFormType\u3067\u306eEnum\u6d3b\u7528<\/h4>\n\n\n\n<p>Symfony 6.0\u3067\u5c0e\u5165\u3055\u308c\u305f<code>EnumType<\/code>\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001Enum\u30d9\u30fc\u30b9\u306e\u30d5\u30a9\u30fc\u30e0\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u7c21\u5358\u306b\u4f5c\u6210\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Form\/UserType.php\nuse App\\Enum\\UserRole;\nuse Symfony\\Component\\Form\\AbstractType;\nuse Symfony\\Component\\Form\\Extension\\Core\\Type\\EnumType;\nuse Symfony\\Component\\Form\\FormBuilderInterface;\n\nclass UserType extends AbstractType\n{\n    public function buildForm(FormBuilderInterface $builder, array $options)\n    {\n        $builder\n            -&gt;add('name', TextType::class, [\n                'label' =&gt; '\u540d\u524d',\n            ])\n            -&gt;add('email', EmailType::class, [\n                'label' =&gt; '\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9',\n            ])\n            \/\/ EnumType\u3092\u4f7f\u7528\n            -&gt;add('role', EnumType::class, [\n                'class' =&gt; UserRole::class,\n                'label' =&gt; '\u6a29\u9650',\n                'choice_label' =&gt; function (UserRole $choice) {\n                    return $choice-&gt;getLabel();\n                },\n                'placeholder' =&gt; '\u6a29\u9650\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044',\n                'required' =&gt; true,\n            ]);\n    }\n}\n<\/pre>\n\n\n\n<p><code>EnumType<\/code>\u306f\u5185\u90e8\u7684\u306b<code>ChoiceType<\/code>\u3092\u62e1\u5f35\u3057\u3066\u3044\u308b\u305f\u3081\u3001<code>ChoiceType<\/code>\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u3059\u3079\u3066\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u30b0\u30eb\u30fc\u30d7\u5316\u3001\u5c5e\u6027\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3001\u62e1\u5f35\u9078\u629e\u306a\u3069\u306e\u9ad8\u5ea6\u306a\u6a5f\u80fd\u3082\u5229\u7528\u53ef\u80fd\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Enum\u306b\u8868\u793a\u30e9\u30d9\u30eb\u3092\u8ffd\u52a0\nenum UserRole: string\n{\n    case ADMIN = 'admin';\n    case MANAGER = 'manager';\n    case EDITOR = 'editor';\n    case USER = 'user';\n    \n    \/\/ \u8868\u793a\u30e9\u30d9\u30eb\u306e\u53d6\u5f97\n    public function getLabel(): string\n    {\n        return match($this) {\n            self::ADMIN =&gt; '\u7ba1\u7406\u8005',\n            self::MANAGER =&gt; '\u30de\u30cd\u30fc\u30b8\u30e3\u30fc',\n            self::EDITOR =&gt; '\u7de8\u96c6\u8005',\n            self::USER =&gt; '\u4e00\u822c\u30e6\u30fc\u30b6\u30fc',\n        };\n    }\n    \n    \/\/ \u30b0\u30eb\u30fc\u30d7\u306e\u53d6\u5f97\uff08\u30d5\u30a9\u30fc\u30e0\u3067\u306e\u30b0\u30eb\u30fc\u30d7\u5316\u306b\u4f7f\u7528\uff09\n    public function getGroup(): string\n    {\n        return match($this) {\n            self::ADMIN, self::MANAGER =&gt; '\u7ba1\u7406\u8077',\n            self::EDITOR, self::USER =&gt; '\u4e00\u822c\u8077',\n        };\n    }\n}\n\n\/\/ \u30b0\u30eb\u30fc\u30d7\u5316\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\n-&gt;add('role', EnumType::class, [\n    'class' =&gt; UserRole::class,\n    'choice_label' =&gt; fn(UserRole $choice) =&gt; $choice-&gt;getLabel(),\n    'group_by' =&gt; fn(UserRole $choice) =&gt; $choice-&gt;getGroup(),\n])\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-163\">EnumType\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/h4>\n\n\n\n<p>\u7279\u5b9a\u306eEnum\u7528\u306b\u5c02\u7528\u306eFormType\u3092\u4f5c\u6210\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Form\/Type\/UserRoleType.php\nuse App\\Enum\\UserRole;\nuse Symfony\\Component\\Form\\AbstractType;\nuse Symfony\\Component\\Form\\Extension\\Core\\Type\\EnumType;\nuse Symfony\\Component\\OptionsResolver\\OptionsResolver;\n\nclass UserRoleType extends AbstractType\n{\n    public function configureOptions(OptionsResolver $resolver)\n    {\n        $resolver-&gt;setDefaults([\n            'class' =&gt; UserRole::class,\n            'choice_label' =&gt; function (UserRole $choice) {\n                return $choice-&gt;getLabel();\n            },\n            'placeholder' =&gt; '\u6a29\u9650\u3092\u9078\u629e',\n            'invalid_message' =&gt; '\u7121\u52b9\u306a\u6a29\u9650\u304c\u9078\u629e\u3055\u308c\u307e\u3057\u305f',\n        ]);\n    }\n    \n    public function getParent()\n    {\n        return EnumType::class;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$builder-&gt;add('role', UserRoleType::class);\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-164\">Doctrine\u3068Enum\u306e\u9023\u643a<\/h4>\n\n\n\n<p>Doctrine ORM\u3068Enum\u3092\u9023\u643a\u3055\u305b\u308b\u306b\u306f\u3001\u30ab\u30b9\u30bf\u30e0\u30bf\u30a4\u30d7\u306e\u5b9a\u7fa9\u304c\u5fc5\u8981\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Doctrine\/Type\/UserRoleType.php\nuse App\\Enum\\UserRole;\nuse Doctrine\\DBAL\\Platforms\\AbstractPlatform;\nuse Doctrine\\DBAL\\Types\\StringType;\n\nclass UserRoleType extends StringType\n{\n    public const NAME = 'user_role';\n    \n    public function convertToDatabaseValue($value, AbstractPlatform $platform)\n    {\n        return $value instanceof UserRole ? $value-&gt;value : $value;\n    }\n    \n    public function convertToPHPValue($value, AbstractPlatform $platform)\n    {\n        return $value !== null ? UserRole::tryFrom($value) : null;\n    }\n    \n    public function getName(): string\n    {\n        return self::NAME;\n    }\n    \n    public function requiresSQLCommentHint(AbstractPlatform $platform): bool\n    {\n        return true;\n    }\n}\n<\/pre>\n\n\n\n<p>\u30bf\u30a4\u30d7\u306e\u767b\u9332\u306f<code>config\/packages\/doctrine.yaml<\/code>\u3067\u884c\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># config\/packages\/doctrine.yaml\ndoctrine:\n    dbal:\n        types:\n            user_role: App\\Doctrine\\Type\\UserRoleType\n<\/pre>\n\n\n\n<p>\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u3067\u306e\u4f7f\u7528\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Entity\/User.php\nuse App\\Doctrine\\Type\\UserRoleType;\nuse App\\Enum\\UserRole;\nuse Doctrine\\ORM\\Mapping as ORM;\n\n#[ORM\\Entity]\nclass User\n{\n    #[ORM\\Id]\n    #[ORM\\GeneratedValue]\n    #[ORM\\Column]\n    private ?int $id = null;\n    \n    #[ORM\\Column(length: 255)]\n    private ?string $name = null;\n    \n    #[ORM\\Column(length: 255)]\n    private ?string $email = null;\n    \n    #[ORM\\Column(type: UserRoleType::NAME)]\n    private ?UserRole $role = null;\n    \n    \/\/ \u30b2\u30c3\u30bf\u30fc\u3068\u30bb\u30c3\u30bf\u30fc\n    public function getId(): ?int\n    {\n        return $this-&gt;id;\n    }\n    \n    public function getName(): ?string\n    {\n        return $this-&gt;name;\n    }\n    \n    public function setName(string $name): self\n    {\n        $this-&gt;name = $name;\n        return $this;\n    }\n    \n    public function getEmail(): ?string\n    {\n        return $this-&gt;email;\n    }\n    \n    public function setEmail(string $email): self\n    {\n        $this-&gt;email = $email;\n        return $this;\n    }\n    \n    public function getRole(): ?UserRole\n    {\n        return $this-&gt;role;\n    }\n    \n    public function setRole(UserRole $role): self\n    {\n        $this-&gt;role = $role;\n        return $this;\n    }\n    \n    \/\/ \u30ed\u30fc\u30eb\u306b\u57fa\u3065\u304f\u5224\u5b9a\u30e1\u30bd\u30c3\u30c9\n    public function isAdmin(): bool\n    {\n        return $this-&gt;role === UserRole::ADMIN;\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-165\">Symfony 6.2\u4ee5\u964d\u3067\u306e\u30b7\u30f3\u30d7\u30eb\u306a\u9023\u643a<\/h4>\n\n\n\n<p>Symfony 6.2\u4ee5\u964d\u3067\u306f\u3001Doctrine EnumType\u306b\u5bfe\u3059\u308b\u3088\u308a\u7c21\u6f54\u306a\u30b5\u30dd\u30fc\u30c8\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002<code>doctrine.yaml<\/code>\u306b\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u8a2d\u5b9a\u3059\u308b\u3060\u3051\u3067\u3001Enum\u306e\u81ea\u52d5\u30de\u30c3\u30d4\u30f3\u30b0\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># config\/packages\/doctrine.yaml\ndoctrine:\n    dbal:\n        types:\n            # \u81ea\u52d5Enum\u30de\u30c3\u30d4\u30f3\u30b0\u3092Symfony\u306b\u4efb\u305b\u308b\n            enum: Doctrine\\DBAL\\Types\\StringType\n    orm:\n        mappings:\n            App:\n                is_bundle: false\n                type: attribute\n                dir: '%kernel.project_dir%\/src\/Entity'\n                prefix: 'App\\Entity'\n                alias: App\n                # \u81ea\u52d5Enum\u578b\u30de\u30c3\u30d4\u30f3\u30b0\u3092\u6709\u52b9\u5316\n                enum_mappings:\n                    App\\Enum: string\n<\/pre>\n\n\n\n<p>\u3053\u306e\u8a2d\u5b9a\u306b\u3088\u308a\u3001<code>App\\Enum<\/code>\u540d\u524d\u7a7a\u9593\u306eEnum\u578b\u304cstring\u578b\u306e\u30ab\u30e9\u30e0\u306b\u81ea\u52d5\u7684\u306b\u30de\u30c3\u30d4\u30f3\u30b0\u3055\u308c\u307e\u3059\u3002\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u30b7\u30f3\u30d7\u30eb\u306b\u5b9a\u7fa9\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Entity\/User.php (Symfony 6.2+)\nuse App\\Enum\\UserRole;\nuse Doctrine\\ORM\\Mapping as ORM;\n\n#[ORM\\Entity]\nclass User\n{\n    \/\/ ...\n    \n    #[ORM\\Column]\n    private ?UserRole $role = null;\n    \n    \/\/ ...\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-166\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u5236\u7d04<\/h4>\n\n\n\n<p>Symofny 6.0\u4ee5\u964d\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001<code>Choice<\/code>\u5236\u7d04\u3067Enum\u578b\u3092\u76f4\u63a5\u4f7f\u7528\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Entity\/User.php\nuse App\\Enum\\UserRole;\nuse Symfony\\Component\\Validator\\Constraints as Assert;\n\nclass User\n{\n    \/\/ ...\n    \n    #[Assert\\NotNull]\n    #[Assert\\Choice(callback: [UserRole::class, 'cases'])]\n    private ?UserRole $role = null;\n    \n    \/\/ ...\n}\n<\/pre>\n\n\n\n<p>\u307e\u305f\u306f\u5c02\u7528\u306eEnum\u5236\u7d04\u3092\u4f7f\u3046\u3053\u3068\u3082\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Validator\/Constraints\/ValidUserRole.php\nuse App\\Enum\\UserRole;\nuse Symfony\\Component\\Validator\\Constraint;\n\n#[\\Attribute]\nclass ValidUserRole extends Constraint\n{\n    public $message = '\u9078\u629e\u3055\u308c\u305f\u6a29\u9650\"{{ value }}\"\u306f\u7121\u52b9\u3067\u3059\u3002';\n}\n\n\/\/ src\/Validator\/Constraints\/ValidUserRoleValidator.php\nuse App\\Enum\\UserRole;\nuse Symfony\\Component\\Validator\\Constraint;\nuse Symfony\\Component\\Validator\\ConstraintValidator;\nuse Symfony\\Component\\Validator\\Exception\\UnexpectedTypeException;\n\nclass ValidUserRoleValidator extends ConstraintValidator\n{\n    public function validate($value, Constraint $constraint)\n    {\n        if (null === $value) {\n            return;\n        }\n        \n        if (!$constraint instanceof ValidUserRole) {\n            throw new UnexpectedTypeException($constraint, ValidUserRole::class);\n        }\n        \n        if (!$value instanceof UserRole) {\n            $this-&gt;context-&gt;buildViolation($constraint-&gt;message)\n                -&gt;setParameter('{{ value }}', $value)\n                -&gt;addViolation();\n            return;\n        }\n        \n        \/\/ \u8ffd\u52a0\u306e\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30ed\u30b8\u30c3\u30af\uff08\u5fc5\u8981\u306b\u5fdc\u3058\u3066\uff09\n        \/\/ \u4f8b: \u7ba1\u7406\u8005\u6a29\u9650\u304c\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b\u304b\u306a\u3069\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n#[Assert\\NotNull]\n#[ValidUserRole]\nprivate ?UserRole $role = null;\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-167\">Twig\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3067\u306e\u4f7f\u7528<\/h4>\n\n\n\n<p>Twig\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u5185\u3067Enum\u3092\u6271\u3046\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{# templates\/user\/show.html.twig #}\n{% extends 'base.html.twig' %}\n\n{% block body %}\n    &lt;h1&gt;\u30e6\u30fc\u30b6\u30fc\u8a73\u7d30&lt;\/h1&gt;\n    \n    &lt;div class=\"user-info\"&gt;\n        &lt;p&gt;\u540d\u524d: {{ user.name }}&lt;\/p&gt;\n        &lt;p&gt;\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9: {{ user.email }}&lt;\/p&gt;\n        \n        {% set roleClass = {\n            'admin': 'badge-danger',\n            'manager': 'badge-warning',\n            'editor': 'badge-info',\n            'user': 'badge-primary'\n        } %}\n        \n        &lt;p&gt;\n            \u6a29\u9650: \n            &lt;span class=\"badge {{ roleClass[user.role.value] }}\"&gt;\n                {{ user.role.label }}\n            &lt;\/span&gt;\n        &lt;\/p&gt;\n        \n        {% if user.role == constant('App\\\\Enum\\\\UserRole::ADMIN') %}\n            &lt;div class=\"admin-actions\"&gt;\n                &lt;h3&gt;\u7ba1\u7406\u8005\u30e1\u30cb\u30e5\u30fc&lt;\/h3&gt;\n                {# \u7ba1\u7406\u8005\u5c02\u7528\u306e\u30a2\u30af\u30b7\u30e7\u30f3 #}\n            &lt;\/div&gt;\n        {% endif %}\n    &lt;\/div&gt;\n{% endblock %}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-168\">\u30b5\u30fc\u30d3\u30b9\u30b3\u30f3\u30c6\u30ca\u3067\u306eEnum\u6d3b\u7528<\/h4>\n\n\n\n<p>\u30b5\u30fc\u30d3\u30b9\u30b3\u30f3\u30c6\u30ca\u306e\u8a2d\u5b9a\u3067Enum\u3092\u6d3b\u7528\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># config\/services.yaml\nservices:\n    # RoleVoter\u306bUserRole\u3092\u6ce8\u5165\n    App\\Security\\Voter\\RoleVoter:\n        arguments:\n            $adminRole: !php\/const App\\Enum\\UserRole::ADMIN\n<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Security\/Voter\/RoleVoter.php\nuse App\\Enum\\UserRole;\n\nclass RoleVoter extends Voter\n{\n    private UserRole $adminRole;\n    \n    public function __construct(UserRole $adminRole)\n    {\n        $this-&gt;adminRole = $adminRole;\n    }\n    \n    \/\/ ...\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-169\">\u30a4\u30d9\u30f3\u30c8\u3068\u30e1\u30c3\u30bb\u30fc\u30b8\u30f3\u30b0\u3067\u306e\u6d3b\u7528<\/h4>\n\n\n\n<p>Symfony\u306e\u30a4\u30d9\u30f3\u30c8\u30b7\u30b9\u30c6\u30e0\u3084Messenger\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067Enum\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u3088\u308a\u578b\u5b89\u5168\u306a\u30b3\u30fc\u30c9\u304c\u66f8\u3051\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ src\/Event\/UserEvent.php\nuse App\\Enum\\UserEventType;\n\nclass UserEvent\n{\n    private UserEventType $type;\n    \n    public function __construct(\n        UserEventType $type,\n        private User $user\n    ) {\n        $this-&gt;type = $type;\n    }\n    \n    public function getType(): UserEventType\n    {\n        return $this-&gt;type;\n    }\n    \n    public function getUser(): User\n    {\n        return $this-&gt;user;\n    }\n}\n\n\/\/ src\/EventSubscriber\/UserEventSubscriber.php\nclass UserEventSubscriber implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents()\n    {\n        return [\n            UserEvent::class =&gt; 'onUserEvent',\n        ];\n    }\n    \n    public function onUserEvent(UserEvent $event)\n    {\n        match($event-&gt;getType()) {\n            UserEventType::REGISTERED =&gt; $this-&gt;handleRegistration($event-&gt;getUser()),\n            UserEventType::ACTIVATED =&gt; $this-&gt;handleActivation($event-&gt;getUser()),\n            UserEventType::PASSWORD_CHANGED =&gt; $this-&gt;handlePasswordChange($event-&gt;getUser()),\n        };\n    }\n    \n    \/\/ ...\n}\n<\/pre>\n\n\n\n<p>Symfony 6.0\u4ee5\u964d\u3067\u306eEnum\u5bfe\u5fdc\u306f\u975e\u5e38\u306b\u5305\u62ec\u7684\u3067\u3001\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u307b\u307c\u3059\u3079\u3066\u306e\u90e8\u5206\u3067Enum\u3092\u6d3b\u7528\u3067\u304d\u307e\u3059\u3002\u7279\u306b\u30d5\u30a9\u30fc\u30e0\u51e6\u7406\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306b\u304a\u3044\u3066\u3001\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u3068\u578b\u5b89\u5168\u6027\u304c\u5927\u5e45\u306b\u5411\u4e0a\u3057\u307e\u3059\u3002\u30b5\u30fc\u30d3\u30b9\u30b3\u30f3\u30c6\u30ca\u3068\u306e\u9023\u643a\u3082\u81ea\u7136\u3067\u3001DDD\uff08\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08\uff09\u30a2\u30d7\u30ed\u30fc\u30c1\u3092\u63a1\u7528\u3059\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u7279\u306b\u9069\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-170\">PHP Enum\u3092\u4f7f\u3044\u3053\u306a\u3059\u305f\u3081\u306e\u6b21\u306e\u30b9\u30c6\u30c3\u30d7<\/h2>\n\n\n\n<p>\u3053\u3053\u307e\u3067\u3001PHP Enum\u306e\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u304b\u3089\u5b9f\u8df5\u7684\u306a\u5fdc\u7528\u4f8b\u307e\u3067\u898b\u3066\u304d\u307e\u3057\u305f\u3002\u6b21\u306b\u3001Enum\u3092\u672c\u683c\u7684\u306b\u6d3b\u7528\u3059\u308b\u305f\u3081\u306e\u767a\u5c55\u7684\u306a\u30c8\u30d4\u30c3\u30af\u3084\u3001\u65e2\u5b58\u30b3\u30fc\u30c9\u306e\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u624b\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-171\">\u8a2d\u8a08\u306e\u898b\u76f4\u3057\u3068Enum\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306e\u30dd\u30a4\u30f3\u30c8<\/h3>\n\n\n\n<p>PHP Enum\u3092\u5c0e\u5165\u3059\u308b\u3053\u3068\u306f\u3001\u5358\u306a\u308b\u69cb\u6587\u5909\u66f4\u4ee5\u4e0a\u306e\u610f\u5473\u3092\u6301\u3061\u307e\u3059\u3002\u305d\u308c\u306f\u30b3\u30fc\u30c9\u306e\u8a2d\u8a08\u3068\u8868\u73fe\u529b\u3092\u898b\u76f4\u3059\u826f\u3044\u6a5f\u4f1a\u3067\u3059\u3002\u4ee5\u4e0b\u306e\u30dd\u30a4\u30f3\u30c8\u306b\u6ce8\u76ee\u3057\u3066Enum\u306e\u5c0e\u5165\u3068\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u3092\u9032\u3081\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-172\">\u6bb5\u968e\u7684\u306a\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u6226\u7565<\/h4>\n\n\n\n<p>\u65e2\u5b58\u306e\u30b7\u30b9\u30c6\u30e0\u306bEnum\u3092\u5c0e\u5165\u3059\u308b\u969b\u306f\u3001\u6bb5\u968e\u7684\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u304c\u52b9\u679c\u7684\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5019\u88dc\u306e\u7279\u5b9a<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u6587\u5b57\u5217\/\u6574\u6570\u5b9a\u6570\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u30b3\u30fc\u30c9\u90e8\u5206\u3092\u7279\u5b9a<\/li>\n\n\n\n<li>\u30de\u30b8\u30c3\u30af\u30ca\u30f3\u30d0\u30fc\u3084\u6587\u5b57\u5217\u30ea\u30c6\u30e9\u30eb\u3092\u63a2\u3059<\/li>\n\n\n\n<li>\u30c9\u30e1\u30a4\u30f3\u306e\u91cd\u8981\u306a\u533a\u5206\u3084\u7a2e\u5225\u3092\u8868\u3059\u90e8\u5206\u3092\u512a\u5148<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u512a\u5148\u9806\u4f4d\u306e\u6c7a\u5b9a<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30c9\u30e1\u30a4\u30f3\u306e\u4e2d\u6838\u6982\u5ff5\u304b\u3089\u7740\u624b<\/li>\n\n\n\n<li>\u30c6\u30b9\u30c8\u304c\u5145\u5b9f\u3057\u3066\u3044\u308b\u90e8\u5206\u3092\u512a\u5148<\/li>\n\n\n\n<li>\u5909\u66f4\u983b\u5ea6\u306e\u9ad8\u3044\u90e8\u5206\u304b\u3089\u6539\u5584<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b3\u30f3\u30d0\u30fc\u30bf\u30fc\u306e\u4f5c\u6210<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u65e2\u5b58\u306e\u5024\u3068Enum\u9593\u306e\u5909\u63db\u30ec\u30a4\u30e4\u30fc\u3092\u7528\u610f<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u306e\u9023\u643a\u90e8\u5206\u306b\u6ce8\u610f<\/li>\n\n\n\n<li>\u4e00\u6642\u7684\u306a\u4e92\u63db\u6027\u95a2\u6570\u306e\u5c0e\u5165<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u306e\u5145\u5b9f<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u524d\u306b\u30c6\u30b9\u30c8\u30ab\u30d0\u30ec\u30c3\u30b8\u3092\u5411\u4e0a<\/li>\n\n\n\n<li>\u5883\u754c\u5024\u30c6\u30b9\u30c8\u3092\u8ffd\u52a0<\/li>\n\n\n\n<li>\u30b3\u30f3\u30d0\u30fc\u30bf\u30fc\u306e\u52d5\u4f5c\u3092\u78ba\u8a8d\u3059\u308b\u30c6\u30b9\u30c8<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u6bb5\u968e\u7684\u7f6e\u304d\u63db\u3048<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u90e8\u5206\u304b\u3089\u5185\u90e8\u5b9f\u88c5\u3078<\/li>\n\n\n\n<li>\u95a2\u9023\u3059\u308b\u30af\u30e9\u30b9\u3092\u30b0\u30eb\u30fc\u30d7\u5316\u3057\u3066\u79fb\u884c<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u5168\u4f53\u306e\u4e00\u8cab\u6027\u3092\u4fdd\u3064<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-173\">\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u4f8b\uff1a\u5b9a\u6570\u30af\u30e9\u30b9\u304b\u3089Enum\u3078<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u524d: \u5b9a\u6570\u30af\u30e9\u30b9\nclass PaymentMethod\n{\n    public const CREDIT_CARD = 'credit_card';\n    public const BANK_TRANSFER = 'bank_transfer';\n    public const PAYPAL = 'paypal';\n    public const CRYPTOCURRENCY = 'crypto';\n    \n    public static function getLabel($method)\n    {\n        return [\n            self::CREDIT_CARD =&gt; '\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9',\n            self::BANK_TRANSFER =&gt; '\u9280\u884c\u632f\u8fbc',\n            self::PAYPAL =&gt; 'PayPal',\n            self::CRYPTOCURRENCY =&gt; '\u6697\u53f7\u901a\u8ca8',\n        ][$method] ?? '\u4e0d\u660e';\n    }\n    \n    public static function getOptions()\n    {\n        return [\n            self::CREDIT_CARD =&gt; self::getLabel(self::CREDIT_CARD),\n            self::BANK_TRANSFER =&gt; self::getLabel(self::BANK_TRANSFER),\n            self::PAYPAL =&gt; self::getLabel(self::PAYPAL),\n            self::CRYPTOCURRENCY =&gt; self::getLabel(self::CRYPTOCURRENCY),\n        ];\n    }\n}\n\n\/\/ \u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u5f8c: Enum\nenum PaymentMethod: string\n{\n    case CREDIT_CARD = 'credit_card';\n    case BANK_TRANSFER = 'bank_transfer';\n    case PAYPAL = 'paypal';\n    case CRYPTOCURRENCY = 'crypto';\n    \n    public function getLabel(): string\n    {\n        return match($this) {\n            self::CREDIT_CARD =&gt; '\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9',\n            self::BANK_TRANSFER =&gt; '\u9280\u884c\u632f\u8fbc',\n            self::PAYPAL =&gt; 'PayPal',\n            self::CRYPTOCURRENCY =&gt; '\u6697\u53f7\u901a\u8ca8',\n        };\n    }\n    \n    public static function getOptions(): array\n    {\n        return array_reduce(\n            self::cases(),\n            fn($options, $case) =&gt; $options + [$case-&gt;value =&gt; $case-&gt;getLabel()],\n            []\n        );\n    }\n    \n    \/\/ Enum\u306a\u3089\u3067\u306f\u306e\u65b0\u6a5f\u80fd: \u30aa\u30f3\u30e9\u30a4\u30f3\u6c7a\u6e08\u304b\u3069\u3046\u304b\u3092\u5224\u5b9a\n    public function isOnlinePayment(): bool\n    {\n        return match($this) {\n            self::CREDIT_CARD, self::PAYPAL, self::CRYPTOCURRENCY =&gt; true,\n            self::BANK_TRANSFER =&gt; false,\n        };\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-174\">\u79fb\u884c\u671f\u306e\u4e92\u63db\u6027\u30ec\u30a4\u30e4\u30fc<\/h4>\n\n\n\n<p>\u5927\u898f\u6a21\u306a\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u3067\u306f\u3001\u4e00\u6642\u7684\u306a\u4e92\u63db\u6027\u30ec\u30a4\u30e4\u30fc\u304c\u6709\u7528\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ \u79fb\u884c\u671f\u306e\u4e92\u63db\u6027\u30ec\u30a4\u30e4\u30fc\nclass LegacyPaymentMethod\n{\n    \/\/ \u5f93\u6765\u306e\u30b3\u30fc\u30c9\u3068\u4e92\u63db\u6027\u306e\u3042\u308b\u9759\u7684\u30e1\u30bd\u30c3\u30c9\n    public static function getLabel($method)\n    {\n        return PaymentMethod::tryFrom($method)?-&gt;getLabel() ?? '\u4e0d\u660e';\n    }\n    \n    public static function getOptions()\n    {\n        return PaymentMethod::getOptions();\n    }\n    \n    \/\/ \u5b9a\u6570\u30a2\u30af\u30bb\u30b9\u306e\u4e92\u63db\u6027\uff08PHP 8.1\u306e__callStatic\u5229\u7528\uff09\n    public static function __callStatic($name, $arguments)\n    {\n        foreach (PaymentMethod::cases() as $case) {\n            if ($case-&gt;name === $name) {\n                return $case-&gt;value;\n            }\n        }\n        \n        throw new \\Error(\"Undefined constant PaymentMethod::$name\");\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-175\">\u767a\u5c55\u7684\u306aEnum\u6d3b\u7528\u30d1\u30bf\u30fc\u30f3<\/h4>\n\n\n\n<p>\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u3092\u8d85\u3048\u3066\u3001\u3088\u308a\u767a\u5c55\u7684\u306a\u30d1\u30bf\u30fc\u30f3\u3092\u53d6\u308a\u5165\u308c\u308b\u3053\u3068\u3067\u3001Enum\u306e\u4fa1\u5024\u3092\u6700\u5927\u5316\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d5\u30a1\u30af\u30c8\u30ea\u30fc\u30e1\u30bd\u30c3\u30c9\u30d1\u30bf\u30fc\u30f3<\/strong> Enum\u3092\u30d5\u30a1\u30af\u30c8\u30ea\u30fc\u3068\u3057\u3066\u4f7f\u7528\u3057\u3001\u9069\u5207\u306a\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u751f\u6210\u3057\u307e\u3059\uff1a <code>enum ReportType: string { case DAILY = 'daily'; case WEEKLY = 'weekly'; case MONTHLY = 'monthly'; case QUARTERLY = 'quarterly'; case YEARLY = 'yearly'; \/\/ \u30d5\u30a1\u30af\u30c8\u30ea\u30fc\u30e1\u30bd\u30c3\u30c9 public function createReport(array $data): Report { return match($this) { self::DAILY =&gt; new DailyReport($data), self::WEEKLY =&gt; new WeeklyReport($data), self::MONTHLY =&gt; new MonthlyReport($data), self::QUARTERLY =&gt; new QuarterlyReport($data), self::YEARLY =&gt; new YearlyReport($data), }; } \/\/ \u671f\u9593\u8a08\u7b97\u30e1\u30bd\u30c3\u30c9 public function calculateDateRange(\\DateTimeInterface $referenceDate): array { return match($this) { self::DAILY =&gt; [ 'start' =&gt; (clone $referenceDate)-&gt;setTime(0, 0), 'end' =&gt; (clone $referenceDate)-&gt;setTime(23, 59, 59), ], self::WEEKLY =&gt; [ 'start' =&gt; (clone $referenceDate)-&gt;modify('monday this week')-&gt;setTime(0, 0), 'end' =&gt; (clone $referenceDate)-&gt;modify('sunday this week')-&gt;setTime(23, 59, 59), ], \/\/ \u4ed6\u306e\u671f\u9593\u3082\u540c\u69d8\u306b... }; } }<\/code><\/li>\n\n\n\n<li><strong>\u30d3\u30b8\u30bf\u30fc\u30d1\u30bf\u30fc\u30f3<\/strong> Enum\u3068\u30d3\u30b8\u30bf\u30fc\u30d1\u30bf\u30fc\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u3066\u3001\u62e1\u5f35\u6027\u3092\u9ad8\u3081\u307e\u3059\uff1a <code>\/\/ \u30d3\u30b8\u30bf\u30fc\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9 interface ShippingMethodVisitor { public function visitStandard(ShippingMethod $method): mixed; public function visitExpress(ShippingMethod $method): mixed; public function visitInternational(ShippingMethod $method): mixed; } \/\/ Enum\u5074\u306e\u5b9f\u88c5 enum ShippingMethod: string { case STANDARD = 'standard'; case EXPRESS = 'express'; case INTERNATIONAL = 'international'; \/\/ \u30d3\u30b8\u30bf\u30fc\u30d1\u30bf\u30fc\u30f3\u306e\u5b9f\u88c5 public function accept(ShippingMethodVisitor $visitor): mixed { return match($this) { self::STANDARD =&gt; $visitor-&gt;visitStandard($this), self::EXPRESS =&gt; $visitor-&gt;visitExpress($this), self::INTERNATIONAL =&gt; $visitor-&gt;visitInternational($this), }; } } \/\/ \u6599\u91d1\u8a08\u7b97\u30d3\u30b8\u30bf\u30fc class ShippingCostCalculator implements ShippingMethodVisitor { private float $weight; private string $destination; public function __construct(float $weight, string $destination) { $this-&gt;weight = $weight; $this-&gt;destination = $destination; } public function visitStandard(ShippingMethod $method): float { return $this-&gt;weight * 100; } public function visitExpress(ShippingMethod $method): float { return $this-&gt;weight * 250; } public function visitInternational(ShippingMethod $method): float { $baseRate = $this-&gt;weight * 350; return match($this-&gt;destination) { 'EU' =&gt; $baseRate * 1.1, 'Asia' =&gt; $baseRate * 1.2, 'Americas' =&gt; $baseRate * 1.3, default =&gt; $baseRate * 1.5, }; } } \/\/ \u4f7f\u7528\u4f8b $method = ShippingMethod::EXPRESS; $calculator = new ShippingCostCalculator(2.5, 'Asia'); $cost = $method-&gt;accept($calculator); \/\/ $625<\/code><\/li>\n\n\n\n<li><strong>\u30b3\u30de\u30f3\u30c9\u30d1\u30bf\u30fc\u30f3<\/strong> Enum\u3092\u30b3\u30de\u30f3\u30c9\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u4f7f\u7528\u3057\u307e\u3059\uff1a <code>enum UserCommand: string { case ACTIVATE = 'activate'; case DEACTIVATE = 'deactivate'; case RESET_PASSWORD = 'reset_password'; case CHANGE_ROLE = 'change_role'; public function execute(User $user, array $params = []): void { match($this) { self::ACTIVATE =&gt; $user-&gt;activate(), self::DEACTIVATE =&gt; $user-&gt;deactivate(), self::RESET_PASSWORD =&gt; $user-&gt;resetPassword( $params['password'] ?? $this-&gt;generateRandomPassword() ), self::CHANGE_ROLE =&gt; $user-&gt;changeRole($params['role']), }; } private function generateRandomPassword(): string { return bin2hex(random_bytes(8)); } \/\/ \u6a29\u9650\u30c1\u30a7\u30c3\u30af public function canExecute(User $currentUser, User $targetUser): bool { return match($this) { self::ACTIVATE, self::DEACTIVATE, self::CHANGE_ROLE =&gt; $currentUser-&gt;isAdmin() || $currentUser-&gt;id === $targetUser-&gt;id, self::RESET_PASSWORD =&gt; $currentUser-&gt;isAdmin() || $currentUser-&gt;id === $targetUser-&gt;id, }; } } \/\/ \u4f7f\u7528\u4f8b $command = UserCommand::RESET_PASSWORD; if ($command-&gt;canExecute($currentUser, $targetUser)) { $command-&gt;execute($targetUser); echo \"\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u30ea\u30bb\u30c3\u30c8\u3055\u308c\u307e\u3057\u305f\"; } else { echo \"\u3053\u306e\u64cd\u4f5c\u3092\u5b9f\u884c\u3059\u308b\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\"; }<\/code><\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-176\">\u30a8\u30f3\u30bf\u30fc\u30d7\u30e9\u30a4\u30ba\u958b\u767a\u306b\u304a\u3051\u308bEnum<\/h4>\n\n\n\n<p>\u30a8\u30f3\u30bf\u30fc\u30d7\u30e9\u30a4\u30ba\u30ec\u30d9\u30eb\u306e\u958b\u767a\u3067\u306f\u3001\u30c1\u30fc\u30e0\u9593\u306e\u9023\u643a\u3084\u9577\u671f\u4fdd\u5b88\u3092\u8003\u616e\u3057\u305fEnum\u6d3b\u7528\u304c\u91cd\u8981\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u751f\u6210\u306e\u81ea\u52d5\u5316<\/strong> PHPDoc\u30b3\u30e1\u30f3\u30c8\u3068Enum\u3092\u9023\u643a\u3055\u305b\u3001API\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u81ea\u52d5\u751f\u6210\u3057\u307e\u3059\uff1a <code>\/** * \u652f\u6255\u3044\u51e6\u7406\u306e\u7d50\u679c\u30b9\u30c6\u30fc\u30bf\u30b9 * * @api *\/ enum PaymentResultStatus: string { \/** * \u652f\u6255\u3044\u304c\u6210\u529f\u3057\u307e\u3057\u305f\u3002\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306f\u5b8c\u4e86\u3057\u3066\u3044\u307e\u3059\u3002 *\/ case SUCCESS = 'success'; \/** * \u652f\u6255\u3044\u51e6\u7406\u4e2d\u3067\u3059\u3002\u7d50\u679c\u306f\u975e\u540c\u671f\u3067\u901a\u77e5\u3055\u308c\u307e\u3059\u3002 *\/ case PENDING = 'pending'; \/** * \u652f\u6255\u3044\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u8a73\u7d30\u306f\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002 *\/ case FAILED = 'failed'; \/** * \u652f\u6255\u3044\u304c\u30e6\u30fc\u30b6\u30fc\u306b\u3088\u3063\u3066\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f\u3002 *\/ case CANCELLED = 'cancelled'; \/** * \u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u8868\u793a\u540d\u3092\u53d6\u5f97\u3057\u307e\u3059\u3002 * * @return string \u30e6\u30fc\u30b6\u30fc\u5411\u3051\u8868\u793a\u540d *\/ public function getDisplayName(): string { return match($this) { self::SUCCESS =&gt; '\u652f\u6255\u3044\u5b8c\u4e86', self::PENDING =&gt; '\u51e6\u7406\u4e2d', self::FAILED =&gt; '\u652f\u6255\u3044\u5931\u6557', self::CANCELLED =&gt; '\u30ad\u30e3\u30f3\u30bb\u30eb\u6e08\u307f', }; } }<\/code><\/li>\n\n\n\n<li><strong>\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u9593\u306e\u901a\u4fe1<\/strong> \u30b5\u30fc\u30d3\u30b9\u9593API\u3067Enum\u3092\u6d3b\u7528\u3057\u307e\u3059\uff1a <code>enum ApiErrorCode: string { case VALIDATION_ERROR = 'validation_error'; case AUTHENTICATION_FAILED = 'authentication_failed'; case RESOURCE_NOT_FOUND = 'resource_not_found'; case RATE_LIMIT_EXCEEDED = 'rate_limit_exceeded'; case INTERNAL_ERROR = 'internal_error'; \/\/ HTTP\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3068\u30de\u30c3\u30d4\u30f3\u30b0 public function getHttpStatusCode(): int { return match($this) { self::VALIDATION_ERROR =&gt; 422, self::AUTHENTICATION_FAILED =&gt; 401, self::RESOURCE_NOT_FOUND =&gt; 404, self::RATE_LIMIT_EXCEEDED =&gt; 429, self::INTERNAL_ERROR =&gt; 500, }; } \/\/ OpenAPI\u4ed5\u69d8\u306b\u5408\u308f\u305b\u305f\u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u751f\u6210 public function toApiResponse(string $message, ?array $details = null): array { return [ 'error' =&gt; [ 'code' =&gt; $this-&gt;value, 'message' =&gt; $message, 'details' =&gt; $details, ] ]; } }<\/code><\/li>\n\n\n\n<li><strong>\u30d0\u30fc\u30b8\u30e7\u30cb\u30f3\u30b0\u5bfe\u5fdc<\/strong> API\u306e\u9032\u5316\u306b\u5408\u308f\u305b\u305fEnum\u5b9a\u7fa9\u306e\u7ba1\u7406\uff1a <code>\/** * @deprecated API v2.0\u304b\u3089\u975e\u63a8\u5968\u3002PaymentType\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044\u3002 *\/ enum LegacyPaymentMethod: string { case CREDIT = 'credit'; case BANK = 'bank'; case PAYPAL = 'paypal'; \/\/ \u65b0\u3057\u3044Enum\u3078\u306e\u5909\u63db public function toNewType(): PaymentType { return match($this) { self::CREDIT =&gt; PaymentType::CREDIT_CARD, self::BANK =&gt; PaymentType::BANK_TRANSFER, self::PAYPAL =&gt; PaymentType::DIGITAL_WALLET, }; } } \/\/ \u65b0\u3057\u3044\u30d0\u30fc\u30b8\u30e7\u30f3\u306eEnum enum PaymentType: string { case CREDIT_CARD = 'credit_card'; case BANK_TRANSFER = 'bank_transfer'; case DIGITAL_WALLET = 'digital_wallet'; case CRYPTOCURRENCY = 'cryptocurrency'; \/\/ \u65e7\u30d0\u30fc\u30b8\u30e7\u30f3\u304b\u3089\u306e\u5909\u63db public static function fromLegacy(LegacyPaymentMethod $legacy): self { return $legacy-&gt;toNewType(); } }<\/code><\/li>\n<\/ol>\n\n\n\n<p>PHP Enum\u3092\u672c\u683c\u7684\u306b\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30b3\u30fc\u30c9\u30d9\u30fc\u30b9\u306e\u8868\u73fe\u529b\u3001\u4fdd\u5b88\u6027\u3001\u578b\u5b89\u5168\u6027\u304c\u5927\u304d\u304f\u5411\u4e0a\u3057\u307e\u3059\u3002\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u304b\u3089\u59cb\u3081\u3066\u3001\u5f90\u3005\u306b\u767a\u5c55\u7684\u306a\u30d1\u30bf\u30fc\u30f3\u3092\u53d6\u308a\u5165\u308c\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u4fa1\u5024\u306e\u9ad8\u3044\u30b3\u30fc\u30c9\u3092\u4f5c\u6210\u3067\u304d\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-177\">\u30c6\u30b9\u30c8\u3068\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\uff1aEnum\u3092\u542b\u3080\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u7ba1\u7406<\/h3>\n\n\n\n<p>PHP Enum\u3092\u6d3b\u7528\u3057\u305f\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u3092\u78ba\u4fdd\u3059\u308b\u306b\u306f\u3001\u9069\u5207\u306a\u30c6\u30b9\u30c8\u3068\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u6226\u7565\u304c\u4e0d\u53ef\u6b20\u3067\u3059\u3002Enum\u306e\u578b\u5b89\u5168\u6027\u306e\u30e1\u30ea\u30c3\u30c8\u3092\u6700\u5927\u9650\u306b\u6d3b\u304b\u3057\u306a\u304c\u3089\u3001\u5805\u7262\u306a\u30b3\u30fc\u30c9\u3092\u5b9f\u73fe\u3059\u308b\u305f\u3081\u306e\u30c6\u30af\u30cb\u30c3\u30af\u3092\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-178\">PHPUnit\u3067\u306eEnum\u578b\u30c6\u30b9\u30c8<\/h4>\n\n\n\n<p>PHPUnit\u3092\u4f7f\u7528\u3057\u305fEnum\u578b\u306e\u30c6\u30b9\u30c8\u4f8b\u304b\u3089\u59cb\u3081\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">use PHPUnit\\Framework\\TestCase;\n\nclass PaymentMethodTest extends TestCase\n{\n    public function testEnumValues(): void\n    {\n        \/\/ \u5024\u306e\u78ba\u8a8d\n        $this-&gt;assertSame('credit_card', PaymentMethod::CREDIT_CARD-&gt;value);\n        $this-&gt;assertSame('bank_transfer', PaymentMethod::BANK_TRANSFER-&gt;value);\n        \n        \/\/ case\u30e1\u30bd\u30c3\u30c9\u306e\u7d50\u679c\u78ba\u8a8d\n        $this-&gt;assertCount(4, PaymentMethod::cases());\n        \n        \/\/ from\u30e1\u30bd\u30c3\u30c9\u306e\u30c6\u30b9\u30c8\n        $this-&gt;assertEquals(\n            PaymentMethod::PAYPAL,\n            PaymentMethod::from('paypal')\n        );\n        \n        \/\/ tryFrom\u30e1\u30bd\u30c3\u30c9\u306e\u30c6\u30b9\u30c8\n        $this-&gt;assertEquals(\n            PaymentMethod::CRYPTOCURRENCY,\n            PaymentMethod::tryFrom('crypto')\n        );\n        $this-&gt;assertNull(PaymentMethod::tryFrom('invalid_method'));\n        \n        \/\/ from\u30e1\u30bd\u30c3\u30c9\u306e\u4f8b\u5916\u30c6\u30b9\u30c8\n        $this-&gt;expectException(\\ValueError::class);\n        PaymentMethod::from('invalid_method');\n    }\n    \n    public function testEnumMethods(): void\n    {\n        \/\/ \u30e1\u30bd\u30c3\u30c9\u306e\u30c6\u30b9\u30c8\n        $this-&gt;assertEquals('\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9', PaymentMethod::CREDIT_CARD-&gt;getLabel());\n        $this-&gt;assertTrue(PaymentMethod::PAYPAL-&gt;isOnlinePayment());\n        $this-&gt;assertFalse(PaymentMethod::BANK_TRANSFER-&gt;isOnlinePayment());\n        \n        \/\/ static\u30e1\u30bd\u30c3\u30c9\u306e\u30c6\u30b9\u30c8\n        $options = PaymentMethod::getOptions();\n        $this-&gt;assertArrayHasKey('credit_card', $options);\n        $this-&gt;assertEquals('\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9', $options['credit_card']);\n    }\n    \n    \/**\n     * @dataProvider paymentMethodsProvider\n     *\/\n    public function testPaymentProcessing(PaymentMethod $method, bool $expectSuccess): void\n    {\n        $processor = new PaymentProcessor();\n        \n        if ($expectSuccess) {\n            $this-&gt;assertTrue($processor-&gt;process($method, 100.00));\n        } else {\n            $this-&gt;expectException(PaymentException::class);\n            $processor-&gt;process($method, 100.00);\n        }\n    }\n    \n    public function paymentMethodsProvider(): array\n    {\n        return [\n            '\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9\u6c7a\u6e08\u306f\u6210\u529f\u3059\u308b' =&gt; [PaymentMethod::CREDIT_CARD, true],\n            'PayPal\u6c7a\u6e08\u306f\u6210\u529f\u3059\u308b' =&gt; [PaymentMethod::PAYPAL, true],\n            '\u9280\u884c\u632f\u8fbc\u306f\u51e6\u7406\u3067\u304d\u306a\u3044' =&gt; [PaymentMethod::BANK_TRANSFER, false],\n            \/\/ \u30c6\u30b9\u30c8\u4e2d\u306f\u6697\u53f7\u901a\u8ca8\u6c7a\u6e08\u306f\u7121\u52b9\n            '\u6697\u53f7\u901a\u8ca8\u6c7a\u6e08\u306f\u5931\u6557\u3059\u308b' =&gt; [PaymentMethod::CRYPTOCURRENCY, false],\n        ];\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-179\">\u30ab\u30b9\u30bf\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/h4>\n\n\n\n<p>Enum\u306b\u7279\u5316\u3057\u305f\u30ab\u30b9\u30bf\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u8ffd\u52a0\u3059\u308b\u3068\u3001\u30c6\u30b9\u30c8\u306e\u53ef\u8aad\u6027\u304c\u5411\u4e0a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">trait EnumAssertions\n{\n    public static function assertEnumEquals(\n        \\UnitEnum $expected,\n        \\UnitEnum $actual,\n        string $message = ''\n    ): void {\n        self::assertSame(\n            $expected,\n            $actual,\n            $message ?: sprintf(\n                'Enum\u5024\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002\u671f\u5f85\u5024: %s, \u5b9f\u969b\u306e\u5024: %s',\n                self::formatEnum($expected),\n                self::formatEnum($actual)\n            )\n        );\n    }\n    \n    public static function assertEnumValueEquals(\n        string|int $expected,\n        \\BackedEnum $actual,\n        string $message = ''\n    ): void {\n        self::assertSame(\n            $expected,\n            $actual-&gt;value,\n            $message ?: sprintf(\n                'Enum\u5024\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002\u671f\u5f85\u5024: %s, \u5b9f\u969b\u306e\u5024: %s',\n                $expected,\n                $actual-&gt;value\n            )\n        );\n    }\n    \n    public static function assertEnumIsOneOf(\n        array $expectedEnums,\n        \\UnitEnum $actual,\n        string $message = ''\n    ): void {\n        $found = false;\n        foreach ($expectedEnums as $expected) {\n            if ($expected === $actual) {\n                $found = true;\n                break;\n            }\n        }\n        \n        self::assertTrue(\n            $found,\n            $message ?: sprintf(\n                'Enum\u5024 %s \u306f\u8a31\u5bb9\u3055\u308c\u308b\u5024\u306e\u30bb\u30c3\u30c8\u306b\u542b\u307e\u308c\u3066\u3044\u307e\u305b\u3093',\n                self::formatEnum($actual)\n            )\n        );\n    }\n    \n    private static function formatEnum(\\UnitEnum $enum): string\n    {\n        if ($enum instanceof \\BackedEnum) {\n            return sprintf('%s::%s(%s)', get_class($enum), $enum-&gt;name, $enum-&gt;value);\n        }\n        \n        return sprintf('%s::%s', get_class($enum), $enum-&gt;name);\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\nclass OrderStatusTest extends TestCase\n{\n    use EnumAssertions;\n    \n    public function testOrderFlow(): void\n    {\n        $order = new Order();\n        $this-&gt;assertEnumEquals(OrderStatus::PENDING, $order-&gt;getStatus());\n        \n        $order-&gt;process();\n        $this-&gt;assertEnumIsOneOf(\n            [OrderStatus::PROCESSING, OrderStatus::ON_HOLD],\n            $order-&gt;getStatus()\n        );\n        \n        \/\/ Backed Enum\u306e\u5024\u30c6\u30b9\u30c8\n        $this-&gt;assertEnumValueEquals('processing', $order-&gt;getStatus());\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-180\">\u30e2\u30c3\u30af\u3068\u30b9\u30bf\u30d6\u3067\u306eEnum\u6d3b\u7528<\/h4>\n\n\n\n<p>\u30c6\u30b9\u30c8\u4e2d\u306e\u30e2\u30c3\u30af\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3067Enum\u3092\u6d3b\u7528\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public function testOrderStatusNotification(): void\n{\n    \/\/ \u901a\u77e5\u30b5\u30fc\u30d3\u30b9\u306e\u30e2\u30c3\u30af\n    $notificationService = $this-&gt;createMock(NotificationService::class);\n    \n    \/\/ Enum\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u542b\u3080\u30e1\u30bd\u30c3\u30c9\u547c\u3073\u51fa\u3057\u306e\u671f\u5f85\u8a2d\u5b9a\n    $notificationService-&gt;expects($this-&gt;once())\n        -&gt;method('sendStatusUpdate')\n        -&gt;with(\n            $this-&gt;anything(), \/\/ \u4efb\u610f\u306e\u30aa\u30fc\u30c0\u30fcID\n            $this-&gt;equalTo(OrderStatus::SHIPPED) \/\/ \u7279\u5b9a\u306eEnum\u5024\u3092\u671f\u5f85\n        )\n        -&gt;willReturn(true);\n    \n    $orderProcessor = new OrderProcessor($notificationService);\n    $result = $orderProcessor-&gt;markAsShipped(1001);\n    \n    $this-&gt;assertTrue($result);\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-181\">\u30d1\u30e9\u30e1\u30bf\u30e9\u30a4\u30ba\u30c9\u30c6\u30b9\u30c8<\/h4>\n\n\n\n<p>\u30c7\u30fc\u30bf\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u4f7f\u7528\u3057\u305fEnum\u30c6\u30b9\u30c8\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * @dataProvider statusTransitionsProvider\n *\/\npublic function testOrderStatusTransitions(\n    OrderStatus $initialStatus,\n    OrderStatus $targetStatus,\n    bool $shouldBeAllowed\n): void {\n    $order = new Order();\n    $order-&gt;setStatus($initialStatus);\n    \n    if (!$shouldBeAllowed) {\n        $this-&gt;expectException(InvalidStatusTransitionException::class);\n    }\n    \n    $order-&gt;transitionTo($targetStatus);\n    \n    if ($shouldBeAllowed) {\n        $this-&gt;assertEnumEquals($targetStatus, $order-&gt;getStatus());\n    }\n}\n\npublic function statusTransitionsProvider(): array\n{\n    return [\n        '\u4fdd\u7559\u304b\u3089\u51e6\u7406\u4e2d\u3078\u306e\u9077\u79fb\u306f\u8a31\u53ef' =&gt; [\n            OrderStatus::PENDING, OrderStatus::PROCESSING, true\n        ],\n        '\u4fdd\u7559\u304b\u3089\u30ad\u30e3\u30f3\u30bb\u30eb\u3078\u306e\u9077\u79fb\u306f\u8a31\u53ef' =&gt; [\n            OrderStatus::PENDING, OrderStatus::CANCELLED, true\n        ],\n        '\u4fdd\u7559\u304b\u3089\u767a\u9001\u6e08\u307f\u3078\u306e\u9077\u79fb\u306f\u7981\u6b62' =&gt; [\n            OrderStatus::PENDING, OrderStatus::SHIPPED, false\n        ],\n        '\u51e6\u7406\u4e2d\u304b\u3089\u767a\u9001\u6e08\u307f\u3078\u306e\u9077\u79fb\u306f\u8a31\u53ef' =&gt; [\n            OrderStatus::PROCESSING, OrderStatus::SHIPPED, true\n        ],\n        '\u767a\u9001\u6e08\u307f\u304b\u3089\u51e6\u7406\u4e2d\u3078\u306e\u9077\u79fb\u306f\u7981\u6b62' =&gt; [\n            OrderStatus::SHIPPED, OrderStatus::PROCESSING, false\n        ],\n        '\u30ad\u30e3\u30f3\u30bb\u30eb\u6e08\u307f\u304b\u3089\u4efb\u610f\u306e\u72b6\u614b\u3078\u306e\u9077\u79fb\u306f\u7981\u6b62' =&gt; [\n            OrderStatus::CANCELLED, OrderStatus::PENDING, false\n        ],\n    ];\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-182\">\u7d71\u5408\u30c6\u30b9\u30c8\u3067\u306eEnum\u4f7f\u7528<\/h4>\n\n\n\n<p>API\u5fdc\u7b54\u306a\u3069\u3092\u691c\u8a3c\u3059\u308b\u7d71\u5408\u30c6\u30b9\u30c8\u3067\u306eEnum\u6d3b\u7528\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class OrderApiTest extends WebTestCase\n{\n    public function testCreateOrder(): void\n    {\n        $client = static::createClient();\n        \n        \/\/ API\u30ea\u30af\u30a8\u30b9\u30c8\u9001\u4fe1\n        $client-&gt;request('POST', '\/api\/orders', [], [], [], json_encode([\n            'customer_id' =&gt; 123,\n            'items' =&gt; [['product_id' =&gt; 456, 'quantity' =&gt; 2]],\n            'payment_method' =&gt; PaymentMethod::CREDIT_CARD-&gt;value\n        ]));\n        \n        $response = $client-&gt;getResponse();\n        $data = json_decode($response-&gt;getContent(), true);\n        \n        \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3068\u5fdc\u7b54\u5185\u5bb9\u306e\u691c\u8a3c\n        $this-&gt;assertResponseIsSuccessful();\n        $this-&gt;assertArrayHasKey('order_id', $data);\n        $this-&gt;assertEquals(OrderStatus::PENDING-&gt;value, $data['status']);\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-183\">PHPDoc\u6a19\u6e96\u3068Enum\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/h4>\n\n\n\n<p>Enum\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u751f\u6210\u3092\u52b9\u679c\u7684\u306b\u884c\u3046\u305f\u3081\u306ePHPDoc\u306e\u66f8\u304d\u65b9\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * \u6ce8\u6587\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u8868\u3059Enum\n *\n * \u3053\u306eEnum\u306f\u6ce8\u6587\u306e\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u5168\u4f53\u3092\u8868\u73fe\u3057\u3001\n * \u5404\u30b9\u30c6\u30fc\u30bf\u30b9\u9593\u306e\u9077\u79fb\u30eb\u30fc\u30eb\u3092\u5b9a\u7fa9\u3057\u307e\u3059\u3002\n *\n * @api\n * @since 2.0.0\n *\/\nenum OrderStatus: string\n{\n    \/**\n     * \u6ce8\u6587\u304c\u4f5c\u6210\u3055\u308c\u3001\u652f\u6255\u3044\u5f85\u3061\u306e\u72b6\u614b\n     *\n     * \u3053\u306e\u72b6\u614b\u3067\u306f\u3001\u6ce8\u6587\u306f\u307e\u3060\u78ba\u5b9a\u3057\u3066\u3044\u307e\u305b\u3093\u3002\n     * \u30e6\u30fc\u30b6\u30fc\u306f\u6ce8\u6587\u5185\u5bb9\u3092\u5909\u66f4\u3057\u305f\u308a\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u305f\u308a\u3067\u304d\u307e\u3059\u3002\n     *\/\n    case PENDING = 'pending';\n    \n    \/**\n     * \u652f\u6255\u3044\u304c\u78ba\u8a8d\u3055\u308c\u3001\u6ce8\u6587\u51e6\u7406\u4e2d\u306e\u72b6\u614b\n     *\n     * \u5546\u54c1\u306e\u30d4\u30c3\u30ad\u30f3\u30b0\u3084\u68b1\u5305\u306a\u3069\u306e\u4f5c\u696d\u304c\u884c\u308f\u308c\u3066\u3044\u308b\u72b6\u614b\u3067\u3059\u3002\n     * \u3053\u306e\u6bb5\u968e\u304b\u3089\u306f\u6ce8\u6587\u5185\u5bb9\u306e\u5909\u66f4\u306f\u3067\u304d\u307e\u305b\u3093\u3002\n     *\/\n    case PROCESSING = 'processing';\n    \n    \/**\n     * \u6ce8\u6587\u5546\u54c1\u304c\u767a\u9001\u3055\u308c\u305f\u72b6\u614b\n     *\n     * \u914d\u9001\u696d\u8005\u306b\u5546\u54c1\u304c\u5f15\u304d\u6e21\u3055\u308c\u3001\u914d\u9001\u4e2d\u306e\u72b6\u614b\u3067\u3059\u3002\n     * \u8ffd\u8de1\u756a\u53f7\u304c\u751f\u6210\u3055\u308c\u307e\u3059\u3002\n     *\/\n    case SHIPPED = 'shipped';\n    \n    \/**\n     * \u5546\u54c1\u304c\u9867\u5ba2\u306b\u914d\u9054\u3055\u308c\u305f\u72b6\u614b\n     *\n     * \u914d\u9001\u696d\u8005\u306b\u3088\u3063\u3066\u5546\u54c1\u304c\u9867\u5ba2\u306b\u5c4a\u3051\u3089\u308c\u305f\u72b6\u614b\u3067\u3059\u3002\n     *\/\n    case DELIVERED = 'delivered';\n    \n    \/**\n     * \u6ce8\u6587\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u305f\u72b6\u614b\n     *\n     * \u9867\u5ba2\u307e\u305f\u306f\u7ba1\u7406\u8005\u306b\u3088\u3063\u3066\u6ce8\u6587\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f\u3002\n     * \u3053\u306e\u72b6\u614b\u306f\u6700\u7d42\u72b6\u614b\u3067\u3042\u308a\u3001\u4ed6\u306e\u72b6\u614b\u306b\u5909\u66f4\u3067\u304d\u307e\u305b\u3093\u3002\n     *\/\n    case CANCELLED = 'cancelled';\n    \n    \/**\n     * \u6b21\u306b\u53ef\u80fd\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u4e00\u89a7\u3092\u53d6\u5f97\n     *\n     * \u73fe\u5728\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u304b\u3089\u9077\u79fb\u53ef\u80fd\u306a\u6b21\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u30ea\u30b9\u30c8\u3092\u8fd4\u3057\u307e\u3059\u3002\n     *\n     * @return array&lt;OrderStatus&gt; \u9077\u79fb\u53ef\u80fd\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u914d\u5217\n     *\/\n    public function getNextPossibleStatuses(): array\n    {\n        \/\/ \u5b9f\u88c5\u5185\u5bb9...\n    }\n}\n<\/pre>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306aPHPDoc\u5f62\u5f0f\u306e\u30b3\u30e1\u30f3\u30c8\u3092\u8ffd\u52a0\u3059\u308b\u3053\u3068\u3067\u3001IDE\u306e\u88dc\u5b8c\u6a5f\u80fd\u304c\u5f37\u5316\u3055\u308c\u308b\u3060\u3051\u3067\u306a\u304f\u3001\u81ea\u52d5\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u751f\u6210\u30c4\u30fc\u30eb\u3092\u4f7f\u3063\u3066\u8a73\u7d30\u306aAPI\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u751f\u6210\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-184\">Swagger\/OpenAPI\u3068\u306e\u9023\u643a<\/h4>\n\n\n\n<p>RESTful API\u3067Enum\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u3001OpenAPI\u4ed5\u69d8\u306b\u9023\u643a\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * @OA\\Schema(\n *     schema=\"OrderStatus\",\n *     type=\"string\",\n *     description=\"\u6ce8\u6587\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\",\n *     enum={\"pending\", \"processing\", \"shipped\", \"delivered\", \"cancelled\"}\n * )\n *\/\nenum OrderStatus: string\n{\n    \/\/ \u5b9f\u88c5...\n}\n\n\/**\n * @OA\\Get(\n *     path=\"\/orders\/{id}\",\n *     summary=\"\u6ce8\u6587\u60c5\u5831\u3092\u53d6\u5f97\",\n *     @OA\\Parameter(\n *         name=\"id\",\n *         in=\"path\",\n *         required=true,\n *         description=\"\u6ce8\u6587ID\",\n *         @OA\\Schema(type=\"integer\")\n *     ),\n *     @OA\\Response(\n *         response=200,\n *         description=\"\u6210\u529f\",\n *         @OA\\JsonContent(\n *             @OA\\Property(property=\"id\", type=\"integer\", example=1234),\n *             @OA\\Property(property=\"status\", ref=\"#\/components\/schemas\/OrderStatus\"),\n *             @OA\\Property(property=\"created_at\", type=\"string\", format=\"date-time\")\n *         )\n *     )\n * )\n *\/\npublic function getOrder(int $id): JsonResponse\n{\n    \/\/ \u5b9f\u88c5...\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-185\">\u9759\u7684\u89e3\u6790\u30c4\u30fc\u30eb\u306b\u3088\u308b\u54c1\u8cea\u4fdd\u8a3c<\/h4>\n\n\n\n<p>PHPStan\u3084Psalm\u306a\u3069\u306e\u9759\u7684\u89e3\u6790\u30c4\u30fc\u30eb\u306f\u3001Enum\u3092\u542b\u3080\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u5411\u4e0a\u306b\u5f79\u7acb\u3061\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ PHPStan level 8 \u306e\u8a2d\u5b9a\u4f8b\n\/\/ phpstan.neon\nparameters:\n    level: 8\n    paths:\n        - src\n    checkMissingIterableValueType: true\n    checkGenericClassInNonGenericObjectType: true\n    checkImplicitMixed: true\n\n\/\/ Psalm \u306e\u8a2d\u5b9a\u4f8b\n\/\/ psalm.xml\n&lt;?xml version=\"1.0\"?&gt;\n&lt;psalm\n    errorLevel=\"2\"\n    resolveFromConfigFile=\"true\"\n    xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n    xmlns=\"https:\/\/getpsalm.org\/schema\/config\"\n    xsi:schemaLocation=\"https:\/\/getpsalm.org\/schema\/config vendor\/vimeo\/psalm\/config.xsd\"\n&gt;\n    &lt;projectFiles&gt;\n        &lt;directory name=\"src\" \/&gt;\n        &lt;ignoreFiles&gt;\n            &lt;directory name=\"vendor\" \/&gt;\n        &lt;\/ignoreFiles&gt;\n    &lt;\/projectFiles&gt;\n&lt;\/psalm&gt;\n<\/pre>\n\n\n\n<p>PHPStan\u3067\u306eEnum\u7279\u6709\u306e\u30c1\u30a7\u30c3\u30af\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ PHPStan\u30ab\u30b9\u30bf\u30e0\u30eb\u30fc\u30eb\u4f8b\n\/\/ src\/PHPStan\/Rules\/Enum\/EnumValueExistsRule.php\nuse PhpParser\\Node;\nuse PHPStan\\Analyser\\Scope;\nuse PHPStan\\Rules\\Rule;\n\nclass EnumValueExistsRule implements Rule\n{\n    public function getNodeType(): string\n    {\n        return Node\\Expr\\StaticCall::class;\n    }\n    \n    public function processNode(Node $node, Scope $scope): array\n    {\n        if (!$node instanceof Node\\Expr\\StaticCall) {\n            return [];\n        }\n        \n        \/\/ Enum\u306efrom\/tryFrom\u30e1\u30bd\u30c3\u30c9\u547c\u3073\u51fa\u3057\u3092\u30c1\u30a7\u30c3\u30af\n        if (!$node-&gt;name instanceof Node\\Identifier) {\n            return [];\n        }\n        \n        if (!in_array($node-&gt;name-&gt;name, ['from', 'tryFrom'], true)) {\n            return [];\n        }\n        \n        \/\/ \u547c\u3073\u51fa\u3057\u5148\u306e\u30af\u30e9\u30b9\u304cEnum\u578b\u304b\u30c1\u30a7\u30c3\u30af\n        $calledOnType = $scope-&gt;getType($node-&gt;class);\n        if (!$calledOnType-&gt;hasMethod($node-&gt;name-&gt;name)-&gt;yes()) {\n            return [];\n        }\n        \n        $enumClassReflection = $calledOnType-&gt;getObjectClassReflections()[0] ?? null;\n        if ($enumClassReflection === null || !$enumClassReflection-&gt;isEnum()) {\n            return [];\n        }\n        \n        \/\/ \u5f15\u6570\u304c\u6587\u5b57\u5217\u30ea\u30c6\u30e9\u30eb\u3067\u3001\u6709\u52b9\u306aEnum\u5024\u304b\u30c1\u30a7\u30c3\u30af\n        if (count($node-&gt;args) &lt; 1) {\n            return [];\n        }\n        \n        $argType = $scope-&gt;getType($node-&gt;args[0]-&gt;value);\n        if (!$argType-&gt;isConstantString()-&gt;yes()) {\n            return [];\n        }\n        \n        $argValue = $argType-&gt;getConstantStrings()[0]-&gt;getValue();\n        \n        $enumValues = [];\n        foreach ($enumClassReflection-&gt;getNativeReflection()-&gt;getCases() as $case) {\n            $caseValue = $case-&gt;getBackingValue();\n            if ($caseValue !== null) {\n                $enumValues[] = $caseValue;\n            }\n        }\n        \n        if (!in_array($argValue, $enumValues, true)) {\n            return [\n                sprintf(\n                    'Call to %s::from() with value \"%s\" will throw a ValueError because the value is not a valid case backing value.',\n                    $enumClassReflection-&gt;getDisplayName(),\n                    $argValue\n                )\n            ];\n        }\n        \n        return [];\n    }\n}\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-186\">CI\/CD\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u3067\u306e\u7d71\u5408<\/h4>\n\n\n\n<p>GitHub Actions\u7b49\u306eCI\/CD\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u3067Enum\u3092\u542b\u3080\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u3092\u30c1\u30a7\u30c3\u30af\u3059\u308b\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># .github\/workflows\/quality.yml\nname: Code Quality\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\njobs:\n  quality:\n    runs-on: ubuntu-latest\n    \n    steps:\n    - uses: actions\/checkout@v3\n    \n    - name: Setup PHP\n      uses: shivammathur\/setup-php@v2\n      with:\n        php-version: '8.1'\n        extensions: mbstring, intl\n        coverage: pcov\n        \n    - name: Install dependencies\n      run: composer install --prefer-dist --no-progress\n        \n    - name: Run PHPStan\n      run: vendor\/bin\/phpstan analyse\n      \n    - name: Run PHPCS\n      run: vendor\/bin\/phpcs\n      \n    - name: Run PHPUnit\n      run: vendor\/bin\/phpunit --coverage-clover=coverage.xml\n      \n    - name: Upload coverage to Codecov\n      uses: codecov\/codecov-action@v2\n      with:\n        files: .\/coverage.xml\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-187\">\u30c6\u30b9\u30c8\u6226\u7565\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h4>\n\n\n\n<p>Enum\u3092\u542b\u3080\u30b3\u30fc\u30c9\u306e\u30c6\u30b9\u30c8\u6226\u7565\u306b\u306f\u3001\u4ee5\u4e0b\u306e\u30dd\u30a4\u30f3\u30c8\u3092\u62bc\u3055\u3048\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u7db2\u7f85\u7684\u306a\u30c6\u30b9\u30c8<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5168\u3066\u306eEnum\u5024\u306b\u3064\u3044\u3066\u500b\u5225\u306b\u30c6\u30b9\u30c8<\/li>\n\n\n\n<li>\u5883\u754c\u6761\u4ef6\u3068\u30a8\u30c3\u30b8\u30b1\u30fc\u30b9\u306e\u91cd\u70b9\u7684\u691c\u8a3c<\/li>\n\n\n\n<li>\u4e0d\u6b63\u306a\u5024\u306b\u5bfe\u3059\u308b\u52d5\u4f5c\u78ba\u8a8d<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30e1\u30bd\u30c3\u30c9\u30c6\u30b9\u30c8\u306e\u5fb9\u5e95<\/strong>\n<ul class=\"wp-block-list\">\n<li>Enum\u306b\u8ffd\u52a0\u3057\u305f\u30e1\u30bd\u30c3\u30c9\u306e\u30c6\u30b9\u30c8<\/li>\n\n\n\n<li>\u623b\u308a\u5024\u306e\u578b\u3068\u5185\u5bb9\u306e\u691c\u8a3c<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u691c\u8a3c\uff08\u5fc5\u8981\u306b\u5fdc\u3058\u3066\uff09<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u7d71\u5408\u30b7\u30ca\u30ea\u30aa\u306e\u30c6\u30b9\u30c8<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5b9f\u969b\u306e\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u306b\u57fa\u3065\u304f\u30b7\u30ca\u30ea\u30aa\u30c6\u30b9\u30c8<\/li>\n\n\n\n<li>\u72b6\u614b\u9077\u79fb\u306e\u4e00\u9023\u306e\u30d5\u30ed\u30fc\u30c6\u30b9\u30c8<\/li>\n\n\n\n<li>\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u3067\u306e\u52d5\u4f5c\u78ba\u8a8d<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u56de\u5e30\u30c6\u30b9\u30c8\u306e\u81ea\u52d5\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u6642\u306e\u56de\u5e30\u30c6\u30b9\u30c8<\/li>\n\n\n\n<li>CI\/CD\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u3067\u306e\u81ea\u52d5\u30c6\u30b9\u30c8<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u30ab\u30d0\u30ec\u30c3\u30b8\u306e\u5b9a\u671f\u7684\u306a\u30c1\u30a7\u30c3\u30af<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"i-188\">\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u7ba1\u7406\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h4>\n\n\n\n<p>Enum\u3092\u6d3b\u7528\u3057\u305f\u30b3\u30fc\u30c9\u3092\u52b9\u679c\u7684\u306b\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5316\u3059\u308b\u30dd\u30a4\u30f3\u30c8\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u81ea\u5df1\u6587\u66f8\u5316\u30b3\u30fc\u30c9<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u660e\u78ba\u306aEnum\u547d\u540d\u898f\u5247<\/li>\n\n\n\n<li>\u30e1\u30bd\u30c3\u30c9\u540d\u3068\u5f15\u6570\u306e\u547d\u540d\u306b\u30c9\u30e1\u30a4\u30f3\u7528\u8a9e\u3092\u4f7f\u7528<\/li>\n\n\n\n<li>\u30b3\u30e1\u30f3\u30c8\u3088\u308a\u30b3\u30fc\u30c9\u306e\u660e\u78ba\u3055\u3092\u512a\u5148<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>PHPDoc\u306e\u5fb9\u5e95<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5168\u3066\u306eEnum\u30b1\u30fc\u30b9\u306b\u7c21\u6f54\u306a\u8aac\u660e<\/li>\n\n\n\n<li>\u30e1\u30bd\u30c3\u30c9\u306e\u5f15\u6570\u3068\u623b\u308a\u5024\u306e\u578b\u60c5\u5831<\/li>\n\n\n\n<li>\u4f8b\u5916\u767a\u751f\u6761\u4ef6\u306e\u660e\u793a<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u4f7f\u7528\u4f8b\u306e\u63d0\u4f9b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5178\u578b\u7684\u306a\u4f7f\u7528\u30d1\u30bf\u30fc\u30f3\u306e\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9<\/li>\n\n\n\n<li>\u5b9f\u969b\u306e\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u306b\u57fa\u3065\u304f\u30b7\u30ca\u30ea\u30aa\u4f8b<\/li>\n\n\n\n<li>\u3088\u304f\u3042\u308b\u9593\u9055\u3044\u3068\u56de\u907f\u7b56<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c1\u30fc\u30e0\u30ca\u30ec\u30c3\u30b8\u306e\u5171\u6709<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u8a2d\u8a08\u610f\u56f3\u3068\u30d1\u30bf\u30fc\u30f3\u306e\u8aac\u660e<\/li>\n\n\n\n<li>\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u5c65\u6b74\u3068Enum\u3078\u306e\u79fb\u884c\u7406\u7531<\/li>\n\n\n\n<li>\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3068\u6ce8\u610f\u70b9\u306e\u5171\u6709<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>Enum\u3092\u542b\u3080\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u7ba1\u7406\u306f\u3001\u30c6\u30b9\u30c8\u3068\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u901a\u3058\u3066\u5805\u7262\u6027\u3068\u4fdd\u5b88\u6027\u3092\u9ad8\u3081\u308b\u30d7\u30ed\u30bb\u30b9\u3067\u3059\u3002\u578b\u5b89\u5168\u6027\u3068\u3044\u3046Enum\u306e\u7279\u6027\u3092\u6d3b\u304b\u3057\u306a\u304c\u3089\u3001\u7d99\u7d9a\u7684\u306b\u54c1\u8cea\u3092\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002\u9069\u5207\u306a\u30c6\u30b9\u30c8\u6226\u7565\u3068\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5316\u306b\u3088\u308a\u3001\u30c1\u30fc\u30e0\u5168\u4f53\u304cEnum\u306e\u6069\u6075\u3092\u6700\u5927\u9650\u306b\u53d7\u3051\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-189\">\u307e\u3068\u3081\uff1aPHP Enum\u3067\u5b9f\u73fe\u3059\u308b\u578b\u5b89\u5168\u3067\u5805\u7262\u306a\u30b3\u30fc\u30c9\u8a2d\u8a08<\/h2>\n\n\n\n<p>PHP 8.1\u3067\u5c0e\u5165\u3055\u308c\u305fEnum\u578b\u306f\u3001PHP\u306e\u578b\u30b7\u30b9\u30c6\u30e0\u306b\u304a\u3051\u308b\u91cd\u8981\u306a\u30de\u30a4\u30eb\u30b9\u30c8\u30fc\u30f3\u3067\u3059\u3002\u3053\u306e\u8a18\u4e8b\u3092\u901a\u3058\u3066\u898b\u3066\u304d\u305f\u3088\u3046\u306b\u3001Enum\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u578b\u5b89\u5168\u3067\u5805\u7262\u306a\u30b3\u30fc\u30c9\u8a2d\u8a08\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-190\">Enum\u304c\u63d0\u4f9b\u3059\u308b\u4e3b\u8981\u306a\u30e1\u30ea\u30c3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u578b\u5b89\u5168\u6027\u306e\u5411\u4e0a<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306e\u30a8\u30e9\u30fc\u691c\u51fa<\/li>\n\n\n\n<li>\u4e0d\u6b63\u306a\u5024\u306e\u6df7\u5165\u9632\u6b62<\/li>\n\n\n\n<li>IDE\u88dc\u5b8c\u3068\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u30b5\u30dd\u30fc\u30c8<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u30ed\u30b8\u30c3\u30af\u306e\u30ab\u30d7\u30bb\u30eb\u5316<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5024\u3068\u632f\u308b\u821e\u3044\u306e\u7d50\u5408<\/li>\n\n\n\n<li>\u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306e\u96c6\u7d04<\/li>\n\n\n\n<li>\u95a2\u9023\u3059\u308b\u6982\u5ff5\u306e\u30b0\u30eb\u30fc\u30d7\u5316<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u30b3\u30fc\u30c9\u306e\u660e\u78ba\u3055\u3068\u8868\u73fe\u529b<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u81ea\u5df1\u6587\u66f8\u5316\u30b3\u30fc\u30c9<\/li>\n\n\n\n<li>\u30c9\u30e1\u30a4\u30f3\u7528\u8a9e\u306e\u76f4\u63a5\u7684\u306a\u8868\u73fe<\/li>\n\n\n\n<li>\u610f\u56f3\u306e\u660e\u78ba\u306a\u4f1d\u9054<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u4fdd\u5b88\u6027\u3068\u62e1\u5f35\u6027\u306e\u5411\u4e0a<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5909\u66f4\u306e\u5c40\u6240\u5316<\/li>\n\n\n\n<li>\u7d71\u4e00\u3055\u308c\u305f\u5909\u66f4\u30dd\u30a4\u30f3\u30c8<\/li>\n\n\n\n<li>\u4e00\u8cab\u3057\u305f\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-191\">\u5b9f\u8df5\u3067\u306e\u6d3b\u7528\u30b7\u30fc\u30f3<\/h3>\n\n\n\n<p>\u672c\u8a18\u4e8b\u3067\u306f\u3001\u4ee5\u4e0b\u306e\u5b9f\u8df5\u30b7\u30fc\u30f3\u3067Enum\u3092\u6d3b\u7528\u3059\u308b\u65b9\u6cd5\u3092\u898b\u3066\u304d\u307e\u3057\u305f\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u3068\u30d5\u30ed\u30fc\u5236\u5fa1<\/strong>\uff1a\u6ce8\u6587\u72b6\u614b\u3084\u627f\u8a8d\u30d5\u30ed\u30fc\u306a\u3069\u3001\u72b6\u614b\u9077\u79fb\u3092\u578b\u5b89\u5168\u306b\u7ba1\u7406\u3067\u304d\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3068\u30c7\u30fc\u30bf\u6574\u5408\u6027<\/strong>\uff1a\u5165\u529b\u5024\u306e\u691c\u8a3c\u304b\u3089\u6c38\u7d9a\u5316\u307e\u3067\u306e\u4e00\u8cab\u3057\u305f\u578b\u30c1\u30a7\u30c3\u30af\u3092\u5b9f\u73fe\u3057\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u30dd\u30ea\u30b7\u30fc\u3068\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406<\/strong>\uff1a\u6a29\u9650\u5236\u5fa1\u3092\u660e\u78ba\u304b\u3064\u67d4\u8edf\u306b\u8a2d\u8a08\u3067\u304d\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08<\/strong>\uff1a\u30c9\u30e1\u30a4\u30f3\u306e\u6982\u5ff5\u3092\u3088\u308a\u6b63\u78ba\u306b\u30b3\u30fc\u30c9\u3067\u8868\u73fe\u3067\u304d\u307e\u3059\u3002<\/li>\n\n\n\n<li><strong>API\u30ec\u30b9\u30dd\u30f3\u30b9\u3068\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/strong>\uff1a\u4e00\u8cab\u6027\u306e\u3042\u308bAPI\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u6d3b\u7528\u30b7\u30fc\u30f3\u306f\u3001\u305d\u308c\u305e\u308c\u304c\u72ec\u7acb\u3057\u3066\u3044\u308b\u308f\u3051\u3067\u306f\u306a\u304f\u3001\u76f8\u4e92\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3055\u3089\u306b\u5927\u304d\u306a\u4fa1\u5024\u3092\u751f\u307f\u51fa\u3057\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u3068API\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u4e00\u8cab\u6027\u306e\u3042\u308bRESTful API\u3092\u7c21\u5358\u306b\u5b9f\u88c5\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-192\">\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3068\u306e\u9023\u643a<\/h3>\n\n\n\n<p>\u73fe\u4ee3\u306ePHP\u958b\u767a\u3067\u306f\u3001Laravel\u3084Symfony\u306a\u3069\u306e\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u304c\u5e83\u304f\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u3089\u306e\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306fEnum\u306b\u5bfe\u3059\u308b\u5305\u62ec\u7684\u306a\u30b5\u30dd\u30fc\u30c8\u3092\u63d0\u4f9b\u3057\u3066\u304a\u308a\u3001\u4ee5\u4e0b\u306e\u9023\u643a\u304c\u53ef\u80fd\u3067\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Laravel<\/strong>\uff1aEloquent\u30e2\u30c7\u30eb\u3078\u306e\u30ad\u30e3\u30b9\u30c8\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u306e\u7d71\u5408<\/li>\n\n\n\n<li><strong>Symfony<\/strong>\uff1aFormType\u3001Doctrine ORM\u3001\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u5236\u7d04\u3068\u306e\u9023\u643a<\/li>\n<\/ul>\n\n\n\n<p>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u6a5f\u80fd\u3068Enum\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u52b9\u7387\u7684\u306a\u958b\u767a\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-193\">Enum\u3092\u8d85\u3048\u3066\uff1aPHP\u578b\u30b7\u30b9\u30c6\u30e0\u306e\u9032\u5316<\/h3>\n\n\n\n<p>PHP Enum\u306f\u3001PHP\u8a00\u8a9e\u306e\u578b\u30b7\u30b9\u30c6\u30e0\u5f37\u5316\u306e\u4e00\u74b0\u3068\u3057\u3066\u5c0e\u5165\u3055\u308c\u307e\u3057\u305f\u3002PHP 7\u304b\u3089PHP 8\u306b\u304b\u3051\u3066\u306e\u9032\u5316\u3092\u898b\u308b\u3068\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u578b\u95a2\u9023\u6a5f\u80fd\u304c\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PHP 7.0\uff1a\u30b9\u30ab\u30e9\u30fc\u578b\u5ba3\u8a00\u3001\u623b\u308a\u5024\u306e\u578b\u5ba3\u8a00<\/li>\n\n\n\n<li>PHP 7.1\uff1anullable\u578b\u3001void\u623b\u308a\u5024\u578b<\/li>\n\n\n\n<li>PHP 7.4\uff1a\u30d7\u30ed\u30d1\u30c6\u30a3\u578b\u5ba3\u8a00<\/li>\n\n\n\n<li>PHP 8.0\uff1aUnion\u578b\u3001\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u30d7\u30ed\u30d1\u30c6\u30a3\u30d7\u30ed\u30e2\u30fc\u30b7\u30e7\u30f3<\/li>\n\n\n\n<li>PHP 8.1\uff1aEnum\u578b\u3001readonly \u30d7\u30ed\u30d1\u30c6\u30a3\u3001intersection\u578b<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306aPHP\u306e\u578b\u30b7\u30b9\u30c6\u30e0\u5f37\u5316\u306e\u6d41\u308c\u306f\u3001\u4eca\u5f8c\u3082\u7d9a\u304f\u3068\u4e88\u60f3\u3055\u308c\u307e\u3059\u3002Enum\u3092\u52b9\u679c\u7684\u306b\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3053\u306e\u9032\u5316\u306e\u6069\u6075\u3092\u6700\u5927\u9650\u306b\u53d7\u3051\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-194\">\u958b\u767a\u30d7\u30ed\u30bb\u30b9\u3078\u306e\u7d71\u5408<\/h3>\n\n\n\n<p>Enum\u3092\u958b\u767a\u30d7\u30ed\u30bb\u30b9\u5168\u4f53\u306b\u7d71\u5408\u3059\u308b\u3053\u3068\u3067\u3001\u3055\u3089\u306a\u308b\u4fa1\u5024\u3092\u5f15\u304d\u51fa\u305b\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8a2d\u8a08\u30d5\u30a7\u30fc\u30ba<\/strong>\uff1a\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30ea\u30f3\u30b0\u6642\u306bEnum\u578b\u3092\u6d3b\u7528\u3057\u3066\u3001\u6982\u5ff5\u3092\u660e\u78ba\u5316<\/li>\n\n\n\n<li><strong>\u5b9f\u88c5\u30d5\u30a7\u30fc\u30ba<\/strong>\uff1a\u578b\u5b89\u5168\u306a\u5b9f\u88c5\u306b\u3088\u308b\u4e0d\u5177\u5408\u306e\u65e9\u671f\u767a\u898b<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u30d5\u30a7\u30fc\u30ba<\/strong>\uff1a\u30c6\u30b9\u30c8\u30b1\u30fc\u30b9\u306e\u660e\u78ba\u5316\u3068\u7db2\u7f85\u6027\u306e\u5411\u4e0a<\/li>\n\n\n\n<li><strong>\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0<\/strong>\uff1a\u5b89\u5168\u306a\u30b3\u30fc\u30c9\u5909\u66f4\u3068IDE\u652f\u63f4\u306e\u6d3b\u7528<\/li>\n\n\n\n<li><strong>\u4fdd\u5b88\u30d5\u30a7\u30fc\u30ba<\/strong>\uff1a\u610f\u56f3\u306e\u660e\u78ba\u306a\u30b3\u30fc\u30c9\u306b\u3088\u308b\u7406\u89e3\u4fc3\u9032\u3068\u5909\u66f4\u306e\u5bb9\u6613\u3055<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-195\">\u6b21\u306e\u30b9\u30c6\u30c3\u30d7<\/h3>\n\n\n\n<p>PHP Enum\u3092\u30de\u30b9\u30bf\u30fc\u3059\u308b\u305f\u3081\u306e\u6b21\u306e\u30b9\u30c6\u30c3\u30d7\u3068\u3057\u3066\u3001\u4ee5\u4e0b\u306e\u30a2\u30af\u30b7\u30e7\u30f3\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u65e2\u5b58\u30b3\u30fc\u30c9\u306e\u898b\u76f4\u3057<\/strong>\uff1a\u73fe\u5728\u306e\u5b9a\u6570\u3084\u30de\u30b8\u30c3\u30af\u30ca\u30f3\u30d0\u30fc\u3092Enum\u5316\u3059\u308b\u5019\u88dc\u3092\u7279\u5b9a<\/li>\n\n\n\n<li><strong>\u5c0f\u898f\u6a21\u306a\u9069\u7528\u304b\u3089\u59cb\u3081\u308b<\/strong>\uff1a\u91cd\u8981\u5ea6\u306e\u9ad8\u3044\u4e00\u90e8\u306e\u30c9\u30e1\u30a4\u30f3\u6982\u5ff5\u304b\u3089Enum\u5316\u3092\u958b\u59cb<\/li>\n\n\n\n<li><strong>\u30c6\u30b9\u30c8\u306e\u5145\u5b9f<\/strong>\uff1aEnum\u3092\u542b\u3080\u30b3\u30fc\u30c9\u306e\u30e6\u30cb\u30c3\u30c8\u30c6\u30b9\u30c8\u3068\u30b1\u30fc\u30b9\u7db2\u7f85\u3092\u5f37\u5316<\/li>\n\n\n\n<li><strong>\u30c1\u30fc\u30e0\u5185\u3067\u306e\u6a19\u6e96\u5316<\/strong>\uff1aEnum\u547d\u540d\u898f\u5247\u3084\u4f7f\u7528\u30d1\u30bf\u30fc\u30f3\u306e\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u3092\u7b56\u5b9a<\/li>\n\n\n\n<li><strong>\u7d99\u7d9a\u7684\u306a\u5b66\u7fd2<\/strong>\uff1aPHP\u8a00\u8a9e\u306e\u9032\u5316\u3068\u5171\u306bEnum\u6d3b\u7528\u6cd5\u3082\u66f4\u65b0\u3057\u3066\u3044\u304f<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-196\">\u304a\u308f\u308a\u306b<\/h3>\n\n\n\n<p>PHP Enum\u306f\u3001\u5358\u306a\u308b\u8a00\u8a9e\u6a5f\u80fd\u3067\u306f\u306a\u304f\u3001\u3088\u308a\u54c1\u8cea\u306e\u9ad8\u3044\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u8a2d\u8a08\u3092\u5b9f\u73fe\u3059\u308b\u305f\u3081\u306e\u5f37\u529b\u306a\u30c4\u30fc\u30eb\u3067\u3059\u3002\u578b\u5b89\u5168\u6027\u3001\u30c9\u30e1\u30a4\u30f3\u8868\u73fe\u529b\u3001\u4fdd\u5b88\u6027\u306e\u5411\u4e0a\u306a\u3069\u3001\u591a\u304f\u306e\u30e1\u30ea\u30c3\u30c8\u3092\u3082\u305f\u3089\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u672c\u8a18\u4e8b\u3067\u7d39\u4ecb\u3057\u305f\u5b9f\u8df5\u4f8b\u3084\u30c6\u30af\u30cb\u30c3\u30af\u3092\u6d3b\u7528\u3057\u3001PHP Enum\u306e\u53ef\u80fd\u6027\u3092\u6700\u5927\u9650\u306b\u5f15\u304d\u51fa\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u9069\u5207\u306aEnum\u306e\u6d3b\u7528\u306f\u3001\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u5411\u4e0a\u3060\u3051\u3067\u306a\u304f\u3001\u958b\u767a\u52b9\u7387\u306e\u5411\u4e0a\u3084\u30d3\u30b8\u30cd\u30b9\u4fa1\u5024\u306e\u8fc5\u901f\u306a\u63d0\u4f9b\u306b\u3082\u7e4b\u304c\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u6700\u5f8c\u306b\u3001PHP Enum\u306f\u6bd4\u8f03\u7684\u65b0\u3057\u3044\u6a5f\u80fd\u3067\u3059\u304c\u3001\u305d\u306e\u4fa1\u5024\u3068\u53ef\u80fd\u6027\u306f\u8a08\u308a\u77e5\u308c\u307e\u305b\u3093\u3002\u30a8\u30f3\u30b8\u30cb\u30a2\u3068\u3057\u3066\u3001\u65b0\u3057\u3044\u6280\u8853\u306b\u7a4d\u6975\u7684\u306b\u53d6\u308a\u7d44\u307f\u3001\u5e38\u306b\u9032\u5316\u3057\u7d9a\u3051\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002PHP Enum\u3092\u8d77\u70b9\u306b\u3001\u3088\u308a\u826f\u3044\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u8a2d\u8a08\u306e\u65c5\u3092\u59cb\u3081\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>PHP\u30d7\u30ed\u30b0\u30e9\u30de\u30fc\u306a\u3089\u8ab0\u3082\u304c\u7d4c\u9a13\u3057\u305f\u3053\u3068\u304c\u3042\u308b\u3067\u3057\u3087\u3046\u3002\u30b9\u30c6\u30fc\u30bf\u30b9\u3084\u7a2e\u5225\u306a\u3069\u306e\u56fa\u5b9a\u5024\u3092\u6271\u3046\u969b\u3001\u30af\u30e9\u30b9\u5b9a\u6570\u3084\u914d\u5217\u3092\u4f7f\u3063\u3066\u4f55\u3068\u304b\u578b\u5b89\u5168\u6027\u3092\u78ba\u4fdd\u3057\u3088\u3046\u3068\u596e\u95d8\u3059\u308b\u65e5\u3005\u3092\u3002\u300c\u3053\u306e\u5024\u304c\u9069\u5207\u304b\u3069\u3046\u304b\u3001\u5b9f\u884c\u6642\u307e\u3067\u308f\u304b\u3089\u306a\u3044\u300d\u300cIDE\u306e\u88dc &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,34],"tags":[],"class_list":{"0":"post-3479","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-php","7":"category-php-symfony","8":"nothumb"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3479"}],"version-history":[{"count":2,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3479\/revisions"}],"predecessor-version":[{"id":3481,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3479\/revisions\/3481"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}