1.Hello World

Help > PHP 熟悉 >
1.Hello World

Hello world PHP!

为什么使用 PHP？

  • PHP 可在不同的平台上运行（Windows、Linux、Unix、Mac OS X 等）
  • PHP 与目前几乎所有的正在被使用的服务器相兼容（Apache、IIS 等）
  • PHP 提供了广泛的数据库支持
  • PHP 是免费的，可从官方的 PHP 资源下载它： www.php.net
  • PHP 易于学习，并可高效地运行在服务器端
Copyright © 2023. All rights reserved. (To change the copyright info, just edit it in template.)


2.PHP 变量相关

2.PHP 变量相关

PHP 变量作用域

变量的作用域是脚本中变量可被引用/使用的部分。

PHP 有四种不同的变量作用域：

  • local
  • global
  • static
  • parameter
  • global
  • static


3.PHP echo 语句

3.PHP echo 语句

1.显示字符串

2.显示变量

3.显示变量


4.PHP 数据类型

4.PHP 数据类型

PHP 变量存储不同的类型的数据，不同的数据类型可以做不一样的事情。

PHP 支持以下几种数据类型:

  • String（字符串）
  • Integer（整型）
  • Float（浮点型）
  • Boolean（布尔型）
  • Array（数组）
  • Object（对象）
  • NULL（空值）
  • Resource（资源类型）

1.PHP 字符串

一个字符串是一串字符的序列，就像 "Hello world!"。

你可以将任何文本放在单引号和双引号中：

2.PHP 整型

3.PHP 浮点型

4.PHP 布尔型

5.PHP 数组

6.PHP 对象

7.PHP NULL 值

8.PHP 资源类型

PHP 资源 resource 是一种特殊变量，保存了到外部资源的一个引用。

常见资源数据类型有打开文件、数据库连接、图形画布区域等。

由于资源类型变量保存有为打开文件、数据库连接、图形画布区域等的特殊句柄，因此将其它类型的值转换为资源没有意义。

使用 get_resource_type() 函数可以返回资源（resource）类型：

get_resource_type(resource $handle): string

此函数返回一个字符串，用于表示传递给它的 resource 的类型。如果参数不是合法的 resource，将产生错误。


5.PHP 类型比较

5.PHP 类型比较

虽然 PHP 是弱类型语言，但也需要明白变量类型及它们的意义，因为我们经常需要对 PHP 变量进行比较，包含松散和严格比较。

  • 松散比较：使用两个等号 == 比较，只比较值，不比较类型。
  • 严格比较：用三个等号 === 比较，除了比较值，也比较类型。

例如，"42" 是一个字符串而 42 是一个整数。FALSE 是一个布尔值而 "FALSE" 是一个字符串。

PHP中 比较 0、false、null

Copyright © 2023. All rights reserved. (To change the copyright info, just edit it in template.)


6.PHP 常量

6.PHP 常量

PHP 中的常量是指一旦定义后其值不能被改变的标识符。

常量值被定义后，在脚本的其他任何地方都不能被改变。

常量可以用 define() 函数或 const 关键字来定义。

常量的特性

PHP 常量

  1. 不变性: 常量一旦定义，其值不能改变。
  2. 全局作用域: 常量在定义后，可以在整个脚本的任何地方使用，无需使用 global 关键字。
  3. 数据类型: 常量的值可以是标量数据类型（如布尔值、整数、浮点数、字符串）或数组（PHP 7 及以上版本）。
  4. 区分大小写: 常量名称默认是区分大小写的。如果需要定义大小写不敏感的常量，可以在 define() 函数的第三个参数设置为 true。

常量是一个简单值的标识符，该值在脚本中不能改变。

一个常量由英文字母、下划线、和数字组成，但数字不能作为首字母出现。 (常量名不需要加 $ 修饰符)。

注意： 常量在整个脚本中都可以使用。

设置 PHP 常量

设置常量，使用 define() 函数，函数语法如下：

bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )

该函数有三个参数:

  • name：必选参数，常量名称，即标志符。

  • value：必选参数，常量的值。

  • case_insensitive ：可选参数，如果设置为 TRUE，该常量则大小写不敏感，默认是大小写敏感的。

    注意：自 PHP 7.3.0 开始，定义不区分大小写的常量已被弃用。从 PHP 8.0.0 开始，只有 false 是可接受的值，传递 true 将产生一个警告。

以下实例我们创建一个 区分大小写的常量（PHP7.3 版本之后不建议使用）

常量是全局的

常量在定义后，默认是全局变量，可以在整个运行的脚本的任何地方使用。

以下实例演示了在函数内使用常量，即便常量定义在函数外也可以正常使用常量。

使用 const 关键字

const CONSTANT_NAME = "value";

以下是一个使用 const 关键字定义常量的实例：

预定义常量

PHP 提供了一些预定义常量，可以在脚本中直接使用。这些常量通常用于获取 PHP 的配置信息、版本信息等。常见的预定义常量有：

  • PHP_VERSION：当前 PHP 解析器的版本。
  • PHP_OS：服务器的操作系统。
  • PHP_INT_MAX：最大的整数值。
  • E_ERROR、E_WARNING、E_PARSE 等：错误报告级别。

常量数组（PHP 7 及以上版本）

在 PHP 7 及以上版本中，常量也可以是数组。

或者使用 const：


7.PHP 字符串变量

7.PHP 字符串变量

PHP 字符串变量

字符串变量用于存储并处理文本。

PHP 中的字符串变量

字符串变量用于包含有字符的值。

在创建字符串之后，我们就可以对它进行操作了。您可以直接在函数中使用字符串，或者把它存储在变量中。

在下面的实例中，我们创建一个名为 txt 的字符串变量，并赋值为 "Hello world!" 。然后我们输出 txt 变量的值：

注释：当您赋一个文本值给变量时，请记得给文本值加上单引号或者双引号。

现在，让我们来看看一些常用的操作字符串的函数和运算符。

1.PHP 并置运算符

在 PHP 中，只有一个字符串运算符。

并置运算符 (.) 用于把两个字符串值连接起来。

下面的实例演示了如何将两个字符串变量连接在一起：

2.PHP strlen() 函数

有时知道字符串值的长度是很有用的。

strlen() 函数返回字符串的长度（字节数）。

下面的实例返回字符串 "Hello world!" 的长度：

3.PHP strpos() 函数

strpos() 函数用于在字符串内查找一个字符或一段指定的文本。

如果在字符串中找到匹配，该函数会返回第一个匹配的字符位置。如果未找到匹配，则返回 FALSE。

下面的实例在字符串 "Hello world!" 中查找文本 "world"：


8.PHP 运算符

8.PHP 运算符

PHP 运算符

本章节我们将讨论 PHP 中不同运算符的应用。

在 PHP 中，赋值运算符 = 用于给变量赋值。

在 PHP 中，算术运算符 + 用于把值加在一起。

PHP 算术运算符

