2.1 Variables & Constants
Variable Basics
PHP variables start with the $ symbol and can be used without declaring a type. Variable names are case-sensitive.
<?php
// 变量无需声明,直接赋值即可
$name = "张三";
$age = 28;
$price = 99.5;
$isActive = true;
// 变量名规则:以字母或下划线开头,后跟字母、数字、下划线
$_privateVar = "合法";
$camelCase = "推荐的命名风格";
// 可变变量(少用,但要知道)
$varName = "hello";
$$varName = "world"; // 等价于 $hello = "world"
echo $hello; // 输出: world
Constants
Constants cannot be modified once defined. It is recommended to use const (compile-time) or define() (runtime).
<?php
// 方式一:const(推荐,编译时定义,可用于类中)
const APP_VERSION = "2.0.0";
const MAX_RETRY = 3;
// 方式二:define()(运行时定义,可用于条件语句中)
define('DB_HOST', 'localhost');
define('FEATURES', ['login', 'register', 'profile']); // 数组常量
// 使用常量(不需要 $ 符号)
echo APP_VERSION; // 2.0.0
echo DB_HOST; // localhost
// 魔术常量(双下划线开头和结尾)
echo __FILE__; // 当前文件完整路径
echo __LINE__; // 当前行号
echo __DIR__; // 当前文件所在目录
echo __FUNCTION__; // 当前函数名
echo __CLASS__; // 当前类名
Variable Scope
<?php
$globalVar = "我是全局变量";
function testScope(): void {
// echo $globalVar; // ❌ 报错!函数内无法直接访问全局变量
// 方式一:global 关键字
global $globalVar;
echo $globalVar; // ✅ 可以了
// 方式二:$GLOBALS 超全局数组
echo $GLOBALS['globalVar']; // ✅ 也可以
// 局部变量
$localVar = "我是局部变量";
// 静态变量:函数调用结束后保留值
static $count = 0;
$count++;
echo "调用次数: $count";
}
testScope(); // 调用次数: 1
testScope(); // 调用次数: 2
testScope(); // 调用次数: 3
🔄 Comparison with Python / JavaScript
| Feature | PHP | Python | JavaScript |
|---|---|---|---|
| Variable prefix | $name |
name |
let name |
| Declaration required | No | No | Yes (let/const/var) |
| Constants | const / define() |
No native constants (uppercase by convention) | const |
| Function scope | Isolated from global by default | Can read global, write needs global |
Closure/block scope |
2.2 Data Types
Type Overview
| Category | Type | Example | Description |
|---|---|---|---|
| Scalar | int |
42, 0xFF, 0b1010, 1_000_000 |
Integer, supports hex, binary, underscore separators |
float |
3.14, 1.2e3 |
Floating-point (double precision) | |
string |
"hello", 'world' |
String | |
bool |
true, false |
Boolean (case-insensitive) | |
| Compound | array |
[1, 2, 3] |
Ordered map (serves as both list and dictionary) |
object |
new stdClass |
Instance of a class | |
| Special | null |
null |
Null value, default for unassigned variables |
| Callable | callable |
fn($x) => $x * 2 |
Functions, closures, or callable objects |
Type Detection & Conversion
<?php
$val = "42";
// 检测类型
echo gettype($val); // string
echo get_debug_type($val); // string(PHP 8.0+,更精确)
var_dump($val); // string(2) "42"
// 类型判断函数
is_int($val); // false
is_string($val); // true
is_numeric($val); // true(字符串 "42" 是数字)
is_null($val); // false
is_array($val); // false
// 类型转换(强制)
$intVal = (int) "42"; // 42
$floatVal = (float) "3.14"; // 3.14
$strVal = (string) 100; // "100"
$boolVal = (bool) ""; // false
$arrVal = (array) "hello"; // ["hello"]
// intval() / floatval() / strval() 函数形式
$num = intval("0xFF", 16); // 255,第二参数指定进制
PHP 8.x Type Declarations
<?php
// 基本类型声明
function add(int $a, int $b): int {
return $a + $b;
}
// 可空类型(参数可以传 null)
function findUser(?int $id): ?array {
if ($id === null) {
return null;
}
return ['id' => $id, 'name' => '张三'];
}
// 联合类型(PHP 8.0+)
function formatId(int|string $id): string {
return "ID: $id";
}
// 交叉类型(PHP 8.1+)
function process(Iterator&Countable $collection): void {
foreach ($collection as $item) {
echo $item;
}
}
// DNF 类型(PHP 8.2+,组合联合与交叉)
function handle((Iterator&Countable)|null $data): void {
// ...
}
// 返回 never(PHP 8.1+,函数永不返回)
function throwError(string $msg): never {
throw new RuntimeException($msg);
}
// 返回 void(无返回值)
function logMessage(string $msg): void {
echo "[LOG] $msg\n";
}
// strict_types 严格模式(文件级别)
declare(strict_types=1);
// 开启后 add("3", "4") 将抛出 TypeError(不再自动转换)
2.3 String Operations
Single Quotes vs Double Quotes
<?php
$name = "张三";
$age = 25;
// 双引号:支持变量插值和转义序列
echo "你好,$name!\n"; // 你好,张三!
echo "年龄:{$age}岁\n"; // 年龄:25岁
echo "花括号用于复杂表达式:{$user['name']}\n";
// 单引号:原样输出(性能略好)
echo '你好,$name!\n'; // 你好,$name!\n(原样输出)
// 字符串拼接用 .(点号),不是 +
$greeting = "你好," . $name . "!";
$greeting .= " 欢迎光临。"; // .= 追加赋值
Heredoc & Nowdoc
<?php
$name = "张三";
// Heredoc:类似双引号,支持变量插值
$html = <<<HTML
<div class="card">
<h2>{$name} 的主页</h2>
<p>欢迎来到我的网站</p>
</div>
HTML;
// Nowdoc:类似单引号,不解析变量
$template = <<<'TPL'
Hello, $name!
这里不会做变量替换。
TPL;
echo $html; // 变量被替换
echo $template; // 原样输出 $name
Common String Functions
<?php
$str = " Hello, PHP World! ";
// 长度与查找
echo strlen($str); // 23(含空格)
echo mb_strlen("你好世界"); // 4(多字节安全)
echo strpos($str, "PHP"); // 9(返回位置,0 起始)
echo str_contains($str, "PHP"); // true(PHP 8.0+)
echo str_starts_with($str, " He"); // true(PHP 8.0+)
echo str_ends_with($str, "! "); // true(PHP 8.0+)
// 截取
echo substr($str, 9, 3); // "PHP"
echo mb_substr("你好世界", 0, 2); // "你好"
// 分割与合并
$parts = explode(",", "a,b,c,d"); // ["a", "b", "c", "d"]
$joined = implode(" | ", $parts); // "a | b | c | d"
// 替换
echo str_replace("PHP", "Laravel", $str); // " Hello, Laravel World! "
echo str_ireplace("php", "Laravel", $str); // 不区分大小写替换
// 格式化
echo sprintf("用户: %s, 年龄: %d, 余额: %.2f", "张三", 25, 1234.5);
// 用户: 张三, 年龄: 25, 余额: 1234.50
// 清理
echo trim($str); // "Hello, PHP World!"(去除两端空白)
echo ltrim($str); // 去除左侧
echo rtrim($str); // 去除右侧
// 大小写转换
echo strtolower("HELLO"); // "hello"
echo strtoupper("hello"); // "HELLO"
echo ucfirst("hello world"); // "Hello world"
echo ucwords("hello world"); // "Hello World"
// 其他常用
echo str_repeat("=-", 20); // 重复字符串
echo str_pad("42", 5, "0", STR_PAD_LEFT); // "00042"
echo nl2br("第一行\n第二行"); // "第一行<br />\n第二行"
💡 Multibyte Strings
When handling multibyte characters such as Chinese, always use mb_ prefixed functions (e.g., mb_strlen, mb_substr), otherwise you may get incorrect lengths or truncated results. Make sure mbstring.internal_encoding = UTF-8 is set in php.ini.
2.4 Arrays (PHP's Most Core Data Structure)
PHP arrays are ordered maps, serving simultaneously as lists, dictionaries, sets, stacks, queues, and more. This is PHP's most important and frequently used type.
🔄 Comparison with Python / JavaScript
PHP's array ≈ Python's list + dict combined. A PHP array can be used as an indexed list ([1, 2, 3]) or as an associative dictionary (['name' => 'Zhang San']), or even both at the same time. The closest JavaScript equivalent would be Array + Object, but PHP arrays are more unified in functionality.
Creating Arrays
<?php
// 索引数组(类似 Python list)
$fruits = ["苹果", "香蕉", "橙子"];
$numbers = [1, 2, 3, 4, 5];
// 关联数组(类似 Python dict)
$user = [
'name' => '张三',
'age' => 28,
'email' => 'zhangsan@example.com',
]; // 末尾逗号是允许的(推荐写法)
// 多维数组
$matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
// 复杂嵌套
$users = [
['name' => '张三', 'age' => 28, 'skills' => ['PHP', 'MySQL']],
['name' => '李四', 'age' => 32, 'skills' => ['Go', 'Docker']],
];
// 访问元素
echo $fruits[0]; // "苹果"
echo $user['name']; // "张三"
echo $users[0]['skills'][1]; // "MySQL"
// 修改与添加
$fruits[] = "葡萄"; // 追加到末尾
$fruits[0] = "红苹果"; // 修改第一个
$user['phone'] = '13800138000'; // 添加新键
// 删除元素
unset($fruits[1]); // 删除索引 1(注意:不会重新索引)
$fruits = array_values($fruits); // 重新索引
Destructuring Assignment
<?php
// 索引数组解构
[$a, $b, $c] = [10, 20, 30];
echo $b; // 20
// 跳过元素
[, , $third] = [10, 20, 30];
echo $third; // 30
// 关联数组解构
$user = ['name' => '张三', 'age' => 28, 'city' => '北京'];
['name' => $name, 'age' => $age] = $user;
echo "$name, $age"; // 张三, 28
// 在 foreach 中解构
$points = [['x' => 1, 'y' => 2], ['x' => 3, 'y' => 4]];
foreach ($points as ['x' => $x, 'y' => $y]) {
echo "($x, $y) "; // (1, 2) (3, 4)
}
Spread Operator
<?php
// 合并数组(PHP 7.4+)
$first = [1, 2, 3];
$second = [4, 5, 6];
$merged = [...$first, ...$second]; // [1, 2, 3, 4, 5, 6]
// 关联数组 spread(PHP 8.1+)
$defaults = ['color' => 'blue', 'size' => 'M'];
$custom = ['size' => 'L', 'weight' => '200g'];
$config = [...$defaults, ...$custom];
// ['color' => 'blue', 'size' => 'L', 'weight' => '200g']
// 用于函数参数展开
function sum(int ...$nums): int {
return array_sum($nums);
}
$numbers = [1, 2, 3, 4, 5];
echo sum(...$numbers); // 15
Common Array Functions
<?php
$arr = [3, 1, 4, 1, 5, 9, 2, 6];
// ---- 基础操作 ----
echo count($arr); // 8(元素个数)
echo in_array(5, $arr); // true(是否存在)
echo array_search(4, $arr); // 2(查找位置)
$user = ['name' => '张三', 'age' => 28];
echo array_key_exists('name', $user); // true
$keys = array_keys($user); // ['name', 'age']
$vals = array_values($user); // ['张三', 28]
// ---- 增删改 ----
array_push($arr, 7); // 末尾添加 → [..., 7]
array_pop($arr); // 弹出末尾
array_unshift($arr, 0); // 头部添加
array_shift($arr); // 弹出头部
$sliced = array_slice($arr, 2, 3); // 从索引2取3个
array_splice($arr, 2, 1, [40, 50]); // 替换:删1个,插入2个
// ---- 合并与组合 ----
$merged = array_merge([1, 2], [3, 4]); // [1, 2, 3, 4]
$combined = array_combine(['a', 'b'], [1, 2]); // ['a'=>1, 'b'=>2]
$unique = array_unique([1, 2, 2, 3, 3]); // [1, 2, 3]
$flipped = array_flip(['a' => 1, 'b' => 2]); // [1 => 'a', 2 => 'b']
// ---- 排序(原地修改) ----
$nums = [3, 1, 4, 1, 5];
sort($nums); // [1, 1, 3, 4, 5] 值排序,重新索引
rsort($nums); // [5, 4, 3, 1, 1] 值逆序
asort($nums); // 值排序,保留键名
ksort($nums); // 按键排序
// 自定义排序
$items = ['banana', 'apple', 'cherry'];
usort($items, fn($a, $b) => strcmp($a, $b)); // 字母序
Functional Operations
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// array_map:对每个元素执行操作,返回新数组
$doubled = array_map(fn($n) => $n * 2, $numbers);
// [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
// array_filter:过滤,保留回调返回 true 的元素
$evens = array_filter($numbers, fn($n) => $n % 2 === 0);
// [2, 4, 6, 8, 10](注意:保留原始键名)
// array_reduce:归约
$sum = array_reduce($numbers, fn($carry, $n) => $carry + $n, 0);
// 55
// array_walk:遍历并修改(原地)
$prices = ['apple' => 5, 'banana' => 3, 'cherry' => 8];
array_walk($prices, function(&$price, $name) {
$price = $price * 1.1; // 加价 10%
});
// array_column:从多维数组中提取一列
$users = [
['id' => 1, 'name' => '张三', 'dept' => '技术'],
['id' => 2, 'name' => '李四', 'dept' => '产品'],
['id' => 3, 'name' => '王五', 'dept' => '技术'],
];
$names = array_column($users, 'name'); // ['张三', '李四', '王五']
$nameById = array_column($users, 'name', 'id'); // [1=>'张三', 2=>'李四', 3=>'王五']
2.5 Control Flow
Conditional Statements
<?php
$score = 85;
// if / elseif / else
if ($score >= 90) {
echo "优秀";
} elseif ($score >= 70) {
echo "良好";
} elseif ($score >= 60) {
echo "及格";
} else {
echo "不及格";
}
// 三元运算符
$status = $score >= 60 ? "通过" : "未通过";
// 短三元(Elvis 运算符)
$displayName = $username ?: "匿名用户"; // $username 为假值时用默认值
// null 合并运算符(后面详细讲)
$name = $_GET['name'] ?? '游客';
match Expression (PHP 8.0+)
match is the modern replacement for switch, using strict comparison (===) and is an expression (has a return value).
<?php
$statusCode = 404;
// match 表达式:简洁、严格比较、有返回值
$message = match($statusCode) {
200 => '成功',
301 => '永久重定向',
302 => '临时重定向',
400 => '错误请求',
401 => '未授权',
403 => '禁止访问',
404 => '页面未找到',
500 => '服务器错误',
default => '未知状态码',
};
echo $message; // "页面未找到"
// 多值匹配
$lang = 'zh-CN';
$greeting = match($lang) {
'zh-CN', 'zh-TW' => '你好',
'en-US', 'en-GB' => 'Hello',
'ja' => 'こんにちは',
default => 'Hi',
};
// 无参数 match(替代 if-elseif 链)
$score = 85;
$grade = match(true) {
$score >= 90 => 'A',
$score >= 80 => 'B',
$score >= 70 => 'C',
$score >= 60 => 'D',
default => 'F',
};
💡 match vs switch
match uses strict comparison ===, does not require break, and is an expression that can be assigned. If there is no match and no default, it throws an UnhandledMatchError. It is recommended to use match over switch in PHP 8+ projects.
Loops
<?php
// for 循环
for ($i = 0; $i < 5; $i++) {
echo $i; // 0 1 2 3 4
}
// while 循环
$count = 0;
while ($count < 3) {
echo $count++;
}
// do-while(至少执行一次)
$input = '';
do {
$input = readline("输入 'quit' 退出: ");
} while ($input !== 'quit');
// foreach —— PHP 中最常用的循环
$colors = ['red', 'green', 'blue'];
// 遍历值
foreach ($colors as $color) {
echo $color;
}
// 遍历键值对
$user = ['name' => '张三', 'age' => 28, 'city' => '北京'];
foreach ($user as $key => $value) {
echo "$key: $value\n";
}
// 通过引用修改元素
$prices = [10, 20, 30];
foreach ($prices as &$price) {
$price *= 1.1; // 每个价格加 10%
}
unset($price); // ⚠️ 务必 unset 引用变量,否则后续代码可能出错
// 嵌套遍历多维数组
$users = [
['name' => '张三', 'skills' => ['PHP', 'MySQL']],
['name' => '李四', 'skills' => ['Go', 'Redis']],
];
foreach ($users as $user) {
echo "{$user['name']} 的技能: ";
foreach ($user['skills'] as $skill) {
echo "$skill ";
}
echo "\n";
}
// 循环控制
for ($i = 0; $i < 10; $i++) {
if ($i === 3) continue; // 跳过 3
if ($i === 7) break; // 到 7 停止
echo $i; // 0 1 2 4 5 6
}
2.6 Operators
Arithmetic & Assignment Operators
<?php
// 算术
$a = 10;
$b = 3;
echo $a + $b; // 13 加
echo $a - $b; // 7 减
echo $a * $b; // 30 乘
echo $a / $b; // 3.33 除
echo $a % $b; // 1 取模
echo $a ** $b; // 1000 幂运算
// 复合赋值
$x = 10;
$x += 5; // $x = $x + 5 → 15
$x -= 3; // 12
$x *= 2; // 24
$x /= 4; // 6
$x %= 4; // 2
$x **= 3; // 8
$x .= "px"; // "8px"(字符串拼接赋值)
// 自增自减
$i = 5;
echo $i++; // 5(先返回再自增)
echo ++$i; // 7(先自增再返回)
Comparison Operators
⚠️ Must Know: Difference Between == and ===
PHP's == (loose comparison) performs type coercion, leading to many confusing behaviors. It is strongly recommended to always use === (strict comparison).
<?php
// == 宽松比较(会类型转换,各种坑)
var_dump(0 == "foo"); // PHP 8: false(PHP 7 是 true!)
var_dump("" == false); // true
var_dump("0" == false); // true
var_dump(null == false); // true
var_dump("" == null); // true
var_dump(0 == null); // true
var_dump("1" == true); // true
var_dump("123" == 123); // true
// === 严格比较(类型和值都必须相同)
var_dump(0 === false); // false(int vs bool)
var_dump("" === false); // false(string vs bool)
var_dump("123" === 123); // false(string vs int)
var_dump(null === false); // false(null vs bool)
// ✅ 经验法则:永远用 === 和 !==
Logical Operators
<?php
$a = true;
$b = false;
echo $a && $b; // false 与(短路求值)
echo $a || $b; // true 或(短路求值)
echo !$a; // false 非
// and / or 优先级低于 && / ||,不建议混用
// 推荐始终使用 && || !
Null-Related Operators
<?php
// null 合并运算符 ??(PHP 7.0+)
// 左侧为 null 或未定义时使用右侧值
$name = $_GET['name'] ?? '游客';
$config = $settings['timeout'] ?? $defaults['timeout'] ?? 30;
// null 合并赋值 ??=(PHP 7.4+)
$data['count'] ??= 0; // 等价于 $data['count'] = $data['count'] ?? 0;
// null 安全运算符 ?->(PHP 8.0+)
// 对象为 null 时不报错,直接返回 null
$user = getUser(42); // 可能返回 null
$city = $user?->getAddress()?->getCity();
// 等价于:$city = ($user !== null && $user->getAddress() !== null)
// ? $user->getAddress()->getCity() : null;
Spaceship Operator
<?php
// 太空船运算符 <=>(PHP 7.0+)
// 返回 -1(小于)、0(等于)、1(大于)
echo 1 <=> 2; // -1
echo 2 <=> 2; // 0
echo 3 <=> 2; // 1
// 常用于排序回调
$users = [
['name' => '张三', 'age' => 28],
['name' => '李四', 'age' => 22],
['name' => '王五', 'age' => 35],
];
usort($users, fn($a, $b) => $a['age'] <=> $b['age']);
// 按年龄升序:李四(22) → 张三(28) → 王五(35)
// 多字段排序
usort($users, fn($a, $b) =>
$a['age'] <=> $b['age'] ?: $a['name'] <=> $b['name']
);
2.7 Error Handling
try / catch / finally
<?php
try {
$result = riskyOperation();
echo "结果: $result";
} catch (InvalidArgumentException $e) {
echo "参数错误: " . $e->getMessage();
} catch (RuntimeException $e) {
echo "运行时错误: " . $e->getMessage();
} catch (Exception $e) {
echo "其他异常: " . $e->getMessage();
} finally {
echo "无论是否异常都会执行(清理资源等)";
}
// 联合捕获(PHP 8.0+)
try {
processInput($data);
} catch (TypeError | ValueError $e) {
echo "输入错误: " . $e->getMessage();
}
// 仅捕获不使用变量(PHP 8.0+)
try {
json_decode($json, flags: JSON_THROW_ON_ERROR);
} catch (JsonException) {
echo "JSON 解析失败";
}
Exception Hierarchy
<?php
// PHP 内置异常层次
// Throwable
// ├── Error (引擎级错误,通常不捕获)
// │ ├── TypeError
// │ ├── ValueError (PHP 8.0+)
// │ ├── ArithmeticError
// │ │ └── DivisionByZeroError
// │ └── ...
// └── Exception (应用级异常)
// ├── RuntimeException
// ├── InvalidArgumentException
// ├── LogicException
// ├── OverflowException
// └── ...
// 自定义异常
class BusinessException extends RuntimeException
{
public function __construct(
string $message,
private readonly string $errorCode,
int $code = 0,
?\Throwable $previous = null,
) {
parent::__construct($message, $code, $previous);
}
public function getErrorCode(): string
{
return $this->errorCode;
}
}
class InsufficientBalanceException extends BusinessException {}
// 使用自定义异常
function withdraw(float $amount, float $balance): float
{
if ($amount <= 0) {
throw new InvalidArgumentException("取款金额必须大于 0");
}
if ($amount > $balance) {
throw new InsufficientBalanceException(
"余额不足",
errorCode: 'INSUFFICIENT_BALANCE',
);
}
return $balance - $amount;
}
try {
$newBalance = withdraw(500, 100);
} catch (InsufficientBalanceException $e) {
echo "{$e->getMessage()} (错误码: {$e->getErrorCode()})";
// 余额不足 (错误码: INSUFFICIENT_BALANCE)
}
Global Error Handling
<?php
// 将传统 PHP 错误转为异常
set_error_handler(function (int $severity, string $message, string $file, int $line): bool {
if (!(error_reporting() & $severity)) {
return false;
}
throw new ErrorException($message, 0, $severity, $file, $line);
});
// 全局异常处理器(兜底)
set_exception_handler(function (Throwable $e): void {
error_log("未捕获的异常: {$e->getMessage()} 在 {$e->getFile()}:{$e->getLine()}");
if (php_sapi_name() === 'cli') {
echo "致命错误: {$e->getMessage()}\n";
} else {
http_response_code(500);
echo "<h1>服务器内部错误</h1>";
}
});
// 关闭函数(捕获致命错误)
register_shutdown_function(function (): void {
$error = error_get_last();
if ($error !== null && in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR])) {
error_log("致命错误: {$error['message']}");
}
});
2.8 Chapter Summary
💲 Variables & Constants
- • Variables use the
$prefix, no type declaration needed - •
constfor compile-time constants,define()for runtime constants - • Global variables are not accessible inside functions by default (use
global)
🏷️ Type System
- • PHP 8.x supports full type declarations: union types, intersection types, nullable
- •
declare(strict_types=1)enables strict mode - • Use
mb_series functions for multibyte strings
📦 Arrays
- • PHP array = ordered map, serving as both list and dictionary
- •
array_map,array_filter,array_reducefor functional operations - • Spread operator
...for merging and unpacking
🔀 Control Flow
- •
matchexpression replacesswitch, strict comparison with return value - •
foreachis the preferred way to iterate arrays - • Always
unsetreference variables after reference iteration
⚖️ Operators
- • Always use
===instead of== - •
??null coalescing,?->null-safe access - •
<=>spaceship operator simplifies sorting
🛡️ Error Handling
- •
try/catch/finally+ custom exception hierarchy - • PHP 8: union catch
catch (A | B $e) - •
set_error_handlerconverts legacy errors to exceptions
Now that you've mastered basic syntax, the next chapter covers Functions & Object-Oriented Programming — PHP 8.x's class system is feature-rich and the cornerstone of modern PHP development.