diff --git a/public/sample/tips/object-oriented/confirm.php b/public/sample/tips/object-oriented/confirm.php new file mode 100644 index 0000000..a2556ff --- /dev/null +++ b/public/sample/tips/object-oriented/confirm.php @@ -0,0 +1,21 @@ +" . print_r($_POST, true) . ""; + // => + // Array + // ( + // [name] => John Doe + // [gender] => male + // [message] => Hello, this is a message. + // ) +} + +if ($_SERVER["REQUEST_METHOD"] === "POST") { + handle_post_request(); +} diff --git a/public/sample/tips/object-oriented/form.html b/public/sample/tips/object-oriented/form.html new file mode 100644 index 0000000..d80010d --- /dev/null +++ b/public/sample/tips/object-oriented/form.html @@ -0,0 +1,183 @@ + + + + + + + お問い合わせフォーム + + + + + +
+
+

お問い合わせ

+

+ 必要事項を入力して、送信ボタンを押してください。 +

+ +
+ + +
+
+
性別
+
+ + + +
+
+
+ + +
+
+ +
+
+
+ + + diff --git a/src/pages/tips/object-oriented.mdx b/src/pages/tips/object-oriented.mdx new file mode 100644 index 0000000..3697907 --- /dev/null +++ b/src/pages/tips/object-oriented.mdx @@ -0,0 +1,464 @@ +--- +# vim: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: +layout: "@/layouts/MarkdownLayout.astro" +--- + +import Toc from "../../components/Toc.astro"; +import ExampleWrapper from "@/components/ExampleWrapper.astro"; +import RenderFile from "@/components/RenderFile"; +import RenderHtml from "@/components/RenderHtml"; +import Details from "@/components/Details.astro"; + +export const title = "オブジェクト指向とクラス"; + +# {title} + +## TOC + +## 大事な用語 + +- Class (クラス) +- インスタンス +- 継承 + +## データのまとまり + +プログラムを組むとき、データのまとまりを扱うことがよくあります。 + +- 設定ファイル +- データベースから取得したデータ +- 入力フォームから送られてきたデータ +- ...etc + +この中でも入力フォームは、開発者自身であってもどのような値が入ってくるかわからなくなることが多いです。 + +このようなフォームがあったとしても、 + + + +データを受け取る側は、どのような値が入ってきているのかわかりません。 +これを知るために、とりあえず変数の中身を表示する処理を書いてみたり、 + +```php file=public/sample/tips/object-oriented/confirm.php +``` + +
+ +もととなるHTMLの`name`属性を直接確認してみたりすることもあるでしょう。 + +
+ +```php file=public/sample/tips/object-oriented/form.html collapse={1-153, 179-183} /name="[a-zA-Z0-9]+"/ +``` + +
+ +
+ +これらの確認を経て、送られてくるデータには以下のものがあるとはじめてわかります。 + +- name +- gender +- message + +しかし、予めどのようなデータが入ってくるのかを把握したいものです。 + +今回の例のような入力フォームであれば、HTMLの変更によって意図しないデータが入ってくる可能性もありますし、そもそもHTMLを見ないとどのようなデータが入ってくるのかわからないのは、あまり良い状態とは言えません。 + +これを解決するために、あるデータの集まりに対して、具体的になにがあるのかを説明するようなアプローチが存在します。 +その最も原始的な方法が、 `構造体(struct)` や `クラス(class)` を使うことです。 + +これはHTMLから送られてくるデータ全体をひとつのまとまりとして扱う考え方です。 +この構造の中に、具体的に何が入ってくるのかを定義することができます。 + +```php + +// NULL +// ["gender"]=> +// NULL +// ["message"]=> +// NULL +// } + +$formField->name = $_POST["name"]; +$formField->gender = $_POST["gender"]; +$formField->message = $_POST["message"]; + +var_dump($formField); +// object(FormField)#1 (3) { +// ["name"]=> +// string(5) "Alice" +// ["gender"]=> +// string(3) "woman" +// ["message"]=> +// string(11) "Hello world" +// } +``` + +### 振る舞いを定義する (メソッド / 関数) + +### 特別なメソッド + +### 敢えてアクセス制限をかける (アクセス修飾子) + +### 派生を作る (継承) + +## よく見るコード例 + +--- + +```c +#include + +typedef char* str; + +struct User { + str name; + int age; +}; + +int main() { + User me = { + .name = "Alice", + .age = 30 + }; + + printf("name: %s\n", me.name); + // name: Alice + + printf("age: %d\n", me.age); + // age: 30 + + return 0; +} +``` + +```php +name = "Alice"; +$user->age = 30; + +echo $user->name . PHP_EOL; +// Alice + +echo $user->age . PHP_EOL; +// 30 +``` + +```php +name; + } +} + +$user = new User(); + +$user->name = "Alice"; +$user->age = 30; + +echo $user->name . PHP_EOL; +echo $user->getName() . PHP_EOL; +// Alice + +echo $user->age . PHP_EOL; +// 30 +``` + +```php +name = $name; + } + + public function getName() { + return $this->name; + } +} + +$user = new User(); + +$user->name = 9817298471982; // 文字じゃねぇ +if (!is_string($user->name)) { + throw new Exception("name must be a string"); +} + +$user->setName("Alice"); +// ok + +$user->setName(123); +// Exception: name must be a string + +$user->age = 30; + +echo $user->name . PHP_EOL; +echo $user->getName() . PHP_EOL; +// Alice + +echo $user->age . PHP_EOL; +// 30 +``` + +```php +name = $name; + } + + public function getName() { + return $this->name; + } +} + +$user = new User(); + +$user->name = 9817298471982; +if (!is_string($user->name)) { + throw new Exception("name must be a string"); +} + +$user->setName("Alice"); +// ok + +$user->setName(123); +// Exception: name must be a string + +$user->age = 30; + +echo $user->name . PHP_EOL; +echo $user->getName() . PHP_EOL; +// Alice + +echo $user->age . PHP_EOL; +// 30 +``` + +constructor コンストラクタ +static + +```php +name = $name; + $this->age = 0; + } + + public static function findUser($id) { + + // $name を使ってDBから取ってくる + + $data = [ + "name" => "bob", + "age" => 35, + ]; + + $instance = new User($data["name"]); + $instance->age = $data["age"]; + + return $instance; + } + + public function setName($name) { + + if (!is_string($name)) { + throw new Exception("name must be a string"); + } + + $this->name = $name; + } + + public function getName() { + return $this->name; + } +} + +$user = new User("Alice"); + +$bob = User::findUser(1); + +$user->name = 9817298471982; +if (!is_string($user->name)) { + throw new Exception("name must be a string"); +} + +$user->setName("Alice"); +// ok + +$user->setName(123); +// Exception: name must be a string + +$user->age = 30; + +echo $user->name . PHP_EOL; +echo $user->getName() . PHP_EOL; +// Alice + +echo $user->age . PHP_EOL; +// 30 +``` + +```php +name = $name; + } + + public function setName($name) { + + if (!is_string($name)) { + throw new Exception("name must be a string"); + } + + $this->name = $name; + } + + public function getName() { + return $this->name; + } +} + +$user1 = new User("Alice"); +// 私は Alice です + + + +class ParttimeUser extends User { + public function __constructor($name) { + echo "吾輩は {$name} です"; + $this->name = $name; + } +} + +$user2 = new ParttimeUser("Bob"); +// 吾輩は Bob です + +$user2->setName("George"); +``` + +スマホでボリュームを上げ下げしたいとき、ボタンを押させる。 +中身に触れさせて、この端子をさわってね みたいなことはさせない。