Skip to content

PHP 变量

变量(Variables)是编程中的基本构建块。可以把它们想象成带标签的容器或盒子,用来存储脚本(script)工作所需的信息(数据)。

这些数据可以是文本、数字,或更复杂的结构。

在 PHP 中,创建变量非常简单。它们总是以美元符号($)开头,后面紧跟着变量的名称:

<?php
// 赋值一个字符串值
$message = "Hello, PHP developers!";
// 赋值一个整数值
$userCount = 150;
// 赋值一个浮点数(小数)值
$price = 99.95;
// 赋值一个布尔值(真或假)
$isLoggedIn = false;
// 赋值一个 null 值(代表“无值”)
$noValue = null;
?>

执行此代码后:

  • $message 存储着文本 “Hello, PHP developers!”。
  • $userCount 存储着整数 150。
  • $price 存储着小数 99.95。
  • $isLoggedIn 存储着布尔值 false。
  • $noValue 存储着特殊值 null。

要点:

  • PHP 会根据赋给变量的值自动确定变量的 数据类型(data type)。
  • 在使用变量之前,你不需要像某些其他语言那样使用特殊命令(例如 int 或 string)来声明(declare)变量。当你第一次使用 赋值运算符(assignment operator)(=)给变量赋值时,变量就被创建了。
  • 赋值文本(字符串/string)值时,使用单引号('...')或双引号("...")括起来。双引号允许 变量内插(variable interpolation)(直接在字符串内部嵌入变量),而单引号不允许。

变量名可以很短(如 $x, $i),也可以具有描述性(如 $customerName, $totalAmount)。通常建议使用描述性的名称,以提高代码的可读性(readability)。

命名变量时请遵循以下规则:

  • 必须以 $ 符号开头。
  • $ 后面的第一个字符必须是字母(a-z, A-Z)或下划线(_)。
  • 不能紧跟在 $ 后面以数字开头($1var 是无效的)。
  • 第一个字符之后,名称可以包含字母、数字和下划线。
  • 变量名是区分大小写的(case-sensitive)。$name 和 $Name 是两个不同的变量。
💡惯例: 虽然 PHP 不强制要求,但常见的惯例(PSR 标准)是使用 camelCase(驼峰命名法)命名变量(例如 $firstName, $orderTotal)。

echo 结构(construct)常用于向浏览器或控制台显示数据,包括存储在变量中的值。

输出文本和变量:

<?php
$websiteName = "CoolSite.com";
echo "Welcome to $websiteName!"; // 双引号中的变量内插
?>

使用 连接运算符(concatenation operator)(.):

<?php
$websiteName = "CoolSite.com";
echo 'Welcome to ' . $websiteName . '!'; // 连接操作在单引号或双引号中均可工作
?>

输出操作的结果:

<?php
$quantity = 5;
$unitPrice = 10.50;
$totalCost = $quantity * $unitPrice;
echo "Total cost: $" . $totalCost; // 输出: Total cost: $52.5
?>

你将在后续章节中学习更多关于 echo、print 以及其他输出数据的方法。

如示例所示,在 PHP 中,你不需要显式地声明变量的数据类型(如 integer、string、float)。PHP 在运行时会根据赋给变量的值 动态(dynamically)确定其类型。

在操作中需要时,PHP 会自动执行 类型杂耍(type juggling)(隐式类型转换/implicit type conversion)。例如,将整数 5 与字符串 "10 apples" 相加可能会得到整数 15(具体取决于上下文和 PHP 版本,并可能伴随警告)。

虽然 动态类型(dynamic typing)提供了灵活性,但现代 PHP(7 及以上版本)也支持对函数 参数(argument)、返回值(return value)和类(class) 属性(property)进行 类型声明(type declarations)(标量类型/scalar types、返回类型/return types、属性类型/property types)。这使得通过在需要的地方强制执行类型检查,可以提早捕获错误,从而编写更健壮和可预测的代码。

这与 静态类型语言(statically typed languages)(如 Java、C#、C++)形成对比,在这些语言中,你必须在使用变量之前声明其类型。

变量的作用域(Scope)定义了在脚本中的哪些地方可以访问或修改它。

PHP 主要有以下变量作用域:

  • 局部(Local): 在函数内部声明的变量是该函数的 局部变量。它们只存在于该特定函数内部,也只能在该函数内部访问。
  • 全局(Global): 在任何函数外部声明的变量具有 全局作用域。它们存在于整个脚本中,但 默认情况下不能直接在函数内部访问。
  • 静态(Static): 函数内部的一种特殊类型的局部变量,它在函数调用之间保留其值(与函数退出时销毁的普通局部变量不同)。

在函数外部声明的变量具有 全局作用域:

<?php
$globalVar = 10; // 全局作用域
function testScope() {
// 尝试在此处直接访问 $globalVar 将导致错误或警告
// echo "Inside function: " . $globalVar; // 这将会失败
echo "Inside function: No direct access to globalVar.";
}
testScope();
echo "<br>Outside function: " . $globalVar; // 在此处访问 globalVar 是可以的
?>

在函数内部声明的变量具有 局部作用域:

<?php
function testLocalScope() {
$localVar = 5; // 局部作用域
echo "Inside function: localVar = " . $localVar;
}
testLocalScope();
// 尝试在函数外部访问 $localVar 将导致错误
// echo "<br>Outside function: localVar = " . $localVar; // 这将会失败
?>
💡你可以在不同的函数中使用同名的局部变量,它们之间不会冲突,因为每个局部变量都局限于其自身函数的 作用域(scope)。

访问全局变量:global 关键字和 $GLOBALS 数组

Section titled “访问全局变量:global 关键字和 $GLOBALS 数组”

如果你需要在函数内部访问或修改 全局变量,你有两种主要选择:

  1. 在函数内部使用 global 关键字,放在变量名之前。这告诉 PHP 该变量引用的是 全局作用域中的变量。
<?php
$count = 0; // 全局变量
function incrementCount() {
global $count; // 声明要使用全局的 $count
$count++;
}
incrementCount();
incrementCount();
echo "Count is: " . $count; // 输出: Count is: 2
?>
  1. 使用特殊的 $GLOBALS 超全局数组(superglobal array)。PHP 将所有 全局变量存储在这个数组中,以变量名作为索引(index)。你可以通过这个数组直接访问和修改全局变量。
<?php
$x = 5;
$y = 10;
function addGlobals() {
$GLOBALS['y'] = $GLOBALS['x'] + $GLOBALS['y'];
}
addGlobals();
echo $y; // 输出 15
?>

最佳实践: 过度依赖 全局变量会使代码难以理解和维护。通常更好的做法是将所需的值作为 参数(argument)传递给函数,并从函数返回结果。

通常情况下,当函数执行完毕时,它的所有 局部变量都会被销毁。如果再次调用该函数,它们会从头开始重新创建。

有时,你希望某个 局部变量能够记住它在上次函数调用结束时的值。在第一次声明变量时使用 static 关键字即可实现这一点。

<?php
function staticCounter() {
static $counter = 0; // 仅在第一次调用时初始化
$counter++;
echo "Counter is now: $counter<br>";
}
staticCounter(); // 输出: Counter is now: 1
staticCounter(); // 输出: Counter is now: 2
staticCounter(); // 输出: Counter is now: 3
?>

staticCounter 的后续每次调用都会使用 $counter 在上次调用结束时的值。static $counter = 0; 这一行在第一次执行后实际上被跳过了。

注意:这个变量仍然是函数的 局部变量;不能从外部访问它。