运算符 | 名称 | 描述 | 实例 | 结果
x + y | 加 | x 和 y 的和 | 2 + 2 | 4
x - y | 减 | x 和 y 的差 | 5 - 2 | 3
x * y | 乘 | x 和 y 的积 | 5 * 2 | 10
x / y | 除 | x 和 y 的商 | 15 / 5 | 3
x % y 模（除法的余数） x 除以 y 的余数 5 % 2
10 % 8
10 % 2 		1
2
0
-x 设置负数 取 x 的相反符号
<?php
$x = 2;
echo -$x;
?>
 -2
~x 取反

x 取反，按二进制位进行"取反"运算。运算规则：

~1=-2;
~0=-1;

<?php
$x = 2;
echo ~$x;
?>
 -3
a . b | 并置 | 连接两个字符串 | "Hi" . "Ha" | HiHa

以下实例演示了使用不同算术运算符得到的不同结果：

PHP7+ 版本新增整除运算符 intdiv()，该函数返回值为第一个参数除于第二个参数的值并取整（向下取整），使用实例：

PHP 赋值运算符

在 PHP 中，基本的赋值运算符是 =。它意味着左操作数被设置为右侧表达式的值。也就是说，$x = 5 的值是 5。

运算符 | 等同于 | 描述
x = y | x = y | 左操作数被设置为右侧表达式的值
x += y | x = x + y | 加
x -= y | x = x - y | 减
x *= y | x = x * y | 乘
x /= y | x = x / y | 除
x %= y | x = x % y | 模（除法的余数）
a .= b | a = a . b | 连接两个字符串

以下实例演示了使用不同赋值运算符得到的不同结果：

以下实例演示了使用不同字符串运算符得到的相同结果：

PHP 递增/递减运算符

运算符 | 名称 | 描述
++ x | 预递增 | x 加 1，然后返回 x
x ++ | 后递增 | 返回 x，然后 x 加 1
-- x | 预递减 | x 减 1，然后返回 x
x -- | 后递减 | 返回 x，然后 x 减 1

以下实例演示了使用递增/递减运算符得到的结果：

PHP 比较运算符

比较操作符可以让您比较两个值：

运算符 | 名称 | 描述 | 实例
x == y | 等于 | 如果 x 等于 y，则返回 true | 5==8 返回 false
x === y | 绝对等于 | 如果 x 等于 y，且它们类型相同，则返回 true | 5==="5" 返回 false
x != y | 不等于 | 如果 x 不等于 y，则返回 true | 5!=8 返回 true
x <> y | 不等于 | 如果 x 不等于 y，则返回 true | 5<>8 返回 true
x !== y | 不绝对等于 | 如果 x 不等于 y，或它们类型不相同，则返回 true | 5!=="5" 返回 true
x > y | 大于 | 如果 x 大于 y，则返回 true | 5>8 返回 false
x < y | 小于 | 如果 x 小于 y，则返回 true | 5<8 返回 true
x >= y | 大于等于 | 如果 x 大于或者等于 y，则返回 true | 5>=8 返回 false
x <= y | 小于等于 | 如果 x 小于或者等于 y，则返回 true | 5<=8 返回 true

PHP 逻辑运算符

运算符 | 名称 | 描述 | 实例
x and y | 与 | 如果 x 和 y 都为 true，则返回 true | x=6 y=3 (x < 10 and y > 1) 返回 true
x or y | 或 | 如果 x 和 y 至少有一个为 true，则返回 true | x=6 y=3 (x==6 or y==5) 返回 true
x xor y | 异或 | 如果 x 和 y 有且仅有一个为 true，则返回 true | x=6 y=3 (x==6 xor y==3) 返回 false
x && y | 与 | 如果 x 和 y 都为 true，则返回 true | x=6 y=3 (x < 10 && y > 1) 返回 true
x || y | 或 | 如果 x 和 y 至少有一个为 true，则返回 true | x=6 y=3 (x==5 || y==5) 返回 false
! x | 非 | 如果 x 不为 true，则返回 true | x=6 y=3 !(x==y) 返回 true

PHP 数组运算符

运算符 | 名称 | 描述
x + y | 集合 | x 和 y 的集合
x == y | 相等 | 如果 x 和 y 具有相同的键/值对，则返回 true
x === y | 恒等 | 如果 x 和 y 具有相同的键/值对，且顺序相同类型相同，则返回 true
x != y | 不相等 | 如果 x 不等于 y，则返回 true
x <> y | 不相等 | 如果 x 不等于 y，则返回 true
x !== y | 不恒等 | 如果 x 不等于 y，则返回 true

三元运算符

另一个条件运算符是"?:"（或三元）运算符 。

语法格式

(expr1) ? (expr2) : (expr3)

对 expr1 求值为 TRUE 时的值为 expr2，在 expr1 求值为 FALSE 时的值为 expr3。

自 PHP 5.3 起，可以省略三元运算符中间那部分。表达式 expr1 ?: expr3 在 expr1 求值为 TRUE 时返回 expr1，否则返回 expr3。

实例

以下实例中通过判断 $_GET 请求中含有 user 值，如果有返回 $_GET['user']，否则返回 nobody：

注意：PHP_EOL 是一个换行符，兼容更大平台。

在 PHP7+ 版本多了一个 NULL 合并运算符 ??，实例如下：

组合比较符(PHP7+)

PHP7+ 支持组合比较符（combined comparison operator）也称之为太空船操作符，符号为 <=>。组合比较运算符可以轻松实现两个变量的比较，当然不仅限于数值类数据的比较。

语法格式如下：

$c = $a <=> $b;

解析如下：

  • 如果 $a > $b, 则 $c 的值为 1。
  • 如果 $a == $b, 则 $c 的值为 0。
  • 如果 $a < $b, 则 $c 的值为 -1。

实例如下：

运算符优先级

下表按照优先级从高到低列出了运算符。同一行中的运算符具有相同优先级，此时它们的结合方向决定求值顺序。

说明：左 ＝ 从左到右，右 ＝ 从右到左。

