CakePHP5入門【WebAPI編⑥】API実装とデプロイ
B美
まずは仕様だけど、どうするの?
A子
(「実施回」を指定しても意味無いし…)
あ、「ナンバーズ3」と「ナンバーズ4」は別々にしたほうが良いかな?
C菜
A子
| URL | numapp/api/get3_ymd/2026/2/27 |
|---|---|
| 戻り値 | 6929(実施回) |
| "2026年2月27日"(年月日) | |
| "金曜日"(曜日1) | |
| "金"(曜日2) | |
| "大安"(六曜) | |
| "682"(当選番号) |
上が「ナンバーズ3」で、下が「ナンバーズ4」ね
| URL | numapp/api/get4_ymd/2026/2/27 |
|---|---|
| 戻り値 | 6929(実施回) |
| "2026年2月27日"(年月日) | |
| "金曜日"(曜日1) | |
| "金"(曜日2) | |
| "大安"(六曜) | |
| "2586"(当選番号) |
ちなみに、ダブルクォートで囲んでいるのは「文字列」って意味だから…
C菜
違いは「当選番号」だけですし~
A子
| URL | numapp/api/get_ymd/2026/2/27 |
|---|---|
| 戻り値 | 6929(実施回) |
| "2026年2月27日"(年月日) | |
| "金曜日"(曜日1) | |
| "金"(曜日2) | |
| "大安"(六曜) | |
| "682"(ナンバーズ3の当選番号) | |
| "2586"(ナンバーズ4の当選番号) |
B美
C菜
この例だと、「2026-02-27」という一つの引数を渡すということです~
B美
A子
| URL | numapp/api/get_ymd1/2026/2/27 |
|---|---|
| 戻り値 | 6929(実施回) |
| "2026年2月27日"(年月日) | |
| "金曜日"(曜日1) | |
| "金"(曜日2) | |
| "大安"(六曜) | |
| "682"(ナンバーズ3の当選番号) | |
| "2586"(ナンバーズ4の当選番号) |
| URL | numapp/api/get_ymd2/2026-02-27 |
|---|---|
| 戻り値 | 6929(実施回) |
| "2026年2月27日"(年月日) | |
| "金曜日"(曜日1) | |
| "金"(曜日2) | |
| "大安"(六曜) | |
| "682"(ナンバーズ3の当選番号) | |
| "2586"(ナンバーズ4の当選番号) |
これでどう?
C菜
良いと思います~
A子
まずはコントローラーをbakeするよ
|
cd html/numapp[Enter]
bin/cake bake controller api[Enter] |
これで「src/Controller/ApiController.php」ができたね
あ、メソッドは全て削除しといたよ(「index」メソッドも含めて)
C菜
A子
C菜
「AdminController.php」からコピーしますね~
A子
|
$numbers = $this->Numbers->find()->where([
'lottery_date_year' => $year, 'lottery_date_month' => $month, 'lottery_date_day' => $day ])->first(); |
|
$numbers = $this->Numbers->find()->where([
'lottery_date_dt' => $ymd ])->first(); |
この二つで良いかな?
上が「get_ymd1」メソッド用で、下が「get_ymd2」メソッド用ね
B美
忘れたの?
C菜
privateメソッドは「スネークケース」でもOKですけど、publicメソッドは「キャメルケース」にしなきゃです~
あと、「'lottery_date_dt' => $ymd」という検索条件って、大丈夫なんですか~?
(「'lottery_date_dt' => new DateTime($ymd.' 00:00:00')」にしなくても良いのでしょうか~?)
B美
ただ、A子の書き方でも問題なく検索はできるわね
A子
|
public function getYmd1($year, $month, $day)
{ //numbersテーブルを検索 $numbers = $this->Numbers->find()->where([ 'lottery_date_year' => $year, 'lottery_date_month' => $month, 'lottery_date_day' => $day ])->first(); if (empty($numbers)) { //NG } else { //OK } } |
|
public function getYmd2($ymd)
{ //numbersテーブルを検索 $numbers = $this->Numbers->find()->where([ 'lottery_date_dt' => $ymd ])->first(); if (empty($numbers)) { //NG } else { //OK } } |
これで良いんじゃない?
B美
(JSONとか意識せず、普通にPHPの連想配列にすれば良いから…)
C菜
|
if (empty($numbers)) {
//NG $status = [ 'code' => 404, 'message' => 'Not Found' ]; $result = null; } else { //OK $status = [ 'code' => 200, 'message' => 'Success' ]; $result = [ 'lottery_time' => $numbers['lottery_time'], 'lottery_date_str' => $numbers['lottery_date_str'], 'lottery_week_str1' => $numbers['lottery_week_str1'], 'lottery_week_str2' => $numbers['lottery_week_str2'], 'lottery_rokuyo_str' => $numbers['lottery_rokuyo_str'], 'num3_str' => $numbers['num3_str'], 'num4_str' => $numbers['num4_str'] ]; } $json = [ 'status' => $status, 'result' => $result ]; |
これでどうでしょうか~?
B美
(まったく問題ないわ)
A子
| return $json; |
…って感じ
B美
手順はこうよ
まずビューへの移動を無効にします
| $this->autoRender = false; |
次にサーバからクライアントへ返すデータのコンテントタイプを設定します
| header("Content-Type: application/json"); |
最後に、エンコードされたJSONデータを返すの
(「retern」ではなく「echo」で出力)
| echo json_encode($json); |
ほかのやり方もあるんだけど、私はいつもこうしてるわ
(正解は一つだけじゃない…ってこと)
A子
まとめると、こうかな?
|
public function getYmd1($year, $month, $day)
{ //numbersテーブルを検索 $numbers = $this->Numbers->find()->where([ 'lottery_date_year' => $year, 'lottery_date_month' => $month, 'lottery_date_day' => $day ])->first(); if (empty($numbers)) { //NG $status = [ 'code' => 404, 'message' => 'Not Found' ]; $result = null; } else { //OK $status = [ 'code' => 200, 'message' => 'Success' ]; $result = [ 'lottery_time' => $numbers['lottery_time'], 'lottery_date_str' => $numbers['lottery_date_str'], 'lottery_week_str1' => $numbers['lottery_week_str1'], 'lottery_week_str2' => $numbers['lottery_week_str2'], 'lottery_rokuyo_str' => $numbers['lottery_rokuyo_str'], 'num3_str' => $numbers['num3_str'], 'num4_str' => $numbers['num4_str'] ]; } //JSON化する前の連想配列 $json = [ 'status' => $status, 'result' => $result ]; //JSONエンコードした結果を返す $this->autoRender = false; header("Content-Type: application/json"); echo json_encode($json); } |
C菜
…ということはprivateな共通メソッドを用意して、「getYmd1」と「getYmd2」の両方から呼び出すようにすれば良いのでは~?
|
//年月日の3つの引数からナンバーズの当選番号をJSONで返却
public function getYmd1($year, $month, $day) { //numbersテーブルを検索 $numbers = $this->Numbers->find()->where([ 'lottery_date_year' => $year, 'lottery_date_month' => $month, 'lottery_date_day' => $day ])->first(); //JSON化する前の連想配列を作成 $json = $this->make_json($numbers); //JSONエンコードした結果を返す $this->autoRender = false; header("Content-Type: application/json"); echo json_encode($json); } //'Y-m-d'形式の引数からナンバーズの当選番号をJSONで返却 public function getYmd2($ymd) { //numbersテーブルを検索 $numbers = $this->Numbers->find()->where([ 'lottery_date_dt' => $ymd ])->first(); //JSON化する前の連想配列を作成 $json = $this->make_json($numbers); //JSONエンコードした結果を返す $this->autoRender = false; header("Content-Type: application/json"); echo json_encode($json); } //データベースの検索結果から連想配列を作成 private function make_json($numbers) { if (empty($numbers)) { //NG $status = [ 'code' => 404, 'message' => 'Not Found' ]; $result = null; } else { //OK $status = [ 'code' => 200, 'message' => 'Success' ]; $result = [ 'lottery_time' => $numbers['lottery_time'], 'lottery_date_str' => $numbers['lottery_date_str'], 'lottery_week_str1' => $numbers['lottery_week_str1'], 'lottery_week_str2' => $numbers['lottery_week_str2'], 'lottery_rokuyo_str' => $numbers['lottery_rokuyo_str'], 'num3_str' => $numbers['num3_str'], 'num4_str' => $numbers['num4_str'] ]; } //JSON化する前の連想配列 $json = [ 'status' => $status, 'result' => $result ]; return $json; } |
B美
(上記の「make_json」メソッドのこと)
それじゃ、テストしてみなさい
ブラウザのURLに直接入力して良いから…
A子
| http://192.168.1.205/numapp/api/get_ymd1/2026/2/27 |
あれ?
「2026\u5e742\u670827\u65e5」って何なのよ
まさか文字化け?
B美
「\u5e74」は「年」、「\u6708」は「月」、「\u65e5」は「日」のことなの
これは『Unicodeエスケープ』と呼ばれるもので、日本語をJSON出力する際の標準的な挙動よ
C菜
B美
あ、存在しない年月日でも試してみてね
A子
| http://192.168.1.205/numapp/api/get_ymd1/2026/2/28 |
この日は土曜日だから抽選は無いんだよね
C菜
あと
| http://192.168.1.205/numapp/api/get_ymd2/2026-02-27 |
と
| http://192.168.1.205/numapp/api/get_ymd2/2026-02-28 |
の二つについてもテストしてみました~
どちらも問題なかったです~
(結果については、上記と同じ)
B美
まずは「html」ディレクトリの中にサンプルのHTMLファイルを作りましょう
C菜
その前に本番環境への設置をやったほうが良いのではないでしょうか~?
そうすればこのページの読者様が実際の挙動を体験できると思いますよ~
A子
読者って誰だよ(苦笑)
B美
それじゃ、あなたたちで設置してみなさい
もう慣れたものでしょ?
C菜
開発環境側ではこうですね~
|
1.キャッシュクリアを実行する
2.「config/const.php」の定数「ENVIRONMENT」を「2」に変更する 3.SCPを使って、本番環境へのアップロードを実行する |
それから、本番環境側では下記の通りです~
|
4.SSH接続してから「numapp/logs」の中にあるファイルを全て削除
5.データベースを作成する(定義ファイルを読み込む) 6.「config/app_local.php」の中にあるデータベースパスワードを書き換えると共に、同ファイルのデバッグモードを「false」にする 7.ブラウザでアクセスし、管理ページ上でExcelファイルをインポートする |
ちなみに、4番についてはアップロード時にファイルのオーナーが変わっちゃうからです~
A子
んじゃ、まずは1番から…
| 1.キャッシュクリアを実行する |
「MATE端末」から下記を実行するよ
|
cd html/numapp[Enter]
bin/cake cache clear_all[Enter] |
C菜
| 2.「config/const.php」の定数「ENVIRONMENT」を「2」に変更する |
ついでに、バージョンについても「0.9.0」にしましたよ~
(未完成なのに「1.0.0」では変なので~)
A子
| 3.SCPを使って、本番環境へのアップロードを実行する |
もちろん、データベース定義ファイルの「numbersdb.sql」も一緒にアップするよ
C菜
| 4.SSH接続してから「numapp/logs」の中にあるファイルを全て削除 |
まずはSSH接続しますね~
| ssh -i .ssh/sakura.pem -p nnnn xxxx@friction-river.jp[Enter] |
(「nnnn(ポート番号)」と「xxxx(ユーザ名)」の部分は伏字ですよ~)
C菜
|
su[Enter]
cd html/numapp/logs[Enter] rm -f *[Enter] exit[Enter] |
あ、よく考えたらrootにならなくても良かったですね~
(ファイルのオーナーが自分自身なので…)
A子
| 5.データベースを作成する(定義ファイルを読み込む) |
さっきアップロードした「numbersdb.sql」を読み込ませよう
| mysql -u root -p < numbersdb.sql[Enter] |
C菜
| 6.「config/app_local.php」の中にあるデータベースパスワードを書き換えると共に、同ファイルのデバッグモードを「false」にする |
エディターには「vi」を使ってみましたけど、別に「nano」でも良いですよ~
↓
・・・
A子
| 7.ブラウザでアクセスし、管理ページ上でExcelファイルをインポートする |
URLは下記の通り
| https://friction-river.jp/numapp/ |
C菜
それでは「管理ページ」に移って、Excelファイルをインポートしましょう~
(あ、BASIC認証も完璧でした~)
↓
↓
A子
|
https://friction-river.jp/numapp/api/get_ymd1/2026/2/27
https://friction-river.jp/numapp/api/get_ymd2/2026-02-27 |
B美
Excelファイルなんだけど、私が毎日追記を行っているファイルは『ナンバーズ3&4.xlsx』だから、それもインポートしてみてね
(最新のデータが入っているから…)
A子
やってみよう
・・・
よし、12件のデータが追加されたよ
C菜
現時点での最新データは、2026年3月17日ということですね~
B美
A子
それにしても、ここまではそんなに難しく感じなかったね
C菜
B美
特に最近は「生成AI」も活用できるしね(苦笑)


