1
0
mirror of https://github.com/php/doc-zh.git synced 2026-03-23 22:52:08 +01:00
Files
archived-doc-zh/language/constants.xml
2025-11-02 17:54:34 +08:00

340 lines
12 KiB
XML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8" ?>
<!-- $Revision$ -->
<!-- EN-Revision: f4f96ef8b2a95283c92ea2183fe1dedf06f3ad22 Maintainer: Avenger Status: ready -->
<!-- CREDITS: Altair, Luffy, mowangjuanzi -->
<chapter xml:id="language.constants" xmlns="http://docbook.org/ns/docbook">
<title>常量</title>
<simpara>
常量是一个简单值的标识符(名字)。如同其名称所暗示的,在脚本执行期间该值不能改变(除了所谓的
<link linkend="language.constants.magic">魔术常量</link>,它们其实不是常量)。常量大小写敏感。传统上常量标识符总是大写的。
</simpara>
<note>
<para>
在 PHP 8.0.0 之前,使用 <function>define</function> 定义的常量可能不区分大小写。
</para>
</note>
<para>
常量名和其它任何 PHP
标签遵循同样的命名规则。合法的常量名以字母或下划线开始,后面跟着任何字母,数字或下划线。用正则表达式是这样表达的:
<code>^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>
</para>
<para>
还可以使用 <function>define</function> 函数来定义包含保留字或非常规名称的常量,这类常量可以通过
<function>constant</function> 函数来获取名称,但是非常不推荐这种用法。
</para>
&tip.userlandnaming;
<para>
<!-- TODO Move into syntax section? -->
<example>
<title>合法与非法的常量名</title>
<programlisting role="php">
<![CDATA[
<?php
// 合法的常量名
define("FOO", "something");
define("FOO2", "something else");
define("FOO_BAR", "something more");
// 非法的常量名
define("2FOO", "something");
// 下面的定义是合法的,但应该避免这样做:(自定义常量不要以__开头)
// 也许将来有一天 PHP 会定义一个 __FOO__ 的魔术常量
// 这样就会与你的代码相冲突
define("__FOO__", "something");
?>
]]>
</programlisting>
</example>
</para>
<note>
<simpara>
在这里,字母指的是 a-zA-Z以及从 128 到 2550x80-0xff的 ASCII 字符。
</simpara>
</note>
<simpara>
&link.superglobals; 一样,常量的范围是全局的。常量可以从脚本的任何地方被访问,而不考虑作用域。有关作用域的更多信息请阅读手册中的<link
linkend="language.variables.scope">变量范围</link>
</simpara>
<note>
<simpara>
从 PHP 7.1.0 开始,类常量可以声明为 protected 或 private 的可见性,
使其只在其定义的类的层次范围内可用。
</simpara>
</note>
<sect1 xml:id="language.constants.syntax">
<title>语法</title>
<simpara>
可以使用 <literal>const</literal> 关键字或 <function>define</function> 函数两种方法来定义一个常量。函数
<function>define</function> 允许将常量定义为一个表达式,而
<literal>const</literal> 关键字有一些限制,具体可参见下述章节。一个常量一旦被定义,就不能再改变或者取消定义。
</simpara>
<simpara>
使用 <literal>const</literal> 关键字定义常量时,只能包含标量数据(<type>bool</type><type>int</type><type>float</type>
<type>string</type>)。可以将常量定义为一个表达式,也可以定义为一个 <type>array</type>。还可以定义
<type>resource</type> 为常量,但应尽量避免,因为可能会造成不可预料的结果。
</simpara>
<simpara>
可以简单的通过指定其名字来取得常量的值,与变量不同,<emphasis>不应该</emphasis>在常量前面加上
<literal>$</literal> 符号。如果常量名是动态的,也可以用函数
<function>constant</function> 来获取常量的值。用
<function>get_defined_constants</function> 可以获得所有已定义的常量列表。
</simpara>
<note>
<simpara>
常量和(全局)变量在不同的名字空间中。这意味着例如 &true;<varname>$TRUE</varname> 是不同的。
</simpara>
</note>
<simpara>
如果使用了一个未定义的常量,则会抛出 <classname>Error</classname>
在 PHP 8.0.0 之前,调用未定义的常量会被解释为一个该常量的
字符串CONSTANT 对应 "CONSTANT" )。
此方法已在 PHP 7.2.0 中被废弃,会抛出一个 <constant>E_WARNING</constant> 级错误。PHP 7.2.0 之前会发出一个
<link linkend="ref.errorfunc">E_NOTICE</link> 级的错误。)参见手册中为什么
<link linkend="language.types.array.foo-bar">$foo[bar]</link>
是错误的(除非 <literal>bar</literal> 是一个常量)。这不适用于 <link linkend="language.namespaces.rules">(完全)限定的常量</link>,如果未定义,将始终引发 <classname>Error</classname>
</simpara>
<note>
<simpara>
如果要检查是否定义了某常量,请使用 <function>defined</function> 函数。
</simpara>
</note>
<para>
常量和变量有如下不同:
<itemizedlist>
<listitem>
<simpara>
常量前面没有美元符号(<literal>$</literal>
</simpara>
</listitem>
<listitem>
<simpara>
常量可以不用理会变量的作用域而在任何地方定义和访问;
</simpara>
</listitem>
<listitem>
<simpara>
常量一旦定义就不能被重新定义或者取消定义;
</simpara>
</listitem>
<listitem>
<simpara>
常量只能计算标量值或数组。
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
<example>
<title>定义常量</title>
<programlisting role="php">
<![CDATA[
<?php
define("CONSTANT", "Hello world.");
echo CONSTANT; // 输出 "Hello world."
echo Constant; // 抛出错误:未定义的常量 "Constant"
// 在 PHP 8.0.0 之前,输出 "Constant" 并发出一个提示级别错误信息
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>使用关键字 <literal>const</literal> 定义常量</title>
<programlisting role="php">
<![CDATA[
<?php
// 简单的标量值
const CONSTANT = 'Hello World';
echo CONSTANT;
// 标量表达式
const ANOTHER_CONST = CONSTANT.'; Goodbye World';
echo ANOTHER_CONST;
const ANIMALS = array('dog', 'cat', 'bird');
echo ANIMALS[1]; // 将输出 "cat"
// 常量数组
define('ANIMALS', array(
'dog',
'cat',
'bird'
));
echo ANIMALS[1]; // 将输出 "cat"
?>
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
和使用 <function>define</function> 来定义常量相反的是,使用 <literal>const</literal>
关键字定义常量必须处于最顶端的作用域,因为用此方法是在编译时定义的。这就意味着不能在函数内,循环内以及
<literal>if</literal><literal>try</literal>/<literal>catch</literal>
语句之内用 <literal>const</literal> 来定义常量。
</para>
</note>
<sect2 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="language.oop5.constants">类常量</link></member>
</simplelist>
</para>
</sect2>
</sect1>
<sect1 xml:id="language.constants.predefined">
<title>预定义常量</title>
<simpara>
PHP 向它运行的任何脚本提供了大量的<link
linkend="reserved.constants">预定义常量</link>。不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了。
</simpara>
</sect1>
<sect1 xml:id="language.constants.magic">
<title>魔术常量</title>
<para>
一些魔术常量会根据使用位置而变化。例如 <constant>__LINE__</constant>
的值取决于它在脚本中使用的行。所有这些“魔术”常量都在编译时解析,而常规常量则在运行时解析。这些特殊的常量不区分大小写,如下:
</para>
<para>
<table>
<title>PHP 的魔术常量</title>
<tgroup cols="2">
<thead>
<row>
<entry>&Name;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row xml:id="constant.line">
<entry><constant>__LINE__</constant></entry>
<entry>
文件中的当前行号。
</entry>
</row>
<row xml:id="constant.file">
<entry><constant>__FILE__</constant></entry>
<entry>
文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
</entry>
</row>
<row xml:id="constant.dir">
<entry><constant>__DIR__</constant></entry>
<entry>
文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于
<literal>dirname(__FILE__)</literal>。除非是根目录,否则目录中名不包括末尾的斜杠。
</entry>
</row>
<row xml:id="constant.function">
<entry><constant>__FUNCTION__</constant></entry>
<entry>
当前函数的名称。匿名函数则为 <literal>{closure}</literal>
</entry>
</row>
<row xml:id="constant.class">
<entry><constant>__CLASS__</constant></entry>
<entry>
当前类的名称。类名包括其被声明的作用域(例如
<literal>Foo\Bar</literal>)。当用在 trait 方法中时,<constant>__CLASS__</constant>
是调用 trait 方法的类的名字。
</entry>
</row>
<row xml:id="constant.trait">
<entry><constant>__TRAIT__</constant></entry>
<entry>
Trait 的名字。Trait 名包括其被声明的作用域(例如
<literal>Foo\Bar</literal>)。
</entry>
</row>
<row xml:id="constant.method">
<entry><constant>__METHOD__</constant></entry>
<entry>
类的方法名。
</entry>
</row>
<row xml:id="constant.property">
<entry><constant>__PROPERTY__</constant></entry>
<entry>
仅在<link linkend="language.oop5.property-hooks">属性挂钩</link>内有效。等同于属性的名称。
</entry>
</row>
<row xml:id="constant.namespace">
<entry><constant>__NAMESPACE__</constant></entry>
<entry>
当前命名空间的名称。
</entry>
</row>
<row xml:id="constant.coloncolonclass">
<entry><constant><replaceable>ClassName</replaceable>::class</constant></entry>
<entry>
完整的类名。
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<sect2 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="language.oop5.basic.class.class">::class</link></member>
<member><function>get_class</function></member>
<member><function>get_object_vars</function></member>
<member><function>file_exists</function></member>
<member><function>function_exists</function></member>
</simplelist>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->