PHPの基礎の基礎の基礎

#前書き

筆者自体PHP初心者ですが、コメント欄と併用してしっかりとした基礎をまとめているシートにできると思いますので、玄人の方は、間違っていたらコメント欄へご指摘願います。

##自己紹介

Twitter [@konojunya](http://twitter.com/konojunya) 

じゅんじゅんというニックネームで、関西を拠点に活動しているフロントエンドエンジニアです。

HAL大阪の新2回生です👍 (2016.4.18現在)

よくstart up系イベントに行くので、大阪らへんの方は会いましょう！

では、早速。

#初めてのPHP

順番にPHPを攻略していきたいと思います。

##環境
筆者はPHP v5.5でやっています。
phpをインストールして、Webサーバ(Apacheなど)にあげれば動きます。
ローカル開発環境は
[vagrantを用いたPHPの環境構築](http://qiita.com/tiwu_official/items/f135e6b6fbbe3ec6aa54)

などをご覧ください。

PHPは、`.php`ファイルに

```index.php
<?php

//insert code...

?>
```

で、書くことができます。

早速PHPに入っていきたいと思います。

##変数

PHPでは、型の宣言がなくJavaScriptのようなvarもありません。（フレームワークとかは知らん！！）

最初に`$`をつけて変数を宣言します。

```index.php
$msg = "Hello World";
echo $msg;
```

`$msg`という変数に、文字列の`"Hello World"`を代入した形です。

`echo`を使う事で、変数を展開してWEBページへ出力してくれます。

この時の`$msg`の型は*String型*ですね。

PHPが扱う型には以下のようなものがあります

- 文字列を扱う
    - string
- 数値を扱う
    - int
    - float
- 真偽値（true / false）
    - boolean
- 配列
- オブジェクト
- null(何もない)

型などは`var_dump`などを用いて簡単に確認できます

```index.php
$msg = "Hello World";
var_dump($msg);
```

##定数

先ほどの変数は、後からでも変更可能な箱でした。

定数は、一度定義すると後から変えることのできないものになっています。

定数を定義するときは`define`というキーワードを使います。

```index.php
define("PI",3.141592);

echo PI;
```

この時に注意したいのが、`$`が**いらない**ということと

定数を定義するときは**全部大文字**にするのが、デファクトスタンダードだということです。

この`PI`は定数なので、後から

```index.php
PI = 3;
```

のような~~ゆとり教育は許さない~~ということです。

なお、定数には幾つか最初から定義されているものがあります。

```index.php
var_dump(__LINE__); //今の行数
var_dump(__FILE__); //そのファイルまでのパス
var_dump(__DIR__);  //ディレクトリのパス
```

##文字列

文字列は`"ダブルクォーテーション"`か`'シングルクォーテーション'`で囲むことで、扱うことができます。

この差は、そのクォーテーションの中で、変数が展開できるか否かです。

```index.php
$name = "konojunya";

echo "My name is $name";
```
こうすることで、ダブルクォーテーションの中で、変数を展開できます。

なお、変数の展開は、もっとわかりやすく書くこともできます。

```index.php
$name = "konojunya";

echo "My name is $name";
echo "My name is ${name}";
echo "My name is {$name}";
```

これはすべて同じ出力結果になります。

では、シングルじゃないとダメな時どうするのか。

##文字列の連結

変数を展開したものと、文字列を連結させれば、同じことができます。

```index.php
$name = "konojunya";

echo 'My name is '.$name;
```

PHPでは`.(ドット)`　を使うことで、連結ができます。

##配列

似たようなデータを一つの名前で管理したい時に使えるのが、配列です。

```index.php
$colors = array("red","blue","yellow");
```

PHP5.4以上なら、`[]`で置き換えることができます。

```index.php
$colors = ["red","blue","yellow"];
```

この場合、例えばredを出したい場合

```index.php
echo $colors[0];
```

先頭から、0..1..2..3..と続いているので、redは0番目。

大カッコに添字で、取り出せます。

これでは、データを取り出しにくいので、先人は名前をつける機能をつけてくれました。

##連想配列

書き方を見てみましょう

```index.php
$members = [
  "jun" => "konojunya",
  "hoge" => "hogehogeo"
];
```

取り出し方も簡単になっています。

```index.php
echo $members["jun"]; //konojunya
```

##ループ＆条件分岐

ループ（for,while）と条件分岐(if,switch)は、他の言語と変わらないので省きます。

PHPでは、HTMLに埋め込むことがよくあると思います。

そこで

```index.php
?><ul>
  <?php for($i=0;$i<10;$i++){ ?>
  <li><?php echo $i ?></li>
  <?php } ?>
</ul>
```

と書くのは、見づらいので、**コロン構文**というものを使い書き換えることができます。

```index.php
?><ul>
  <?php for($i=0;$i<10;$i++): ?>
  <li><?php echo $i ?></li>
  <?php endfor; ?>
</ul>
```

初めの波カッコを`:`に変えて、終わりの波カッコを`end〇〇`に置き換えることができます。

##関数

関数は、複数の処理を一つにまとめてくれるものです。

関数は、**引数**と**戻り値**が存在します。

まず単純に`Hello World`を`echo`するhello関数を作りましょう

```index.php
function hello(){
  echo "Hello World";
}

hello(); //Hello World
```

その他の言語と同じですね。`function`を使って、関数を定義します。

では、名前を引数にとった場合どうなるか。

```index.php
function hello($name){
  echo "Hello ${name}";
}

hello("junya"); // Hello junya
```

`junya`を`$name`に代入して、使っています。

なお、この`$name`はこのhello関数の中だけで使える**ローカル変数**になります。

この関数の外から`$name`にアクセスはできません。

戻り値を使った場合はどうなるでしょうか。

```index.php
function hello($name){
  return "Hello ${name}";
}

echo hello("junya"); // Hello junya
```

`return`というキーワードで、その関数から値を返すことができます。

##クラス

クラスというのは、設計図とよく言われています。

何回も同じようなものが登場する場合は、このクラスを使った方が良いとされています。

書き方を見てみましょう。

では、ユーザーを管理する`User`クラスを作りましょう。

```index.php
class User{
  //property
  public $name;
  
  //constructor
  public function __construct($name){
    $this->name = $name;
  }

  //method
  public function sayName(){
    echo "Hello $this->name !";
  }
}
```

クラス名は**最初が大文字**という決まりがあるので注意しましょう。

クラスは、`property`、`constructor`、`method`を持ちます。

`property`は、そのクラスが持つ値です。
`constructor`は、そのクラスがインスタンス化される時に絶対呼ばれるものです。
`method`は、そのクラスが持っている関数だと思ってください。

このUserクラスは、`$name`というプロパティを持っています。

インスタンスする際に、constructorによってその$nameに引数で入ってきたものが代入されます。

インスタンスするには、`new`というキーワードを使います。

```index.php
$junya = new User("junya");
```

これで、`$junya`は、自分の名前や、sayName()が使えます。

自分の名前にアクセスするには

```index.php
echo $junya->name;
```

sayNameを使えば

```index.php
$junya->sayName();
```

という風に使えます。

##クラスの継承

クラスを作る際に、さっきのクラスに似てるけどここで差別化してるし、、

ちょっと違う挙動をさせたい。。

みたいなものがあったとして、そのクラスをまた１から書くのはあまり、よろしくないです。

そんな時に、前作ったクラスを引き継いで新しいものを作る**クラスの継承**が便利でしょう。

さっき作ったUserクラスを継承させて、SpecialUserというクラスを作ります。


```index.php
class User {
  public $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function saySpecialHi(){
    echo "I am Special $this->name";
  }
}
```

SpecialUserクラスを作るのに、Userクラスを継承するには、

`extends`を使います。

これで、SpecialUserクラスは独自のメソッドも使えますが、Userクラスのものも使えます。

SpecialUserをインスタンスする際も

```index.php
$junya = new SpecialUser("junya");
```

で、大丈夫です。

この時できたSpecialUserはUserを継承しているので、

SpecialUserが子クラス。Userが親クラスと言います。

### over ride

ここで、Userクラスにある`sayHi`メソッドをSpecialUserクラスでも書くとどうなるのでしょうか。

```index.php
class User {
  public $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function sayHi(){
    echo "I am Special $this->name";
  }
}
```

このようにすると

```index.php
$junya = User("junya"); //Userクラス
$kono = SpecialUser("kono"); //SPUserクラス

$junya->sayHi(); // Hello junya
$kono->sayHi(); // I am Special kono
```

同じメソッドなのに、スペシャルなkonoくんとパンピなjunyaでは挙動が違います。

これを**over ride**と言います。

単純に「上書き」です。

このover ride便利ですが、して欲しくない場合もあると思います。

この時に使えるのが`final`というキーワードです。

さっきのUserクラスのsayHiをfinalを使って、over rideできないようにしましょう。

```index.php
class User {
  public $name;

  public function __construct($name){
    $this->name = $name;
  }

  final public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function sayHi(){
    echo "I am Special $this->name";
  }
}
```

Userクラスに`final`をつけることで、SpecialUserのsayHiメソッドはover rideに失敗するので、

エラーになると思います。

そろそろアクセス権を見ていきたい時期ですね。

##アクセス権

今まで、クラスの中に出てくる`public`ですね。これがアクセス権です。

アクセス権には次の３つがあります。

1. public
2. protected
3. private

- public

publicは、***全域からアクセスが可能***

- protected

protectedは、***親子クラスとクラス内からのみアクセス可能***

- private

privateは、***クラス内からのみアクセス可能***

に、なっています。

```index.php
class User {
  public $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function sayHi(){
    echo "I am Special $this->name";
  }
}
```

この状態では、Userクラスの`$name`はpublicで宣言しているため

インスタンス化した`$junya`からも`$junya->name`でアクセスできました。

これを

```index.php
class User {
  private $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function sayHi(){
    echo "Hello $this->name !";
  }
}

class SpecialUser extends User {
  public function sayHi(){
    echo "I am Special $this->name";
  }
}
```

privateにすると、クラス内からはアクセスできますが、そのほかからはアクセスできないので、

SpecialUserの`$this->name`もアクセスできませんし、`$junya->name`もアクセスできません。

SpecialUserは許可したい、、、、時は、privateをprotectedにしましょう！

##staticについて

staticは、クラスをインスタンス化しなくても、使えるようにする仕組みです。

```index.php
class User {
  public $name;
  public static $count = 0;
  public function __construct($name){
    $this->name = $name;
    self::$count++;
  }
  public static function getMes(){
    echo "Hello from static!";
  }
}

User::getMes();
$tom = new User("tom");
echo User::$count; //1
```

staticをつけたメソッドやプロパティは`そのクラス名::メソッドなど`でアクセスできます。

Userクラスの中で、自分自身を参照したい場合。

その時は`self`を使って、`self::$count`のように使っていますね。

##抽象クラス

```index.php
abstract class BaseUser{ //抽象クラス
  public $name;
  abstract public function sayHi();
}

class User extends BaseUser{
  public function sayHi(){
    echo "Hello";
  }
}
```

宣言する際に`abstract`というキーワードをつけてあげます。

抽象クラスは、それ自体をインスタンス化することはできません。

抽象クラスのメソッドは、その拡張クラスに実装しないといけないという決まりをもたせることができます。

実装してない場合、エラーになります。

アクセス権なども、抽象クラスに合わせないといけません。

##interface

さて、抽象クラスと似ているものに`interface`というものがあります。

```index.php
interface sayHi {
  public function sayHi(); //interfaceは絶対public
}
interface sayHello{
  public function sayHello();
}

class User implements sayHi,sayHello {
  public function sayHi(){
    echo "Hi!";
  }
  public function sayHello(){
    echo "hello";
  }
}
```

classは、大きくそのものの設計図なのに対して、interfaceはもっと細かい部品部品で見たものという認識をしています。（間違っていたらコメントください。）

interfaceで宣言したものも、クラスの中で実装していかないといけません。

ですが、今までの`extends`ではなく、`implements`というものを使います。

ここで、大きな違いが、**抽象クラスは1つだけど、interfaceは複数同時に追加できる**という点です。

なので、より細かい部品（歩く、話す）を作るのにはinterfaceを使い、大部分（人間、生物、車など）を定義するのにクラスを使うのかなぁという具合です。

##外部ファイルの読み込み

では、そろそろ長くなりすぎていませんか？

ファイルを分けて見やすくしていきましょう。

新しく、functions.phpを作ります。

functions.phpには以下の内容があるとします。

```functions.php
function hello(){
  echo "Hello";
}

.......
```

関数を定義している`functions.php`を`index.php`で読み込みましょう。

```index.php
require "functions.php"; // どれか
require_once "functions.php";
include "functions.php";
include_once "functions.php";
```

この4つでファイルの読み込みができます。

requireとincludeの違いは、

requireは、ファイル名が違うかったりするとエラーが出ます。

includeは、無視してそのまま進みます。

???_onceは、一度読み込んでいればスルー。読んでいなければ読み込むものです。

```index.php
require "functions.php";

hello();
```

ライブラリなどもこの方法で、読み込むことができますね。

では、自分の作ったものと他人の作ったものの名前が同じ場合どうすればいいでしょうか。

##名前空間

それを解決してくれるのが、**名前空間**です。

まずは、使ってみましょう。

functions.phpの最初に

```functions.php
namespace junya\functions;

function hello(){
  echo "Hello";
}
```

のように書きます。

注意しなければならないのが、名前空間の宣言は一番最初にしないといけません。

これをindex.phpで使ってみましょう

```index.php
// use konojunya\functions as func;
// use konojunya\functions
```

useを使うことで、その名前空間を使うことができます。

なお、 `use konojunya\functions as func`はkonojunya\functionsにfuncという名前をつけてこの中では使うよというものです。

`use konojunya\functions`だと、一番最後のfunctionsを取ってくれます。

この名前空間をどう使うのか。

```index.php
require "functions.php";
use konojunya\functions as func;

func\hello();
```

このように、その関数の最初に、useで指定した文字をつけます。

これで、ライブラリなどとの衝突を避けることができます。


##例外処理

そろそろ終盤です。

最後に、例外の処理方法について、まとめたいと思います。

例えば、割り算をする`division()`という関数を作りたいと思います。

```index.php
function division($num1,$num2){
  return $num1 / $num2;
}

echo division(4,2); // 2
```

この関数の弱点は、`$num2`に0が入った場合です。

学校では

```index.php
function division($num1,$num2){
  if($num2 === 0){
    return "２つ目に0は指定できません。";
  }else{
    return $num1 / $num2;
  }
}
```

こんな風にして、まず0が来たらifで弾く。みたいな感じです。

これは、例外処理の書き方で次のように書き直せます。

```index.php
function division($num1,$num2){
  try {
    if($b === 0){
      throw new Exception("can not use 0");
    }
    return $num1 / $num2;
  } catch (Exception $e) {
    return $e->getMessage();
  }
}
```

throwで Exceptionというクラスをインスタンス化したものをcatchに投げているという感じです。

Exceptionは、クラスなので、catchの方で、$eというのに格納してあげます。

そのあと、`getMessage()`というメソッドを使うことで、Exceptionをインスタンスするときに、引数に入れた値を取得することができます。

これで、例外処理が来た場合でも、ただのエラーではなく、自分で作ったものに変えることができました。


##あとがき

まだまだPHPは奥が深いですが、基礎の基礎の基礎ということで、今回抑えていきました。

説明が間違えている！などあれば、コメント欄で指摘してください。

至急、これはQiitaの記事を書き変えないと、間違った情報になってしまう！というのがあれば、

Twitter [@konojunya](http://twitter.com/konojunya) へご連絡くだされば、幸いです。。

ホームページ [hello world](http://konojunya.com)

ありがとうございました！