Friction River Software

  • お問い合わせ

CakePHP5入門【WebAPI編①】プロローグ

A子

宝くじってさぁ

実際問題、儲かるの?

C菜

確率論的には絶対に損をしますね~

だって還元率50%以下というのは日本の法律で決まってますし~

B美

そうね

例えば、ナンバーズ3って選択肢が1000通りあるわけだけど、100通り買えば10分の1の確率で当選するわ(ストレートの場合)
そのとき購入費用は、100通り×200円で20,000円かかるのよ
(一口200円なので…)

んで、それを10回繰り返せば1回は当選するわよね(確率的に)
当選金額は約100,000円くらいなんだけど、使うお金は200,000円になるの(20,000円×10回)

つまり、(確率的には)購入金額の半分しか回収できないってわけ
それが還元率50%ってことよ

A子

え?
それって、買えば買うほど損するじゃん

ジャンボ宝くじも同じなの?

B美

年末ジャンボやドリームジャンボ等、様々なジャンボ宝くじがあるけど、全て50%未満になるように調整されているわよ

C菜

あ、でもですよ~

さっきのナンバーズ3の場合、100通りを買う作業の1回目か2回目(できれば4回目以内に)当選すれば利益が出ますよね~?

B美

そうね
結局は「運の強さ」というか「引きの強さ」なのかもしれないわ

10枚の内、当たり券が1枚だけ入っている箱の中から、手探りで当たりを引けるくらい(確率10%)の運があれば良いんだけどねぇ(苦笑)

A子

いや、2分の1の確率(50%)を毎回当てられるくらいの「引きの強さ」さえあれば良いんじゃないの?

それなら絶対に損しないよね?

C菜

ナンバーズなんかの数字選択式なら、その理屈も通りますね~

でも二つの選択肢の中から(常に!)必ず正解のほうを引ける能力なんて、普通の人にはありませんよ~

A子

そこは当選番号の傾向なんかを統計的に調べて、当選確率を向上させられるようにできないかな?

ナンバーズって、どれくらいの回数実施されてきたんだっけ?

B美

約7,000回かな

統計を取る標本サンプル数としては、ちょっと少なすぎるのよね(苦笑)

A子

うーん、それでもちょっと調べてみたいよね

もしかしたら何らかの傾向(というか、確率のかたより)があるかもしれないし…

C菜

では、当選番号のデータベース化ですね~

そのデータ自体は公開されてるんですか~?

B美

宝くじの販売元である「みずほ銀行」のWebサイトで公開されてるわよ

ただねぇ…

A子

ん?
なんか問題があるの?

B美

データとして一つにまとまっていないのよ

Webサイトをスクレイピングするか、手作業で地道にデータ収集するか…

C菜

(スクレイピングの)プログラムを組んだとしても一回だけしか使わないですし、手作業のほうが良いかもですね~

B美

まぁ、実は私が(手作業で)収集したExcelデータがあるんだけどね
(大変だった…(苦笑))

・A列が実施回で、第1回目から第6929回目まで
・B列は抽選日
・C列がナンバーズ3の当選番号
・D列がナンバーズ4の当選番号

になってるわ
(注:2026年2月28日時点での話です)

・・・
・・・
・・・

A子

はやく言えや!

んじゃ、そのExcelデータをデータベースに取り込むWebシステムを作ろう

C菜

良いですねぇ~
そのデータを広く一般に公開すれば、誰かしらに喜ばれるかもしれませんし~

あ、C列とD列が左詰めなのはなぜですか~?

B美

文字列型にしてるからよ
だって「012」や「0123」みたいに左側が「ゼロ」になる場合があるからね

あ、それとC菜の言うように「広く一般に公開する」には、良い方法があるわよ

C菜

それはなんでしょうか~

B美

WebAPIウェブエーピーアイ』よ

非プログラマのWebクリエイター(もしくはデザイナー)であっても、JavaScriptの知識が少しだけあればデータ活用できる仕組みね

A子

Webは分かるけど、APIって何なのよ

なんかの略?

B美

Applicationアプリケーション Programmingプログラミング Interfaceインターフェース』の頭文字を並べたものよ

アプリを作る(プログラムする)際、あらかじめ用意されている便利機能を呼び出すための仕組み(窓口…インターフェース)って感じね

C菜

WindowsAPIって言葉を聞いたことがあります~

B美

WindowsAPIって、Windows上で動作するプログラム(アプリ)を作る際に呼び出す関数みたいなものよ
(大量のAPI群がMicrosoftによって用意されているわ)

WebAPIは、それのWeb版…具体的に言うと「HTTP(またはHTTPS)」経由で呼び出すことができる機能(関数)と考えればOKかな

A子

ん?

でもURLを指定するなら、結果はHTMLデータになるからブラウザでしか表示できないんじゃないの?

B美

お、良い質問ね

WebAPIの場合、URLを指定して取得するのは、ほとんどの場合『JSONジェイソン』データになるの

A子

また謎の単語が出てきたよ(汗)

C菜

以前、チャットアプリで「json_decode」という関数が登場したような~?
(【CakePHP5実用編⑤】を参照)

あと「json_encode」や「JSON.parse」というのもあった気がするです~
(【CakePHP5実用編⑦】を参照)

B美

さすがはC菜ね
以前は説明せずに流しちゃったけど、ここではきちんと講義しておきましょう

JSONってのは『JavaScript Object Notation』の頭文字を並べたもので、PHPで例えると「連想配列」みたいなものかな
(実際は、単なるテキストデータになるんだけど)

A子

連想配列って、キーと値のペアで複数のデータを格納するやつだよね?

C菜

データ形式を教えてください~

B美

基本形は

{
    "キー1":"値1",
    "キー2":"値2",
    "キー3":"値3"
}

…って感じなんだけど、値として「配列」や「連想配列」も持てるのよ

{
    "キー4":["値4-1", "値4-2"],
    "キー5":
    {
        "キー5-1":"値5-1",
        "キー5-2":"値5-2",
        "キー5-3":"値5-3"
    }

}

…って感じにね
(「キー4」の値部分(緑色)が「配列」で、「キー5」の値部分(青色)が「連想配列」)

A子

キーと値をコロン(:)でつないで、そのペア同士をカンマ(,)で区分するってことか

うーん、中カッコ({ })で囲むと連想配列で、大カッコ([ ])で囲むと配列になるのかな?

B美

JSONでは「連想配列」ではなく、「オブジェクト」って呼ぶんだけどね
(まぁ、実態はPHPの「連想配列」と同じなんだけど…)

C菜

具体例を考えてみました~

{
    "社員番号":"R0001",
    "氏名":"A子",
    "生年月日":"xxxx/xx/xx",
    "役職":"代表取締役",
    "スキル":["経営", "PHP言語"],
    "住所":
    {
        "郵便番号":"330-xxxx",
        "都道府県":"埼玉県",
        "市区町村":"さいたま市",
        "住所1":"浦和区○○町",
        "住所2":"xx-xx-xx"
    },
    "電話番号":"xxx-xxxx-xxxx"
}

こんな感じでどうでしょうか~?

A子

値のほうはともかく、キーが日本語なのはマズいんじゃないの?

B美

いいえ、大丈夫よ
あ、ただし文字コードが『UTF-8』であることが条件だけどね
(まぁ、半角英数字にしたほうが無難ではあるけど…)

それと値部分が単なる数値であれば、ダブルクォートで囲む必要はないから…
(値が文字列の場合とキー自体は、ダブルクォート必須だけど)

A子

なるほどねぇ
だったらナンバーズアプリの場合、こうしたらどうかな?

・プロジェクト名:numapp
・コントローラ名:LotteryController
・メソッド名:num3
・引数:実施回
・URL:https://(ドメイン名)/numapp/lottery/num3/6929

で、戻り値が下記のJSONね

{
    "no":6929,
    "number":682
}

あ、第6929回目のナンバーズ3の当選番号が「682」ってことね

B美

引数として存在しない実施回(例えば「0」や「未来の数字」)を指定された場合、どうするの?

WebAPIではエラーかどうかもJSONデータとして返さないといけないのよ
(例えば、Webだったら「404 Not Found」や「500 Internal Server Error」のようにステータスコードを返すわよね)

C菜

だったら、こうしたらどうでしょうか~

{
    "status":
    {
        "code":404,
        "message":"Not Found",
    },
    "result":
    {
        "no":0,
        "date":"",
        "number":0
    }
}

引数として「0」を渡した場合です~

B美

さすがはC菜ね

あ、ただ「result」の中の「date」と「number」の値については、「null」にしたほうが良いかもね
(「null」以外にも「true」と「false」のような真偽値も使えるわ)

A子

ふむ
…ってことは、成功時が

{
    "status":
    {
        "code":200,
        "message":"Success",
    },
    "result":
    {
        "no":6929,
        "date":"2026/2/27",
        "number":682
    }
}

で、失敗時がこうかな?
(引数として「0」を指定した場合ね)

{
    "status":
    {
        "code":404,
        "message":"Not Found",
    },
    "result":
    {
        "no":0,
        "date":null,
        "number":null
    }
}

B美

(Webにおいて)成功時のステータスコードが「200」であることをよく知ってたわね
(A子のくせに…)

A子

まぁ、なんとなくね(苦笑)

B美

あと気になる点としては、当選番号である「number」の値は文字列にしたほうが良いかもしれない…
(数値のままでも特に問題は無いけど、このWebAPIの利用者が使いやすい形式のほうが良いからね)

A子

ん?
それって、当選番号が数値の「12」だった場合、わざわざ「012」という文字列に変換して表示しなきゃいけないってことか…

だったら、最初から文字列データとしての「012」にしといたほうが良いわけだね

C菜

であれば、成功時はこうですかね~

{
    "status":
    {
        "code":200,
        "message":"Success",
    },
    "result":
    {
        "no":6927,
        "date":"2026/2/25",
        "number":"099"
    }
}

第6927回目の当選番号は「099」ですけど、これを数値の「99」ではなく、文字列の「099」で返すわけです~

A子

うん、良いんじゃない?

あとは統計情報を取得できるようにもしたいよね
(例えば、「曜日」ごとの出現数字のかたよりとか…)

B美

まぁ、そのへんはおいおい改良していけば良いわ
とりあえずはベースとなる形(基本形)を作ってみましょう

…ってわけで、次回は「要件定義」ね

A子

うっ…、面倒くさいなぁ

C菜、頼むよ

C菜

だめですよ~、社長

一緒にやるです~

A子

うへぇ