结合方向 | 运算符 | 附加信息
无 | clone new | clone 和 new
左 | [ | array()
右 | ++ -- ~ (int) (float) (string) (array) (object) (bool) @ | 类型和递增／递减
无 | instanceof | 类型
右 | ! | 逻辑运算符
左 | * / % | 算术运算符
左 | + – . | 算术运算符和字符串运算符
左 | << >> | 位运算符
无 | == != === !== <> | 比较运算符
左 | & | 位运算符和引用
左 | ^ | 位运算符
左 | | | 位运算符
左 | && | 逻辑运算符
左 | || | 逻辑运算符
左 | ? : | 三元运算符
右 | = += -= *= /= .= %= &= |= ^= <<= >>= => | 赋值运算符
左 | and | 逻辑运算符
左 | xor | 逻辑运算符
左 | or | 逻辑运算符
左 | , | 多处用到


9.PHP If

9.PHP If

PHP 条件语句

当您编写代码时，您常常需要为不同的判断执行不同的动作。您可以在代码中使用条件语句来完成此任务。

在 PHP 中，提供了下列条件语句：

  • if 语句 - 在条件成立时执行代码
  • if...else 语句 - 在条件成立时执行一块代码，条件不成立时执行另一块代码
  • if...elseif....else 语句 - 在若干条件之一成立时执行一个代码块

1.PHP - if 语句

if 语句用于仅当指定条件成立时执行代码。

语法

if (条件)
{
    条件成立时要执行的代码;
}

如果当前时间小于 20，下面的实例将输出 "Have a good day!"：

2.PHP - if...else 语句

在条件成立时执行一块代码，条件不成立时执行另一块代码，请使用 if....else 语句。

语法

if
(条件)
{
条件成立时执行的代码;
}
else
{
条件不成立时执行的代码;
}

如果当前时间小于 20，下面的实例将输出 "Have a good day!"，否则输出 "Have a good night!"：

3.PHP - if...elseif....else 语句

在若干条件之一成立时执行一个代码块，请使用 if....elseif...else 语句。.

语法

if (条件)
{
    if 条件成立时执行的代码;
}
elseif (条件)
{
    elseif 条件成立时执行的代码;
}
else
{
    条件不成立时执行的代码;
}

如果当前时间小于 10，下面的实例将输出 "Have a good morning!"，如果当前时间不小于 10 且小于 20，则输出 "Have a good day!"，否则输出 "Have a good night!"：


10.PHP Switch

10.PHP Switch

PHP Switch 语句

switch 语句用于根据多个不同条件执行不同动作。

PHP Switch 语句

如果您希望有选择地执行若干代码块之一，请使用 switch 语句。

语法

<?php
switch (expression)
{
case value1: // 代码块1
break;
case value2: // 代码块2
break; // 更多的 case 语句
default: // 如果没有匹配的值
}
?>

参数说明：

  • expression 是要被比较的表达式。
  • case value: 是可能的值，如果 expression 的值等于某个 case 的值，就执行相应的代码块。
  • break; 用于终止 switch 语句，防止继续执行下一个 case。
  • default: 是可选的，用于指定当没有匹配的 case 时执行的代码块。

工作原理：首先对一个简单的表达式 n（通常是变量）进行一次计算。将表达式的值与结构中每个 case 的值进行比较。如果存在匹配，则执行与 case 关联的代码。代码执行后，使用 break 来阻止代码跳入下一个 case 中继续执行。default 语句用于不存在匹配（即没有 case 为真）时执行。


11.PHP 数组

11.PHP 数组

PHP 数组

数组能够在单个变量中存储多个值：

数组是什么？

数组是一个能在单个变量中存储多个值的特殊变量。

如果您有一个项目清单（例如：车名字的清单），将其存储到单个变量中，如下所示：

$cars1="Volvo";
$cars2="BMW";
$cars3="Toyota";

然而，如果您想要遍历数组并找出特定的一个呢？如果数组的项不只 3 个而是 300 个呢？

解决办法是创建一个数组！

数组可以在单个变量中存储多个值，并且您可以根据键访问其中的值。

在 PHP 中创建数组

在 PHP 中，array() 函数用于创建数组：

array();

在 PHP 中，有三种类型的数组：

  • 数值数组 - 带有数字 ID 键的数组
  • 关联数组 - 带有指定的键的数组，每个键关联一个值
  • 多维数组 - 包含一个或多个数组的数组

PHP 数值数组

这里有两种创建数值数组的方法：

自动分配 ID 键（ID 键总是从 0 开始）：

$cars=array("Volvo","BMW","Toyota");

人工分配 ID 键：

$cars[0]="Volvo";
$cars[1]="BMW";
$cars[2]="Toyota";

1.获取数组的长度 - count() 函数

2.遍历数值数组

遍历并打印数值数组中的所有值，您可以使用 for 循环，如下所示：

3.PHP 关联数组（键值对）

关联数组是使用您分配给数组的指定的键的数组。

这里有两种创建关联数组的方法：

$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");

or:

$age['Peter']="35";
$age['Ben']="37";
$age['Joe']="43";

随后可以在脚本中使用指定的键：

4.遍历关联数组

遍历并打印关联数组中的所有值，您可以使用 foreach 循环，如下所示：


12.PHP 数组排序

12.PHP 数组排序

PHP 数组排序

数组中的元素可以按字母或数字顺序进行降序或升序排列。

PHP - 数组排序函数

在本章中，我们将一一介绍下列 PHP 数组排序函数：

  • sort() - 对数组进行升序排列
  • rsort() - 对数组进行降序排列
  • asort() - 根据关联数组的值，对数组进行升序排列
  • ksort() - 根据关联数组的键，对数组进行升序排列
  • arsort() - 根据关联数组的值，对数组进行降序排列
  • krsort() - 根据关联数组的键，对数组进行降序排列

1.sort() - 对数组进行升序排列

下面的实例将 $cars 数组中的元素按照字母升序排列：

下面的实例将 $numbers 数组中的元素按照数字升序排列：

2.rsort() - 对数组进行降序排列

下面的实例将 $cars 数组中的元素按照字母降序排列：

3.asort() - 根据数组的值，对数组进行升序排列

下面的实例根据数组的值，对关联数组进行升序排列：

4.ksort() - 根据数组的键，对数组进行升序排列

下面的实例根据数组的键，对关联数组进行升序排列：

5.arsort() - 根据数组的值，对数组进行降序排列

下面的实例根据数组的值，对关联数组进行降序排列：

6.krsort() - 根据数组的键，对数组进行降序排列

下面的实例根据数组的值，对关联数组进行降序排列：


13.PHP 超级全局变量

13.PHP 超级全局变量

PHP 超级全局变量

超级全局变量在PHP 4.1.0之后被启用, 是PHP系统中自带的变量，在一个脚本的全部作用域中都可用。

PHP 超级全局变量

PHP中预定义了几个超级全局变量（superglobals） ，这意味着它们在一个脚本的全部作用域中都可用。 你不需要特别说明，就可以在函数及类中使用。

PHP 超级全局变量列表:

  • $GLOBALS
  • $_SERVER
  • $_REQUEST
  • $_POST
  • $_GET
  • $_FILES
  • $_ENV
  • $_COOKIE
  • $_SESSION

本章节我们将讲解几个常用的超级全局变量,其余变量我们在接下来几个章节会介绍到。

1.PHP $GLOBALS

$GLOBALS 是PHP的一个超级全局变量组，在一个PHP脚本的全部作用域中都可以访问。

$GLOBALS 是一个包含了全部变量的全局组合数组。变量的名字就是数组的键。

以下实例介绍了如何使用超级全局变量 $GLOBALS:

以上实例中 z 是一个$GLOBALS数组中的超级全局变量，该变量同样可以在函数外访问。

2.PHP $_SERVER

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目；服务器可能会忽略一些，或者提供一些没有在这里列举出来的项目。

以下实例中展示了如何使用$_SERVER中的元素:

下表列出了所有 $_SERVER 变量中的重要元素:

元素/代码 | 描述
$_SERVER['PHP_SELF'] | 当前执行脚本的文件名，与 document root 有关。例如，在地址为 http://example.com/test.php/foo.bar 的脚本中使用 $_SERVER['PHP_SELF'] 将得到 /test.php/foo.bar。__FILE__ 常量包含当前(例如包含)文件的完整路径和文件名。 从 PHP 4.3.0 版本开始，如果 PHP 以命令行模式运行，这个变量将包含脚本名。之前的版本该变量不可用。
$_SERVER['GATEWAY_INTERFACE'] | 服务器使用的 CGI 规范的版本；例如，"CGI/1.1"。
$_SERVER['SERVER_ADDR'] | 当前运行脚本所在的服务器的 IP 地址。
$_SERVER['SERVER_NAME'] | 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中，该名称是由那个虚拟主机所设置的值决定。(如: www.runoob.com)
$_SERVER['SERVER_SOFTWARE'] | 服务器标识字符串，在响应请求时的头信息中给出。 (如：Apache/2.2.24)
$_SERVER['SERVER_PROTOCOL'] | 请求页面时通信协议的名称和版本。例如，"HTTP/1.0"。
$_SERVER['REQUEST_METHOD'] | 访问页面使用的请求方法；例如，"GET", "HEAD"，"POST"，"PUT"。
$_SERVER['REQUEST_TIME'] | 请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如：1377687496)
$_SERVER['QUERY_STRING'] | query string（查询字符串），如果有的话，通过它进行页面访问。
$_SERVER['HTTP_ACCEPT'] | 当前请求头中 Accept: 项的内容，如果存在的话。
$_SERVER['HTTP_ACCEPT_CHARSET'] | 当前请求头中 Accept-Charset: 项的内容，如果存在的话。例如："iso-8859-1,*,utf-8"。
$_SERVER['HTTP_HOST'] | 当前请求头中 Host: 项的内容，如果存在的话。
$_SERVER['HTTP_REFERER'] | 引导用户代理到当前页的前一页的地址（如果存在）。由 user agent 设置决定。并不是所有的用户代理都会设置该项，有的还提供了修改 HTTP_REFERER 的功能。简言之，该值并不可信。)
$_SERVER['HTTPS'] | 如果脚本是通过 HTTPS 协议被访问，则被设为一个非空的值。
$_SERVER['REMOTE_ADDR'] | 浏览当前页面的用户的 IP 地址。
$_SERVER['REMOTE_HOST'] | 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。
$_SERVER['REMOTE_PORT'] | 用户机器上连接到 Web 服务器所使用的端口号。
$_SERVER['SCRIPT_FILENAME'] | 当前执行脚本的绝对路径。
$_SERVER['SERVER_ADMIN'] | 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上，则该值是那个虚拟主机的值。(如：someone@runoob.com)
$_SERVER['SERVER_PORT'] | Web 服务器使用的端口。默认值为 "80"。如果使用 SSL 安全连接，则这个值为用户设置的 HTTP 端口。
$_SERVER['SERVER_SIGNATURE'] | 包含了服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] | 当前脚本所在文件系统（非文档根目录）的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。
$_SERVER['SCRIPT_NAME'] | 包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 常量包含当前脚本(例如包含文件)的完整路径和文件名。
$_SERVER['SCRIPT_URI'] | URI 用来指定要访问的页面。例如 "/index.html"。

3.PHP $_REQUEST

PHP $_REQUEST 用于收集HTML表单提交的数据。

以下实例显示了一个输入字段（input）及提交按钮(submit)的表单(form)。 当用户通过点击 "Submit" 按钮提交表单数据时, 表单数据将发送至<form>标签中 action 属性中指定的脚本文件。 在这个实例中，我们指定文件来处理表单数据。如果你希望其他的PHP文件来处理该数据，你可以修改该指定的脚本文件名。 然后，我们可以使用超级全局变量 $_REQUEST 来收集表单中的 input 字段数据:

效果：

4.PHP $_POST

PHP $_POST 被广泛应用于收集表单数据，在HTML form标签的指定该属性："method="post"。

以下实例显示了一个输入字段（input）及提交按钮(submit)的表单(form)。 当用户通过点击 "Submit" 按钮提交表单数据时, 表单数据将发送至<form>标签中 action 属性中指定的脚本文件。 在这个实例中，我们指定文件来处理表单数据。如果你希望其他的PHP文件来处理该数据，你可以修改该指定的脚本文件名。 然后，我们可以使用超级全局变量 $_POST 来收集表单中的 input 字段数据:

效果：

5.PHP $_GET

PHP $_GET 同样被广泛应用于收集表单数据，在HTML form标签的指定该属性："method="get"。

$_GET 也可以收集URL中发送的数据。

假定我们有一个包含参数的超链接HTML页面：

<html>
<body>

<a href="test_get.php?subject=PHP&web=runoob.com">Test $GET</a>

</body>
</html>

当用户点击链接 "Test $GET", 参数 "subject" 和 "web" 将发送至"test_get.php",你可以在 "test_get.php" 文件中使用 $_GET 变量来获取这些数据。

以下实例显示了 "test_get.php" 文件的代码:

效果：


14.PHP While 循环

14.PHP While 循环

PHP 循环 - While 循环

循环执行代码块指定的次数，或者当指定的条件为真时循环执行代码块。

PHP 循环

在您编写代码时，您经常需要让相同的代码块一次又一次地重复运行。我们可以在代码中使用循环语句来完成这个任务。

在 PHP 中，提供了下列循环语句：

  • while - 只要指定的条件成立，则循环执行代码块
  • do...while - 首先执行一次代码块，然后在指定的条件成立时重复这个循环
  • for - 循环执行代码块指定的次数
  • foreach - 根据数组中每个元素来循环代码块

1.while 循环

while 循环将重复执行代码块，直到指定的条件不成立。

语法

while (条件)
{
    要执行的代码;
}

实例

下面的实例首先设置变量 i 的值为 1 ($i=1;)。

然后，只要 i 小于或者等于 5，while 循环将继续运行。循环每运行一次，i 就会递增 1：

<html>
<body>

<?php
$i=1;
while($i<=5)
{
    echo "The number is " . $i . "<br>";
    $i++;
}
?>

</body>
</html>

输出：

The number is 1
The number is 2
The number is 3
The number is 4
The number is 5

2.do...while 语句

do...while 语句会至少执行一次代码，然后检查条件，只要条件成立，就会重复进行循环。

语法

do
{
    要执行的代码;
}
while (条件);

实例

下面的实例首先设置变量 i 的值为 1 ($i=1;)。

然后，开始 do...while 循环。循环将变量 i 的值递增 1，然后输出。先检查条件（i 小于或者等于 5），只要 i 小于或者等于 5，循环将继续运行：

<html>
<body>

<?php
$i=1;
do
{
    $i++;
    echo "The number is " . $i . "<br>";
}
while ($i<=5);
?>

</body>
</html>

输出：

The number is 2
The number is 3
The number is 4
The number is 5
The number is 6

for 循环和 foreach 循环将在下一章进行讲解。


15.PHP For 循环

15.PHP For 循环

PHP 循环 - For 循环

循环执行代码块指定的次数，或者当指定的条件为真时循环执行代码块。

for 循环

for 循环用于您预先知道脚本需要运行的次数的情况。

语法

for (初始值; 条件; 增量)
{
    要执行的代码;
}

参数：

  • 初始值：主要是初始化一个变量值，用于设置一个计数器（但可以是任何在循环的开始被执行一次的代码）。
  • 条件：循环执行的限制条件。如果为 TRUE，则循环继续。如果为 FALSE，则循环结束。
  • 增量：主要用于递增计数器（但可以是任何在循环的结束被执行的代码）。

注释：上面的初始值和增量参数可为空，或者有多个表达式（用逗号分隔）。

实例

下面的实例定义一个初始值为 i=1 的循环。只要变量 i 小于或者等于 5，循环将继续运行。循环每运行一次，变量 i 就会递增 1：

实例

<?php for ($i=1; $i<=5; $i++) { echo "数字为 " . $i . PHP_EOL; } ?>

输出：

数字为 1
数字为 2
数字为 3
数字为 4
数字为 5

foreach 循环

foreach 循环用于遍历数组。

语法

foreach ($array as $value)
{
    要执行代码;
}

每进行一次循环，当前数组元素的值就会被赋值给 $value 变量（数组指针会逐一地移动），在进行下一次循环时，您将看到数组中的下一个值。

foreach ($array as $key => $value)
{
    要执行代码;
}

每一次循环，当前数组元素的键与值就都会被赋值给 $key 和 $value 变量（数字指针会逐一地移动），在进行下一次循环时，你将看到数组中的下一个键与值。

实例

下面的实例演示了一个输出给定数组的值的循环：

实例

<?php $x=array("Google","Runoob","Taobao"); foreach ($x as $value) { echo $value . PHP_EOL; } ?>

输出：

Google
Runoob
Taobao

下面的实例演示了一个输出给定数组键与值的循环：

实例

<?php $x=array(1=>"Google", 2=>"Runoob", 3=>"Taobao"); foreach ($x as $key => $value) { echo "key 为 " . $key . "，对应的 value 为 ". $value . PHP_EOL; } ?>

输出：

key  为 1，对应的 value 为 Google
key  为 2，对应的 value 为 Runoob
key  为 3，对应的 value 为 Taobao


16.PHP 函数

16.PHP 函数

PHP 函数

PHP 的真正威力源自于它的函数。

在 PHP 中，提供了超过 1000 个内建的函数。

PHP 函数

在本章中，我们将为您讲解如何创建自己的函数。

如要在页面加载时执行脚本，您可以把它放到函数里。

函数是通过调用函数来执行的。

你可以在页面的任何位置调用函数。

1.创建 PHP 函数

函数是通过调用函数来执行的。

语法

<?php
function functionName()
{
 // 要执行的代码
}
?>

PHP 函数准则：

  • 函数的名称应该提示出它的功能
  • 函数名称以字母或下划线开头（不能以数字开头）

实例

一个简单的函数，在其被调用时能输出我的名称：

实例

<?php
function writeName()
{
echo "Kai Jim Refsnes";
}
echo "My name is ";
writeName();
?>

输出：

My name is Kai Jim Refsnes

2.PHP 函数 - 添加参数

为了给函数添加更多的功能，我们可以添加参数，参数类似变量。

参数就在函数名称后面的一个括号内指定。

实例 1

下面的实例将输出不同的名字，但姓是相同的：

实例

<?php
function writeName($fname)
{
echo $fname . " Refsnes.<br>";
}
echo "My name is ";
writeName("Kai Jim");
echo "My sister's name is ";
writeName("Hege");
echo "My brother's name is ";
writeName("Stale");
?>

输出：

My name is Kai Jim Refsnes.
My sister's name is Hege Refsnes.
My brother's name is Stale Refsnes.

实例 2

下面的函数有两个参数：

实例

<?php
function writeName($fname,$punctuation)
{
echo $fname . " Refsnes" . $punctuation . "<br>";
}

echo "My name is ";
writeName("Kai Jim",".");
echo "My sister's name is ";
writeName("Hege","!");
echo "My brother's name is ";
writeName("St?le","?");
?>

输出：

My name is Kai Jim Refsnes.
My sister's name is Hege Refsnes!
My brother's name is St?le Refsnes?

3.PHP 函数 - 返回值

如需让函数返回一个值，请使用 return 语句。

实例

<?php
function add($x,$y)
{
$total=$x+$y;
return $total;
}
echo "1 + 16 = " . add(1,16);
?>

输出：

1 + 16 = 17

4.PHP 变量函数

变量函数是指在 PHP 中，将一个变量作为函数名来调用的函数。

变量函数可以让我们在运行时动态地决定调用哪个函数。

实例

<?php
function foo() {
echo "In foo()<br />\n";
}

function bar($arg = '')
{
echo "In bar(); argument was '$arg'.<br />\n";
}

// 使用 echo 的包装函数
function echoit($string)
{
echo $string;
}

$func = 'foo';
$func();
     // 调用 foo()

$func = 'bar';
$func('test');  // 调用 bar()

$func = 'echoit';
$func('test');  // 调用 echoit()
?>

也可以用变量函数的语法来调用一个对象的方法。

实例

<?php
class Foo
{
    function Variable()
    {
        $name = 'Bar';
        $this->$name(); // 调用 Bar() 方法
    }

    function Bar()
    {
        echo "This is Bar";
    }
}

$foo = new Foo();
$funcname = "Variable";
$foo->$funcname();  // 调用 $foo->Variable()

?>


17.PHP 魔术常量

17.PHP 魔术常量

PHP 魔术常量

PHP 向它运行的任何脚本提供了大量的预定义常量。

不过很多常量都是由不同的扩展库定义的，只有在加载了这些扩展库时才会出现，或者动态加载后，或者在编译时已经包括进去了。

有八个魔术常量它们的值随着它们在代码中的位置改变而改变。

例如 __LINE__ 的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写，如下：

1.__LINE__

文件中的当前行号。

实例

<?php
echo '这是第 " ' . __LINE__ . ' " 行';
?>

以上实例输出结果为：

这是第 “ 2 ” 行

2.__FILE__

文件的完整路径和文件名。如果用在被包含文件中，则返回被包含的文件名。

自 PHP 4.0.2 起，__FILE__ 总是包含一个绝对路径（如果是符号连接，则是解析后的绝对路径），而在此之前的版本有时会包含一个相对路径。

实例:

实例

<?php
echo '该文件位于 " ' . __FILE__ . ' " ';
?>

以上实例输出结果为：

该文件位于 “ E:\wamp\www\test\index.php ”

3.__DIR__

文件所在的目录。如果用在被包括文件中，则返回被包括的文件所在的目录。

它等价于 dirname(__FILE__)。除非是根目录，否则目录中名不包括末尾的斜杠。（PHP 5.3.0中新增）

实例

<?php
echo '该文件位于 " ' . __DIR__ . ' " ';
?>

以上实例输出结果为：

该文件位于 “ E:\wamp\www\test ”

4.__FUNCTION__

函数名称（PHP 4.3.0 新加）。

自 PHP 5 起本常量返回该函数被定义时的名字（区分大小写）。

在 PHP 4 中该值总是小写字母的。

实例

<?php
function test()
{
echo '函数名为：' . __FUNCTION__ ;
}
test();
?>

