• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 魔术常量

    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 中该值总是小写字母的。类名包括其被声明的作用区域(例如FooBar)。注意自 PHP 5.4 起 __CLASS__ 对 trait 也起作用。当用在 trait 方法中时,__CLASS__ 是调用 trait 方法的类的名字。
    __TRAIT__ Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4 起此常量返回 trait 被定义时的名字(区分大小写)。Trait 名包括其被声明的作用区域(例如FooBar)。
    __METHOD__类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
    __NAMESPACE__当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。

    参见get_class(),get_object_vars(),file_exists()和function_exists()。

    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
    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
    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!
    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__)/'
    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!
    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
    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.
    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
    ?>
    

    上篇:语法