名前空間に関して勉強したことをまとめていく①

## 名前空間の概要

- namespaceは名前空間とも呼ばれ、項目をカプセル化するときに使用します。
- 名前空間とは、例えば通常同じファイルに同じクラスや関数名、定数名が存在することはできませんが、名前空間を使用することにより、関連するクラスや、インターフェイス、関数、定数などをグループ化することが可能です。
- そのため、名前空間を指定しておけば自分が作ったクラスが、サードパーティのクラスや関数などと名前が衝突することを防ぐことができます。

```A.php
<?php
 
namespace name1;
 
function getName(){
  return 'Tanaka';
}
 
namespace name2;
 
function getName(){
  return 'Taro';
}
```

```B.php
<?php

require_once 'A.php';
 
//関数の呼出し
echo name1\getName();
echo name2\getName();
```

`名前空間を使わないとFatalエラーが起こる`

```A.php
<?php
 
function getName(){
  return 'Tanaka';
}
 
function getName(){
  return 'Taro';
}
```

```
<?php

require_once 'A.php';
 
echo getName();


Fatal error: Cannot redeclare getName() (previously declared in /var/www/html/php2/28/A.php:6) in /var/www/html/php2/28/A.php on line 13

```

## 名前空間の定義
- 名前空間を宣言するには、キーワード namespace を使用します。
- 名前空間を含むファイルでは、他のコードより前にファイルの先頭で名前空間を宣言しなければなりません。 
- ただし declare キーワードは例外です。(あるコードブロックに対して、何らかの設定をするための構文。declare(ディレクティブ)のように書いて使う。)

```namaekuukanteigi.php
<?php
 
namespace name1; //名前空間の定義
 
function getName(){
  return 'Tanaka';
}

echo getName();
```

## サブ名前空間
- 名前空間は、ディレクトリ構造の概念と同じく階層を持たせて記述することが可能です。
- \ で区切ってサブ名前空間を記述できます。

```subnamaekuukan.php
<?php
namespace japan\chiba\matsudo\tokiwadaira;

function test() {
  return 'おはよう';
}
```

```subnamaekuukan2.php
<?php
require_once 'subnamaekuukan.php';

echo japan\chiba\matsudo\tokiwadaira\test();
```

## 同一ファイル内での複数の名前空間の定義
- namespaceで名前空間を宣言した後に記述した関数などは、その名前空間に属します。
- その後にまた namespace で名前空間を宣言すれば、その名前空間に属します。

`シンプルな組み合わせ方式による複数の名前空間の宣言`
```douitsufile.php
namespace takahashi;

function test() {
  return 'ハロー';
}

namespace tanaka;

function test() {
  return 'Hello';
}
```
`波括弧構文による複数の名前空間の宣言`
```douitsufile.php
namespace takahashi {
  function test() {
    return 'ハロー';
  }
}

namespace tanaka {
  function test() {
    return 'Hello';
  }
}
```

```douitsufile2.php
<?php
require_once 'douitsufile.php';

echo takahashi\test();
echo tanaka\test();
```

## 名前空間の使用法: 基本編
ディレクトリ構造のように階層によって指定方法が異なる。
名前空間の指定方法には

- 非修飾形式
- 修飾形式
- 完全修飾形式

がある。

### 非修飾形式
ディレクトリ構造で言うところの同ディレクトリ内からの指定になります。
namaekuukansiyouhou.php には chiba\matsudo; という名前空間名を定義し、test() 関数を記述します。

同じ名前空間にあるため、関数を呼ぶときは名前空間を記述しません。
このように同じ名前空間にあるため、 \ を含まない指定が非修飾形式です。

```namaekuukansiyouhou.php
<?php
  namespace chiba\matsudo;
  function test() {
    return '名前空間';
  }
```

```namaekuukansiyouhou2.php
<?php
// 非修飾形式
namespace chiba\matsudo;

require_once 'namaekuukansiyouhou.php';
echo test();
```

### 修飾形式
ディレクトリ構造で言うところのドキュメント相対パスです。
先ほどと同様に namaekuukankisiyouhou.php には namespace chiba\matsudo; という名前空間名を定義し、test() 関数を記述します
ディレクトリ構造で言うと 1(このファイル) の名前空間より一つ上の階層に位置するので、2 には chiba という名前空間を定義します。
一つ上の階層にあるため、関数を呼ぶときは echo matsudo\test(); と記述します
このように上位階層にあるため、途中に \ を含めて階層も指定するのが修飾形式です。

```namaekuukansiyouhou.php
<?php
  namespace chiba\matsudo;
  function test() {
    return '名前空間';
  }
```
```namaekuukansiyouhou2.php
<?php
// 修飾形式
namespace chiba;

require_once 'namaekuukansiyouhou.php';
echo matsudo\test();
```

### 完全修飾形式
ディレクトリ構造で言うところのルート相対パスです。(絶対パスのようなイメージ)
先ほどと同様に namaekuukansiyouhou.php には namespace chiba\matsudo; という名前空間名を定義し、test() 関数を記述します。
関数を呼ぶときに最上位階層から指定するため、namaekuukansiyouhou2.phpの名前空間はどこでも構いませんが、hogeとします。
関数を呼ぶときは、最初に \ を記述して最上位階層から指定します。
echo \chiba\matsudo\test(); と記述します。

```namaekuukansiyouhou.php
<?php
  namespace chiba\matsudo;
  function test() {
    return '名前空間';
  }
```

```namaekuukansiyouhou2.php
<?php
// 完全修飾形式
namespace hoge; //なんでもいい

require_once 'namaekuukansiyouhou.php';
echo \chiba\matsudo\test();
```

### グローバルなクラス、関数および定数への名前空間内からのアクセス
グローバルなクラス、関数あるいは定数にアクセスするには、完全修飾名を使用して \strlen()、\Exception あるいは \INI_ALL などとすることができます。

```namaekuukansiyouhou.php
namespace Foo;

function strlen() {
  return 1;
}
const INI_ALL = 3;
class Exception {}

$a = \strlen('hi'); // グローバル関数 strlen をコールします
$b = \INI_ALL; // グローバル定数 INI_ALL にアクセスします
$c = new \Exception('error'); // グローバルクラス Exception のインスタンスを作成します

```
```namaekuukansiyouhou2.php
namespace Foo;
require_once 'namaekuukansiyouhou.php';
echo $a;
echo $b;
echo $c;
```