以上实例输出结果为：

函数名为：test

5.__CLASS__

类的名称（PHP 4.3.0 新加）。自 PHP 5 起本常量返回该类被定义时的名字（区分大小写）。

在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域（例如 Foo\Bar）。

注意自 PHP 5.4 起 __CLASS__ 对 trait 也起作用。

当用在 trait 方法中时，__CLASS__ 是调用 trait 方法的类的名字。

实例

<?php
class test
{
function _print()
{
echo '类名为：' . __CLASS__ . "<br>";
echo '函数名为：' . __FUNCTION__ ;
}
}
$t = new test();
$t->_print();
?>

以上实例输出结果为：

类名为：test
函数名为：_print

6.__TRAIT__

Trait 的名字（PHP 5.4.0 新加）。自 PHP 5.4.0 起，PHP 实现了代码复用的一个方法，称为 traits。

Trait 名包括其被声明的作用区域（例如 Foo\Bar）。

从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。

优先顺序是当前类中的方法会覆盖 trait 方法，而 trait 方法又覆盖了基类中的方法。

实例

<?php
class Base
{
public function sayHello()
{
echo 'Hello ';
}
}
 trait SayWorld
{
public function sayHello()
{
parent::sayHello();
echo 'World!';
}
}
class MyHelloWorld extends Base
{
use SayWorld;
}
$o = new MyHelloWorld();
$o->sayHello(); ?>

以上例程会输出：

Hello World!

7.__METHOD__

类的方法名（PHP 5.0.0 新加）。返回该方法被定义时的名字（区分大小写）。

实例:

实例

<?php function test()
{
echo '函数名为：' . __METHOD__ ;
}
test();
?>

以上实例输出结果为：

函数名为：test

8.__NAMESPACE__

当前命名空间的名称（区分大小写）。此常量是在编译时定义的（PHP 5.3.0 新增）。

实例:

实例

<?php
namespace MyProject;
echo '命名空间为："', __NAMESPACE__, '"';// 输出 "MyProject"
?>

以上实例输出结果为：

命名空间为："MyProject"


18.PHP 命名空间

18.PHP 命名空间

PHP 命名空间(namespace)

PHP 命名空间(namespace)是在 PHP 5.3 中加入的，目的是解决重名问题，PHP中不允许两个函数或者类出现相同的名字，否则会产生一个致命的错误。

PHP 命名空间可以解决以下两类问题：

  1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
  2. 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名（或简短）的名称，提高源代码的可读性。

定义命名空间

默认情况下，所有常量、类和函数名都放在全局空间下，就和PHP支持命名空间之前一样。

命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间，它必须在其它所有代码之前声明命名空间。

语法格式如下:

<?php
// 定义代码在 'MyProject' 命名空间中
namespace MyProject;

// ... 代码 ...

你也可以在同一个文件中定义不同的命名空间代码，如：

<?php
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
?>

不建议使用这种语法在单个文件中定义多个命名空间。建议使用下面的大括号形式的语法。

<?php
namespace MyProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}

namespace AnotherProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}
?>

将全局的非命名空间中的代码与命名空间中的代码组合在一起，只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来，例如：

<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。

<?php
declare(encoding='UTF-8'); //定义多个命名空间和不包含在命名空间中的代码
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

以下代码会出现语法错误：

<html>
<?php
namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 -　命名空间必须是程序脚本的第一条语句
?>

子命名空间

与目录和文件的关系很像，PHP 命名空间也允许指定层次化的命名空间的名称。因此，命名空间的名字可以使用分层次的方式定义：

<?php
namespace MyProject\Sub\Level;  //声明分层次的单个命名空间

const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */  }

?>

上面的例子创建了常量 MyProject\Sub\Level\CONNECT_OK，类 MyProject\Sub\Level\Connection 和函数 MyProject\Sub\Level\Connect。

命名空间使用

PHP 命名空间中的类名可以通过三种方式引用：

  1. 非限定名称，或不包含前缀的类名称，例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace，foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的，不包含在任何命名空间中的代码，则 foo 会被解析为foo。 警告：如果命名空间中的函数或常量未定义，则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。

  2. 限定名称,或包含前缀的名称，例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace，则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的，不包含在任何命名空间中的代码，foo 会被解析为subnamespace\foo。

  3. 完全限定名称，或包含了全局前缀操作符的名称，例如， $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下，foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。

下面是一个使用这三种方式的实例：

file1.php 文件代码

<?php
namespace Foo\Bar\subnamespace;

const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}
?>

file2.php 文件代码

<?php
namespace Foo\Bar;
include 'file1.php';

const FOO = 2;
function foo() {}
class foo
{
    static function staticmethod() {}
}

/* 非限定名称 */
foo(); // 解析为函数 Foo\Bar\foo
foo::staticmethod(); // 解析为类 Foo\Bar\foo ，方法为 staticmethod
echo FOO; // 解析为常量 Foo\Bar\FOO

/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
                                  // 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO

/* 完全限定名称 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
?>

注意访问任意全局类、函数或常量，都可以使用完全限定名称，例如 \strlen() 或 \Exception 或 \INI_ALL。

在命名空间内部访问全局类、函数和常量：

<?php
namespace Foo;

function strlen() {}
const INI_ALL = 3;
class Exception {}

$a = \strlen('hi'); // 调用全局函数strlen
$b = \INI_ALL; // 访问全局常量 INI_ALL
$c = new \Exception('error'); // 实例化全局类 Exception
?>

命名空间和动态语言特征

PHP 命名空间的实现受到其语言自身的动态特征的影响。因此，如果要将下面的代码转换到命名空间中，动态访问元素。

example1.php 文件代码：

<?php
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "global";

$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "\n"; // prints global
?>

必须使用完全限定名称（包括命名空间前缀的类名称）。注意因为在动态的类名称、函数名称或常量名称中，限定名称和完全限定名称没有区别，因此其前导的反斜杠是不必要的。

动态访问命名空间的元素

<?php
namespace namespacename;
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "namespaced";

include 'example1.php';

$a = 'classname';
$obj = new $a; // 输出 classname::__construct
$b = 'funcname';
$b(); // 输出函数名
echo constant('constname'), "\n"; // 输出 global

/* 如果使用双引号，使用方法为 "\\namespacename\\classname"*/
$a = '\namespacename\classname';
$obj = new $a; // 输出 namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // 输出 namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // 输出 namespacename\funcname
$b = '\namespacename\funcname';
$b(); // 输出 namespacename\funcname
echo constant('\namespacename\constname'), "\n"; // 输出 namespaced
echo constant('namespacename\constname'), "\n"; // 输出 namespaced
?>

namespace关键字和__NAMESPACE__常量

PHP支持两种抽象的访问当前命名空间内部元素的方法，__NAMESPACE__ 魔术常量和namespace关键字。

常量__NAMESPACE__的值是包含当前命名空间名称的字符串。在全局的，不包括在任何命名空间中的代码，它包含一个空的字符串。

__NAMESPACE__ 示例, 在命名空间中的代码

<?php
namespace MyProject;

echo '"', __NAMESPACE__, '"'; // 输出 "MyProject"
?>

