欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

php常量

shiping1 的头像
<语法
[edit] Last updated: Fri, 11 Oct 2013

view this page in

魔术常量

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

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

 

几个 PHP 的“魔术常量”
名称说明
__LINE__文件中的当前行号。
__FILE__文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。
__DIR__文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(__FILE__)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增) =
__FUNCTION__函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
__CLASS__类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域(例如 Foo\Bar)。注意自 PHP 5.4 起 __CLASS__ 对 trait 也起作用。当用在 trait 方法中时,__CLASS__ 是调用 trait 方法的类的名字。
__TRAIT__Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4 起此常量返回 trait 被定义时的名字(区分大小写)。Trait 名包括其被声明的作用区域(例如 Foo\Bar)。
__METHOD__类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
__NAMESPACE__当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。

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



表达式> <语法
[edit] Last updated: Fri, 11 Oct 2013
 
reject note add a note add a note User Contributed Notes 魔术常量 - [28 notes]
vijaykoul_007 at rediffmail dot com
8 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
madboyka at yahoo dot com
3 years ago
Since namespace were introduced, it would be nice to have a magic constant or function (like get_class()) which would return the class name without the namespaces.

On windows I used basename(__CLASS__). (LOL)
user9 at voloreport dot com
2 years ago
Note that __FILE__ has a quirk when used inside an eval() call. It will tack on something like "(80) : eval()'d code" (the number may change) on the end of the string at run-time. The workaround is:

$script = php_strip_whitespace('myprogram.php');
$script = str_replace('__FILE__',"preg_replace('@\(.*\(.*$@', '', __FILE__,1)",$script);
eval($script);
php at kennel17 dot co dot uk
6 years ago
Further to my previous note, the 'object' element of the array can be used to get the parent object.  So changing the get_class_static() function to the following will make the code behave as expected:

<?php
   
function get_class_static() {
       
$bt = debug_backtrace();
   
        if (isset(
$bt[1]['object']))
            return
get_class($bt[1]['object']);
        else
            return
$bt[1]['class'];
    }

?>

HOWEVER, it still fails when being called statically.  Changing the last two lines of my previous example to

<?php
  foo
::printClassName();
 
bar::printClassName();
?>

...still gives the same problematic result in PHP5, but in this case the 'object' property is not set, so that technique is unavailable.
david at thegallagher dot net
1 year 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
Anonymous
1 year 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
?>
chris dot kistner at gmail dot com
2 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__)/'
raat1979 at gmail dot com
1 month ago
Magic constants can not be tested with defined($name)

<?php
   
if(!defined(__DIR__)){
       
//will not work
   
}
?>

when __DIR__ is not defined and you use it anyway php assumes you meant '__DIR__' and  throws a notice.
because of this assumption we can do:

<?php
if(@__DIR__ == '__DIR__'){
    echo
'magic __DIR__ constant NOT defined';
  
//insert this code where needed, remember that because they are MAGIC constants defining __DIR__ is completely useless
}echo{
    echo
'magic __DIR__ constant IS defined';
 
}


?>
Tomek Perlak [tomekperlak at tlen pl]
6 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
claude at NOSPAM dot claude dot nl
9 years ago
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";
lm arobase bible point ch
8 years ago
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)
eyecatchup at gmail dot com
28 days ago
As pointed out by david at thegallagher dot net[1], you can NOT use the defined() function to check if a *magic* constant is defined.  Often seen, but will not work:
<?php
   
if (!defined('__MAGIC_CONSTANT__')) {
       
// FAIL! even if __MAGIC_CONSTANT__ is defined,
        // defined('__MAGIC_CONSTANT__') will ALWAYS return (bool)false.
   
}
?>

Now, raat1979 at gmail dot com[2] pointed out a solution to check if a magic constant is defined or not (which actually works reliable). Thanks to dynamic typecasting in PHP, if a constant lookup fails PHP interprets the given constant name as string (note that a notice is thrown nonetheless. thus, use "@" to suppress it).
<?php
    var_dump
