質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.63%

定数の定義より前にその定数を使う関数の定義を書いても大丈夫なのか

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 536

intron

score 31

下記のtest01.phpのように、定数の定義より前にその定数を使う関数の定義を書いてもきちんと定数の値が表示されました。
なぜ後で定義される定数を使っても大丈夫なのでしょうか。

test01.php

function funcA() { print CONST_B . PHP_EOL; }

define('CONST_B', '定数テスト');

funcA();

実行結果

$ php -f test01.php
定数テスト
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+4

function より define の方が先に処理されるからです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/26 06:52 編集

    つまり、function の評価が始まる時には define の構文木の構築は終わっており、いつでも評価できる状態にあると推測されます。

    キャンセル

  • 2017/04/26 06:54

    実際にはソースを読んで確かめてください。

    キャンセル

  • 2017/04/26 22:52

    詳しく説明していただいてありがとうございます。

    キャンセル

+3

プログラム実行時、最初にソースコード全体を解析されるということでしょうか?

現在のほとんどの言語はPHPも含め実行前にソースコード全体を解析しますが、それは必須では無いです。
冒頭から実行あるいは定義しながらソースを読んでいくPHP風な言語があったとしても、funcAの定義の中で、構文解析をすればCONST_Bは定数だと言うことは分かりますので、そのまま関数funcAが定義されます。

その次に、CONST_Adefineされます。

その次に、funcAを呼び出して、呼び出されたfuncAの中でようやくCONST_Bの価を参照しようとしてすでにdefineされているので値の取り出しに成功します。

つまりfuncAの定義時にはCONST_Aが定数だと言うことさえ分かれば良くて、値が入っている必要は無いです。値は参照するときに必要です。

CONST_AdefinefuncAの呼び出し順序を入れ替えると、funcAの実行時点で、CONST_Bは未定義で、普通の言語だとエラーになります。PHPの場合はその辺がいい加減なので、CONST_B"CONST_B"という文字列値を持っている事になりエラーにはなりません。ただし警告が出ますが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/26 22:49

    詳しく説明していただいてありがとうございます。

    キャンセル

+1

単純に言うと、
define は読み込み時に評価され、
関数の中身は実行時に評価されるからさ!

本当はもっと複雑ですが……。

コンピュータ言語というのは、何段階かに分けて解釈し、徐々にマシン語に近づいていきます。
define は最初の方に解釈され、関数の中身は後の方に解釈されるので、大丈夫なのです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

なぜ後で定義される定数を使っても大丈夫なのでしょうか。

同じように、funcA の中で利用している別の funcB があったとして、その論でいくと funcA よりも先に funcB を定義する必要がありそうですね。

さらに funcB から別の関数 funcC が使用されていたら...

とまぁ、そんな感じで定義する順番を考えなければならないとすると、とてもプログラムを書くことはできなさそうですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/26 00:00

    プログラム実行時、最初にソースコード全体を解析されるということでしょうか?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る