__NAMESPACE__ 示例，全局代码

<?php

echo '"', __NAMESPACE__, '"'; // 输出 ""
?>

常量 __NAMESPACE__ 在动态创建名称时很有用，例如：

使用__NAMESPACE__动态创建名称

<?php
namespace MyProject;

function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;
    return new $a;
}
?>

关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。

namespace操作符，命名空间中的代码

<?php
namespace MyProject;

use blah\blah as mine; // 引入了 blah\blah 命名空间，并定义了个别名mine

mine\mine(); // 调用函数 blah\blah\mine()
namespace\blah\mine(); // 调用函数 MyProject\blah\mine()

namespace\func(); // 调用函数 MyProject\func()
namespace\sub\func(); // 调用函数 MyProject\sub\func()
namespace\cname::method(); // 调用 MyProject\cname 类的静态方法
$a = new namespace\sub\cname(); // 实例化 MyProject\sub\cname 类的对象
$b = namespace\CONSTANT; // 将常量 MyProject\CONSTANT 的值赋给 $b
?>

namespace操作符, 全局代码

<?php

namespace\func(); // calls function func()
namespace\sub\func(); // calls function sub\func()
namespace\cname::method(); // calls static method "method" of class cname
$a = new namespace\sub\cname(); // instantiates object of class sub\cname
$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b
?>

使用命名空间：别名/导入

PHP 命名空间支持 有两种使用别名或导入方式：为类名称使用别名，或为命名空间名称使用别名。

在PHP中，别名是通过操作符 use 来实现的. 下面是一个使用所有可能的三种导入方式的例子：

1、使用use操作符导入/使用别名

<?php
namespace foo;
use My\Full\Classname as Another;

// 下面的例子与 use My\Full\NSname as NSname 相同
use My\Full\NSname;

// 导入一个全局类
use \ArrayObject;

$obj = new namespace\Another; // 实例化 foo\Another 对象
$obj = new Another; // 实例化 My\Full\Classname　对象
NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象
// 如果不使用 "use \ArrayObject" ，则实例化一个 foo\ArrayObject 对象
?>

2、 一行中包含多个use语句

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化 My\Full\Classname 对象
NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
?>

导入操作是在编译执行的，但动态的类名称、函数名称或常量名称则不是。

3、导入和动态名称

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化一个 My\Full\Classname 对象
$a = 'Another';
$obj = new $a;      // 实际化一个 Another 对象
?>

另外，导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的，故不受导入的影响。

4、导入和完全限定名称

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化 My\Full\Classname 类
$obj = new \Another; // 实例化 Another 类
$obj = new Another\thing; // 实例化 My\Full\Classname\thing 类
$obj = new \Another\thing; // 实例化 Another\thing 类
?>

使用命名空间：后备全局函数/常量

在一个命名空间中，当 PHP 遇到一个非限定的类、函数或常量名称时，它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时，必须使用完全限定名称，例如：

1、在命名空间中访问全局类

<?php
namespace A\B\C;
class Exception extends \Exception {}

$a = new Exception('hi'); // $a 是类 A\B\C\Exception 的一个对象
$b = new \Exception('hi'); // $b 是类 Exception 的一个对象

$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
?>

对于函数和常量来说，如果当前命名空间中不存在该函数或常量，PHP 会退而使用全局空间中的函数或常量。

2、 命名空间中后备的全局函数/常量

<?php
namespace A\B\C;

const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}

echo E_ERROR, "\n"; // 输出 "45"
echo INI_ALL, "\n"; // 输出 "7" - 使用全局常量 INI_ALL

echo strlen('hi'), "\n"; // 输出 "1"
if (is_array('hi')) { // 输出 "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}
?>

全局空间

如果没有定义任何命名空间，所有的类与函数的定义都是在全局空间，与 PHP 引入命名空间概念前一样。在名称前加上前缀 \ 表示该名称是全局空间中的名称，即使该名称位于其它的命名空间中时也是如此。

使用全局空间说明

<?php
namespace A\B\C;

/* 这个函数是 A\B\C\fopen */
function fopen() {
     /* ... */
     $f = \fopen(...); // 调用全局的fopen函数
     return $f;
}
?>

命名空间的顺序

自从有了命名空间之后，最容易出错的该是使用类的时候，这个类的寻找路径是什么样的了。

<?php
namespace A;
use B\D, C\E as F;

// 函数调用

foo();      // 首先尝试调用定义在命名空间"A"中的函数foo()
            // 再尝试调用全局函数 "foo"

\foo();     // 调用全局空间函数 "foo"

my\foo();   // 调用定义在命名空间"A\my"中函数 "foo"

F();        // 首先尝试调用定义在命名空间"A"中的函数 "F"
            // 再尝试调用全局函数 "F"

// 类引用

new B();    // 创建命名空间 "A" 中定义的类 "B" 的一个对象
            // 如果未找到，则尝试自动装载类 "A\B"

new D();    // 使用导入规则，创建命名空间 "B" 中定义的类 "D" 的一个对象
            // 如果未找到，则尝试自动装载类 "B\D"

new F();    // 使用导入规则，创建命名空间 "C" 中定义的类 "E" 的一个对象
            // 如果未找到，则尝试自动装载类 "C\E"

new \B();   // 创建定义在全局空间中的类 "B" 的一个对象
            // 如果未发现，则尝试自动装载类 "B"

new \D();   // 创建定义在全局空间中的类 "D" 的一个对象
            // 如果未发现，则尝试自动装载类 "D"

new \F();   // 创建定义在全局空间中的类 "F" 的一个对象
            // 如果未发现，则尝试自动装载类 "F"

// 调用另一个命名空间中的静态方法或命名空间函数

B\foo();    // 调用命名空间 "A\B" 中函数 "foo"

B::foo();   // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
            // 如果未找到类 "A\B" ，则尝试自动装载类 "A\B"

D::foo();   // 使用导入规则，调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
            // 如果类 "B\D" 未找到，则尝试自动装载类 "B\D"

\B\foo();   // 调用命名空间 "B" 中的函数 "foo"

\B::foo();  // 调用全局空间中的类 "B" 的 "foo" 方法
            // 如果类 "B" 未找到，则尝试自动装载类 "B"

// 当前命名空间中的静态方法或函数

A\B::foo();   // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\A\B" 未找到，则尝试自动装载类 "A\A\B"

\A\B::foo();  // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\B" 未找到，则尝试自动装载类 "A\B"
?>

名称解析遵循下列规则：

  1. 对完全限定名称的函数，类和常量的调用在编译时解析。例如 new \A\B 解析为类 A\B。
  2. 所有的非限定名称和限定名称（非完全限定名称）根据当前的导入规则在编译时进行转换。例如，如果命名空间 A\B\C 被导入为 C，那么对 C\D\e() 的调用就会被转换为 A\B\C\D\e()。
  3. 在命名空间内部，所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如，在命名空间 A\B 内部调用 C\D\e()，则 C\D\e() 会被转换为 A\B\C\D\e() 。
  4. 非限定类名根据当前的导入规则在编译时转换（用全名代替短的导入名称）。例如，如果命名空间 A\B\C 导入为C，则 new C() 被转换为 new A\B\C() 。
  5. 在命名空间内部（例如A\B），对非限定名称的函数调用是在运行时解析的。例如对函数 foo() 的调用是这样解析的：
    1. 在当前命名空间中查找名为 A\B\foo() 的函数
    2. 尝试查找并调用 全局(global) 空间中的函数 foo()。
  6. 在命名空间（例如A\B）内部对非限定名称或限定名称类（非完全限定名称）的调用是在运行时解析的。下面是调用 new C() 及 new D\E() 的解析过程： new C()的解析:
    1. 在当前命名空间中查找A\B\C类。
    2. 尝试自动装载类A\B\C。
    new D\E()的解析:
    1. 在类名称前面加上当前命名空间名称变成：A\B\D\E，然后查找该类。
    2. 尝试自动装载类 A\B\D\E。
    为了引用全局命名空间中的全局类，必须使用完全限定名称 new \C()。


19.PHP 面向对象

19.PHP 面向对象

PHP 面向对象

面向对象（Object-Oriented，简称 OO）是一种编程思想和方法，它将程序中的数据和操作数据的方法封装在一起，形成"对象"，并通过对象之间的交互和消息传递来完成程序的功能。面向对象编程强调数据的封装、继承、多态和动态绑定等特性，使得程序具有更好的可扩展性、可维护性和可重用性。

在面向对象的程序设计（英语：Object-oriented programming，缩写：OOP）中，对象是一个由信息及对信息进行处理的描述所组成的整体，是对现实世界的抽象。

在现实世界里我们所面对的事情都是对象，如计算机、电视机、自行车等。

对象的主要三个特性：

  • 对象的行为：对象可以执行的操作，比如：开灯，关灯就是行为。
  • 对象的形态：对对象不同的行为是如何响应的，比如：颜色，尺寸，外型。
  • 对象的表示：对象的表示就相当于身份证，具体区分在相同的行为与状态下有什么不同。

比如 Animal(动物) 是一个抽象类，我们可以具体到一只狗跟一只羊，而狗跟羊就是具体的对象，他们有颜色属性，可以写，可以跑等行为状态。

面向对象编程的三个主要特性：

  • 封装（Encapsulation）：指将对象的属性和方法封装在一起，使得外部无法直接访问和修改对象的内部状态。通过使用访问控制修饰符（public、private、protected）来限制属性和方法的访问权限，从而实现封装。

  • 继承（Inheritance）：指可以创建一个新的类，该类继承了父类的属性和方法，并且可以添加自己的属性和方法。通过继承，可以避免重复编写相似的代码，并且可以实现代码的重用。

  • 多态（Polymorphism）：指可以使用一个父类类型的变量来引用不同子类类型的对象，从而实现对不同对象的统一操作。多态可以使得代码更加灵活，具有更好的可扩展性和可维护性。在 PHP 中，多态可以通过实现接口（interface）和使用抽象类（abstract class）来实现。

面向对象内容

  • 类 ? 定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。

  • 对象 ? 是类的实例。

  • 成员变量 ? 定义在类内部的变量。该变量的值对外是不可见的，但是可以通过成员函数访问，在类被实例化为对象后，该变量即可成为对象的属性。

  • 成员函数 ? 定义在类的内部，可用于访问对象的数据。

  • 继承 ? 继承性是子类自动共享父类数据结构和方法的机制，这是类之间的一种关系。在定义和实现一个类的时候，可以在一个已经存在的类的基础之上来进行，把这个已经存在的类所定义的内容作为自己的内容，并加入若干新的内容。

  • 父类 ? 一个类被其他类继承，可将该类称为父类，或基类，或超类。

  • 子类 ? 一个类继承其他类称为子类，也可称为派生类。

  • 多态 ? 多态性是指相同的函数或方法可作用于多种类型的对象上并获得不同的结果。不同的对象，收到同一消息可以产生不同的结果，这种现象称为多态性。

  • 重载 ? 简单说，就是函数或者方法有同样的名称，但是参数列表不相同的情形，这样的同名不同参数的函数或者方法之间，互相称之为重载函数或者方法。

  • 抽象性 ? 抽象性是指将具有一致的数据结构（属性）和行为（操作）的对象抽象成类。一个类就是这样一种抽象，它反映了与应用有关的重要性质，而忽略其他一些无关内容。任何类的划分都是主观的，但必须与具体的应用有关。

  • 封装 ? 封装是指将现实世界中存在的某个客体的属性与行为绑定在一起，并放置在一个逻辑单元内。

  • 构造函数 ? 主要用来在创建对象时初始化对象， 即为对象成员变量赋初始值，总与new运算符一起使用在创建对象的语句中。

  • 析构函数 ? 析构函数(destructor) 与构造函数相反，当对象结束其生命周期时（例如对象所在的函数已调用完毕），系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作（例如在建立对象时用new开辟了一片内存空间，应在退出前在析构函数中用delete释放）。

下图中我们通过 Car 类 创建了三个对象：Mercedes, Bmw, 和 Audi。

$mercedes = new Car ();
$bmw = new Car ();
$audi = new Car ();

PHP 类定义

PHP 定义类通常语法格式如下：

<?php
class phpClass {
  var $var1;
  var $var2 = "constant string";

  function myfunc ($arg1, $arg2) {
     [..]
  }
  [..]
}
?>

解析如下：

  • 类使用 class 关键字后加上类名定义。

  • 类名后的一对大括号({})内可以定义变量和方法。

  • 类的变量使用 var 来声明, 变量也可以初始化值。

  • 函数定义类似 PHP 函数的定义，但函数只能通过该类及其实例化的对象访问。

实例

<?php
class Site {
  /* 成员变量 */
  var $url;
  var $title;

  /* 成员函数 */
  function setUrl($par){
     $this->url = $par;
  }

  function getUrl(){
     echo $this->url . PHP_EOL;
  }

  function setTitle($par){
     $this->title = $par;
  }

  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
?>

变量 $this 代表自身的对象。

PHP_EOL 为换行符。

PHP 中创建对象

类创建后，我们可以使用 new 运算符来实例化该类的对象：

$runoob = new Site;
$taobao = new Site;
$google = new Site;

以上代码我们创建了三个对象，三个对象各自都是独立的，接下来我们来看看如何访问成员方法与成员变量。

调用成员方法

在实例化对象后，我们可以使用该对象调用成员方法，该对象的成员方法只能操作该对象的成员变量：

// 调用成员函数，设置标题和URL
$runoob->setTitle( "菜鸟教程" );
$taobao->setTitle( "淘宝" );
$google->setTitle( "Google 搜索" );

$runoob->setUrl( 'www.runoob.com' );
$taobao->setUrl( 'www.taobao.com' );
$google->setUrl( 'www.google.com' );

// 调用成员函数，获取标题和URL
$runoob->getTitle();
$taobao->getTitle();
$google->getTitle();

$runoob->getUrl();
$taobao->getUrl();
$google->getUrl();

完整代码如下：


20.PHP 测验

20.PHP 测验