(@UNDEFINED_CONSTANT_NAME);  //prints: string(23) "UNDEFINED_CONSTANT_NAME"
?>

Meaning we can check for all constants - including magic constants (eg __DIR__) - as follows:
<?php
   
if (@__DIR__ == '__DIR__'){
       
// __DIR__ was interpreted as string. thus, (magic) constant __DIR__ is not defined.
   
}
?>

However, what is wrong in raat1979 at gmail dot com's note[2] is this comment:
> "remember that because they are MAGIC constants defining __DIR__ is completely useless"

In fact, you *can* define magic constants (as long as they haven't been defined before, of course).

Based on all I've read and tested today, here is my code I use to make the `__DIR__` magic constant work with all PHP versions (4.3.1 - 5.5.3):
<?php
   
// Ensure that PHP's magic constant __DIR__ is defined - no matter of the PHP version.

    // If magic __DIR__ constant is not defined, define it.
   
(@__DIR__ == '__DIR__') && define('__DIR__', dirname(__FILE__));

   
// All PHP versions (>= 4.3.1) can use the magic __DIR__ constant now..
    // Demo (outputs and VLD opcodes) here: http://3v4l.org/bm6e1

?>

[1] http://us2.php.net/manual/en/language.constants.predefined.php#107614
[2] http://us2.php.net/manual/en/language.constants.predefined.php#113130
wyattstorch42 at outlook dot com
3 months ago
<?php
/*
 * I wrote this because I was including a file with classes in it. Let's say that
 * I have a contact page at mysite.com/contact/index.php and a Form class at
 * mysite.com/classes/Form.php. So in index.php, I have this statement:
 * require '../classes/Form.php';
 * The Form class includes a method to generate the HTML markup for a number of
 * form elements, including a CAPTCHA image and associated text field. To do so,
 * it must generate an <img /> element and give it a src of Form.php?captcha.
 * But I wanted it to automatically generate a src attribute without index.php
 * giving it a relative path. This script comes in handy by automatically
 * locating the directory that contains the included file (Form.php) and converting
 * it from an absolute path to a relative path that could be used for an img src,
 * an a href, a link href, etc.
 */

function relativeURL () {
   
$dir = str_replace('\\', '/', __DIR__);
       
// Resolves inconsistency with PATH_SEPARATOR on Windows vs. Linux
        // Use dirname(__FILE__) in place of __DIR__ for older PHP versions
   
return substr($dir, strlen($_SERVER['DOCUMENT_ROOT']));
       
// Clip off the part of the path outside of the document root
}

/*
 *contact/index.php
 */

require '../classes/Form.php';
new
Form()->drawCaptchaField();
   
// Writes: <img src="/classes/Form.php?captcha" />

   
/*
 * classes/Form.php
 */

if (isset($_GET['captcha'])) {
   
// generate/return CAPTCHA image
}

class
Form {
   
// ...
   
public function drawCaptchaField () {
        echo
'<img src="'.relativeURL().'?captcha" />';
    }
}

?>
Anonymous
1 year ago
A note about __FUNCTION__ and create_function():

If you use __FUNCTION__ inside the body of a function you create with create_function(), the __FUNCTION__ always evaluates to the string "__lambda_func" (even in different functions created by create_function()), not the function name that is returned by create_function().
tc0nn
1 year ago
Also worth noting, I use a extreme-logger when doing intense troubleshooting. It basically does a debug_backtrace and logs certain info. I noticed on some older PHP installs (<5) I had to prepend __FILE__ and __LINE__ with ''. just to force PHP output a string. Specifically I was loading those two in an array which were concat'd onto a log file eventually.

example:
if($a['debug']){$of->logger(array('file'=>__FILE__,'line'=>''.__LINE__,'data'=>$sql_data_array));}
Jamie
2 years ago
Note that as mentioned, __FILE__ resolves any aliases. Other real path information, such as $_SERVER["SCRIPT_FILENAME"], doesn't.

__FILE__ => /volume1/web/mysite/admin/inc/includeFile.inc.php
$_SERVER["SCRIPT_FILENAME"] => /var/services/web/mysite/admin/products.php

If you need to compare one with the other, use
realpath($_SERVER["SCRIPT_FILENAME"])
me at jamessocol dot com
5 years ago
We need an eighth magic constant, something along the lines of __STATIC__. This should return the name of the class from which a static method was called, regardless of where in the inheritance tree the method was defined.

PHP 5.3 has the new use of the static keyword which will help, but it isn't perfect. You still have to repeat yourself frequently.

For example, trying to implement Active Record:

<?php

// In PHP 5.3

class Model
{
    public static function
find()
    {
        echo static::
$class;
    }
}

class
Product extends Model
{
    protected static
$class = __CLASS__;
}

class
User extends Model
{
    protected static
$class = __CLASS__;
}


Product::find(); // "Product"
User::find(); // "User"

?>

<?php

// With __STATIC__ keyword. (Would be better.)

class Model
{
    public static function
find()
    {
        echo
__STATIC__;
    }
}

class
Product extends Model {}

class
User extends Model {}

Product::find(); // "Product"
User::find(); // "User"

?>

[EDITED : Use get_called_class()]
stangelanda at gmail dot com
7 years ago
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
7 years ago
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.
karl __at__ streetlampsoftware__dot__com
8 years ago
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
8 years ago
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);
}

