本章目标
- 掌握PHP的基本语法规则
- 学会使用变量和常量
- 了解PHP的数据类型
- 掌握运算符的使用
- 学会编写注释和文档
2.1 PHP语法基础
2.1.1 PHP标记
PHP代码必须包含在PHP标记内:
<?php
// PHP代码
echo "Hello, World!";
?>
标记类型:
<?php
// 标准开始标记(推荐)
echo "标准标记";
?>
<?= "短标记输出" ?>
<!-- 不推荐的标记 -->
<script language="php">
echo "脚本标记";
</script>
<% echo "ASP风格标记"; %>
2.1.2 语句分隔符
PHP使用分号(;)作为语句分隔符:
<?php
echo "第一条语句";
echo "第二条语句";
// 最后一条语句的分号可以省略(不推荐)
echo "最后一条语句"
?>
2.1.3 大小写敏感性
<?php
// 关键字、函数名、类名不区分大小写
ECHO "Hello";
echo "World";
Echo "PHP";
// 变量名区分大小写
$name = "张三";
$Name = "李四";
$NAME = "王五";
echo $name; // 输出:张三
echo $Name; // 输出:李四
echo $NAME; // 输出:王五
?>
2.1.4 空白字符
PHP忽略空白字符(空格、制表符、换行符):
<?php
// 以下代码等价
echo"Hello";
echo "Hello";
echo "Hello";
echo
"Hello";
?>
2.2 变量
2.2.1 变量声明
PHP变量以美元符号($)开头:
<?php
// 变量声明和赋值
$name = "张三";
$age = 25;
$height = 1.75;
$isStudent = true;
// 变量可以改变类型
$value = 100; // 整数
$value = "Hello"; // 字符串
$value = 3.14; // 浮点数
?>
2.2.2 变量命名规则
<?php
// 正确的变量名
$name = "有效";
$_name = "有效";
$name123 = "有效";
$userName = "有效";
$user_name = "有效";
// 错误的变量名
// $123name = "无效"; // 不能以数字开头
// $user-name = "无效"; // 不能包含连字符
// $user name = "无效"; // 不能包含空格
// $class = "无效"; // class是关键字
?>
2.2.3 变量作用域
<?php
// 全局变量
$globalVar = "全局变量";
function testScope() {
// 局部变量
$localVar = "局部变量";
// 访问全局变量
global $globalVar;
echo $globalVar;
// 或使用$GLOBALS
echo $GLOBALS['globalVar'];
}
// 静态变量
function counter() {
static $count = 0;
$count++;
echo "调用次数: $count";
}
counter(); // 调用次数: 1
counter(); // 调用次数: 2
counter(); // 调用次数: 3
?>
2.2.4 可变变量
<?php
$var = "name";
$$var = "张三";
// 等价于 $name = "张三";
echo $name; // 输出:张三
// 多层可变变量
$a = "b";
$b = "c";
$c = "Hello";
echo $$$a; // 输出:Hello
?>
2.2.5 引用变量
<?php
$a = 10;
$b = &$a; // $b是$a的引用
$b = 20;
echo $a; // 输出:20
// 函数引用传递
function increment(&$value) {
$value++;
}
$num = 5;
increment($num);
echo $num; // 输出:6
?>
2.3 常量
2.3.1 定义常量
<?php
// 使用define()函数
define("SITE_NAME", "我的网站");
define("VERSION", "1.0.0");
define("DEBUG", true);
// 使用const关键字(PHP 5.3+)
const DATABASE_HOST = "localhost";
const DATABASE_PORT = 3306;
echo SITE_NAME; // 输出:我的网站
echo DATABASE_HOST; // 输出:localhost
?>
2.3.2 常量特性
<?php
// 常量不能被重新定义
define("PI", 3.14);
// define("PI", 3.14159); // 会产生警告
// 常量默认区分大小写
define("GREETING", "Hello");
define("greeting", "Hi");
echo GREETING; // 输出:Hello
echo greeting; // 输出:Hi
// 定义不区分大小写的常量(PHP 7.3+已废弃)
define("WELCOME", "欢迎", true);
echo WELCOME; // 输出:欢迎
echo welcome; // 输出:欢迎
?>
2.3.3 预定义常量
<?php
// 魔术常量
echo __FILE__; // 当前文件的完整路径
echo __DIR__; // 当前文件所在目录
echo __LINE__; // 当前行号
echo __FUNCTION__; // 当前函数名
echo __CLASS__; // 当前类名
echo __METHOD__; // 当前方法名
echo __NAMESPACE__; // 当前命名空间
// 系统常量
echo PHP_VERSION; // PHP版本
echo PHP_OS; // 操作系统
echo PHP_EOL; // 换行符
echo DIRECTORY_SEPARATOR; // 目录分隔符
// 数学常量
echo M_PI; // 圆周率
echo M_E; // 自然对数的底
echo M_LOG2E; // log_2 e
?>
2.3.4 类常量
<?php
class MathConstants {
const PI = 3.14159;
const E = 2.71828;
public function getCircleArea($radius) {
return self::PI * $radius * $radius;
}
}
echo MathConstants::PI; // 输出:3.14159
$math = new MathConstants();
echo $math->getCircleArea(5);
?>
2.4 数据类型
2.4.1 标量类型
布尔型(boolean):
<?php
$isTrue = true;
$isFalse = false;
// 转换为布尔值
var_dump((bool) 0); // false
var_dump((bool) 1); // true
var_dump((bool) ""); // false
var_dump((bool) "0"); // false
var_dump((bool) "false"); // true
var_dump((bool) []); // false
var_dump((bool) null); // false
?>
整型(integer):
<?php
$decimal = 123; // 十进制
$octal = 0123; // 八进制
$hex = 0x1A; // 十六进制
$binary = 0b1010; // 二进制(PHP 5.4+)
// 整数范围
echo PHP_INT_MAX; // 最大整数
echo PHP_INT_MIN; // 最小整数
echo PHP_INT_SIZE; // 整数字节数
// 整数溢出
$large = PHP_INT_MAX + 1;
var_dump($large); // 自动转换为浮点数
?>
浮点型(float/double):
<?php
$float1 = 1.234;
$float2 = 1.2e3; // 科学计数法:1200
$float3 = 7E-10; // 0.0000000007
// 浮点数精度问题
var_dump(0.1 + 0.2 == 0.3); // false
// 正确的浮点数比较
function floatEqual($a, $b, $epsilon = 0.00001) {
return abs($a - $b) < $epsilon;
}
var_dump(floatEqual(0.1 + 0.2, 0.3)); // true
?>
字符串(string):
<?php
// 单引号字符串
$single = 'Hello World';
$single2 = 'He said: \'Hello\'';
// 双引号字符串
$name = "张三";
$double = "Hello, $name";
$double2 = "Hello, {$name}";
// Heredoc语法
$heredoc = <<<EOT
这是一个多行字符串
可以包含变量:$name
可以包含特殊字符
EOT;
// Nowdoc语法(PHP 5.3+)
$nowdoc = <<<'EOT'
这是一个多行字符串
不解析变量:$name
EOT;
echo $heredoc;
echo $nowdoc;
?>
2.4.2 复合类型
数组(array):
<?php
// 索引数组
$fruits = ["苹果", "香蕉", "橙子"];
$numbers = array(1, 2, 3, 4, 5);
// 关联数组
$person = [
"name" => "张三",
"age" => 25,
"city" => "北京"
];
// 多维数组
$matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// 访问数组元素
echo $fruits[0]; // 苹果
echo $person["name"]; // 张三
echo $matrix[1][2]; // 6
?>
对象(object):
<?php
class Person {
public $name;
public $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
public function introduce() {
return "我是{$this->name},今年{$this->age}岁";
}
}
$person = new Person("张三", 25);
echo $person->introduce();
?>
2.4.3 特殊类型
NULL类型:
<?php
$null1 = null;
$null2 = NULL;
$null3; // 未初始化的变量
// 检查NULL
var_dump(is_null($null1)); // true
var_dump($null1 === null); // true
var_dump(isset($null1)); // false
var_dump(empty($null1)); // true
// unset()会将变量设为NULL
$var = "Hello";
unset($var);
var_dump($var); // NULL
?>
资源类型(resource):
<?php
// 文件资源
$file = fopen("test.txt", "r");
var_dump($file); // resource
var_dump(is_resource($file)); // true
fclose($file);
// 数据库连接资源
$connection = mysqli_connect("localhost", "user", "pass", "db");
var_dump(is_resource($connection));
mysqli_close($connection);
?>
2.4.4 类型检查和转换
类型检查函数:
<?php
$var = 123;
// 类型检查
var_dump(is_int($var)); // true
var_dump(is_string($var)); // false
var_dump(is_bool($var)); // false
var_dump(is_array($var)); // false
var_dump(is_object($var)); // false
var_dump(is_null($var)); // false
var_dump(is_numeric($var)); // true
var_dump(is_scalar($var)); // true
// 获取类型
echo gettype($var); // integer
echo get_class($object); // 获取对象类名
?>
类型转换:
<?php
$str = "123";
// 强制类型转换
$int = (int) $str; // 123
$float = (float) $str; // 123.0
$bool = (bool) $str; // true
$array = (array) $str; // ["123"]
// 使用函数转换
$int2 = intval($str); // 123
$float2 = floatval($str); // 123.0
$bool2 = boolval($str); // true
// 自动类型转换
$result = "10" + 5; // 15 (字符串转为数字)
$concat = 10 . 5; // "105" (数字转为字符串)
?>
2.5 运算符
2.5.1 算术运算符
<?php
$a = 10;
$b = 3;
echo $a + $b; // 13 (加法)
echo $a - $b; // 7 (减法)
echo $a * $b; // 30 (乘法)
echo $a / $b; // 3.333... (除法)
echo $a % $b; // 1 (取模)
echo $a ** $b; // 1000 (幂运算,PHP 5.6+)
// 一元运算符
echo +$a; // 10 (正号)
echo -$a; // -10 (负号)
echo ++$a; // 11 (前置递增)
echo $a++; // 11 (后置递增,返回原值)
echo --$a; // 11 (前置递减)
echo $a--; // 11 (后置递减,返回原值)
?>
2.5.2 赋值运算符
<?php
$a = 10; // 基本赋值
$a += 5; // $a = $a + 5; 结果:15
$a -= 3; // $a = $a - 3; 结果:12
$a *= 2; // $a = $a * 2; 结果:24
$a /= 4; // $a = $a / 4; 结果:6
$a %= 5; // $a = $a % 5; 结果:1
$a **= 3; // $a = $a ** 3; 结果:1
// 字符串连接赋值
$str = "Hello";
$str .= " World"; // $str = $str . " World"; 结果:"Hello World"
// 引用赋值
$b = &$a; // $b是$a的引用
?>
2.5.3 比较运算符
<?php
$a = 5;
$b = "5";
$c = 10;
// 相等比较
var_dump($a == $b); // true (值相等)
var_dump($a === $b); // false (值和类型都相等)
var_dump($a != $c); // true (不等于)
var_dump($a !== $b); // true (值或类型不等)
var_dump($a <> $c); // true (不等于,同!=)
// 大小比较
var_dump($a < $c); // true
var_dump($a > $c); // false
var_dump($a <= $b); // true
var_dump($a >= $b); // true
// 太空船操作符(PHP 7+)
var_dump($a <=> $c); // -1 (小于)
var_dump($c <=> $a); // 1 (大于)
var_dump($a <=> $b); // 0 (等于)
// NULL合并操作符(PHP 7+)
$username = $_GET['user'] ?? 'guest';
$config = $config ?? [];
// NULL合并赋值操作符(PHP 7.4+)
$config['debug'] ??= false;
?>
2.5.4 逻辑运算符
<?php
$a = true;
$b = false;
$c = true;
// 逻辑与
var_dump($a && $c); // true
var_dump($a and $c); // true (优先级较低)
// 逻辑或
var_dump($a || $b); // true
var_dump($a or $b); // true (优先级较低)
// 逻辑非
var_dump(!$a); // false
var_dump(!$b); // true
// 逻辑异或
var_dump($a xor $c); // false (两个都为true)
var_dump($a xor $b); // true (一个true,一个false)
// 短路求值
$result = $a && someFunction(); // 如果$a为false,不会执行someFunction()
$result = $b || someFunction(); // 如果$b为true,不会执行someFunction()
?>
2.5.5 位运算符
<?php
$a = 12; // 二进制:1100
$b = 10; // 二进制:1010
echo $a & $b; // 8 (1000) 按位与
echo $a | $b; // 14 (1110) 按位或
echo $a ^ $b; // 6 (0110) 按位异或
echo ~$a; // -13 按位取反
echo $a << 2; // 48 (110000) 左移
echo $a >> 2; // 3 (11) 右移
?>
2.5.6 字符串运算符
<?php
$first = "Hello";
$second = "World";
// 字符串连接
$result = $first . " " . $second; // "Hello World"
// 连接赋值
$first .= " PHP"; // "Hello PHP"
// 字符串比较
var_dump("apple" < "banana"); // true (字典序)
var_dump("10" < "9"); // true (字符串比较)
var_dump(10 < 9); // false (数值比较)
?>
2.5.7 数组运算符
<?php
$a = ["a" => "apple", "b" => "banana"];
$b = ["a" => "apricot", "c" => "cherry"];
// 数组合并
$union = $a + $b;
print_r($union);
// 结果:["a" => "apple", "b" => "banana", "c" => "cherry"]
// 数组比较
var_dump($a == $b); // false (值不同)
var_dump($a === $b); // false (值和类型不同)
var_dump($a != $b); // true
var_dump($a !== $b); // true
?>
2.5.8 运算符优先级
<?php
// 优先级从高到低
echo 2 + 3 * 4; // 14 (先乘后加)
echo (2 + 3) * 4; // 20 (括号改变优先级)
echo true || false && false; // true (&&优先级高于||)
echo (true || false) && false; // false
// 建议使用括号明确优先级
$result = ($a > $b) && ($c < $d) || ($e == $f);
?>
2.6 注释
2.6.1 注释类型
<?php
// 单行注释
echo "Hello"; // 行尾注释
# Shell风格注释
echo "World";
/*
多行注释
可以跨越多行
*/
/**
* 文档注释(PHPDoc)
* 用于生成API文档
* @param string $name 用户名
* @return string 问候语
*/
function greet($name) {
return "Hello, $name";
}
?>
2.6.2 PHPDoc注释
<?php
/**
* 用户类
*
* 这个类用于管理用户信息
*
* @package App\Models
* @author 张三 <zhangsan@example.com>
* @version 1.0.0
* @since 2024-01-01
*/
class User
{
/**
* 用户名
*
* @var string
*/
private $username;
/**
* 用户年龄
*
* @var int
*/
private $age;
/**
* 构造函数
*
* @param string $username 用户名
* @param int $age 年龄
* @throws InvalidArgumentException 当参数无效时
*/
public function __construct($username, $age)
{
if (empty($username)) {
throw new InvalidArgumentException('用户名不能为空');
}
$this->username = $username;
$this->age = $age;
}
/**
* 获取用户信息
*
* @return array 包含用户信息的数组
* @example
* $user = new User('张三', 25);
* $info = $user->getInfo();
* // 返回:['username' => '张三', 'age' => 25]
*/
public function getInfo()
{
return [
'username' => $this->username,
'age' => $this->age
];
}
}
?>
2.6.3 常用PHPDoc标签
<?php
/**
* @param type $param 参数描述
* @return type 返回值描述
* @throws ExceptionType 异常描述
* @var type 变量类型
* @see ClassName::method() 参考链接
* @since version 版本信息
* @deprecated version 废弃信息
* @todo 待办事项
* @example 示例代码
* @link http://example.com 相关链接
* @author 作者信息
* @copyright 版权信息
* @license 许可证信息
* @package 包名
* @subpackage 子包名
* @version 版本号
* @access public|private|protected 访问级别
* @static 静态方法标记
* @abstract 抽象方法标记
* @final 最终方法标记
* @ignore 忽略此项
* @internal 内部使用
* @override 重写方法
* @inheritdoc 继承文档
*/
?>
2.7 输入输出
2.7.1 输出函数
<?php
// echo - 输出字符串
echo "Hello World";
echo "Hello", " ", "World"; // 可以输出多个参数
// print - 输出字符串(返回1)
print "Hello World";
$result = print "Hello"; // $result = 1
// printf - 格式化输出
printf("姓名:%s,年龄:%d岁", "张三", 25);
printf("价格:%.2f元", 19.99);
// sprintf - 格式化字符串(不输出)
$formatted = sprintf("用户ID:%05d", 123); // "用户ID:00123"
// var_dump - 输出变量信息
$data = ["name" => "张三", "age" => 25];
var_dump($data);
// print_r - 输出变量信息(更易读)
print_r($data);
// var_export - 输出PHP代码形式
var_export($data);
?>
2.7.2 输入函数
<?php
// 命令行输入
echo "请输入您的姓名:";
$name = trim(fgets(STDIN));
echo "您好,$name!";
// 从文件读取
$content = file_get_contents('input.txt');
echo $content;
// 逐行读取文件
$handle = fopen('input.txt', 'r');
while (($line = fgets($handle)) !== false) {
echo $line;
}
fclose($handle);
// Web输入(表单数据)
$username = $_POST['username'] ?? '';
$email = $_GET['email'] ?? '';
$file = $_FILES['upload'] ?? null;
?>
2.7.3 格式化输出
<?php
$name = "张三";
$age = 25;
$price = 19.99;
// 字符串格式化
printf("姓名:%s\n", $name); // 字符串
printf("年龄:%d岁\n", $age); // 整数
printf("价格:%.2f元\n", $price); // 浮点数(2位小数)
printf("十六进制:%x\n", 255); // 十六进制
printf("八进制:%o\n", 64); // 八进制
printf("科学计数法:%e\n", 1234.5); // 科学计数法
// 填充和对齐
printf("|%10s|\n", $name); // 右对齐,宽度10
printf("|%-10s|\n", $name); // 左对齐,宽度10
printf("|%010d|\n", $age); // 用0填充,宽度10
printf("|%+d|\n", $age); // 显示正负号
// 位置参数
printf("%2\$s今年%1\$d岁", $age, $name); // "张三今年25岁"
?>
2.8 错误处理基础
2.8.1 错误类型
<?php
// 语法错误(Parse Error)
// echo "Hello World" // 缺少分号
// 致命错误(Fatal Error)
// call_undefined_function(); // 调用未定义函数
// 警告(Warning)
include 'nonexistent.php'; // 包含不存在的文件
// 注意(Notice)
echo $undefined_variable; // 使用未定义变量
// 用户错误
trigger_error("自定义错误", E_USER_ERROR);
trigger_error("自定义警告", E_USER_WARNING);
trigger_error("自定义注意", E_USER_NOTICE);
?>
2.8.2 错误报告设置
<?php
// 设置错误报告级别
error_reporting(E_ALL); // 报告所有错误
error_reporting(E_ERROR | E_WARNING); // 只报告错误和警告
error_reporting(0); // 不报告任何错误
// 显示错误
ini_set('display_errors', 1); // 显示错误
ini_set('display_startup_errors', 1); // 显示启动错误
// 记录错误日志
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/error.log');
// 自定义错误处理函数
function customErrorHandler($errno, $errstr, $errfile, $errline) {
echo "错误 [$errno]: $errstr 在 $errfile 第 $errline 行\n";
return true; // 阻止PHP默认错误处理
}
set_error_handler('customErrorHandler');
?>
2.9 代码风格和最佳实践
2.9.1 PSR编码标准
<?php
namespace App\Controllers;
use App\Models\User;
use Exception;
/**
* 用户控制器
*/
class UserController
{
/**
* 用户模型
*
* @var User
*/
private $userModel;
/**
* 构造函数
*
* @param User $userModel
*/
public function __construct(User $userModel)
{
$this->userModel = $userModel;
}
/**
* 获取用户列表
*
* @param int $page 页码
* @param int $limit 每页数量
* @return array
* @throws Exception
*/
public function getUsers(int $page = 1, int $limit = 10): array
{
if ($page < 1) {
throw new Exception('页码必须大于0');
}
if ($limit < 1 || $limit > 100) {
throw new Exception('每页数量必须在1-100之间');
}
$offset = ($page - 1) * $limit;
return $this->userModel->getUsers($offset, $limit);
}
}
2.9.2 命名约定
<?php
// 类名:大驼峰命名法(PascalCase)
class UserController {}
class DatabaseConnection {}
// 方法名和变量名:小驼峰命名法(camelCase)
public function getUserById($userId) {}
$userName = "张三";
$isLoggedIn = true;
// 常量:全大写,下划线分隔
const MAX_LOGIN_ATTEMPTS = 3;
define('DATABASE_HOST', 'localhost');
// 私有属性:下划线前缀(可选)
private $_privateProperty;
protected $_protectedProperty;
// 文件名:小写,下划线或连字符分隔
// user_controller.php 或 user-controller.php
?>
2.9.3 代码组织
<?php
// 1. 开始标签
// 2. 文件级文档注释
/**
* 用户管理相关功能
*
* @package App\Controllers
* @author 张三 <zhangsan@example.com>
*/
// 3. 命名空间声明
namespace App\Controllers;
// 4. use声明
use App\Models\User;
use App\Services\EmailService;
use Exception;
use InvalidArgumentException;
// 5. 类声明
class UserController
{
// 6. 常量
const DEFAULT_PAGE_SIZE = 20;
// 7. 属性
private $userModel;
private $emailService;
// 8. 构造函数
public function __construct(User $userModel, EmailService $emailService)
{
$this->userModel = $userModel;
$this->emailService = $emailService;
}
// 9. 公共方法
public function createUser(array $userData): User
{
// 方法实现
}
// 10. 受保护方法
protected function validateUserData(array $userData): bool
{
// 方法实现
}
// 11. 私有方法
private function sendWelcomeEmail(User $user): void
{
// 方法实现
}
}
// 12. 结束标签(可选,纯PHP文件建议省略)
2.10 小结
本章详细介绍了PHP的基本语法:
- 语法基础:PHP标记、语句分隔符、大小写敏感性
- 变量:声明、命名规则、作用域、引用变量
- 常量:定义方法、预定义常量、类常量
- 数据类型:标量类型、复合类型、特殊类型、类型转换
- 运算符:算术、赋值、比较、逻辑、位运算等
- 注释:单行、多行、PHPDoc文档注释
- 输入输出:各种输出函数和格式化方法
- 错误处理:错误类型和基本处理方法
- 代码风格:PSR标准和最佳实践
2.11 实践练习
变量练习:
- 创建不同类型的变量并输出
- 练习变量作用域和引用
- 使用可变变量
运算符练习:
- 编写计算器程序
- 练习各种比较和逻辑运算
- 使用位运算符进行权限管理
类型转换练习:
- 练习显式和隐式类型转换
- 处理用户输入的数据验证
- 实现安全的类型转换函数
格式化输出练习:
- 创建格式化的报表输出
- 练习printf的各种格式符
- 实现多语言格式化
2.12 扩展阅读
下一章预告:在下一章中,我们将学习PHP的控制结构,包括条件语句、循环语句和跳转语句。