마법 상수

PHP는 어떤스크립트에서도 유효한 많은 수의 미리 정의된 상수를 제공한다. 하지만 이 상수의 대부분은 다양한 확장(extension)에 의해 생성된다. 그래서 그 확장이 같이 컴파일되어 유효하거나 동적인 로딩이 되어있어야 이런 상수가 존재하게 된다.

여덟 가지 마법 상수가 존재한다. 이 상수들은 어디에서 쓰느냐에 따라 용도가 변경된다. 예를 들면, __LINE__상수의 값은 스크립트의 해당 줄과 관련이 있다. 이 특별한 상수들은 대소문자 구별이 없고 다음과 같다:

약간의 "마법" PHP 상수
이름 설명
__LINE__ 파일의 현재 줄 번호
__FILE__ 심볼릭 링크를 통해 해석된 경우를 포함한 파일의 전체 경로와 이름. include 내부에서 사용할 경우, include된 파일명이 반환됩니다.
__DIR__ 파일의 디렉토리. 포함한 파일 안에서는, 포함된 파일의 디렉토리를 반환합니다. 이는 dirname(__FILE__)과 동일합니다. 디렉토리명은 루트 디렉토리가 아닌 이상, 마지막에 슬래시가 없습니다.
__FUNCTION__ The function name.
__CLASS__ 클래스명. (PHP 4.3.0에서 추가) PHP 5부터 이 상수는 정의된 그대로의 클래스명을 반환합니다. (대소문자 구분) PHP 4에서는 항상 소문자였습니다. 클래스명은 선언한 이름공간을 포함합니다. (예. Foo\Bar) PHP 5.4부터 __CLASS__는 trait에서도 동작합니다. trait 메소드 안에서 사용할 때, __CLASS__는 trait가 사용되는 클래스명입니다.
__TRAIT__ trait 명. trait 명은 이를 선언한 네임스페이스를 포함합니다. (예. Foo\Bar)
__METHOD__ 클래스 메소드명.
__NAMESPACE__ 현재 네임스페이스 이름.

참고: get_class(), get_object_vars(), file_exists(), function_exists().

변경점

버전 설명
5.4.0 __TRAIT__ 상수 추가됨
5.3.0 __DIR____NAMESPACE__ 상수가 추가됨
5.0.0 __METHOD__ 상수가 추가됨
5.0.0 이 버전 이전에는 마법 상수의 값은 언제나 소문자였습니다. 이제는 모든 버전에서 대소문자를 구분합니다(선언 당시의 이름이 됩니다).
4.3.0 __FUNCTION____CLASS__ 상수가 추가됨
4.0.2 __FILE__은 기존 버전에서 특정 상황에서 상대경로로 나타나는 것과 달리 언제나 심볼릭 링크로 해석된 절대경로를 나타냅니다.

add a note add a note

User Contributed Notes 9 notes

up
285
vijaykoul_007 at rediffmail dot com
18 years ago
the difference between
__FUNCTION__ and __METHOD__ as in PHP 5.0.4 is that

__FUNCTION__ returns only the name of the function

while as __METHOD__ returns the name of the class alongwith the name of the function

class trick
{
      function doit()
      {
                echo __FUNCTION__;
      }
      function doitagain()
      {
                echo __METHOD__;
      }
}
$obj=new trick();
$obj->doit();
output will be ----  doit
$obj->doitagain();
output will be ----- trick::doitagain
up
38
Tomek Perlak [tomekperlak at tlen pl]
17 years ago
The __CLASS__ magic constant nicely complements the get_class() function.

Sometimes you need to know both:
- name of the inherited class
- name of the class actually executed

Here's an example that shows the possible solution:

<?php

class base_class
{
    function
say_a()
    {
        echo
"'a' - said the " . __CLASS__ . "<br/>";
    }

    function
say_b()
    {
        echo
"'b' - said the " . get_class($this) . "<br/>";
    }

}

class
derived_class extends base_class
{
    function
say_a()
    {
       
parent::say_a();
        echo
"'a' - said the " . __CLASS__ . "<br/>";
    }

    function
say_b()
    {
       
parent::say_b();
        echo
"'b' - said the " . get_class($this) . "<br/>";
    }
}