?>
ulrik
9 years ago
note that __FUNCTION__ define gives the the function name in lowercase
michiel ed thalent circle nl
1 year ago
__METHOD__ will return bother the method name, as the class and namespace name.

__FUNCTION__ will only return the method name.

<?php
namespace General;

class
ArgumentValidation {

    public static function
validateIntArguments() {
        echo
__FUNCTION__ . "\n";
        echo
__METHOD__ . "\n";
    }
}


ArgumentValidation::validateIntArguments(new ArgumentValidation);
?>

Will return:

validateIntArguments
General\ArgumentValidation::validateIntArguments

If you want to get a ReflectionMethod instance of your sattis method is to use __FUNCTION__.

$refl = new \ReflectionMethod(__CLASS__, __FUNCTION__);
darwin[at]buchner[dot]net
11 years ago
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.
Anonymous
3 years ago
__DIR__ befor PHP 5.3.0

<?php
if (!defined('__DIR__')) {
  class
__FILE_CLASS__ {
    function 
__toString() {
     
$X = debug_backtrace();
      return
dirname($X[1]['file']);
    }
  }
 
define('__DIR__', new __FILE_CLASS__);
}

?>
php at kennel17 dot co dot uk
6 years ago
In response to stangelanda at gmail dot com, (who suggested a possible fix to get the actual class name of the object, when being called statically).

in PHP5, this fix no longer works. 

Here is some example code:

<?php

 
function get_class_static() {
   
$bt = debug_backtrace();
   
$name = $bt[1]['class'];
    return
$name;
  }

  class
foo {
    function
printClassName() {
      print(
get_class_static() . "<br>");
     }
  }

  class
bar extends foo {
  }


$f = new foo();
$b = new bar();
$f->printClassName();
$b->printClassName();

?>

In PHP4, it outputs
  foo
  bar
as you described.

However, in PHP5, due to the way the debug_backtrace() function has been modified (see http://bugs.php.net/bug.php?id=30828) the output is now
  foo
  foo

I have yet to figure out a way to get the original output in PHP5.  Any suggestions would be very useful, and if I find an answer I'll post it here.
stefan at efectos dot nl
2 years ago
When __DIR__ is not defined, you can also use this workaround to generate it:

<?php
if(!defined('__DIR__')) {
   
$iPos = strrpos(__FILE__, "/");
   
define("__DIR__", substr(__FILE__, 0, $iPos) . "/");
}

?>

Keep in mind this sets __DIR__ to the directory you are running this snippet from.
jrivero24 at yahoo dot es
2 years ago
When __DIR__ is not defined, prior 5.3.0:

<?php if ( !defined('__DIR__') ) define('__DIR__', dirname(__FILE__)); ?>

来自 http://php.net/manual/zh/language.constants.predefined.php
普通分类: