Help us understand the problem. What is going on with this article?

[PHP] スコープ

More than 1 year has passed since last update.

はじめに

PHP中級者を目指す_言語を使いこなすための本
こちらを参考にさせて頂き、今一度スコープについて復習も兼ねて確認してみました。

さっそく、例として以下のPHPの挙動を見てみましょう。

<?php

if(true) {
    $hoge = 'hoge';
}

echo $hoge;
// >> hoge

このようにif{}のブロック内だけにスコープを限定することは出来ません。
他の言語だとPythonも同じく、ブロック単位でのスコープは出来ないです。
Rubyは一部繰り返しメソッドでのみ可能です。

逆に、JavaScriptや静的型付け言語では
ブロック単位でスコープを限定することが出来ます。以下はJavaScriptの例です。(ES6から)

if(true) {
    // constで宣言(letでも可) 
    // ブロックの中でしかアクセスできない変数になる。
    const hoge = 'hoge';
}

// ここではアクセスできない
console.log(hoge)

変数のスコープを意識すべき理由

不要な変数を残す事は、以下のデメリットがあります。

  • 変数を確保してる分のメモリを食う。
  • 変数の生存期間が長くなるほど、変数の使われ方や軌跡を追うのが大変になる。

本来であれば、使い終わった変数は破棄されることが望ましいですが、毎回unset()するのも大変です。
そのため、PHPにおける変数のスコープをしっかり理解した上で、取り扱う必要があります。

スコープは3種類

  • ローカルスコープ(関数内スコープ)
  • グローバルスコープ
  • スーパーグローバル

この中で最も重要なのはローカルスコープです。
なぜなら、PHPにおいて最小のスコープ単位だからです。

ローカルスコープ(関数内スコープ)

関数内で定義された変数は、関数を外れると未定義扱いとなります。

<?php

// ローカルスコープ(関数内スコープ)
function localScope() {
    // 
    $hoge = 'hoge';
    return $hoge;
}

// 関数呼び出し
localScope();

echo $hoge;
// >> PHP Notice:  Undefined variable

上記の結果の通り、関数内で定義した変数$hogeはローカル変数として扱われています。

ここで重要となるのは「関数を利用して、長く生存する変数を減らそう」 という事です。

つまり

  • 大きすぎる関数を作らない
  • 適度に関数分割する

上記2つの工夫をすれば良いのです。

悪い例としては、定義された変数が300行目後で使われてたら、保守,可読性に欠けてしまいます。
また、必要であるにも関わらず無闇にスコープを小さくしても、却って保守性は劣化してしまうのが難しいところです。

グローバルスコープ

関数の外で定義された普通の変数です。

<?php

function localScope() {
    // ローカルスコープ
    $hoge = 'hoge';
    return $hoge;
}

// グローバルスコープ
// クラスや関数やの外で定義している変数
$hoge = 'hoge';

グローバルスコープは変数が不用意に生存してしまうため、多様はおすすめしません。

global 宣言は使わない。

ほぼ使うことは無い、というか使わない方が良いのですが、
global宣言という構文があり、関数内からグローバル変数を使うことができます。

<?php

$hoge = '';

function globalScope() {
    // グローバルスコープ
    global $hoge;
    // 値を代入
    $hoge = 'hoge';

    return $hoge;
}
// 関数呼び出し
globalScope();

echo $hoge;
// >> hoge

上記の様な事をせずとも、外部の値を関数で使いたい場合は、普通に引数で受け取ってあげればいいです。
グローバル領域が汚れるのと、テストが書きにくくなってしまいます。

スーパーグローバル

先頭に「$_」が付いている変数がこれに該当します。

  • $_POST
  • $_GET
  • $_FILES
  • etc.

よく使うやつですね。
予めPHP側で変数が定義されていて、いつでも取り出せる便利な存在です。
($_SESSIONを除いて) 基本的には、直接書き換えることはせず、利用するだけに留めましょう。コードが追いづらくなります。

参考

PHP中級者を目指す_言語を使いこなすための本

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away