{"id":3385,"date":"2025-03-24T08:46:19","date_gmt":"2025-03-23T23:46:19","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=3385"},"modified":"2025-03-24T08:46:50","modified_gmt":"2025-03-23T23:46:50","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91codeigniter-4%e5%ae%8c%e5%85%a8%e5%85%a5%e9%96%80%e3%82%ac%e3%82%a4%e3%83%89-%e7%92%b0%e5%a2%83%e6%a7%8b%e7%af%89%e3%81%8b%e3%82%89%e5%ae%9f%e8%b7%b5","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=3385","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011CodeIgniter 4\u5b8c\u5168\u5165\u9580\u30ac\u30a4\u30c9 &#8211; \u74b0\u5883\u69cb\u7bc9\u304b\u3089\u5b9f\u8df5\u7684\u306a\u958b\u767a\u624b\u6cd5\u307e\u3067\u89e3\u8aac"},"content":{"rendered":"\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\">CodeIgniter 4 \u3068\u306f\uff1f\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u7279\u5fb4\u3068\u5f37\u307f<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">\u8efd\u91cf\u3067\u9ad8\u901f\u306aPHP\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u4ee3\u8868\u683c<\/a>      <\/li>      <li>        <a href=\"#i-2\">\u30d0\u30fc\u30b8\u30e7\u30f34\u3067\u5287\u7684\u306b\u9032\u5316\u3057\u305f\u65b0\u6a5f\u80fd\u3068\u6539\u5584\u70b9<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-3\">\u4ed6\u306ePHP\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3068\u6bd4\u8f03\u3057\u305f\u30e1\u30ea\u30c3\u30c8<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-4\">CodeIgniter 4 \u306e\u74b0\u5883\u69cb\u7bc9\u624b\u9806<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-5\">\u5fc5\u8981\u306a\u958b\u767a\u74b0\u5883\u3068\u30b7\u30b9\u30c6\u30e0\u8981\u4ef6<\/a>      <\/li>      <li>        <a href=\"#i-6\">Composer \u3092\u4f7f\u7528\u3057\u305f\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-7\">\u521d\u671f\u8a2d\u5b9a\u3068\u57fa\u672c\u7684\u306a\u74b0\u5883\u8a2d\u5b9a\u306e\u30dd\u30a4\u30f3\u30c8<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-8\">CodeIgniter 4 \u306e\u57fa\u672c\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u7406\u89e3<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-9\">MVC\u30d1\u30bf\u30fc\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5\u3068\u7279\u5fb4<\/a>      <\/li>      <li>        <a href=\"#i-10\">\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u8a2d\u5b9a\u3068\u6d3b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-11\">\u4f9d\u5b58\u6027\u6ce8\u5165\u3068\u30b5\u30fc\u30d3\u30b9\u306e\u6d3b\u7528\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-12\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30e2\u30c7\u30eb\u306e\u5b9f\u8df5\u7684\u306a\u4f7f\u3044\u65b9<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-13\">\u30e2\u30c7\u30eb\u30af\u30e9\u30b9\u3092\u4f7f\u7528\u3057\u305fCRUD\u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-14\">\u30af\u30a8\u30ea\u30d3\u30eb\u30c0\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-15\">\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30b7\u30fc\u30c7\u30a3\u30f3\u30b0\u306e\u904b\u7528\u624b\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-16\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u3068\u5b9f\u52d9\u3067\u306e\u6ce8\u610f\u70b9<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-17\">CSRF\u30d7\u30ed\u30c6\u30af\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-18\">XSS\u5bfe\u7b56\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u8a2d\u5b9a<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-19\">\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u3068\u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u306e\u5b9f\u88c5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-20\">\u5b9f\u8df5\u7684\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u624b\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-21\">RESTful API\u306e\u69cb\u7bc9\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-22\">\u30ad\u30e3\u30c3\u30b7\u30e5\u6a5f\u80fd\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-23\">\u30e6\u30cb\u30c3\u30c8\u30c6\u30b9\u30c8\u3068\u30c7\u30d0\u30c3\u30b0\u306e\u9032\u3081\u65b9<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-24\">CodeIgniter 4\u3067\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-25\">\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u3068\u305d\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-26\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u6700\u9069\u5316\u624b\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-27\">\u672c\u756a\u74b0\u5883\u3067\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30c1\u30e5\u30fc\u30cb\u30f3\u30b0<\/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\">CodeIgniter 4 \u3068\u306f\uff1f\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u7279\u5fb4\u3068\u5f37\u307f<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">\u8efd\u91cf\u3067\u9ad8\u901f\u306aPHP\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u4ee3\u8868\u683c<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">CodeIgniter 4\uff08\u4ee5\u4e0b\u3001CI4\uff09\u306f\u3001\u30b7\u30f3\u30d7\u30eb\u306a\u304c\u3089\u30d1\u30ef\u30d5\u30eb\u306a\u6a5f\u80fd\u3092\u5099\u3048\u305fPHP\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3068\u3057\u3066\u77e5\u3089\u308c\u3066\u3044\u307e\u3059\u3002\u7279\u306b\u4ee5\u4e0b\u306e\u7279\u5fb4\u304c\u3001\u591a\u304f\u306e\u958b\u767a\u8005\u304b\u3089\u652f\u6301\u3055\u308c\u3066\u3044\u308b\u7406\u7531\u3067\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30e1\u30e2\u30ea\u52b9\u7387\u306e\u9ad8\u3055\n<ul class=\"wp-block-list\">\n<li>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u30b3\u30a2\u304c\u7d042MB\u672a\u6e80\u3068\u8efd\u91cf<\/li>\n\n\n\n<li>\u6700\u5c0f\u9650\u306e\u4f9d\u5b58\u30d1\u30c3\u30b1\u30fc\u30b8\u3067\u52d5\u4f5c<\/li>\n\n\n\n<li>\u52b9\u7387\u7684\u306a\u30e1\u30e2\u30ea\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u51e6\u7406\u901f\u5ea6\u306e\u512a\u4f4d\u6027<\/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=\"\">\/\/ \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u8a08\u6e2c\u4f8b\nuse CodeIgniter\\Debug\\Timer;\n\n$timer = new Timer();\n$timer-&gt;start('benchmark');\n\n\/\/ \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b3\u30fc\u30c9\n$result = $model-&gt;find();\n\n$timer-&gt;stop('benchmark');\necho $timer-&gt;getElapsedTime('benchmark'); \/\/ \u4e00\u822c\u7684\u306a\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e1.5-2\u500d\u306e\u901f\u5ea6\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30b7\u30f3\u30d7\u30eb\u306a\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\n<ul class=\"wp-block-list\">\n<li>\u76f4\u611f\u7684\u306aMVC\u30d1\u30bf\u30fc\u30f3<\/li>\n\n\n\n<li>\u660e\u78ba\u306a\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u69cb\u9020<\/li>\n\n\n\n<li>\u6700\u5c0f\u9650\u306e\u8a2d\u5b9a\u3067\u958b\u59cb\u53ef\u80fd<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">\u30d0\u30fc\u30b8\u30e7\u30f34\u3067\u5287\u7684\u306b\u9032\u5316\u3057\u305f\u65b0\u6a5f\u80fd\u3068\u6539\u5584\u70b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30e2\u30c0\u30f3PHP\u306e\u5b8c\u5168\u63a1\u7528<\/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=\"\">namespace App\\Controllers;\n\nuse CodeIgniter\\Controller;\nuse App\\Models\\UserModel;\n\nclass Users extends Controller\n{\n    protected $userModel;\n\n    public function __construct()\n    {\n        $this-&gt;userModel = new UserModel();\n    }\n\n    public function index()\n    {\n        return view('users\/index', [\n            'users' =&gt; $this-&gt;userModel-&gt;findAll()\n        ]);\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u4e3b\u8981\u306a\u6a5f\u80fd\u5f37\u5316\n<ul class=\"wp-block-list\">\n<li>PSR-4\u6e96\u62e0\u306e\u540d\u524d\u7a7a\u9593\u5bfe\u5fdc<\/li>\n\n\n\n<li>Composer\u306b\u3088\u308b\u4f9d\u5b58\u7ba1\u7406<\/li>\n\n\n\n<li>\u5f37\u5316\u3055\u308c\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u62bd\u8c61\u5316\u5c64<\/li>\n\n\n\n<li>\u65b0\u3057\u3044\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u6a5f\u80fd\u306e\u5c0e\u5165<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u958b\u767a\u52b9\u7387\u3092\u5411\u4e0a\u3055\u305b\u308b\u65b0\u6a5f\u80fd\n<ul class=\"wp-block-list\">\n<li>\u5145\u5b9f\u3057\u305fCLI\u30c4\u30fc\u30eb<\/li>\n\n\n\n<li>\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u30af\u30e9\u30b9\u306e\u30b5\u30dd\u30fc\u30c8<\/li>\n\n\n\n<li>\u9ad8\u5ea6\u306a\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u30b7\u30b9\u30c6\u30e0\u306e\u5237\u65b0<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-3\">\u4ed6\u306ePHP\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3068\u6bd4\u8f03\u3057\u305f\u30e1\u30ea\u30c3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u958b\u767a\u751f\u7523\u6027\u306e\u6bd4\u8f03<\/li>\n<\/ol>\n\n\n<div id=\"id-ef3ba071-d9a8-436a-b1dd-b2020c1e3816\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u6a5f\u80fd<\/th><th>CodeIgniter 4<\/th><th>Laravel<\/th><th>Symfony<\/th><\/tr><\/thead><tbody><tr><td>\u521d\u671f\u5b66\u7fd2\u6642\u9593<\/td><td>1-2\u9031\u9593<\/td><td>1-2\u30f6\u6708<\/td><td>2-3\u30f6\u6708<\/td><\/tr><tr><td>\u8a2d\u5b9a\u306e\u8907\u96d1\u3055<\/td><td>\u4f4e<\/td><td>\u4e2d<\/td><td>\u9ad8<\/td><\/tr><tr><td>\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5145\u5b9f\u5ea6<\/td><td>\u25ce<\/td><td>\u25ce<\/td><td>\u25cb<\/td><\/tr><tr><td>\u65e5\u672c\u8a9e\u8cc7\u6599<\/td><td>\u25cb<\/td><td>\u25ce<\/td><td>\u25b3<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u9762\u3067\u306e\u512a\u4f4d\u6027\n<ul class=\"wp-block-list\">\n<li>\u6700\u5c0f\u69cb\u6210\u6642\u306e\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\uff1a\u7d044MB<\/li>\n\n\n\n<li>\u30ea\u30af\u30a8\u30b9\u30c8\u51e6\u7406\u6642\u9593\uff1a\u5e73\u574730%\u524a\u6e1b<\/li>\n\n\n\n<li>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u8d77\u52d5\u6642\u9593\uff1aLaravel\u6bd4\u7d0450%\u6e1b<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u6700\u9069\u306a\u9078\u629e\u57fa\u6e96\n<ul class=\"wp-block-list\">\n<li>\u30b9\u30d4\u30fc\u30c7\u30a3\u30fc\u306a\u958b\u767a\u304c\u6c42\u3081\u3089\u308c\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8<\/li>\n\n\n\n<li>\u30ea\u30bd\u30fc\u30b9\u306b\u5236\u7d04\u306e\u3042\u308b\u74b0\u5883\u3067\u306e\u958b\u767a<\/li>\n\n\n\n<li>API\u30b5\u30fc\u30d0\u30fc\u306e\u69cb\u7bc9<\/li>\n\n\n\n<li>\u4e2d\u5c0f\u898f\u6a21\u306eWeb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u67d4\u8edf\u6027\n<ul class=\"wp-block-list\">\n<li>\u6700\u5c0f\u9650\u306e\u5236\u7d04<\/li>\n\n\n\n<li>\u5bb9\u6613\u306a\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/li>\n\n\n\n<li>\u30b5\u30fc\u30c9\u30d1\u30fc\u30c6\u30a3\u30e9\u30a4\u30d6\u30e9\u30ea\u3068\u306e\u7d71\u5408\u306e\u3057\u3084\u3059\u3055<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">\u4ee5\u4e0a\u306e\u7279\u5fb4\u304b\u3089\u3001CI4\u306f\u7279\u306b\u300c\u9ad8\u901f\u306a\u958b\u767a\u300d\u3068\u300c\u9ad8\u3044\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u300d\u304c\u6c42\u3081\u3089\u308c\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u304a\u3044\u3066\u3001\u6700\u9069\u306a\u9078\u629e\u80a2\u306e\u4e00\u3064\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-4\">CodeIgniter 4 \u306e\u74b0\u5883\u69cb\u7bc9\u624b\u9806<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">\u5fc5\u8981\u306a\u958b\u767a\u74b0\u5883\u3068\u30b7\u30b9\u30c6\u30e0\u8981\u4ef6<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">CodeIgniter 4\u3092\u5feb\u9069\u306b\u52d5\u4f5c\u3055\u305b\u308b\u305f\u3081\u306b\u3001\u4ee5\u4e0b\u306e\u30b7\u30b9\u30c6\u30e0\u8981\u4ef6\u3092\u6e80\u305f\u3059\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>PHP\u8981\u4ef6\n<ul class=\"wp-block-list\">\n<li>PHP \u30d0\u30fc\u30b8\u30e7\u30f3 7.4\u4ee5\u4e0a\uff088.0\u4ee5\u4e0a\u63a8\u5968\uff09<\/li>\n\n\n\n<li>\u5fc5\u9808PHP\u62e1\u5f35\u6a5f\u80fd\uff1a\n<ul class=\"wp-block-list\">\n<li>intl<\/li>\n\n\n\n<li>json<\/li>\n\n\n\n<li>mbstring<\/li>\n\n\n\n<li>mysqlnd\uff08MySQL\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\uff09<\/li>\n\n\n\n<li>xml<\/li>\n\n\n\n<li>curl<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8981\u4ef6\uff08\u9078\u629e\u53ef\u80fd\uff09\n<ul class=\"wp-block-list\">\n<li>MySQL (5.1+)<\/li>\n\n\n\n<li>PostgreSQL (7.4+)<\/li>\n\n\n\n<li>SQLite3<\/li>\n\n\n\n<li>Microsoft SQL Server (2005+)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Web\u30b5\u30fc\u30d0\u30fc\u8981\u4ef6<ul><li>Apache 2.4+ with mod_rewrite<\/li><li>Nginx 1.13+<\/li><\/ul><code># Nginx\u306e\u57fa\u672c\u8a2d\u5b9a\u4f8b location \/ { try_files $uri $uri\/ \/index.php$is_args$args; }<\/code><\/li>\n\n\n\n<li>\u63a8\u5968\u958b\u767a\u30c4\u30fc\u30eb\n<ul class=\"wp-block-list\">\n<li>Composer\uff08\u30d1\u30c3\u30b1\u30fc\u30b8\u7ba1\u7406\uff09<\/li>\n\n\n\n<li>Git\uff08\u30d0\u30fc\u30b8\u30e7\u30f3\u7ba1\u7406\uff09<\/li>\n\n\n\n<li>VS Code \/ PHPStorm\uff08IDE\uff09<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">Composer \u3092\u4f7f\u7528\u3057\u305f\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u65b0\u898f\u4f5c\u6210<\/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=\"\"># \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u4f5c\u6210\u30b3\u30de\u30f3\u30c9\ncomposer create-project codeigniter4\/appstarter ci4-project\n\n# \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u79fb\u52d5\ncd ci4-project\n\n# \u958b\u767a\u30b5\u30fc\u30d0\u30fc\u306e\u8d77\u52d5\nphp spark serve\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u65e2\u5b58\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u5c0e\u5165<\/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=\"\"># Composer\u3092\u4f7f\u7528\u3057\u3066CodeIgniter 4\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\ncomposer require codeigniter4\/framework\n\n# \u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3068public\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u6e96\u5099\nphp spark install:config\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u5f8c\u306e\u78ba\u8a8d<\/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=\"\"># \u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d\nphp spark --version\n\n# \u74b0\u5883\u30c1\u30a7\u30c3\u30af\nphp spark env:check\n\n# \u30eb\u30fc\u30c8\u306e\u78ba\u8a8d\nphp spark routes\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-7\">\u521d\u671f\u8a2d\u5b9a\u3068\u57fa\u672c\u7684\u306a\u74b0\u5883\u8a2d\u5b9a\u306e\u30dd\u30a4\u30f3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u74b0\u5883\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u6e96\u5099<\/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=\"\"># .env\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210\ncp env .env\n\n# \u74b0\u5883\u8a2d\u5b9a\u306e\u7de8\u96c6\n# CI_ENVIRONMENT = development\n# app.baseURL = 'http:\/\/localhost:8080\/'\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u5b9a<\/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=\"\">\/\/ app\/Config\/Database.php\npublic $default = [\n    'DSN'      =&gt; '',\n    'hostname' =&gt; 'localhost',\n    'username' =&gt; 'your_username',\n    'password' =&gt; 'your_password',\n    'database' =&gt; 'your_database',\n    'DBDriver' =&gt; 'MySQLi',\n    'DBPrefix' =&gt; '',\n    'pConnect' =&gt; false,\n    'DBDebug'  =&gt; true,\n    'charset'  =&gt; 'utf8',\n    'DBCollat' =&gt; 'utf8_general_ci',\n    'swapPre'  =&gt; '',\n    'encrypt'  =&gt; false,\n    'compress' =&gt; false,\n    'strictOn' =&gt; false,\n    'failover' =&gt; [],\n    'port'     =&gt; 3306,\n];\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a<\/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=\"\">\/\/ app\/Config\/Security.php\npublic $tokenName  = 'csrf_token_name';\npublic $headerName = 'X-CSRF-TOKEN';\npublic $cookieName = 'csrf_cookie_name';\npublic $expires    = 7200;\n<\/pre>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u57fa\u672c\u8a2d\u5b9a<\/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=\"\">\/\/ app\/Config\/App.php\npublic $baseURL = 'http:\/\/localhost:8080\/';\npublic $indexPage = '';\npublic $defaultLocale = 'ja';\npublic $negotiateLocale = true;\npublic $supportedLocales = ['en', 'ja'];\n<\/pre>\n\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li>\u30a8\u30e9\u30fc\u5831\u544a\u3068\u30ed\u30ae\u30f3\u30b0\u8a2d\u5b9a<\/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=\"\">\/\/ app\/Config\/Logger.php\npublic $threshold = 4; \/\/ \u958b\u767a\u74b0\u5883\u3067\u306f4\uff08\u5168\u3066\u306e\u30ed\u30b0\u3092\u8a18\u9332\uff09\n\n\/\/ \u30ed\u30b0\u30cf\u30f3\u30c9\u30e9\u306e\u8a2d\u5b9a\npublic $handlers = [\n    'file' =&gt; [\n        'class'     =&gt; 'CodeIgniter\\Log\\Handlers\\FileHandler',\n        'baseDir'   =&gt; WRITEPATH . 'logs\/',\n        'filePermission' =&gt; 0644,\n        'fileExtension' =&gt; 'log'\n    ]\n];\n<\/pre>\n\n\n\n<ol start=\"6\" class=\"wp-block-list\">\n<li>\u958b\u767a\u74b0\u5883\u7279\u6709\u306e\u8a2d\u5b9a<\/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=\"\">\/\/ \u958b\u767a\u6642\u306e\u63a8\u5968\u8a2d\u5b9a\nerror_reporting(-1);\nini_set('display_errors', '1');\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u4ee5\u4e0a\u306e\u8a2d\u5b9a\u304c\u5b8c\u4e86\u3059\u308c\u3070\u3001CodeIgniter 4\u3067\u306e\u958b\u767a\u3092\u958b\u59cb\u3059\u308b\u6e96\u5099\u304c\u6574\u3044\u307e\u3059\u3002\u74b0\u5883\u69cb\u7bc9\u6642\u306b\u7279\u306b\u6ce8\u610f\u304c\u5fc5\u8981\u306a\u70b9\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u672c\u756a\u74b0\u5883\u3067\u306f\u5fc5\u305a <code>CI_ENVIRONMENT<\/code> \u3092 <code>production<\/code> \u306b\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u95a2\u9023\u306e\u8a2d\u5b9a\u306f\u672c\u756a\u74b0\u5883\u3067\u518d\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u60c5\u5831\u306f\u74b0\u5883\u3054\u3068\u306b\u9069\u5207\u306b\u7ba1\u7406<\/li>\n\n\n\n<li>\u30ed\u30b0\u30ec\u30d9\u30eb\u306f\u74b0\u5883\u306b\u5fdc\u3058\u3066\u9069\u5207\u306b\u8a2d\u5b9a<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u8a2d\u5b9a\u3092\u9069\u5207\u306b\u884c\u3046\u3053\u3068\u3067\u3001\u5b89\u5168\u3067\u52b9\u7387\u7684\u306a\u958b\u767a\u74b0\u5883\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-8\">CodeIgniter 4 \u306e\u57fa\u672c\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u7406\u89e3<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">MVC\u30d1\u30bf\u30fc\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5\u3068\u7279\u5fb4<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">CodeIgniter 4\u306eMVC\u30d1\u30bf\u30fc\u30f3\u306f\u3001\u30b7\u30f3\u30d7\u30eb\u306a\u304c\u3089\u5f37\u529b\u306a\u5b9f\u88c5\u3092\u63d0\u4f9b\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u57fa\u672c\u5b9f\u88c5<\/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=\"\">namespace App\\Controllers;\n\nuse CodeIgniter\\Controller;\nuse App\\Models\\UserModel;\n\nclass Users extends Controller\n{\n    protected $userModel;\n\n    public function __construct()\n    {\n        \/\/ \u30e2\u30c7\u30eb\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u5316\n        $this-&gt;userModel = new UserModel();\n    }\n\n    public function index()\n    {\n        $data = [\n            'users' =&gt; $this-&gt;userModel-&gt;findAll(),\n            'title' =&gt; '\u30e6\u30fc\u30b6\u30fc\u4e00\u89a7'\n        ];\n\n        \/\/ \u30d3\u30e5\u30fc\u306e\u8aad\u307f\u8fbc\u307f\u3068\u8868\u793a\n        return view('users\/index', $data);\n    }\n\n    public function show($id)\n    {\n        $user = $this-&gt;userModel-&gt;find($id);\n        \n        if ($user === null) {\n            throw \\CodeIgniter\\Exceptions\\PageNotFoundException::forPageNotFound();\n        }\n\n        return view('users\/show', ['user' =&gt; $user]);\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30e2\u30c7\u30eb\u306e\u5b9f\u88c5\u4f8b<\/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=\"\">namespace App\\Models;\n\nuse CodeIgniter\\Model;\n\nclass UserModel extends Model\n{\n    protected $table      = 'users';\n    protected $primaryKey = 'id';\n    protected $returnType = 'array';\n    protected $allowedFields = ['name', 'email', 'password'];\n\n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30eb\n    protected $validationRules = [\n        'name'     =&gt; 'required|min_length[3]',\n        'email'    =&gt; 'required|valid_email|is_unique[users.email]',\n        'password' =&gt; 'required|min_length[8]'\n    ];\n\n    \/\/ \u30ab\u30b9\u30bf\u30e0\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\n    protected $beforeInsert = ['hashPassword'];\n    \n    protected function hashPassword(array $data)\n    {\n        if (isset($data['data']['password'])) {\n            $data['data']['password'] = password_hash($data['data']['password'], PASSWORD_DEFAULT);\n        }\n        return $data;\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30d3\u30e5\u30fc\u306e\u5b9f\u88c5\u65b9\u6cd5<\/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=\"\">&lt;!-- app\/Views\/users\/index.php --&gt;\n&lt;?= $this-&gt;extend('layouts\/main') ?&gt;\n\n&lt;?= $this-&gt;section('content') ?&gt;\n    &lt;h1&gt;&lt;?= esc($title) ?&gt;&lt;\/h1&gt;\n    \n    &lt;div class=\"user-list\"&gt;\n        &lt;?php foreach ($users as $user): ?&gt;\n            &lt;div class=\"user-item\"&gt;\n                &lt;h3&gt;&lt;?= esc($user['name']) ?&gt;&lt;\/h3&gt;\n                &lt;p&gt;&lt;?= esc($user['email']) ?&gt;&lt;\/p&gt;\n                &lt;a href=\"\/users\/&lt;?= $user['id'] ?&gt;\"&gt;\u8a73\u7d30\u3092\u898b\u308b&lt;\/a&gt;\n            &lt;\/div&gt;\n        &lt;?php endforeach; ?&gt;\n    &lt;\/div&gt;\n&lt;?= $this-&gt;endSection() ?&gt;\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u8a2d\u5b9a\u3068\u6d3b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u57fa\u672c\u7684\u306a\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u8a2d\u5b9a<\/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=\"\">\/\/ app\/Config\/Routes.php\n$routes-&gt;get('\/', 'Home::index');\n$routes-&gt;get('users', 'Users::index');\n$routes-&gt;get('users\/(:num)', 'Users::show\/$1');\n\n\/\/ RESTful\u30ea\u30bd\u30fc\u30b9\u30eb\u30fc\u30c8\n$routes-&gt;resource('api\/users');\n\n\/\/ \u30b0\u30eb\u30fc\u30d7\u5316\u3057\u305f\u30eb\u30fc\u30c8\n$routes-&gt;group('admin', ['filter' =&gt; 'auth'], function($routes) {\n    $routes-&gt;get('users', 'Admin\\Users::index');\n    $routes-&gt;get('users\/new', 'Admin\\Users::new');\n    $routes-&gt;post('users', 'Admin\\Users::create');\n});\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30ab\u30b9\u30bf\u30e0\u30eb\u30fc\u30c8\u30d5\u30a3\u30eb\u30bf\u30fc\u306e\u5b9f\u88c5<\/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=\"\">\/\/ app\/Filters\/AuthFilter.php\nnamespace App\\Filters;\n\nuse CodeIgniter\\HTTP\\RequestInterface;\nuse CodeIgniter\\HTTP\\ResponseInterface;\nuse CodeIgniter\\Filters\\FilterInterface;\n\nclass AuthFilter implements FilterInterface\n{\n    public function before(RequestInterface $request, $arguments = null)\n    {\n        if (!session()-&gt;get('logged_in')) {\n            return redirect()-&gt;to('\/login');\n        }\n    }\n\n    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)\n    {\n        \/\/ \u30a2\u30af\u30b7\u30e7\u30f3\u5f8c\u306e\u51e6\u7406\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-11\">\u4f9d\u5b58\u6027\u6ce8\u5165\u3068\u30b5\u30fc\u30d3\u30b9\u306e\u6d3b\u7528\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30b5\u30fc\u30d3\u30b9\u30af\u30e9\u30b9\u306e\u4f5c\u6210<\/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=\"\">namespace App\\Services;\n\nclass UserService\n{\n    protected $userModel;\n    protected $emailService;\n\n    public function __construct(UserModel $userModel, EmailService $emailService)\n    {\n        $this-&gt;userModel = $userModel;\n        $this-&gt;emailService = $emailService;\n    }\n\n    public function registerUser(array $userData)\n    {\n        \/\/ \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u51e6\u7406\n        $db = \\Config\\Database::connect();\n        $db-&gt;transStart();\n\n        try {\n            \/\/ \u30e6\u30fc\u30b6\u30fc\u767b\u9332\n            $userId = $this-&gt;userModel-&gt;insert($userData);\n            \n            \/\/ \u30a6\u30a7\u30eb\u30ab\u30e0\u30e1\u30fc\u30eb\u9001\u4fe1\n            $this-&gt;emailService-&gt;sendWelcomeEmail($userData['email']);\n            \n            $db-&gt;transComplete();\n            return $userId;\n        } catch (\\Exception $e) {\n            $db-&gt;transRollback();\n            throw $e;\n        }\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>Services.php\u3067\u306e\u30b5\u30fc\u30d3\u30b9\u767b\u9332<\/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=\"\">\/\/ app\/Config\/Services.php\npublic static function userService($getShared = true)\n{\n    if ($getShared) {\n        return static::getSharedInstance('userService');\n    }\n\n    return new \\App\\Services\\UserService(\n        model('UserModel'),\n        service('email')\n    );\n}\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u30b5\u30fc\u30d3\u30b9\u5229\u7528<\/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=\"\">class RegistrationController extends Controller\n{\n    protected $userService;\n\n    public function __construct()\n    {\n        $this-&gt;userService = service('userService');\n    }\n\n    public function register()\n    {\n        try {\n            $userData = $this-&gt;request-&gt;getPost();\n            $userId = $this-&gt;userService-&gt;registerUser($userData);\n            \n            return redirect()-&gt;to('\/login')\n                            -&gt;with('success', '\u767b\u9332\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f');\n        } catch (\\Exception $e) {\n            return redirect()-&gt;back()\n                            -&gt;with('error', '\u767b\u9332\u306b\u5931\u6557\u3057\u307e\u3057\u305f')\n                            -&gt;withInput();\n        }\n    }\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u30d1\u30bf\u30fc\u30f3\u3092\u9069\u5207\u306b\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u62e1\u5f35\u6027\u306e\u3042\u308b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u53ef\u80fd\u3067\u3059\u3002\u7279\u306b\u3001\u4f9d\u5b58\u6027\u6ce8\u5165\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30c6\u30b9\u30bf\u30d3\u30ea\u30c6\u30a3\u306e\u5411\u4e0a\u3084\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u9593\u306e\u7d50\u5408\u5ea6\u306e\u4f4e\u6e1b\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-12\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30e2\u30c7\u30eb\u306e\u5b9f\u8df5\u7684\u306a\u4f7f\u3044\u65b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u30e2\u30c7\u30eb\u30af\u30e9\u30b9\u3092\u4f7f\u7528\u3057\u305fCRUD\u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30e2\u30c7\u30eb\u306e\u57fa\u672c\u8a2d\u5b9a\u3068\u5b9f\u88c5<\/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=\"\">namespace App\\Models;\n\nuse CodeIgniter\\Model;\n\nclass ProductModel extends Model\n{\n    protected $table = 'products';\n    protected $primaryKey = 'id';\n    protected $useAutoIncrement = true;\n    protected $returnType = 'array';\n    protected $useSoftDeletes = true;\n    \n    protected $allowedFields = [\n        'name', 'description', 'price', \n        'category_id', 'stock', 'status'\n    ];\n    \n    \/\/ \u65e5\u4ed8\u95a2\u9023\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\n    protected $useTimestamps = true;\n    protected $dateFormat = 'datetime';\n    protected $createdField = 'created_at';\n    protected $updatedField = 'updated_at';\n    protected $deletedField = 'deleted_at';\n    \n    \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30eb\n    protected $validationRules = [\n        'name' =&gt; 'required|min_length[3]|max_length[255]',\n        'price' =&gt; 'required|numeric|greater_than[0]',\n        'category_id' =&gt; 'required|integer|is_not_unique[categories.id]',\n        'stock' =&gt; 'required|integer|greater_than_equal_to[0]'\n    ];\n    \n    protected $validationMessages = [\n        'name' =&gt; [\n            'required' =&gt; '\u5546\u54c1\u540d\u306f\u5fc5\u9808\u3067\u3059',\n            'min_length' =&gt; '\u5546\u54c1\u540d\u306f3\u6587\u5b57\u4ee5\u4e0a\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044'\n        ],\n        'price' =&gt; [\n            'required' =&gt; '\u4fa1\u683c\u306f\u5fc5\u9808\u3067\u3059',\n            'numeric' =&gt; '\u4fa1\u683c\u306f\u6570\u5024\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044',\n            'greater_than' =&gt; '\u4fa1\u683c\u306f0\u3088\u308a\u5927\u304d\u3044\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044'\n        ]\n    ];\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>CRUD\u64cd\u4f5c\u306e\u5b9f\u88c5\u4f8b<\/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=\"\">class ProductController extends BaseController\n{\n    protected $productModel;\n    \n    public function __construct()\n    {\n        $this-&gt;productModel = new ProductModel();\n    }\n    \n    \/\/ Create\u64cd\u4f5c\n    public function create()\n    {\n        $data = [\n            'name' =&gt; $this-&gt;request-&gt;getPost('name'),\n            'price' =&gt; $this-&gt;request-&gt;getPost('price'),\n            'category_id' =&gt; $this-&gt;request-&gt;getPost('category_id'),\n            'stock' =&gt; $this-&gt;request-&gt;getPost('stock')\n        ];\n        \n        try {\n            $this-&gt;productModel-&gt;insert($data);\n            return redirect()-&gt;to('\/products')\n                           -&gt;with('success', '\u5546\u54c1\u304c\u767b\u9332\u3055\u308c\u307e\u3057\u305f');\n        } catch (\\Exception $e) {\n            return redirect()-&gt;back()\n                           -&gt;with('error', '\u5546\u54c1\u306e\u767b\u9332\u306b\u5931\u6557\u3057\u307e\u3057\u305f')\n                           -&gt;withInput();\n        }\n    }\n    \n    \/\/ Read\u64cd\u4f5c\uff08\u4e00\u89a7\u53d6\u5f97\uff09\n    public function index()\n    {\n        $data['products'] = $this-&gt;productModel\n            -&gt;select('products.*, categories.name as category_name')\n            -&gt;join('categories', 'categories.id = products.category_id')\n            -&gt;paginate(10);\n            \n        $data['pager'] = $this-&gt;productModel-&gt;pager;\n        \n        return view('products\/index', $data);\n    }\n    \n    \/\/ Update\u64cd\u4f5c\n    public function update($id)\n    {\n        $data = $this-&gt;request-&gt;getPost();\n        \n        try {\n            $this-&gt;productModel-&gt;update($id, $data);\n            return redirect()-&gt;to('\/products')\n                           -&gt;with('success', '\u5546\u54c1\u304c\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f');\n        } catch (\\Exception $e) {\n            return redirect()-&gt;back()\n                           -&gt;with('error', '\u5546\u54c1\u306e\u66f4\u65b0\u306b\u5931\u6557\u3057\u307e\u3057\u305f');\n        }\n    }\n    \n    \/\/ Delete\u64cd\u4f5c\uff08\u30bd\u30d5\u30c8\u30c7\u30ea\u30fc\u30c8\uff09\n    public function delete($id)\n    {\n        try {\n            $this-&gt;productModel-&gt;delete($id);\n            return redirect()-&gt;to('\/products')\n                           -&gt;with('success', '\u5546\u54c1\u304c\u524a\u9664\u3055\u308c\u307e\u3057\u305f');\n        } catch (\\Exception $e) {\n            return redirect()-&gt;back()\n                           -&gt;with('error', '\u5546\u54c1\u306e\u524a\u9664\u306b\u5931\u6557\u3057\u307e\u3057\u305f');\n        }\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">\u30af\u30a8\u30ea\u30d3\u30eb\u30c0\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u9ad8\u5ea6\u306a\u691c\u7d22\u6761\u4ef6\u306e\u5b9f\u88c5<\/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=\"\">public function search()\n{\n    $builder = $this-&gt;productModel-&gt;builder();\n    \n    \/\/ \u691c\u7d22\u6761\u4ef6\u306e\u69cb\u7bc9\n    if ($category = $this-&gt;request-&gt;getGet('category')) {\n        $builder-&gt;where('category_id', $category);\n    }\n    \n    if ($minPrice = $this-&gt;request-&gt;getGet('min_price')) {\n        $builder-&gt;where('price &gt;=', $minPrice);\n    }\n    \n    if ($maxPrice = $this-&gt;request-&gt;getGet('max_price')) {\n        $builder-&gt;where('price &lt;=', $maxPrice);\n    }\n    \n    if ($keyword = $this-&gt;request-&gt;getGet('keyword')) {\n        $builder-&gt;groupStart()\n                -&gt;like('name', $keyword)\n                -&gt;orLike('description', $keyword)\n                -&gt;groupEnd();\n    }\n    \n    \/\/ \u5728\u5eab\u72b6\u6cc1\u3067\u306e\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\n    if ($this-&gt;request-&gt;getGet('in_stock') === 'true') {\n        $builder-&gt;where('stock &gt;', 0);\n    }\n    \n    return $builder-&gt;select('products.*, categories.name as category_name')\n                   -&gt;join('categories', 'categories.id = products.category_id')\n                   -&gt;orderBy('products.created_at', 'DESC')\n                   -&gt;paginate(10);\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u96c6\u8a08\u30af\u30a8\u30ea\u306e\u5b9f\u88c5<\/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=\"\">public function getProductStats()\n{\n    $builder = $this-&gt;productModel-&gt;builder();\n    \n    return $builder-&gt;select('\n        COUNT(*) as total_products,\n        SUM(stock) as total_stock,\n        AVG(price) as average_price,\n        MIN(price) as min_price,\n        MAX(price) as max_price\n    ')-&gt;get()-&gt;getRow();\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30b7\u30fc\u30c7\u30a3\u30f3\u30b0\u306e\u904b\u7528\u624b\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210\u3068\u5b9f\u88c5<\/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=\"\">namespace App\\Database\\Migrations;\n\nuse CodeIgniter\\Database\\Migration;\n\nclass CreateProductsTable extends Migration\n{\n    public function up()\n    {\n        $this-&gt;forge-&gt;addField([\n            'id' =&gt; [\n                'type' =&gt; 'INT',\n                'constraint' =&gt; 11,\n                'unsigned' =&gt; true,\n                'auto_increment' =&gt; true\n            ],\n            'name' =&gt; [\n                'type' =&gt; 'VARCHAR',\n                'constraint' =&gt; 255\n            ],\n            'description' =&gt; [\n                'type' =&gt; 'TEXT',\n                'null' =&gt; true\n            ],\n            'price' =&gt; [\n                'type' =&gt; 'DECIMAL',\n                'constraint' =&gt; '10,2'\n            ],\n            'category_id' =&gt; [\n                'type' =&gt; 'INT',\n                'constraint' =&gt; 11,\n                'unsigned' =&gt; true\n            ],\n            'stock' =&gt; [\n                'type' =&gt; 'INT',\n                'constraint' =&gt; 11,\n                'default' =&gt; 0\n            ],\n            'status' =&gt; [\n                'type' =&gt; 'ENUM',\n                'constraint' =&gt; ['active', 'inactive'],\n                'default' =&gt; 'active'\n            ],\n            'created_at' =&gt; [\n                'type' =&gt; 'DATETIME',\n                'null' =&gt; true\n            ],\n            'updated_at' =&gt; [\n                'type' =&gt; 'DATETIME',\n                'null' =&gt; true\n            ],\n            'deleted_at' =&gt; [\n                'type' =&gt; 'DATETIME',\n                'null' =&gt; true\n            ]\n        ]);\n        \n        $this-&gt;forge-&gt;addKey('id', true);\n        $this-&gt;forge-&gt;addForeignKey('category_id', 'categories', 'id', 'CASCADE', 'CASCADE');\n        $this-&gt;forge-&gt;createTable('products');\n    }\n\n    public function down()\n    {\n        $this-&gt;forge-&gt;dropTable('products');\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30b7\u30fc\u30c0\u30fc\u306e\u5b9f\u88c5<\/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=\"\">namespace App\\Database\\Seeds;\n\nuse CodeIgniter\\Database\\Seeder;\n\nclass ProductSeeder extends Seeder\n{\n    public function run()\n    {\n        $data = [\n            [\n                'name' =&gt; '\u30b5\u30f3\u30d7\u30eb\u5546\u54c11',\n                'description' =&gt; '\u5546\u54c1\u306e\u8aac\u660e\u6587\u3067\u3059\u3002',\n                'price' =&gt; 1000,\n                'category_id' =&gt; 1,\n                'stock' =&gt; 100,\n                'status' =&gt; 'active',\n                'created_at' =&gt; date('Y-m-d H:i:s'),\n                'updated_at' =&gt; date('Y-m-d H:i:s')\n            ],\n            \/\/ \u4ed6\u306e\u30b5\u30f3\u30d7\u30eb\u30c7\u30fc\u30bf...\n        ];\n        \n        $this-&gt;db-&gt;table('products')-&gt;insertBatch($data);\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30b7\u30fc\u30c7\u30a3\u30f3\u30b0\u306e\u5b9f\u884c\u30b3\u30de\u30f3\u30c9<\/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=\"\"># \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u884c\nphp spark migrate\n\n# \u7279\u5b9a\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u884c\nphp spark migrate --group=products\n\n# \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u30ed\u30fc\u30eb\u30d0\u30c3\u30af\nphp spark migrate:rollback\n\n# \u30b7\u30fc\u30c7\u30a3\u30f3\u30b0\u306e\u5b9f\u884c\nphp spark db:seed ProductSeeder\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u52b9\u7387\u7684\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u64cd\u4f5c\u3068\u4fdd\u5b88\u6027\u306e\u9ad8\u3044\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\u7279\u306b\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3068\u30b7\u30fc\u30c7\u30a3\u30f3\u30b0\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u958b\u767a\u74b0\u5883\u3068\u30c6\u30b9\u30c8\u74b0\u5883\u306e\u4e00\u8cab\u6027\u3092\u4fdd\u3061\u3084\u3059\u304f\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-16\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u3068\u5b9f\u52d9\u3067\u306e\u6ce8\u610f\u70b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">CSRF\u30d7\u30ed\u30c6\u30af\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u57fa\u672c\u7684\u306aCSRF\u5bfe\u7b56\u306e\u8a2d\u5b9a<\/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=\"\">\/\/ app\/Config\/Security.php\npublic $csrfProtection = 'cookie';\npublic $tokenName   = 'csrf_token_name';\npublic $cookieName  = 'csrf_cookie_name';\npublic $expires     = 7200;\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30d5\u30a9\u30fc\u30e0\u3067\u306eCSRF\u30c8\u30fc\u30af\u30f3\u306e\u5b9f\u88c5<\/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=\"\">&lt;!-- \u30d3\u30e5\u30fc\u30d5\u30a1\u30a4\u30eb\u3067\u306e\u5b9f\u88c5 --&gt;\n&lt;form method=\"post\" action=\"\/users\/create\"&gt;\n    &lt;?= csrf_field() ?&gt;\n    &lt;input type=\"text\" name=\"username\"&gt;\n    &lt;input type=\"password\" name=\"password\"&gt;\n    &lt;button type=\"submit\"&gt;\u767b\u9332&lt;\/button&gt;\n&lt;\/form&gt;\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>API\u3067\u306eCSRF\u5bfe\u7b56<\/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=\"\">\/\/ app\/Filters\/APICSRFFilter.php\nnamespace App\\Filters;\n\nuse CodeIgniter\\Filters\\FilterInterface;\nuse CodeIgniter\\HTTP\\RequestInterface;\nuse CodeIgniter\\HTTP\\ResponseInterface;\n\nclass APICSRFFilter implements FilterInterface\n{\n    public function before(RequestInterface $request, $arguments = null)\n    {\n        \/\/ API\u30c8\u30fc\u30af\u30f3\u306e\u691c\u8a3c\n        $token = $request-&gt;getHeaderLine('X-CSRF-TOKEN');\n        if (!$token || !csrf_verify($token)) {\n            return service('response')\n                -&gt;setStatusCode(403)\n                -&gt;setJSON(['error' =&gt; 'Invalid CSRF token']);\n        }\n    }\n\n    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)\n    {\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">XSS\u5bfe\u7b56\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u8a2d\u5b9a<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5165\u529b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/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=\"\">\/\/ app\/Models\/UserModel.php\nprotected $validationRules = [\n    'username' =&gt; [\n        'rules'  =&gt; 'required|min_length[4]|max_length[20]|alpha_numeric',\n        'errors' =&gt; [\n            'required' =&gt; '\u30e6\u30fc\u30b6\u30fc\u540d\u306f\u5fc5\u9808\u3067\u3059',\n            'min_length' =&gt; '\u30e6\u30fc\u30b6\u30fc\u540d\u306f4\u6587\u5b57\u4ee5\u4e0a\u5fc5\u8981\u3067\u3059',\n            'alpha_numeric' =&gt; '\u82f1\u6570\u5b57\u306e\u307f\u4f7f\u7528\u53ef\u80fd\u3067\u3059'\n        ]\n    ],\n    'email' =&gt; [\n        'rules'  =&gt; 'required|valid_email|is_unique[users.email]',\n        'errors' =&gt; [\n            'is_unique' =&gt; '\u3053\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u65e2\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u307e\u3059'\n        ]\n    ],\n    'password' =&gt; [\n        'rules'  =&gt; 'required|min_length[8]|containsSpecialCharacter[1]|containsNumber[1]',\n        'errors' =&gt; [\n            'containsSpecialCharacter' =&gt; '\u7279\u6b8a\u6587\u5b57\u30921\u6587\u5b57\u4ee5\u4e0a\u542b\u3081\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059',\n            'containsNumber' =&gt; '\u6570\u5b57\u30921\u6587\u5b57\u4ee5\u4e0a\u542b\u3081\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059'\n        ]\n    ]\n];\n\n\/\/ \u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30eb\npublic function containsSpecialCharacter(string $str, string $fields, array $data): bool\n{\n    return preg_match('\/[^a-zA-Z0-9]\/', $str) &gt; 0;\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>XSS\u5bfe\u7b56\u306e\u5b9f\u88c5<\/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=\"\">\/\/ \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u51fa\u529b\u30a8\u30b9\u30b1\u30fc\u30d7\npublic function show($id)\n{\n    $user = $this-&gt;userModel-&gt;find($id);\n    \n    return view('users\/show', [\n        'user' =&gt; [\n            'name' =&gt; esc($user['name']),\n            'bio' =&gt; esc($user['bio'], 'html'),\n            'website' =&gt; esc($user['website'], 'url')\n        ]\n    ]);\n}\n\n\/\/ \u30d3\u30e5\u30fc\u3067\u306e\u5b89\u5168\u306a\u51fa\u529b\n&lt;div class=\"user-profile\"&gt;\n    &lt;h1&gt;&lt;?= esc($user['name']) ?&gt;&lt;\/h1&gt;\n    &lt;div class=\"bio\"&gt;&lt;?= esc($user['bio'], 'html') ?&gt;&lt;\/div&gt;\n    &lt;a href=\"&lt;?= esc($user['website'], 'url') ?&gt;\"&gt;\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8&lt;\/a&gt;\n&lt;\/div&gt;\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-19\">\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u3068\u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u8a2d\u5b9a<\/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=\"\">\/\/ app\/Config\/Session.php\npublic $driver = 'CodeIgniter\\Session\\Handlers\\FileHandler';\npublic $cookieName = 'ci_session';\npublic $expiration = 7200;\npublic $savePath = WRITEPATH . 'session';\npublic $matchIP = false;\npublic $timeToUpdate = 300;\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5<\/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=\"\">\/\/ app\/Libraries\/Auth.php\nnamespace App\\Libraries;\n\nclass Auth\n{\n    protected $session;\n    protected $userModel;\n\n    public function __construct()\n    {\n        $this-&gt;session = service('session');\n        $this-&gt;userModel = new \\App\\Models\\UserModel();\n    }\n\n    public function attempt(string $email, string $password): bool\n    {\n        $user = $this-&gt;userModel-&gt;where('email', $email)-&gt;first();\n\n        if (!$user) {\n            return false;\n        }\n\n        if (!password_verify($password, $user['password'])) {\n            \/\/ \u5931\u6557\u56de\u6570\u306e\u30ab\u30a6\u30f3\u30c8\u3068\u5236\u9650\n            $this-&gt;incrementLoginAttempts($email);\n            return false;\n        }\n\n        \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u518d\u751f\u6210\uff08\u30bb\u30c3\u30b7\u30e7\u30f3\u56fa\u5b9a\u653b\u6483\u5bfe\u7b56\uff09\n        $this-&gt;session-&gt;regenerate();\n        \n        $this-&gt;session-&gt;set([\n            'user_id' =&gt; $user['id'],\n            'user_email' =&gt; $user['email'],\n            'isLoggedIn' =&gt; true,\n            'last_activity' =&gt; time()\n        ]);\n\n        return true;\n    }\n\n    protected function incrementLoginAttempts(string $email): void\n    {\n        $attempts = cache()-&gt;get('login_attempts_' . md5($email)) ?? 0;\n        cache()-&gt;save('login_attempts_' . md5($email), ++$attempts, 300);\n\n        if ($attempts &gt;= 5) {\n            throw new \\Exception('Too many login attempts. Please try again later.');\n        }\n    }\n\n    public function check(): bool\n    {\n        if (!$this-&gt;session-&gt;get('isLoggedIn')) {\n            return false;\n        }\n\n        \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6709\u52b9\u671f\u9650\u30c1\u30a7\u30c3\u30af\n        $lastActivity = $this-&gt;session-&gt;get('last_activity');\n        if (time() - $lastActivity &gt; config('Session')-&gt;expiration) {\n            $this-&gt;session-&gt;destroy();\n            return false;\n        }\n\n        \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u66f4\u65b0\n        $this-&gt;session-&gt;set('last_activity', time());\n        return true;\n    }\n\n    public function logout(): void\n    {\n        $this-&gt;session-&gt;destroy();\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u8a8d\u8a3c\u30d5\u30a3\u30eb\u30bf\u30fc\u306e\u5b9f\u88c5<\/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=\"\">\/\/ app\/Filters\/AuthFilter.php\nnamespace App\\Filters;\n\nuse CodeIgniter\\HTTP\\RequestInterface;\nuse CodeIgniter\\HTTP\\ResponseInterface;\nuse CodeIgniter\\Filters\\FilterInterface;\n\nclass AuthFilter implements FilterInterface\n{\n    public function before(RequestInterface $request, $arguments = null)\n    {\n        $auth = service('auth');\n        \n        if (!$auth-&gt;check()) {\n            \/\/ API\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u5834\u5408\n            if ($request-&gt;isAJAX()) {\n                return service('response')\n                    -&gt;setStatusCode(401)\n                    -&gt;setJSON(['error' =&gt; 'Unauthorized']);\n            }\n            \n            \/\/ \u901a\u5e38\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u5834\u5408\n            return redirect()\n                -&gt;to('\/login')\n                -&gt;with('error', '\u30ed\u30b0\u30a4\u30f3\u304c\u5fc5\u8981\u3067\u3059');\n        }\n    }\n\n    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)\n    {\n    }\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u4e00\u822c\u7684\u306a\u653b\u6483\u304b\u3089\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u4fdd\u8b77\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u305f\u3060\u3057\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306f\u5e38\u306b\u6700\u65b0\u306e\u8105\u5a01\u306b\u5bfe\u5fdc\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u3001\u5b9a\u671f\u7684\u306a\u898b\u76f4\u3057\u3068\u66f4\u65b0\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-20\">\u5b9f\u8df5\u7684\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u624b\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">RESTful API\u306e\u69cb\u7bc9\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>RESTful API\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5<\/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=\"\">namespace App\\Controllers\\API;\n\nuse CodeIgniter\\RESTful\\ResourceController;\nuse CodeIgniter\\API\\ResponseTrait;\n\nclass Products extends ResourceController\n{\n    use ResponseTrait;\n    \n    protected $modelName = 'App\\Models\\ProductModel';\n    protected $format = 'json';\n\n    \/\/ GET \/api\/products\n    public function index()\n    {\n        $products = $this-&gt;model-&gt;findAll();\n        return $this-&gt;respond($products);\n    }\n\n    \/\/ GET \/api\/products\/{id}\n    public function show($id = null)\n    {\n        $product = $this-&gt;model-&gt;find($id);\n        \n        if ($product === null) {\n            return $this-&gt;failNotFound('\u5546\u54c1\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093');\n        }\n\n        return $this-&gt;respond($product);\n    }\n\n    \/\/ POST \/api\/products\n    public function create()\n    {\n        $data = $this-&gt;request-&gt;getJSON();\n        \n        if (!$this-&gt;validate($this-&gt;model-&gt;validationRules)) {\n            return $this-&gt;failValidationErrors($this-&gt;validator-&gt;getErrors());\n        }\n\n        $id = $this-&gt;model-&gt;insert($data);\n        \n        if ($id === false) {\n            return $this-&gt;failServerError('\u5546\u54c1\u306e\u767b\u9332\u306b\u5931\u6557\u3057\u307e\u3057\u305f');\n        }\n\n        $product = $this-&gt;model-&gt;find($id);\n        return $this-&gt;respondCreated($product);\n    }\n\n    \/\/ PUT \/api\/products\/{id}\n    public function update($id = null)\n    {\n        $data = $this-&gt;request-&gt;getJSON();\n        \n        if (!$this-&gt;model-&gt;find($id)) {\n            return $this-&gt;failNotFound('\u66f4\u65b0\u5bfe\u8c61\u306e\u5546\u54c1\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093');\n        }\n\n        if (!$this-&gt;validate($this-&gt;model-&gt;validationRules)) {\n            return $this-&gt;failValidationErrors($this-&gt;validator-&gt;getErrors());\n        }\n\n        if ($this-&gt;model-&gt;update($id, $data) === false) {\n            return $this-&gt;failServerError('\u5546\u54c1\u306e\u66f4\u65b0\u306b\u5931\u6557\u3057\u307e\u3057\u305f');\n        }\n\n        return $this-&gt;respond(['message' =&gt; '\u5546\u54c1\u304c\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f']);\n    }\n\n    \/\/ DELETE \/api\/products\/{id}\n    public function delete($id = null)\n    {\n        if (!$this-&gt;model-&gt;find($id)) {\n            return $this-&gt;failNotFound('\u524a\u9664\u5bfe\u8c61\u306e\u5546\u54c1\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093');\n        }\n\n        if ($this-&gt;model-&gt;delete($id) === false) {\n            return $this-&gt;failServerError('\u5546\u54c1\u306e\u524a\u9664\u306b\u5931\u6557\u3057\u307e\u3057\u305f');\n        }\n\n        return $this-&gt;respondDeleted(['message' =&gt; '\u5546\u54c1\u304c\u524a\u9664\u3055\u308c\u307e\u3057\u305f']);\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>API\u30d5\u30a3\u30eb\u30bf\u30fc\u306e\u5b9f\u88c5<\/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=\"\">namespace App\\Filters;\n\nuse CodeIgniter\\Filters\\FilterInterface;\nuse CodeIgniter\\HTTP\\RequestInterface;\nuse CodeIgniter\\HTTP\\ResponseInterface;\n\nclass APIAuthFilter implements FilterInterface\n{\n    public function before(RequestInterface $request, $arguments = null)\n    {\n        $apiKey = $request-&gt;getHeaderLine('X-API-Key');\n        \n        if (!$this-&gt;validateApiKey($apiKey)) {\n            return service('response')\n                -&gt;setStatusCode(401)\n                -&gt;setJSON([\n                    'status' =&gt; 401,\n                    'error' =&gt; '\u7121\u52b9\u306aAPI\u30ad\u30fc\u3067\u3059'\n                ]);\n        }\n    }\n\n    protected function validateApiKey($apiKey)\n    {\n        \/\/ API\u30ad\u30fc\u306e\u691c\u8a3c\u30ed\u30b8\u30c3\u30af\n        return true; \/\/ \u5b9f\u969b\u306e\u5b9f\u88c5\u3067\u306f\u9069\u5207\u306a\u691c\u8a3c\u3092\u884c\u3046\n    }\n\n    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)\n    {\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u30ad\u30e3\u30c3\u30b7\u30e5\u6a5f\u80fd\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u57fa\u672c\u8a2d\u5b9a<\/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=\"\">\/\/ app\/Config\/Cache.php\npublic $handler = 'file';\npublic $backupHandler = 'dummy';\npublic $prefix = '';\npublic $ttl = 60;\npublic $reservedCharacters = '{}()\/\\@:';\n\n\/\/ Redis\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8a2d\u5b9a\u4f8b\npublic $redis = [\n    'host' =&gt; '127.0.0.1',\n    'password' =&gt; null,\n    'port' =&gt; 6379,\n    'timeout' =&gt; 0,\n    'database' =&gt; 0,\n];\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u5b9f\u8df5\u7684\u306a\u6d3b\u7528\u4f8b<\/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=\"\">class ProductController extends BaseController\n{\n    public function index()\n    {\n        $cache = \\Config\\Services::cache();\n        $cacheKey = 'products_list_' . md5(json_encode($this-&gt;request-&gt;getGet()));\n        \n        \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u53d6\u5f97\u3092\u8a66\u307f\u308b\n        if ($products = $cache-&gt;get($cacheKey)) {\n            return $this-&gt;response-&gt;setJSON($products);\n        }\n        \n        \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u304c\u306a\u3044\u5834\u5408\u306f\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\n        $products = $this-&gt;productModel\n            -&gt;select('products.*, categories.name as category_name')\n            -&gt;join('categories', 'categories.id = products.category_id')\n            -&gt;findAll();\n            \n        \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306b\u4fdd\u5b58\uff085\u5206\u9593\uff09\n        $cache-&gt;save($cacheKey, $products, 300);\n        \n        return $this-&gt;response-&gt;setJSON($products);\n    }\n\n    \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u624b\u52d5\u30af\u30ea\u30a2\n    protected function clearProductCache()\n    {\n        $cache = \\Config\\Services::cache();\n        $cache-&gt;deleteMatching('products_list_*');\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-23\">\u30e6\u30cb\u30c3\u30c8\u30c6\u30b9\u30c8\u3068\u30c7\u30d0\u30c3\u30b0\u306e\u9032\u3081\u65b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30c6\u30b9\u30c8\u30af\u30e9\u30b9\u306e\u5b9f\u88c5<\/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=\"\">namespace App\\Tests;\n\nuse CodeIgniter\\Test\\CIUnitTestCase;\nuse CodeIgniter\\Test\\DatabaseTestTrait;\nuse CodeIgniter\\Test\\FeatureTestTrait;\n\nclass ProductTest extends CIUnitTestCase\n{\n    use DatabaseTestTrait;\n    use FeatureTestTrait;\n\n    protected $refresh = true;\n    protected $seed = 'ProductSeeder';\n\n    public function testCreate()\n    {\n        $data = [\n            'name' =&gt; '\u30c6\u30b9\u30c8\u5546\u54c1',\n            'price' =&gt; 1000,\n            'category_id' =&gt; 1,\n            'stock' =&gt; 100\n        ];\n\n        $result = $this-&gt;withHeaders([\n            'X-API-Key' =&gt; 'your-api-key'\n        ])-&gt;post('api\/products', $data);\n\n        $result-&gt;assertStatus(201)\n               -&gt;assertJSONFragment(['name' =&gt; '\u30c6\u30b9\u30c8\u5546\u54c1']);\n    }\n\n    public function testInvalidCreate()\n    {\n        $data = [\n            'name' =&gt; '', \/\/ \u7a7a\u306e\u540d\u524d\uff08\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\uff09\n            'price' =&gt; -100, \/\/ \u8ca0\u306e\u4fa1\u683c\n        ];\n\n        $result = $this-&gt;withHeaders([\n            'X-API-Key' =&gt; 'your-api-key'\n        ])-&gt;post('api\/products', $data);\n\n        $result-&gt;assertStatus(400)\n               -&gt;assertJSONFragment(['errors']);\n    }\n\n    public function testUpdate()\n    {\n        $data = [\n            'name' =&gt; '\u66f4\u65b0\u5f8c\u306e\u5546\u54c1\u540d',\n            'price' =&gt; 2000\n        ];\n\n        $result = $this-&gt;withHeaders([\n            'X-API-Key' =&gt; 'your-api-key'\n        ])-&gt;put('api\/products\/1', $data);\n\n        $result-&gt;assertStatus(200)\n               -&gt;assertJSONFragment(['message' =&gt; '\u5546\u54c1\u304c\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f']);\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30c7\u30d0\u30c3\u30b0\u30c4\u30fc\u30eb\u306e\u6d3b\u7528<\/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=\"\">\/\/ \u30c7\u30d0\u30c3\u30b0\u30d0\u30fc\u306e\u8a2d\u5b9a\n\/\/ app\/Config\/Toolbar.php\npublic $collectors = [\n    \\CodeIgniter\\Debug\\Toolbar\\Collectors\\Timers::class,\n    \\CodeIgniter\\Debug\\Toolbar\\Collectors\\Database::class,\n    \\CodeIgniter\\Debug\\Toolbar\\Collectors\\Logs::class,\n    \\CodeIgniter\\Debug\\Toolbar\\Collectors\\Views::class,\n    \\CodeIgniter\\Debug\\Toolbar\\Collectors\\Cache::class,\n    \\CodeIgniter\\Debug\\Toolbar\\Collectors\\Files::class,\n    \\CodeIgniter\\Debug\\Toolbar\\Collectors\\Routes::class,\n    \\CodeIgniter\\Debug\\Toolbar\\Collectors\\Events::class,\n];\n\n\/\/ \u30b3\u30fc\u30c9\u5185\u3067\u306e\u30c7\u30d0\u30c3\u30b0\npublic function debugExample()\n{\n    \/\/ \u30ed\u30b0\u306e\u51fa\u529b\n    log_message('debug', '\u30c7\u30d0\u30c3\u30b0\u30e1\u30c3\u30bb\u30fc\u30b8: {value}', ['value' =&gt; $someValue]);\n    \n    \/\/ \u5909\u6570\u306e\u5185\u5bb9\u78ba\u8a8d\n    dd($variable); \/\/ die and dump\n    \n    \/\/ \u30bf\u30a4\u30de\u30fc\u306e\u4f7f\u7528\n    $benchmark = \\Config\\Services::timer();\n    $benchmark-&gt;start('my_timer');\n    \n    \/\/ \u51e6\u7406\n    \n    $benchmark-&gt;stop('my_timer');\n    echo $benchmark-&gt;getElapsedTime('my_timer');\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u5b9f\u8df5\u7684\u306a\u958b\u767a\u624b\u6cd5\u3092\u9069\u5207\u306b\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u52b9\u7387\u7684\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\u7279\u306b\u3001\u30c6\u30b9\u30c8\u3068\u30c7\u30d0\u30c3\u30b0\u3092\u91cd\u8996\u3059\u308b\u3053\u3068\u3067\u3001\u54c1\u8cea\u306e\u9ad8\u3044\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u63d0\u4f9b\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-24\">CodeIgniter 4\u3067\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-25\">\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u3068\u305d\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u968e\u5c64\u7684\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u5b9f\u88c5<\/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=\"\">class ProductService\n{\n    protected $cache;\n    protected $productModel;\n    \n    public function __construct()\n    {\n        $this-&gt;cache = \\Config\\Services::cache();\n        $this-&gt;productModel = new \\App\\Models\\ProductModel();\n    }\n    \n    public function getProductDetails($productId)\n    {\n        \/\/ \u7b2c1\u5c64: \u30e1\u30e2\u30ea\u30ad\u30e3\u30c3\u30b7\u30e5\n        $cacheKey = \"product_{$productId}\";\n        $product = $this-&gt;cache-&gt;get($cacheKey);\n        \n        if ($product === null) {\n            \/\/ \u7b2c2\u5c64: Redis\u30ad\u30e3\u30c3\u30b7\u30e5\n            $redis = new \\Redis();\n            $redis-&gt;connect('127.0.0.1', 6379);\n            $product = $redis-&gt;get($cacheKey);\n            \n            if ($product === null) {\n                \/\/ \u7b2c3\u5c64: \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\n                $product = $this-&gt;productModel-&gt;find($productId);\n                \n                \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u66f4\u65b0\n                if ($product) {\n                    $redis-&gt;setex($cacheKey, 3600, serialize($product));\n                    $this-&gt;cache-&gt;save($cacheKey, $product, 300);\n                }\n            } else {\n                $product = unserialize($product);\n                $this-&gt;cache-&gt;save($cacheKey, $product, 300);\n            }\n        }\n        \n        return $product;\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30d3\u30e5\u30fc\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6d3b\u7528<\/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=\"\">class CatalogController extends BaseController\n{\n    public function categoryPage($categoryId)\n    {\n        $cacheKey = \"category_page_{$categoryId}\";\n        \n        if (! $output = cache($cacheKey)) {\n            $data = [\n                'products' =&gt; $this-&gt;productModel\n                    -&gt;where('category_id', $categoryId)\n                    -&gt;findAll(),\n                'category' =&gt; $this-&gt;categoryModel-&gt;find($categoryId)\n            ];\n            \n            $output = view('catalog\/category', $data);\n            \n            \/\/ \u30d3\u30e5\u30fc\u3092\u30ad\u30e3\u30c3\u30b7\u30e5\u306b\u4fdd\u5b58\uff081\u6642\u9593\uff09\n            cache()-&gt;save($cacheKey, $output, 3600);\n        }\n        \n        return $output;\n    }\n}\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-26\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u6700\u9069\u5316\u624b\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30af\u30a8\u30ea\u306e\u6700\u9069\u5316<\/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=\"\">class OptimizedProductModel extends \\CodeIgniter\\Model\n{\n    public function getProductsWithEfficiency($categoryId)\n    {\n        return $this-&gt;select('products.*, \n                            categories.name as category_name,\n                            COUNT(reviews.id) as review_count')\n                    -&gt;join('categories', 'categories.id = products.category_id')\n                    -&gt;join('reviews', 'reviews.product_id = products.id', 'left')\n                    -&gt;where('products.category_id', $categoryId)\n                    -&gt;groupBy('products.id')\n                    -&gt;having('review_count &gt;', 0)\n                    -&gt;useIndex('idx_category') \/\/ \u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u660e\u793a\u7684\u306a\u4f7f\u7528\n                    -&gt;findAll();\n    }\n    \n    \/\/ \u30d0\u30eb\u30af\u30a4\u30f3\u30b5\u30fc\u30c8\u306e\u5b9f\u88c5\n    public function bulkInsertProducts($products, $batchSize = 100)\n    {\n        $chunks = array_chunk($products, $batchSize);\n        \n        $this-&gt;db-&gt;transStart();\n        try {\n            foreach ($chunks as $chunk) {\n                $this-&gt;insertBatch($chunk);\n            }\n            $this-&gt;db-&gt;transComplete();\n            return $this-&gt;db-&gt;transStatus();\n        } catch (\\Exception $e) {\n            $this-&gt;db-&gt;transRollback();\n            throw $e;\n        }\n    }\n}\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u6700\u9069\u5316<\/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=\"\">-- \u5fc5\u8981\u306a\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u4f5c\u6210\nCREATE INDEX idx_category ON products(category_id);\nCREATE INDEX idx_price ON products(price);\nCREATE INDEX idx_created_at ON products(created_at);\nCREATE INDEX idx_status_category ON products(status, category_id);\n\n-- \u8907\u5408\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u4f5c\u6210\nCREATE INDEX idx_category_price ON products(category_id, price);\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b3\u30cd\u30af\u30b7\u30e7\u30f3\u306e\u6700\u9069\u5316<\/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=\"\">\/\/ app\/Config\/Database.php\npublic $default = [\n    'hostname' =&gt; 'localhost',\n    'username' =&gt; 'your_username',\n    'password' =&gt; 'your_password',\n    'database' =&gt; 'your_database',\n    'DBDriver' =&gt; 'MySQLi',\n    'DBPrefix' =&gt; '',\n    'pConnect' =&gt; false,\n    'DBDebug'  =&gt; true,\n    'charset'  =&gt; 'utf8mb4',\n    'DBCollat' =&gt; 'utf8mb4_unicode_ci',\n    'swapPre'  =&gt; '',\n    'encrypt'  =&gt; false,\n    'compress' =&gt; false,\n    'strictOn' =&gt; false,\n    'failover' =&gt; [],\n    'port'     =&gt; 3306,\n    'persistent' =&gt; true,\n    \/\/ \u30b3\u30cd\u30af\u30b7\u30e7\u30f3\u30d7\u30fc\u30ea\u30f3\u30b0\u306e\u8a2d\u5b9a\n    'pooling'  =&gt; true,\n    'pool'     =&gt; [\n        'max_connections' =&gt; 100,\n        'idle_timeout'   =&gt; 60,\n        'wait_timeout'   =&gt; 30,\n    ],\n];\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-27\">\u672c\u756a\u74b0\u5883\u3067\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30c1\u30e5\u30fc\u30cb\u30f3\u30b0<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u8a2d\u5b9a\u306e\u6700\u9069\u5316<\/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=\"\">\/\/ app\/Config\/App.php\npublic $baseURL = 'https:\/\/your-production-domain.com\/';\n\n\/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6709\u52b9\u5316\npublic $cache = 'file';\n\n\/\/ \u30a8\u30e9\u30fc\u8868\u793a\u306e\u7121\u52b9\u5316\npublic $displayErrors = false;\n\n\/\/ \u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u8abf\u6574\npublic $logThreshold = 3; \/\/ Error\u4ee5\u4e0a\u306e\u307f\u8a18\u9332\n\n\/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u8a2d\u5b9a\u306e\u6700\u9069\u5316\npublic $sessionDriver = 'redis';\npublic $sessionExpiration = 7200;\n<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u306e\u5b9f\u88c5<\/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=\"\">class PerformanceMonitor\n{\n    protected $timer;\n    protected $logger;\n    \n    public function __construct()\n    {\n        $this-&gt;timer = \\Config\\Services::timer();\n        $this-&gt;logger = \\Config\\Services::logger();\n    }\n    \n    public function startMeasurement($point)\n    {\n        $this-&gt;timer-&gt;start($point);\n    }\n    \n    public function endMeasurement($point)\n    {\n        $this-&gt;timer-&gt;stop($point);\n        \n        $elapsed = $this-&gt;timer-&gt;getElapsedTime($point);\n        if ($elapsed &gt; 1.0) { \/\/ 1\u79d2\u4ee5\u4e0a\u304b\u304b\u3063\u305f\u51e6\u7406\u3092\u8a18\u9332\n            $this-&gt;logger-&gt;warning(\"Performance Alert: {$point} took {$elapsed} seconds\");\n        }\n        \n        return $elapsed;\n    }\n    \n    public function getMemoryUsage()\n    {\n        $memory = memory_get_usage(true);\n        if ($memory &gt; 64 * 1024 * 1024) { \/\/ 64MB\u4ee5\u4e0a\u4f7f\u7528\u3057\u3066\u3044\u308b\u5834\u5408\n            $this-&gt;logger-&gt;warning(\"High Memory Usage: {$memory} bytes\");\n        }\n        return $memory;\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$monitor = new PerformanceMonitor();\n$monitor-&gt;startMeasurement('database_query');\n\/\/ \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30af\u30a8\u30ea\u306e\u5b9f\u884c\n$monitor-&gt;endMeasurement('database_query');\n<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u672c\u756a\u74b0\u5883\u5411\u3051\u306e.env\u30d5\u30a1\u30a4\u30eb\u8a2d\u5b9a<\/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=\"\"># \u30d7\u30ed\u30c0\u30af\u30b7\u30e7\u30f3\u74b0\u5883\u8a2d\u5b9a\nCI_ENVIRONMENT = production\n\n# \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u5b9a\ndatabase.default.hostname = your_production_db_host\ndatabase.default.database = your_production_db\ndatabase.default.username = your_production_user\ndatabase.default.password = your_production_password\ndatabase.default.DBDriver = MySQLi\ndatabase.default.port = 3306\n\n# \u30ad\u30e3\u30c3\u30b7\u30e5\u8a2d\u5b9a\ncache.handler = redis\ncache.redis.host = your_redis_host\ncache.redis.port = 6379\ncache.redis.password = your_redis_password\n\n# \u30bb\u30c3\u30b7\u30e7\u30f3\u8a2d\u5b9a\nsession.handler = redis\nsession.savePath = 'tcp:\/\/your_redis_host:6379'\n\n# \u30e1\u30fc\u30eb\u8a2d\u5b9a\nemail.protocol = smtp\nemail.SMTPHost = your_smtp_host\nemail.SMTPUser = your_smtp_user\nemail.SMTPPass = your_smtp_password\nemail.SMTPPort = 587\nemail.SMTPCrypto = tls\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u30c6\u30af\u30cb\u30c3\u30af\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u5fdc\u7b54\u6027\u3068\u5b89\u5b9a\u6027\u3092\u5927\u5e45\u306b\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u305f\u3060\u3057\u3001\u6700\u9069\u5316\u306f\u5fc5\u305a\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3068\u8a08\u6e2c\u306b\u57fa\u3065\u3044\u3066\u884c\u3044\u3001\u5b9f\u969b\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6539\u5584\u3092\u78ba\u8a8d\u3057\u306a\u304c\u3089\u9032\u3081\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Warning: Undefined array key &#8220;is_admin&#8221; in \/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/ &#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],"tags":[],"class_list":["post-3385","post","type-post","status-publish","format-standard","category-php","nothumb"],"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3385","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=3385"}],"version-history":[{"count":2,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3385\/revisions"}],"predecessor-version":[{"id":3387,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/3385\/revisions\/3387"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}