$obj_b = new derived_class();

$obj_b->say_a();
echo
"<br/>";
$obj_b->say_b();

?>

The output should look roughly like this:

'a' - said the base_class
'a' - said the derived_class

'b' - said the derived_class
'b' - said the derived_class
up
12
david at thegallagher dot net
12 years ago
You cannot check if a magic constant is defined. This means there is no point in checking if __DIR__ is defined then defining it. `defined('__DIR__')` always returns false. Defining __DIR__ will silently fail in PHP 5.3+. This could cause compatibility issues if your script includes other scripts.

Here is proof:

<?php
echo (defined('__DIR__') ? '__DIR__ is defined' : '__DIR__ is NOT defined' . PHP_EOL);
echo (
defined('__FILE__') ? '__FILE__ is defined' : '__FILE__ is NOT defined' . PHP_EOL);
echo (
defined('PHP_VERSION') ? 'PHP_VERSION is defined' : 'PHP_VERSION is NOT defined') . PHP_EOL;
echo
'PHP Version: ' . PHP_VERSION . PHP_EOL;
?>

Output:
__DIR__ is NOT defined
__FILE__ is NOT defined
PHP_VERSION is defined
PHP Version: 5.3.6
up
10
php at kenman dot net
10 years ago
Just learned an interesting tidbit regarding __FILE__ and the newer __DIR__ with respect to code run from a network share: the constants will return the *share* path when executed from the context of the share.

Examples:

// normal context
// called as "php -f c:\test.php"
__DIR__ === 'c:\';
__FILE__ === 'c:\test.php';

// network share context
// called as "php -f \\computerName\c$\test.php"
__DIR__ === '\\computerName\c$';
__FILE__ === '\\computerName\c$\test.php';

NOTE: realpath('.') always seems to return an actual filesystem path regardless of the execution context.
up
10
Sbastien Fauvel
8 years ago
Note a small inconsistency when using __CLASS__ and __METHOD__ in traits (stand php 7.0.4): While __CLASS__ is working as advertized and returns dynamically the name of the class the trait is being used in, __METHOD__ will actually prepend the trait name instead of the class name!
up
11
chris dot kistner at gmail dot com
13 years ago
There is no way to implement a backwards compatible __DIR__ in versions prior to 5.3.0.

The only thing that you can do is to perform a recursive search and replace to dirname(__FILE__):
find . -type f -print0 | xargs -0 sed -i 's/__DIR__/dirname(__FILE__)/'
up
4
meindertjan at gmail dot spamspamspam dot com
10 years ago
A lot of notes here concern defining the __DIR__ magic constant for PHP versions not supporting the feature. Of course you can define this magic constant for PHP versions not yet having this constant, but it will defeat its purpose as soon as you are using the constant in an included file, which may be in a different directory then the file defining the __DIR__ constant. As such, the constant has lost its *magic*, and would be rather useless unless you assure yourself to have all of your includes in the same directory.

Concluding: eye catchup at gmail dot com's note regarding whether you can or cannot define magic constants is valid, but stating that defining __DIR__ is not useless, is not!
up
0
public at taliesinnuin dot net
3 years ago
If you're using PHP with fpm (common in this day and age), be aware that __DIR__ and __FILE__ will return values based on the fpm root which MAY differ from its actual location on the file system.

This can cause temporary head-scratching if deploying an app where php files within the web root pull in PHP files from outside of itself (a very common case). You may be wondering why __DIR__ returns "/" when the file itself lives in /var/www/html or whathaveyou.

You might handle such a situation by having NGINX explicitly add the necessary part of the path in its fastcgi request and then you can set the root on the FPM process / server / container to be something other than the webroot (so long as no other way it could become publicly accessible).

Hope that saves someone five minutes who's moving code to FPM that uses __DIR__.
up
-39
Anonymous
12 years ago
Further clarification on the __TRAIT__ magic constant.

<?php
trait PeanutButter {
    function
traitName() {echo __TRAIT__;}
}

trait
PeanutButterAndJelly {
    use
PeanutButter;
}

class
Test {
    use
PeanutButterAndJelly;
}

(new
Test)->traitName(); //PeanutButter
?>
To Top