魔术常量

PHP 向它运行的任何脚本提供了大量的预定义常量。不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了。

有五个魔术常量根据它们使用的位置而改变。例如 __LINE__ 的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写,如下:

表格 13-1. 几个 PHP 的“魔术常量”

名称说明
__LINE__ 文件中的当前行号。
__FILE__ 文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。
__FUNCTION__ 函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
__CLASS__ 类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
__METHOD__ 类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。

参见 get_class()get_object_vars()file_exists()function_exists()


add a note add a note User Contributed Notes
stangelanda at gmail dot com
06-Sep-2006 12:17
claude noted that __CLASS__ always contains the class that it is called in, if you would rather have the class that called the method use get_class($this) instead.  However this only works with instances, not when called statically.

<?php
 
class A {
     function
showclass() {
         echo
get_class($this);
     }
  }

  class
B extends A {}

 
$a = new A();
 
$b = new B();

 
$a->showclass();
 
$b->showclass();
 
A::showclass();
 
B::showclass();

 
//results in "a", "b", false, false
?>

I tried keeping track of the class manually within the properties, but the following doesn't work either:

<?php
 
class A {
     var
$class = __CLASS__;
     function
showclass() {
         echo
$this->class;
     }
  }

  class
B extends A {
     var
$class = __CLASS__;
  }

 
//results in "a", "b", NULL, NULL
?>

The best solution I could come up with was using debug_backtrace.  I assume there is a better way somehow, but I can't find it.  However the following works:

<?php
 
class A {
     function
showclass() {
      
$backtrace = debug_backtrace();
       echo
$backtrace[0]['class'];
     }
  }

  class
B extends A {}

 
//results in "a", "b", "a", "b"
?>
warhog at warhog dot net
19-Dec-2005 05:33
There is another magic constant not mentioned above: __COMPILER_HALT_OFFSET__ - contains where the compiler halted - see http://www.php.net/manual/function.halt-compiler.php for further information.
vijaykoul_007 at rediffmail dot com
22-Sep-2005 12:59
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
karl __at__ streetlampsoftware__dot__com
04-Mar-2005 05:39
Note that the magic constants cannot be included in quoted strings.

For instance,
echo "This is the filename: __FILE__";
will return exactly what's typed above.

echo "This is the filename: {__FILE__}";
will also return what's typed above.

The only way to get magic constants to parse in strings is to concatenate them into strings:
echo "This is the filename: ".__FILE__;
csaba at alum dot mit dot edu
03-Mar-2005 08:04
Sometimes you might want to know whether a script is the top level script or whether it has been included.  That could be useful if you want to reuse the routines in another script, but you don't want to separate them out.  Here's a way that seems to be working for me (for both Apache2 module and CLI versions of PHP) on my Win XP Pro system.

By the way, if __FILE__ is within a function call, its value corresponds to the file it was defined in and not the file that it was called from.  Also, I used $script and strtolower instead of realpath because if the script is deleted after inclusion but before realpath is called (which could happen if the test is deferred), then realpath would return empty since it requires an extant file or directory.

Csaba Gabor from Vienna

<?php
if (amIincluded()) return;    // if we're included we only want function defs
function amIincluded() {
//    returns true/false depending on whether the currently
//    executing script is included or not
//    Don't put this function in an include file (duh)!
  
$webP = !!$_SERVER['REQUEST_METHOD'];    // a web request?
  
$script = preg_replace('/\//',DIRECTORY_SEPARATOR,
                          
$_SERVER['SCRIPT_FILENAME']);
   return (
$webP) ? (strtolower(__FILE__)!=strtolower($script)) :
           !
array_key_exists("_REQUEST", $GLOBALS);
}
?>
lm arobase bible point ch
09-Dec-2004 06:17
in reply to x123 at bestof dash inter:
I believe, this is not a bug, but a feature.
__FILE__ returns the name of the include file, while $PHP_SELF returns the relative name of the main file.
It is then easy to get the file name only with substr(strrchr($PHP_SELF,'/'),1)
claude at NOSPAM dot claude dot nl
18-Jul-2004 11:29
Note that __CLASS__ contains the class it is called in; in lowercase. So the code:

class A
{
   function showclass()
   {
       echo __CLASS__;
   }
}

class B extends A
{
}

$a = new A();
$b = new B();

$a->showclass();
$b->showclass();
A::showclass();
B::showclass();

results in "aaaa";
ulrik
04-Mar-2004 11:44
note that __FUNCTION__ define gives the the function name in lowercase
warhog at warhog dot net
07-Feb-2004 04:49
just to read out the filename of the currently proceeded file use
<?php basename(__FILE__); ?>
hixon at colorado dot edu
16-May-2003 08:21
You can use the following in files that you want to include, but not run directly.  The script will exit if it's run as the top-level script, but will not exit if it's included from another script.  Of course this won't work in the command line mode.

if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) {
  exit;
}
kop at meme dot com
14-Feb-2003 07:34
The keywords TRUE and FALSE (case insensitive), which represent their respective boolean values, are worth noting here.
darwin[at]buchner[dot]net
15-Mar-2002 08:54
As of version 4.0.6, there is also a handy predefined DIRECTORY_SEPARATOR constant which you can use to make you scripts more portatable between OS's with different directory structures.