Advertisement
Guest User

Untitled

a guest
Mar 3rd, 2016
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.33 KB | None | 0 0
  1. # PHP基礎について
  2. ## 変数について
  3. - `$変数名`で変数を表す。
  4. - 型表示はしなくて良い。入れるデータによって型が変換される
  5. - 可変変数
  6. `$$変数`ある変数に格納された文字列を別の変数の識別子と認識し、その識別子にアクセスする方法
  7. ```php
  8. <?php
  9. $var = 1;
  10. $var_name = 'var';
  11.  
  12. echo $$var_name , PHP_EOL; //1が出力される
  13. ?>
  14. ```
  15. `var_name`にvarの文字列が入っており、$$をすることで`$var_name`が`$var`となり、1が出力される結果となる。
  16.  
  17. - グローバルスコープとローカルスコープ
  18. - グローバルスコープ
  19. phpブロック`<?php ?>`の中はグローバルスコープとされ、別のPHPブロックや、別のファイルでグローバルスコープに定義された変数は
  20. 同じようにグローバルスコープで使うことが出来る。
  21. PHPにはブロックスコープ(<?php ?> ごとの定義の範囲のこと)は存在せずブロックを抜けた後でも定義された変数を使うことが出来る。
  22. - ローカルスコープ
  23. 関数やクラスのメソッド内のスコープのこと。このスコープではグローバルスコープなど、その関数やメソッドの外側で定義された変数にはアクセス出来ない。
  24. 例)
  25. ```php
  26. $foo = 1;
  27. function example function() {
  28. $foo = 10; //グローバルスコープのfooではなく、ローカルスコープで新しく定義されたfooになる
  29. $bar = 20;
  30. }
  31. some_function();
  32.  
  33. echo $foo , PHP_EOL; //1
  34. echo $bar , PHP_EOL; //エラー 値が入っていない。
  35. ```
  36. もしローカルスコープ内でグローバルスコープの値を参照したい場合は先頭に`global`をつけると参照できるが、
  37. ローカルスコープないで変数が変化しないとは限らないので`global`は極力避けたほうが良い
  38.  
  39. ## 型
  40. - 型の種類
  41. PHPには全部で8種類の型が存在する
  42. 1. 整数型 (int)
  43. 2. 浮動小数点数型 (float,double)
  44. 3. 文字列(string)
  45. シングルクォートの場合、エスケープシーケンスは展開されない。ダブルクォートは展開される。
  46. 4. 論理型 (true,false)
  47. 5. 配列型
  48. 連想配列と普通の配列(明示的に添字配列)は区別されていない。
  49. 6. オブジェクト型
  50. 7. リソース型
  51. 8. null型
  52.  
  53. ## 型変換
  54. - 方の明示的なキャストと関数
  55.  
  56. | 型 | C言語風のキャスト | 変換関数 |
  57. |:-----------|-------------------------:|:--------------------------:|
  58. | This | (bool),(boolean) | - |
  59. | column | (int), (integer) | intval() |
  60. | will | (float),(double),(real) | floatval(),doubleval() |
  61. | be | (string) | strval() |
  62. | left | (array) | - |
  63. | aligned | (object) | - |
  64.  
  65. - 自動キャストの発生条件
  66. - 異なる方同士で演算を行う場合
  67. - 演算子、制御構造、関数やメソッドが特定の型の引数を必要としており、それとは異なる型を渡した時
  68. 関数の中に違う型が渡され、その関数ではその型がサポートされていない場合、警告が発生する。
  69.  
  70. - 自動キャストの危険性
  71. 比較演算子を用いて、文字列'0'と'0.0'が等しいかどうか判定するプログラムを書いたとする。
  72. ```php
  73. if ('0' == '0.0'){
  74. echo '文字列は正しいです';
  75. }
  76. else {
  77. echo '正しくないです';
  78. }
  79. // 文字列がは正しいです と出力されてしまう。
  80. ```
  81. これは数値らしい文字列を整数型と浮動小数点型に変換し、
  82. 整数型と浮動小数点型を合わせるために自動で整数型に変換して比較したためである。
  83. このようなプログラムは危険性をはらんでいる。
  84. 例えばユーザ登録の際に、パスワードを確認のために2回入力する時に一致しているかの判定。
  85. ユーザが0123を入力し、確認用に123を入力してしまったら、0123を入力したのに登録した際には0123で登録されてしまうことがある。
  86.  
  87. - ===と!===
  88. 2つの演算子は`==`と`!=`とほぼ一緒の役割だが、比較対象の型が違う場合、キャストされないので、型が違うとtrueかfalseを出力される。
  89. これにより、上記の問題を解決することが出来る。
  90.  
  91. ## 型変換の注意
  92. webアプリケーションの場合、クライアントから送信された値は数値であろうと文字列であろうとすべて文字列型になる。
  93. しかし、PHPでは比較演算を使った自動キャスト等が行われるが、お作法的によろしくない。
  94. そこで、引数として期待している値の型が決まっている場合は明示的にキャストを行い、厳密な比較演算子(===)を使うと安全
  95.  
  96.  
  97. ## 論理型
  98. PHPでは、なにか値があるものはほとんどがtrueとされる。
  99. PHPがfalseと判断する要因は7つ
  100. - false(論理型)
  101. - 0(整数型)
  102. - 0.0(浮動小数点型)
  103. - 空の文字列("")、文字列のゼロ("0")
  104. - 要素の数がゼロの配列
  105. - null(値がセットされていない変数を含む)
  106. - からのタグから作成されたSimpleXMLオブジェクト
  107.  
  108. ## ヒアドキュメント
  109. - ヒアドキュメントとは?
  110. ヒアドキュメント構文`<<<`のあとに終端識別子(EOI等)を定義し、終端識別子が出現するまで文字列とする。
  111. 終端識別子は必ず行頭から始まり、直前に空白(インデント)を含めず、すぐに改行する必要がある。
  112. ヒアドキュメント内で使用する変数はそのまま`$変数名`で置き、配列やメンバ変数などは`{$変数名[キー]}`のように、
  113. {}で囲む。
  114. 例)
  115. ```php
  116. $foo = 10;
  117. $text = <<< EOI
  118. ヒアドキュメントではこのように
  119. 複数行に渡る文章をそのまま表示することが出来る。
  120.  
  121. ちなみに"$foo"の中身は$fooである。
  122.  
  123. EOI;
  124. //ちなみに"$foo"の中身は10である。 と出力される。
  125. ```
  126.  
  127. ## マジック定数について
  128. - マジック定数とは?
  129. その定数が記述された場所によって動的にその値が変化する定義済み変数
  130.  
  131. | マジック定数 | 意味 |
  132. |:---------------------|----------------------------------------------------:|
  133. | `__FILE__` | ファイルの名前とフルパス |
  134. | `__DIR__` | そのファイルの存在するディレクトリ名 |
  135. | `__LINE__` | そのファイル上の行番号 |
  136. | `__FUNCTION__` | 関数名 宣言時の関数名を大文字小文字区別して返す |
  137. | `__CLASS__` | クラス名 宣言時の関数名を大文字小文字区別して返す |
  138. | `__METHOD__` | メソッド名 宣言時の関数名を大文字小文字区別して返す|
  139. | `__NAMESPACE__` | 現在の名前空間の名前 |
  140. ## PHPの変数命名規則について
  141. スネークケースが一般的だが、最近のトレンドとしてキャメルケースを用いることが多い。
  142. キャメルケースを使いましょう。
  143.  
  144. ## エラーケースについて
  145. PHPの実行時にエラーが発生するが、エラーの種類は大きく分けて4つある
  146. - Parse error, Syntax error
  147. 構文に何かしらのミスが有るときにエラーを吐く
  148. - Fatal error
  149. 実行が停止するエラー
  150. 定義されていない関数を呼びだそうとした時などに発生する。
  151. - Warning, Notice
  152. 注意、警告はするが、実行されるエラー
  153. - 何も表示されない
  154. 構文等にはエラーはないが、実行された結果がそぐわない時
  155.  
  156. ## htmlとの連携
  157. - formについて
  158. `<input>`タグの`name`属性をPHPが操作する。ここは設定しなければならない
  159. - hiddenタグの使いドコロについて
  160. データを何処かのファイルを経由しながら移動したい時に使うと良い。
  161. 特に経由ファイルの中でデータ表示しなくていい場合に使う。
  162. - hiddenタグのvalueについて
  163. valueには渡したいデータが入るのだが、変数を渡さなければならない時は、
  164. valueの値に `.$変数名.`で変数の両脇に結合演算子を入れてやると良い。
  165. 無いとエラーになるので注意
  166. - ラジオボタンやチェックボックス、リストボックスの値取得
  167. これらの入力した値はvalue属性に入っているので、valueを変更すると良い。
  168. - checkboxなどの複数選択可の場合の処理
  169. 複数選択の値を出力させるにはhtml側とPHP側に工夫が必要
  170. - html側の処理
  171. name属性に`データ名[]`と入力する。これにより、PHP側に配列として渡される。
  172. 配列には順番に内容が格納されていく。
  173. フォームに記入された内容はもともと、配列として格納されているので、配列の配列として格納される。
  174. - PHP側の処理
  175. foreach文を使って格納された配列を他の変数に格納して表示する。
  176.  
  177. ## 文字列の連結について
  178. - 文字の連結は`.`で連結する
  179.  
  180. ## シングルクォートとダブルクォートの違い
  181. `'`は文字列がそのまま出てくるが、`"`だと変数の内容が表示される。
  182. 一般的にどちらを使っても良いが、クォートが重なるときはわかるように区別しながら書くと良い
  183. 自分的にはどちらかを統一して書いたほうが綺麗で読みやすいと思う
  184. - クォーテーションの使い分け
  185. `print 'I'm studying'`などの省略形を入れるとシングルクォートが入るのだが、
  186. この時に文字列を囲むシングルクォートと省略形のシングルクォートがダブってエラーを起こしてしまう。
  187. そこで、次の2つの方法を使ってシングルクォートを回避する。
  188. 1. `"`を使う方法 (これが一般的)
  189. `print "I'm studying";`
  190. 2. エスケープシーケンスを使う方法(どうしてもシングルクォートが使いたい場合)
  191. `print 'I\'m studying';
  192.  
  193. ## エスケープシーケンスについて
  194. - エスケープシーケンスとは?
  195. \マークを記述するとその直後の記号はPHPの要素として無視されるようになり混ぜることが出来る。
  196. - エスケープシーケンスの種類
  197.  
  198. | エスケープシーケンス | 意味 |
  199. |:---------------------|-------------------:|
  200. | \n | 改行 |
  201. | \r | キャリッジリターン |
  202. | \t | タブ |
  203. | \\\ | \ |
  204. | \$ | $ |
  205. | \" | " |
  206. | \' | ' |
  207.  
  208. - PHP_EOLとは?
  209. php側で自動的に改行を行ってくれる定数である。`echo 'aaaaa', PHP_EOL;`
  210.  
  211. ## クロスサイトスクリプト対策について
  212. - クロスサイトスクリプトとは?
  213. ウェブページの入力部分をアプリケーションがオウム返しすることによって生成するアプリケーションの性質を利用して悪意のあるスクリプトを注入する攻撃のこと
  214. つまり、フォーム入力などユーザが入力できる部分で悪意のあるユーザがスクリプトを入力し、送信することを指す。
  215. - 対策方法(サニタイジングという)
  216. 入力フォームに入る変数に対して`htmlspecialchars($変数名,ENT_QUOTES)`をつけてやると文字列を実行せずそのまま表示されるようになるので良い。
  217. ちなみに`ENT_QUOTES`は定数扱いなので絶対にシングルクォートで囲まないこと。
  218.  
  219.  
  220. ## データベースとの連携について
  221. ### mysqli関数を使う方法
  222. - 連携ステップ
  223. 1. データベースに接続する
  224. 2. データベースエンジンにSQL文で命令を書く
  225. 3. データベースから切断する
  226. - 実際のコード
  227. ```php
  228. //データベース接続
  229. $db = mysqli_connect('ホスト名','ユーザ名','パスワード','データベース名');
  230. if(!$db){
  231. die(mysqli_connecet_error());
  232. }
  233. $db = mysqli_set_charset('$db','文字コード');
  234.  
  235. //SQLの実行
  236. mysqli_query('$db','SQL文') or die(mysqli_error($db));
  237.  
  238. ```
  239.  
  240. - 接続プログラムを共通プログラムにする
  241. まず、データベースに接続するプログラムを別に制作する。
  242. dbconnect.php
  243. ```php
  244. <?php
  245. $db = mysqli_connect('localhost','root','','mydb') or die(mysqli_connect_error());
  246. ?>
  247. ```
  248. 別のプログラムでそのデータベースに接続したいときは`require(dbconnect.php)`の関数を使うだけで接続が可能となる。
  249. このrequireは別のプログラムを指定して読み込む関数である。
  250. - データベースのデータを取得
  251. `$recodSet = mysqli_query('$db','SQL文') or die(mysqli_error($db));`をプリント表示しても何も表示されない。
  252. そこで`mysqli_fetch_assoc()`関数を使ってデータを取得する。
  253. ```php
  254. $db = mysqli_connect('ホスト名','ユーザ名','パスワード','データベース名');
  255. if(!$db){
  256. die(mysqli_connecet_error());
  257. }
  258. $db = mysqli_set_charset('$db','文字コード');
  259.  
  260. //SQLの実行したデータを取得
  261. $recordSet = mysqli_query('$db','SQL文') or die(mysqli_error($db));
  262. $data = mysqli_fetch_assoc($recordSet);
  263. echo $data['フィールド名']; //フィールドにある1件目のデータのみ表示
  264.  
  265. //フィールドのデータをすべて表示したい場合
  266. while ($data = mysqli_fetch_assoc($recordSet)){
  267. echo $data['フィールド名'];
  268. }
  269. ```
  270. `mysqli_query()`関数での戻り値は「レコードセット」と呼ばれるテーブルでの横軸を指すレコードが複数集まったものが帰ってくる。
  271. このレコードセットから1件のデータを取り出さなければデータとしては利用できない。
  272. `mysqli_fetch_assoc()`でこのレコードセットを1件ごとに連想配列に変換して取ってくる。
  273. 連想配列のキーはフィールド名に相当する。
  274.  
  275. ### COUNTなどが出てきた場合の`mysqli_fetch_assoc()`
  276. 下記のレコードセットを取ってくる場合、連想配列名がめんどくさいことになってしまう。
  277. ```php
  278. $recordSet = mysqli_query($db,'SELECT COUNT(フィールド名) FROM テーブル名');
  279. $data = mysqli_fetch_assoc($recordSet);
  280. echo '件数は' .data['COUNT(フィールド名)]'. '件です'; //フィールド名にはSQLで計算した関数名が入るのでキーがめんどくさくなる
  281. ```
  282. そこで、このめんどくさいキー名を解消するためにSQLの`AS`を使ってフィールド名を変更してやる
  283. ```php
  284. //AS を使用し、変数名を簡潔にした
  285. $recordSet = mysqli_query($db,'SELECT COUNT(フィールド名) AS record_count FROM テーブル名');
  286. $data = mysqli_fetch_assoc($recordSet);
  287. //キー入力も簡単になった
  288. echo '件数は' .data['COUNT(record_count)]'. '件です';
  289. ```
  290.  
  291. - フォームからの情報をSQLに保存する
  292. sprintfを用いて入力したデータの書式を整えてSQL文にする
  293. ```php
  294. $sql = sprintf('INSERT INTO テーブル名 SET フィールド名1 = %d, フィールド名2 = "%s", フィールド名3 = %d, フィールド名4 = "%s", フィールド名5 = NOW()',
  295. mysqli_real_escape_string($db,$_POST['maker_id']),
  296. mysqli_real_escape_string($db,$_POST['item_name']),
  297. mysqli_real_escape_string($db,$_POST['price']),
  298. mysqli_real_escape_string($db,$_POST['keyword'])
  299. );
  300. mysqli_query($db,$sql) or die(mysqli_error());
  301. ```
  302.  
  303. ### PDO関数を使う方法
  304. - 連携ステップ
  305. 1. データベースに接続する
  306. 2. データベースエンジンにSQL文で命令を書く
  307. 3. データベースから切断する
  308. - 実際のコード
  309. ```php
  310. <?php
  311. //1. データベース接続
  312. $dsn = 'mysql:dbname=データベース名;host=ホスト名';
  313. $user = 'ユーザ名'; //mysqlで設定したユーザ名を入力
  314. $password = 'パスワード'; //mysqlで設定したパスワードを入力
  315. $dbh = new PDO($dsn, $user, $password);
  316.  
  317. //2. データベースエンジンにSQL文で命令を書く
  318. $sql = 'INSERT INTO anketo(nickname,email,goiken) VALUES("'.$nickname.'","'.$email.'","'.$iken.'")'; //SQL文を書く
  319. $stmt = $dbh -> prepare($sql);
  320. $stmt -> execute();
  321.  
  322. //3. データベースから切断
  323. $dbh = null;
  324. ?>
  325.  
  326. ```
  327. - データ格納場所について
  328. $stmtの変数に(厳密には変数ではない)データが格納されている
  329. `$rec = $stmt -> fetch(PDO::FETCH_ASSOC)`
  330. これにより1タプルのデータを取得できる。
  331. その後に
  332. ```php
  333. <?php
  334. print $rec['属性名'];
  335. print $rec['属性名'];
  336. print $rec['属性名'];
  337. ?>
  338. ```
  339. とやればデータを表示することが出来る。
  340. ちなみにデータが取得できなくなるとfalseを返す
  341.  
  342. ## SQLインジェクションについて
  343. - SQLインジェクションとは?
  344. SQLのデータを検索する際に入力フォームからSQL文を入力することで個人情報の不正取得や改ざんなどが行われる行為
  345.  
  346. - SQLインジェクション対策(mysqli編)
  347. `mysqli_real_escape_string($db,'文字列')`を使ってsqlインジェクションを防ぐ
  348. この関数は危険な文字を無害化してくれる関数である
  349.  
  350. - SQLインジェクション対策(PDO編)
  351. 1. 文字の連結をやめてデータを入れたい部分を?にする
  352. `$sql = 'SELECT * FROM テーブル名 WHERE 属性名 = ?`
  353. 2. データを別の変数に格納する
  354. `$data[] = $code;`
  355. 3. SQL文で命令を出すときにデータを格納した変数を指定する。
  356. `$stmt ->execute($data);`
  357.  
  358. - 複数のデータを検索する場合
  359. 1. 文字の連結をやめてデータを入れたい部分を?にする
  360. `$sql = 'SELECT * FROM テーブル名 WHERE 属性名 = ? AND 属性名=?`
  361. 2. データを別の変数に格納する(配列なのでデータを何個でも格納できる)
  362. `$data[] = $変数名;`
  363. `$data[] = $変数名;`
  364. 3. SQL文で命令を出すときにデータを格納した変数を指定する。
  365. `$stmt ->execute($data);`
  366.  
  367. ## エラートラップについて
  368. - エラー回避方法
  369. `try-catch`をすることでサーバーダウンなどのエラー時に別の処理を行うことが出来る。
  370. ```php
  371. <?php
  372. try{
  373. //本来の処理
  374. }
  375. catch (Exception $e){
  376. //エラー時の処理
  377. }
  378. ```
  379.  
  380. ## 時刻表示について
  381. - 時刻表示の関数
  382. `date`関数を用いる。
  383.  
  384.  
  385. ```php
  386. date(フォーマット)
  387. date(フォーマット,タイムスタンプ)
  388. ```
  389. - 引数1つの時
  390. 現在時刻を指定したフォーマットで出力する
  391. - 引数2つの時
  392. 第2引数のタイムスタンプを指定したフォーマットで出力
  393.  
  394. ```php
  395. <? php
  396. date_default_timezone_set('Asia/Tokyo');
  397.  
  398. print date("Y/m/d" H:i:s") . '<br>';
  399. print date("Y/m/01") . '<br>';
  400. print date("Y/m/t") .'<br>';
  401.  
  402. //日付と曜日を出力する
  403. $w = date("w");
  404. $week_name = array("日","月","火","水","木","金","土");
  405. print date("Y/m/d") . "($weekname[$w])\n";
  406. ```
  407.  
  408. date関数を使うときは`date_default_timezone_set('Asia/Tokyo');`を必ず入力すること
  409.  
  410. - date関数のパラメータについて
  411.  
  412. | 引数 | 指定内容 |
  413. |:---------------------|------------------------------------------------:|
  414. | Y | 年を4桁で(一般的) |
  415. | y | 年を2桁で |
  416. | n | 月 |
  417. | m | 月で、1桁の場合、前に0をつける |
  418. | F | 月を英語表記 |
  419. | M | 月を英語の3文字表記 |
  420. | j | 日 |
  421. | d | 日で1桁の場合、前に0をつける |
  422. | w | 曜日を数字表記(日曜日=0,土曜日=6) |
  423. | H | 時間を24時間単位で、1桁の場合0を前につける |
  424. | h | 時間を12時間単位で、1桁の場合0を前につける |
  425. | i | 分で、1桁の場合前に0をつける |
  426. | s | 秒で、1桁の場合前に0をつける |
  427.  
  428. ## 特別な変数について
  429. - フォームの送信方法 (get)
  430. getは「URLパラメータ」と呼ばれており、URLの後ろに`?=data`を表示する。
  431. データがURLで丸見えになってしまうので、メールでURLを配信、検索結果のURLを表示などに使う
  432. - フォームの送信方法 (post)
  433. データを隠して飛ばすことができる。
  434. このため、会員登録や問い合わせフォームに使用する。
  435. - $_GET
  436. formのgetの値をそのまま取得する変数
  437. formの値がpostの場合に`$_GET`をするとエラーを吐くので注意
  438. - $_POST
  439. formのmethodの値がpostの時に値を取得する変数
  440. formの値がgetの場合に`$_POST`をするとエラーを吐くので注意
  441. -$_REQUEST
  442. formのmethodの値がgetまたはpostの時に使えるオールマイティーな変数
  443. オールマイティーさ故に危険性がある。
  444. `$_GET`の代わりに`$_REQUEST`を使うのは問題ないが
  445. `$_POST`の代わりに使うとフォームから送信された内容をURLから上書きできるなど、かなり危険
  446. 特別な理由がない限り`$_GETか` `$_POST`を使い分けて使う
  447.  
  448. ## 配列について
  449. - array
  450. 配列はarray関数を用いてデータを格納する。
  451. 配列のデータには予め番号が振っており、0から始まる。
  452. 配列の要素を追加する際は末尾に,を付け忘れてエラーを引き起こすことを防ぐため、基本的には最後の要素にも,をつけて初期化する。
  453. - 要素の追加について
  454. 2つの方法があり、関数を使う方法とブラケット[]を使って挿入する方法がある。
  455. - ブラケット
  456. `配列名[] = 'データ名';`で配列に要素を加える事が出来る。
  457. - array_push
  458. 配列にデータを挿入する関数`array_push(配列名,データ);`
  459. - array_pop
  460. 配列からデータを削除する関数`array_pop(配列名,データ);`
  461. - foreach
  462. ```php
  463. foreach($pref[] as $value){
  464. //処理内容
  465. }
  466. ```
  467. 配列の値を新たに変数宣言したvalueに入れて1回の処理、次の配列の値をvalueに入れて2回めの処理・・・と繰り返していく関数
  468. 利点として絶対に無限にならない、参照スべき変数を限定できる、要素の内容を表す変数名で参照できる。などがある
  469. PHPで配列または連想配列を繰り返す処理であればこれを使うべきである。
  470.  
  471. - 連想配列でのforeach
  472. ```php
  473. <?php
  474. foreach($pref as キー => データ){
  475. //処理内容
  476. }
  477. ?>
  478. ```
  479. prefの連想配列からキーとデータを分解して1つずつ格納し、繰り返し処理を1回繰り返す、次の連想配列をキーとデータに分解し、処理を1回繰り返す・・・と繰り返していく。
  480. この新しく格納したキーとデータはforeachブロックを抜けた後も生き残る。
  481.  
  482. - foreachの参照渡し
  483. foreachを用いた場合、要素は一時的な変数にコピーされるが、&をつけることで、
  484. 要素の参照(関数の中で変数の値を変更すると元の変数の値も同じように変更されること)を行うことが出来る。
  485. ```php
  486. foreach($配列名 = &$データ名){
  487. データ名 = 'black';
  488. }
  489. //すべての要素がblackになる
  490. ```
  491. この参照渡しは余り推奨されていない。ブロックスコープがないため、foreachブロックを抜けた後も値が維持され、
  492. 配列の最後の要素への参照を持ち続けるため、思わぬところで配列の最後の要素を破壊する可能性がある。
  493. そこでforeach参照を使う場合は`unset()`を使って参照を解除すると良い
  494. ```php
  495. foreach($配列名 = &$データ名){
  496. データ名 = 'black';
  497. }
  498. unset($データ名); //参照渡しが消える
  499. ```
  500.  
  501.  
  502. ## 連想配列
  503. 配列のインデックス(0...n)と数字で割り振られていたが、連想配列ではこのインデックスを自由に割り振ることが出来る。
  504. 入力順が保証されている順序付きマップである。
  505. `$data = array('インデックス名(キー)'=>'データ')`で連想配列を構成する
  506. 連想配列を取り出すには`$data['インデックス名(キー)']`のように配列のキー名を入れることでデータを参照できる。
  507. - キーに用いる要素
  508. - 文字列
  509. - 整数
  510. のみだが、下記の3つも使うことが出来る。その場合の条件は
  511. - 論理型(trueは整数の1,falseは整数の0)
  512. - 浮動小数点型(小数点以下は切り捨て、整数で表示)
  513. - null (空文字列)
  514. となる。
  515. - キーの重複
  516. キーが重複している場合は後に定義された要素のデータに上書きされる。
  517. - 連想配列での操作方法
  518. `array_key_exists()` : 配列の中に指定したキーが有るかどうかを検索する
  519. `array_key()` : 配列のキーを全て取り出し、配列として取得することが出来る。
  520. `key()` : 配列からキーを取り出すことができる。`prev`や`next`,`each`などのファンクションと一緒に使う
  521. `ksort,krsort()` : 配列をキーを基準に並び替える
  522.  
  523. ## 繰り返し制御
  524. - for
  525. C言語と同じく`for($i=0; $i<$n $i++){処理内容}`で繰り返しを構成する。
  526. 配列の個数を使ったfor文を作る場合,cont関数を使うことで`for($i=0; i<count($n) i++){処理内容}`よりよいfor文を構成することができる
  527. - while
  528. こちらも同じくC言語と同じく `while(条件){処理内容}` 条件がfalseになるまで繰り返される。
  529. - 制御について
  530. - break
  531. 繰り返し制御や分岐制御などのブロックから抜ける時に使う
  532. 特定の条件時に反復を終わらせたい時に使用する
  533. - continue
  534. 現在の繰り返し処理を途中で修了し、次の繰り返しを行う。 fizz-buzz問題にいいかも
  535.  
  536. ## 条件分岐
  537. - if-else
  538. C言語と同じく`if(条件){処理内容}else{処理内容}`で条件分岐を構成する
  539.  
  540. (わかりづらくなるため推奨はできない)
  541. - trueの省略
  542. ifでの条件を記入する際に出力する値がtrueであれば、`==true`を省略することが出来る
  543. - falseの省略
  544. ifでの条件を記入する際に出力する値がfalseであれば、`==false`を省略し,条件の一番前に!をつけることで省略出来る
  545.  
  546. - switch文
  547. 複雑な分岐を行いたい場合、switch文を使うことでif-else構文を繰り返すよりも綺麗に記述できる。
  548. 変数を格納し、与えられたデータにマッチするcaseに入る。
  549. もし与えられたデータにマッチしなかった場合はdefaultの値になる。
  550. breakがないと次にbreak文があるか、switch文が閉じるまですべて実行される。
  551. ```php
  552. switch ($変数){
  553. case 'データ1':
  554. echo 'テスト1';
  555. break;
  556. case 'データ2':
  557. echo 'テスト2';
  558. break;
  559. case 'データ3':
  560. echo 'テスト3';
  561. break;
  562. case 'データ4':
  563. echo 'テスト2';
  564. break;
  565. default:
  566. echo 'デフォルトですよ';
  567. break;
  568. }
  569. ```
  570.  
  571. - 条件分岐の際のテクニック
  572. - 値が空だった時
  573. `$data==""` よりも`empty($data)`のほうがかっこよくていい
  574. `empty(変数)`は変数の中が空かどうか確かめる関数で、空の時はtrue,入っているときはfalseを出力する
  575. - is_numeric
  576. 数字かどうか判定し、数字であればtrue,数字でなければfalseを出力する。
  577.  
  578.  
  579. ## 便利な関数について
  580. - `mb_convert_kana`
  581. 全角文字を半角文字に変換する。 `mb_convert_kana('文字列','n','文字コード')` nで全角から半角に変換できる。
  582. - `preg_match`
  583. 正規表現が正しく入力されているかを判定する。正規表現にマッチしない場合はfalseを返し、あっている場合はその値を返す
  584. - `header`
  585. webページのヘッダー情報を出力させるための関数。以下の様なことが出来る。
  586. - ページの遷移(主に使われる)
  587. - エラーとしてwebブラウザに認識させる
  588. - ファイルをダウンロードさせる
  589. - webブラウザのキャッシュ機能を無効にする
  590. ページを移動させるときはそれ以降のプログラムを実行させないように`exit()`を合わせて記述する
  591. header関数を使うとたまにエラーを吐く時があるが、これはヘッダーがすでに送信されてしまっているのでヘッダーを変更できなかったという意味で、
  592. webページは内容を送信する直前にヘッダー情報を送信する。そのため内容が送信された後でheaderで送信しようとしても遅いという状態になる
  593. なのでhtm文をかかずに直接phpの文章から始めるとエラーを吐かずに実行できる
  594. - `isset`
  595. 変数が格納されているか(NULLでないか)を調べる関数
  596. 格納されている場合はTRUE、NULLの場合はFALSEを返す
  597. - `rand`
  598. 乱数を生成する関数。`rand(最小の数字,最大の数字)` 最小の数字から最大の数字の範囲で乱数を生成する
  599. - `floor`.`ceil`,`round`
  600. 左から順番に切り捨て、切り上げ、四捨五入である。`round(数値,少数第何位を四捨五入するか);`
  601. - `substr`
  602. `substr(文字列,切り取りはじめる文字, 長さ);` or `substr(文字列,長さ);` で切り取る文字数のはじめは0から始まる。 負の数を指定すると一番最後の文字からスタートする。
  603. - `max`
  604. `max(数字1,数字2)`2つのパラメータを比べて大きい方を返す関数
  605.  
  606. - `var_dump()`
  607. 変数や式などを引数として、その変数や式の中に何のデータが入っているかを確認することが出来る。
  608. 主にデバック用やテスト用で使うと効果的
  609.  
  610. ## 写真のアップロード
  611. - html側の処理
  612. ```html
  613. <form class="" action="sample21.php" method="post" enctype="multipart/form-data">
  614. <p>写真</p>
  615. <input type="file" name="my_img">
  616. <input type="submit" value="送信する">
  617. </form>
  618. ```
  619. formの属性に`enctype="multipart/form-data"`を追加する。
  620. これは文字情報のみのフォームに加えてファイルをそのまま送信することが出来る方式
  621. ファイルを送信する際はmethodが`get`ではなく、`post`でなければならない
  622.  
  623. - php側の処理①
  624. ファイルの取得は`$_FILES`で取得でき、このデータは連想配列で格納されている
  625. | データのキー | データ内容 |
  626. |:---------------------|------------------------------------------------:|
  627. | name | ファイル名 |
  628. | type | ファイルのタイプ |
  629. | tmp_name | 一時的に格納されたファイル名 |
  630. | error | エラー内容を表示 (ない場合は0 |
  631. | size | ファイルサイズ |
  632.  
  633. `tmp_name`についてだが、このファイルアップロードはフォームが送信されると一時的にそのファイルをtmpディレクトリに保存する。
  634. なので、この一時的なフォルダから適切なディレクトリに移動させてwebブラウザに表示させる。
  635. `move_uplode_file(コピー元,コピー先)`でファイルを移動させることが出来る。
  636. ちなみにコピー先のファイルパスについてだが、`$filePath= './image '. $file['name'];`とすると
  637. 本来imageフォルダに入れたいのに入らずに名前に`image+ファイル名`になってしまい、場所がうまく設定できなくなるので、
  638. 必ず`$filePath= './image/ '. $file['name'];` のようにディレクトリの最後には`/`を入れること。
  639. - php側の処理②
  640. ファイルアップロードはセキュリティ的に最も危険なものの1つでウィルスやスクリプトをアップロードされることもあるので気をつけなければならない
  641. そこで拡張子に着目して、画像だけを受け入れたい場合は拡張子がgif,jpg,pngの画像ファイルのみを受け入れれば良い。
  642. ```php
  643. $ext= substr($file['name'],-4); //後ろから4文字切り取る
  644. if($ext == .gif || $ext == .jpg || $ext == .png){
  645. //処理内容
  646. }
  647. ```
  648. このように拡張子を取り出して、画像の拡張子に当てはまっているか判定を行う
  649.  
  650. ## ファイル操作
  651. - ファイルに内容を書き込む
  652. `file_put_contents('ファイルパス','書き込む内容');`
  653. ファイルパスには予めファイルの格納場所を作っておく。
  654. ファイルに内容を書き込めなかった時、falseを返す。
  655. ファイルの内容については簡単に見られてしまう。なので、通常はhtdocsフォルダなどのドキュメントルートと呼ばれる場所よりも外に保存すると良い
  656. `file_put_contents(''../../test/test.txt,'書き込む内容')`このようにドキュメントルートよりも階層を上げて保存すれば良い
  657. - ファイルの内容を取得する
  658. `file_get_contents('ファイルパス/ファイル名');`
  659. テキストから読み込んだ内容は変数に保存するなど自由に利用することが出来る。
  660. - ファイルの内容を取得して出力する
  661. `readfile('ファイルパス/ファイル名')`;
  662. この場合は読み込んだ内容を変数に代入できないので、読み込んだ内容を加工したい場合は`file_get_contents`を使う
  663.  
  664.  
  665. ## PHPブロックをまたぐブロック文
  666. PHPはファイル中のPHPブロックのみをソースコードとして認識して実行するが、
  667. 1つのファイル内であれば、複数のPHPブロックをまたぐ文をつくることができ、処理される。
  668. つまり、1度、PHPブロックを抜け、HTMLコードが交じる場合でも、if文の構文ブロックは継続されている。
  669. ```php
  670. <?php
  671. if(isset($データ)){
  672. ?>
  673. <p><?php echo $data;</p>
  674. <?php
  675. }
  676. ?>
  677. //わかりづらいが、 ifのphpブロックを閉じた後,htmlがあり、その後またphpブロックで}をやっている。
  678. //このような文になっても正しく実行される
  679. ```
  680. このようなhtmlをまたぐコードには`{}`だけでなく、`:`や、endifなどを用いる。
  681. これらはPHP文だけでは使うことはないが、htmlとの混合は可読性を高めるために用いられる。
  682.  
  683. ```php
  684. <?php if ($value) : ?>
  685. <P> このメッセージは$valueがtrueの時に表示される </p>
  686. <?php else : ?>
  687. <p> このメッセージは$valueがfalseの時に表示される</p>
  688. <?php endif; ?>
  689. ```
  690. ## requireとrequire_onece
  691. - requireとは
  692. 別のファイルに記述されたphpファイルを読み込むための関数。
  693. 読み込む対象のファイルがない場合、Fatal errorになり実行が終了する。
  694. 名前空間が定義されていないファイルを読み込んだ時読み込んだファイルに定義されているクラスはグローバルとなり、
  695. 読み込んだ先でも利用することが出来る。
  696. また、読み込むファイルで何らかの処理や出力をしている場合は読み込んだ時点で実行される
  697.  
  698. - require と require_onceの違い
  699. require_onceは一度だけrequireをする関数で、ファイルが既に読みこまれている場合は再読み込みをしない。
  700. 同じファイルが何回も読み込まれると関数の再定義などが行われ、エラーの原因となる。また、変数が再代入されて値が変わったりすることもあるので
  701. これを起こさないためにもrequire_onceを使うと良い
  702.  
  703. -include と include_once
  704. これもrequireとrequire_onceと同じ挙動をするのだが、明らかな違いとして、ファイルが存在しなかった時、Fatalエラーではなく、警告を出して実行する
  705.  
  706. ## 関数
  707. - 関数の基本
  708. ```php
  709. function 関数名(引数,・・・){
  710. //関数の中身
  711. }
  712. ```
  713. このように定義された関数は名前空間を定義していない場合はグローバルスコープに定義される。
  714. どのような型でも渡す事ができ、どのような型でも返すことが出来る。
  715. PHPに標準で備わっている関数との名前の衝突に注意。
  716. - 引数のデフォルト値
  717. 関数の引数にデフォルト値を与えることが出来る。
  718. 引数にすることが出来るのは定数値のみとなっており、デフォルト値に演算結果を代入はできない。
  719. ```php
  720. function hello($name,$greeting = 'Hello!'){
  721. echo $greeting,$name ,PHP_EOL;
  722. }
  723. hello('Bob','Good morning'); // Good morning ! Bob
  724. hello('Tom'); // Hello! Tom
  725. ```
  726. 引数にデフォルト値を与えると、呼び出す際に省略すると、デフォルト値が出力される。
  727. また、呼び出す際に、引数をちゃんと入れてやるとデフォルト値から変更されて出力される。
  728. デフォルトを持つ引数は、持たない引数よりも後に定義しなければならない。
  729.  
  730. - タイプヒンティング
  731. 引数に渡されるべき値を特定のクラスまたは配列(array)に限定することが出来る。
  732. スカラー型(in,string,boolなど)には使えない。
  733. もし設定した場合、関数を呼び出す際にちゃんとした型の変数を入れないとFatal errorになり、実行が中断される。
  734. ```php
  735. function 関数名 (array $変数名){ //タイプヒンティング
  736. //処理内容
  737. }
  738.  
  739. $array = array(1,2,3,);
  740. 関数名($array) //ちゃんと実行される
  741. 関数名(1) //配列ではないので、エラーが起こる
  742. ```
  743.  
  744. - 可変関数
  745. 関数の名前を変数として格納して、それを呼び出して関数として使う方法
  746. ```php
  747. function 関数名1($変数名1) {
  748. if(function_exists($変数名){
  749. $name(); //可変関数での呼び出し
  750. }
  751. }
  752. function foo(){
  753. echo 'foo called',PHP_EOL;
  754. }
  755.  
  756. 関数名1('foo'); //関数fooを呼び出す
  757. ```
  758.  
  759. - 無名関数
  760. 名前の無い関数。 変数に関数を代入する事もできる。
  761. ```php
  762. $add = function($v1,$v2){
  763. return $v1 + $v2;
  764. }
  765. //関数の呼び出し
  766. echo $add();
  767. ```
  768.  
  769. - クロージャー
  770. 関数の中に関数を作成して関数で使用していた値を継承して中の関数で操作すること。
  771. 間違った例)
  772. ```PHP
  773. function test(){
  774. $hello = "hello world";
  775. $myFunc = function(){
  776. echo($hello);
  777. }
  778. }
  779. //エラーを吐く
  780. ```
  781. この場合、無名関数内では無名関数外の変数は使えないので`$hello`に値が入らず、エラーが出てしまう。
  782. そこで、`use`を使って無名関数外のtest()の値を使って無名関数の操作をする。
  783.  
  784. ```php
  785. function test(){
  786. $hello = "hello world";
  787. $myFunc = function() use ($hello);{
  788. echo($hello);
  789. }
  790. }
  791. //hello world
  792. ```
  793. 無名関数の中の値を外の関数で使いたい場合は&を使って参照渡しをする
  794. ```php
  795. function method() {
  796. $hello = 'hello';
  797. $closure = function() use (&$hello){ //参照渡し
  798. $hello = 'goodby';
  799. echo "${hello}! world!", PHP_EOL;
  800. };
  801. $closure(); // goodby! world!
  802. echo $hello; // goodby
  803. }
  804. method();
  805. ```
  806.  
  807. - クロージャーの利点
  808. 1. 関数の中に関数を作って操作するので、グローバル変数の宣言を減らすことが出来る。
  809. 2. 関数を内包化するので外部からアクセスできないようになる。 他で同じ変数を使っても値が干渉しない
  810.  
  811. ## PHPでのオブジェクト指向
  812. - クラスの定義
  813. ```php
  814. class クラス名{
  815. クラスの実装
  816. }
  817. ```
  818.  
  819. - インスタンスの記述と生成
  820. work()メソッドを持った従業員クラスEmplyeeクラスを作成したとする。
  821. ```php
  822. class Employee{
  823. public function work(){
  824. echo '働いています' ,PHP_EOL;
  825. }
  826. }
  827. ```
  828. クラスを使うときはnew 演算子を使ってクラスをインスタンス化(実際に値を入れて生成すること)する。
  829. メソッドの呼び出しには`->`アロー演算子を使って呼び出す。
  830. ```php
  831. $yamada = new Employee();
  832. $yamada->work();
  833. $suzuki = clone $yamada;
  834. ```
  835. 同じクラスを使ってインスタンスを生成するときは`clone`を使って複製する。
  836. newによって生成されたオブジェクトは`unset()`で開放できる。
  837.  
  838. - アクセス修飾子
  839. メソッドやプロパティ(メンバ変数)がどこからアクセス可能かを表す修飾子
  840. - public
  841. クラスの外部から呼び出し、参照ができる。
  842. - private
  843. 自分のクラスの内側のみからの参照、呼び出しができる。 クラス内でのみデータを使うときに使う
  844. - protected
  845. 自分のクラスの内側または自分のクラスを継承したクラスの内側ののみ参照、呼び出しができる。
  846. ```php
  847. class Employee{
  848. public name; //従業員の名前
  849. private $state = '働いている'; //従業員の状態を表す
  850. public function work(){
  851. echo $state;
  852. }
  853. }
  854.  
  855. $yamada = new Employee();
  856. $yamada->name = '山田';
  857. echo $yamada->state,$yamada->name, 'さん'; //stateがprivateに設定されているため、呼び出すことができず、エラー
  858. yamada->work(); //workメソッドはpublicなので $stateをメソッド内で処理して呼び出すことが出来る。
  859. ```
  860.  
  861. - $this
  862. オブジェクトのインスタンス化をすると、クラス内のメソッドで利用できる$thisという変数が定義される。
  863. $thisはクラス内で使われ、自分自身のオブジェクトの参照を意味する。
  864.  
  865. ```php
  866. class Employee{
  867. public name; //従業員の名前
  868. private $state = '働いている'; //従業員の状態を表す
  869. public function getState()
  870. {
  871. return $this->$state; //$thisは呼ばれたインスタンスを指す
  872. }
  873. public function setState($state)
  874. {
  875. $this ->state =$state;
  876. }
  877. public function work(){
  878. echo $state;
  879. }
  880. }
  881.  
  882. $yamada = new Employee();
  883. $yamada->name = 'やまだ';
  884. $yamada->setState('休憩している');
  885. $yamada->name,'さんは', $yamada->getState(),PHP_EOL;//山田さんは休憩していると出力される
  886. ```
  887. - static~~おじさん~~プロパティ
  888. 静的なプロパティで、プロパティ宣言時にstaticをつけると
  889. そのプロパティはクラスがインスタンス化されてなくても呼び出すことが出来る。
  890. staticを呼び出すときは`クラス名::$プロパティ名`
  891.  
  892. ```php
  893. class Employee
  894. {
  895. public $name;
  896. public static $company = '香川高専';
  897. }
  898.  
  899. echo '従業員はみんな、', Employee::$comperny, 'に努めています', PHP_EOL; //香川高専に勤めていると出る。
  900. ```
  901.  
  902. - self
  903. クラスの内部でのstaticプロパティを使ってメソッドを作る場合、$thisではなくselfを使ってアクセスする。
  904. $thisとの違いはインスタンス化したデータを指すのか、内部で生成したデータを指すのかのちがいである。
  905. ```php
  906. class Employee{
  907. public static $company = '香川高専';
  908.  
  909. public static function getCompany(){
  910. return self::$company;
  911. }
  912. public static function setCompany($value){
  913. self::company = $value;
  914. }
  915. }
  916.  
  917. echo Employee::getCompany(),PHP_EOL; //社名の出力
  918. Employee::setCompany('技術評論社'); //社名を変えるとき
  919. ```
  920.  
  921. - コンストラクタとデストラクタ
  922. - コンストラクタ
  923. クラスのインスタンスが作られるタイミングで自動的に呼ばれるメソッド
  924. インスタンスを生成するときに、無駄な入力を避けることが出来る。
  925. `function __construct(){//処理}`で使うことが出来る。
  926. - デストラクタ
  927. クラスのインスタンスが消されるタイミングで自動的に呼ばれるメソッド
  928. ```php
  929. class Employee{
  930. public name; //従業員の名前
  931. private $state = '働いている'; //従業員の状態を表す
  932. public function __construct($name){ //インスタンスが生成された時に名前を格納する
  933. $this->name = $name;
  934. }
  935. public function getState()
  936. {
  937. return $this->$state;
  938. }
  939. public function setState($state)
  940. {
  941. $this ->state =$state;
  942. }
  943. public function work(){
  944. echo $state;
  945. }
  946. }
  947.  
  948. $yamada = new Employee('山田');
  949. ```
  950. コンストラクタに入れる場合は外部で呼び出すことはなくなるのでプロパティを`private`にする。
  951.  
  952. - 継承
  953. あるメソッドやプロパティを引き継いで新しいクラスを定義すること。
  954. 継承されたクラスを親クラス、継承したクラスを子クラスという。
  955. 子クラスではプロパティやメソッドをすべて引き継ぐ。
  956. 引き継いだもののうち、publicまたはprotectedなものに限定して内部からアクセスすることが出来る
  957. 外部からのアクセスはpublicに限定される
  958. PHPでは多重継承(1つの親クラスと外の親クラスを継承すること)は許されておらず、継承する親クラスは1つだけ
  959. ```php
  960. class Programmer extends Employee{ //Programmerクラスは Employeeクラスを継承する
  961. }
  962. ```
  963. - オーバーライド
  964. 親クラスに定義したメソッドやプロパティを子クラスに同じ名前で定義すると、
  965. 子クラスでの実装が上書きされ、別の動きを実装する。
  966. ```php
  967. //Employeeクラスの子クラス
  968. class Programmer extends Employee
  969. {
  970. //親クラスのworkメソッドをオーバーライド
  971. public function work(){
  972. echo 'プログラムを書いています',PHP_EOL;
  973. }
  974. }
  975. ```
  976. オーバーライドしたメソッドは親クラスのメソッドと引数が違ってはいけない。
  977. コンストラクタはインスタンスを構築するための特別なメソッドなので、親クラスのコンストラクタと違っても良い
  978.  
  979. - parent
  980. 親クラスを表すワードで、親のクラスを呼ぶときに使う。
  981. selfと同じく`parent::`
  982. ```php
  983. //親クラスのコンストラクタを呼び出したい時
  984. class Programmer extends Employee
  985. {
  986. public function __construct($name,$type){
  987. parent::__construct($name,$type); //親クラスのコンストラクタを呼び出す
  988. }
  989. }
  990. ```
  991.  
  992. - final
  993. finalキーワードをつけて宣言すると、そのメソッドは継承された子クラスでオーバーライドできなくなる
  994.  
  995. ```php
  996. class Employee {
  997. public $salary = 20;
  998. public final function getSalary
  999. {
  1000. return $this->salary;
  1001. }
  1002. }
  1003. class Programmer extend Employee{
  1004. //メソッドをオーバーライドするとエラーを吐く
  1005. public function getSalary()
  1006. {
  1007. return $this->salary *2;
  1008. }
  1009. }
  1010. ```
  1011.  
  1012. - 標準クラス
  1013. プロパティやメソッドを持たない`stdClass`と呼ばれる標準クラスがある。
  1014. 未定義のインスタンスプロパティを新たに作成できる。
  1015. ```php
  1016. $obj = new stdClass(); //空のクラスを作成
  1017. $obj->some_member = 1; //クラスの中にプロパティを生成(初期化)
  1018. ```
  1019.  
  1020. - 抽象クラス
  1021. 共通の機能を抽象的な親クラスで定義し、特有の機能は個々の子クラスでそれぞれ実装させたい場合に実装する
  1022. 抽象クラスではメソッドの実装はせず、宣言するのみにする。
  1023. 抽象クラスはabstructメソッド以外の実態のあるメソッドを定義することもできる。
  1024. その場合はabstructキーワードを付けず、普通のメソッドと同様に定義する。
  1025. 抽象クラスはそれ自体をインスタンス化することはできない。
  1026. 必ずその抽象クラスを継承したクラスをインスタンス化する必要がある
  1027. ```php
  1028. abstract クラス名
  1029. {
  1030. abstract public function work();
  1031. abstract public function state();
  1032. public function メソッド名
  1033. }
  1034. class Programmer extends クラス名
  1035. {
  1036. public function work()
  1037. {
  1038.  
  1039. }
  1040. }
  1041. //抽象クラスのstate()メソッドを子クラスで使っていないのでエラーが起こる
  1042. ```
  1043.  
  1044. - インターフェース
  1045. 複数の異なるクラスに共通の機能を実装するために、その実体を定義することなく指定する仕組み
  1046. interfaceを用いると特定のオブジェクトが特定の機能を有することを保証する。
  1047. interfaceのメソッドは`public`でなければならない
  1048. ```php
  1049. //インターフェースの定義
  1050. interface インターフェース名
  1051. {
  1052. インターフェースの定義;
  1053. }
  1054. ```
  1055. インターフェースでは実態のあるメソッドを定義できない。
  1056. ```php
  1057. //インターフェースの利用
  1058. class クラス名 implements インターフェース名,・・・
  1059. {
  1060. クラスの定義
  1061. }
  1062. ```
  1063.  
  1064. 実装例)
  1065. ```php
  1066. interface Reader
  1067. {
  1068. public function read();
  1069. }
  1070.  
  1071. interface Writer
  1072. {
  1073. public function write($value);
  1074. }
  1075.  
  1076. class Configure implements Reader,Writer
  1077. {
  1078. public function write($value)
  1079. {
  1080. //書き込みの処理
  1081. }
  1082. public function read();
  1083. {
  1084. //読み込みの処理
  1085. }
  1086. }
  1087. ```
  1088. インターフェースを取り込んでいる状態でインターフェース内のメソッドを実装しないとエラーを吐く
  1089.  
  1090. - インターフェースのチェック
  1091. タイプヒンティングを使ってインターフェースのメソッドの引数が正しく使われているか判定する
  1092. ```
  1093. interface MyInterface
  1094. {
  1095. public function メソッド名($データ名);
  1096. }
  1097. class クラス名
  1098. {
  1099. public function メソッド名(MyInterface $データ名){
  1100.  
  1101. }
  1102. }
  1103. ```
  1104.  
  1105. - マジックメソッド
  1106. コンストラクタ`__constract`のような特定の条件で自動的に呼び出されるメソッド。
  1107. どんなクラスでも定義でき、定義されている場合は必要に応じて呼び出される。
  1108. - オーバロード
  1109. 特定の処理がクラスまたはオブジェクトに施された時のデフォルトの挙動を上書きする機能
  1110. クラスやオブジェクトのアクセス不可能なプロパティやメソッドが参照された時、通常エラーが発生する挙動を
  1111. `__get()`,`__set()`,`__isset()`,`__unset()`,`__call()`,`__callStatic()`のマジックメソッドを使ってエラーの挙動を上書きできる。
  1112. - `__get()`
  1113. アクセス不可能なプロパティを取得するときに呼び出す
  1114. - `__set()`
  1115. アクセス不可能なプロパティに代入するときに呼び出す
  1116. - `__isset()`
  1117. アクセス不可能なプロパティに対してisset()かempty()を実行した時に呼び出す
  1118. - `__unset()`
  1119. アクセス不可能なプロパティに対してunset()を実行した時に呼び出す
  1120. - `__call()`
  1121. アクセス不能なメソッドを呼び出す時に呼び出すときに呼び出す
  1122. - `__callStatic()`
  1123. アクセス不可能なメソッドをstaticに呼び出すときに呼び出す
  1124.  
  1125. - 遅延静的束縛
  1126. 子クラスでインスタンスを生成したのにもかかわらず、メソッドを実行すると`self`を使っているために継承された親クラスの静的メソッドで実行されてしまう。
  1127. これを防ぐためにstaticを使ってこクラスで実行してもらう方法
  1128. 例)
  1129. ```php
  1130. class Foo {
  1131. public function helloGateway(){
  1132. self::hello();
  1133. }
  1134. public function hello(){
  1135. echo __CLASS__,'hello',PHP_EOL;
  1136. }
  1137. }
  1138.  
  1139. class Bar extends Foo{
  1140. public static function hello(){
  1141. echo __CLASS__ ,'hello',PHP_EOL;
  1142. }
  1143.  
  1144. }
  1145. $bar = new Bar();
  1146. $bar -> helloGateway(); // Foo hello が出てきてしまう。
  1147. ```
  1148.  
  1149. この例の場合、`self`を使っているため親クラスの`hello()`メソッドを実行してしまった。
  1150. このselfをstaticに変えて実行すると
  1151. ```php
  1152. class Foo {
  1153. public function helloGateway(){
  1154. static::hello(); //selfからstaticに変更した
  1155. }
  1156. public function hello(){
  1157. echo __CLASS__,'hello',PHP_EOL;
  1158. }
  1159. }
  1160.  
  1161. class Bar extends Foo{
  1162. public static function hello(){
  1163. echo __CLASS__ ,'hello',PHP_EOL;
  1164. }
  1165.  
  1166. }
  1167. $bar = new Bar();
  1168. $bar -> helloGateway(); // bar hello 正常に動作した
  1169. ```
  1170.  
  1171. - オートロード
  1172. 自動的にそのクラスが定義されているファイルを読み込む機能
  1173. 定義されていないクラスを使おうとした時に、指定されたオートロード関数が呼び出される。
  1174. `__autoload()`はクラス名を引数として渡してそのクラスファイルを読み込むメソッドを返す
  1175. require_onceでファイルを読み込むよりオートロードを使ってファイルを読み込むほうがモダンである(らしい)
  1176. - `__autoload()`関数を使用したファイル内のクラスを呼び出すコード
  1177. ```php
  1178. function __autoload($name) //クラス名を引数として取得する
  1179. {
  1180. $filename = $name . 'php';
  1181. if(is_readable($filename)){
  1182. require $filename; //ファイルの読み込み
  1183. }
  1184. }
  1185.  
  1186. $obj = new Foo();
  1187. ```
  1188. `__autoload()`を呼び出した後にそのファイルの中に呼びだそうとしているクラスがない場合、エラーを吐く
  1189.  
  1190. - `sql_autoload_register()`関数
  1191. `__autoload()`には2つの問題がある。
  1192. 1. グローバル関数でなければならない
  1193. 2. 処理を1つしか登録できない
  1194. あるファイルでオートロードの仕組みを使い、それを別のオートロードの仕組みを使ったスクリプトから読み込みたいということはできない。
  1195. それを解決するのが `sql_autoload_register()`。 出来ることは2つある。
  1196. 1. オートロードに使われる処理をコールバック関数の形式で指定できる
  1197. 2. クラスを複数のコールバック関数で登録できる
  1198. 複数のコールバック関数が登録されている場合、そのクラスが定義されるまでコールバック関数を呼び出し続ける。
  1199. `sql_autoload_register()`で登録したクラス、関数を格納し、新しい定義されていないクラスを呼び出すと、それらの登録したクラスで処理し、
  1200. 結果を出力する
  1201. ```php
  1202. <?php
  1203. function __autoload($name)
  1204. {
  1205. echo '__autoload(' . $name . ') was called.', PHP_EOL;
  1206. }
  1207. class Hoge
  1208. {
  1209. public static function load($name)
  1210. {
  1211. echo 'Hoge::load(' . $name . ') was called.', PHP_EOL;
  1212. }
  1213. }
  1214. class Bar
  1215. {
  1216. public function load($name)
  1217. {
  1218. echo '$bar->load(' . $name . ') was called.', PHP_EOL;
  1219. $file = $name . '.php';
  1220. if (is_readable($file)) {
  1221. require_once $file;
  1222. }
  1223. }
  1224. }
  1225. function load($name)
  1226. {
  1227. echo 'load(' . $name . ') was called.', PHP_EOL;
  1228. }
  1229. spl_autoload_register('__autoload');
  1230. spl_autoload_register('Hoge::load');
  1231. $bar = new Bar();
  1232. spl_autoload_register(array($bar, 'load'));
  1233. spl_autoload_register('load');
  1234. $foo = new Foo();
  1235. /* 出力:
  1236. __autoload(Foo) was called.
  1237. Hoge::load(Foo) was called.
  1238. $bar->load(Foo) was called.
  1239. */
  1240. ?>
  1241. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement