变量和常量
概述
变量和常量是PHP中的基本构建块。本章涵盖变量声明、作用域、生命周期、超全局变量、常量,以及在PHP应用程序中管理数据的最佳实践。
变量
变量基础
声明和赋值
php
<?php
// 变量声明和赋值
$name = "John Doe";
$age = 30;
$salary = 50000.50;
$isActive = true;
// 多重赋值
$a = $b = $c = 10;
// 变量引用赋值
$original = "Hello";
$reference = &$original;
$reference = "World";
echo $original; // "World"(因为引用而改变)
?>变量命名规则
php
<?php
// 有效的变量名
$userName = "john";
$user_name = "jane";
$_private = "hidden";
$user2 = "second user";
$HTML = "<h1>Title</h1>";
// 无效的变量名(会导致错误)
// $2user = "error"; // 不能以数字开头
// $user-name = "error"; // 不能包含连字符
// $user name = "error"; // 不能包含空格
// $class = "error"; // 不能使用保留字作为变量
?>可变变量
php
<?php
$var = "name";
$name = "John";
// 可变变量 - 使用$var的值作为变量名
echo $$var; // 输出:John(相当于$name)
// 更复杂的例子
$prefix = "user_";
$user_id = 123;
$user_name = "Alice";
$user_email = "alice@example.com";
$field = "id";
echo ${$prefix . $field}; // 123(相当于$user_id)
$field = "name";
echo ${$prefix . $field}; // Alice(相当于$user_name)
// 动态属性访问
class User {
public $name = "John";
public $email = "john@example.com";
}
$user = new User();
$property = "name";
echo $user->$property; // "John"
?>变量作用域
全局作用域
php
<?php
$globalVar = "我是全局变量";
function testGlobal() {
// 这不会工作 - $globalVar在这里无法访问
// echo $globalVar; // 未定义变量错误
// 使用global关键字访问全局变量
global $globalVar;
echo $globalVar; // "我是全局变量"
// 修改全局变量
$globalVar = "全局修改";
}
testGlobal();
echo $globalVar; // "全局修改"
// 替代方法:使用$GLOBALS超全局变量
function testGlobals() {
echo $GLOBALS['globalVar']; // "全局修改"
$GLOBALS['globalVar'] = "通过GLOBALS修改";
}
testGlobals();
echo $globalVar; // "通过GLOBALS修改"
?>局部作用域
php
<?php
function testLocal() {
$localVar = "我是局部变量";
echo $localVar; // 工作正常
// 局部变量在函数结束时被销毁
}
testLocal();
// echo $localVar; // 未定义变量错误
// 函数参数是局部的
function greet($name) {
$message = "你好," . $name;
return $message;
}
echo greet("Alice"); // "你好,Alice"
// echo $name; // 未定义变量错误
// echo $message; // 未定义变量错误
?>静态变量
php
<?php
function counter() {
static $count = 0; // 只初始化一次
$count++;
echo "计数: $count\n";
}
counter(); // 计数: 1
counter(); // 计数: 2
counter(); // 计数: 3
// 类中的静态变量
class PageView {
public static $totalViews = 0;
public function __construct() {
self::$totalViews++;
}
public static function getTotalViews() {
return self::$totalViews;
}
}
$page1 = new PageView();
$page2 = new PageView();
echo PageView::getTotalViews(); // 2
?>超全局变量
$_GET 和 $_POST
php
<?php
// URL: http://example.com/page.php?name=John&age=30
echo $_GET['name']; // "John"
echo $_GET['age']; // "30"
// 使用空合并运算符安全访问
$name = $_GET['name'] ?? '访客';
$age = $_GET['age'] ?? 0;
// 来自表单的POST数据
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
// 处理表单数据
if (!empty($username) && !empty($password)) {
// 认证用户
}
}
// 合并GET和POST数据
$allInput = $_REQUEST; // 包含GET和POST(出于安全考虑不推荐)
?>$_SESSION
php
<?php
// 启动会话
session_start();
// 设置会话变量
$_SESSION['user_id'] = 123;
$_SESSION['username'] = 'john_doe';
$_SESSION['is_logged_in'] = true;
// 访问会话变量
if (isset($_SESSION['is_logged_in']) && $_SESSION['is_logged_in']) {
echo "欢迎回来," . $_SESSION['username'];
} else {
echo "请登录";
}
// 删除会话变量
unset($_SESSION['temp_data']);
// 销毁整个会话
// session_destroy();
?>$_COOKIE
php
<?php
// 设置cookie
setcookie('user_preference', 'dark_theme', time() + 3600); // 1小时后过期
// 访问cookie
$theme = $_COOKIE['user_preference'] ?? 'light_theme';
// 设置带更多选项的cookie
setcookie('secure_cookie', 'value', [
'expires' => time() + 3600,
'path' => '/',
'domain' => '.example.com',
'secure' => true, // 仅HTTPS
'httponly' => true, // 无法通过JavaScript访问
'samesite' => 'Strict'
]);
// 删除cookie
setcookie('user_preference', '', time() - 3600);
?>$_SERVER
php
<?php
// 服务器和环境信息
echo $_SERVER['HTTP_HOST']; // example.com
echo $_SERVER['REQUEST_URI']; // /path/to/page.php?query=value
echo $_SERVER['REQUEST_METHOD']; // GET、POST等
echo $_SERVER['HTTP_USER_AGENT']; // 浏览器信息
echo $_SERVER['REMOTE_ADDR']; // 客户端IP地址
echo $_SERVER['SERVER_NAME']; // 服务器主机名
echo $_SERVER['DOCUMENT_ROOT']; // Web服务器文档根目录
// 有用的服务器变量
$isHTTPS = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
$currentURL = ($isHTTPS ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$userIP = $_SERVER['REMOTE_ADDR'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? 'unknown';
?>$_FILES
php
<?php
// 文件上传处理
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['upload'])) {
$file = $_FILES['upload'];
// 文件信息
echo "名称:" . $file['name']; // 原始文件名
echo "类型:" . $file['type']; // MIME类型
echo "大小:" . $file['size']; // 文件大小(字节)
echo "临时:" . $file['tmp_name']; // 临时文件路径
echo "错误:" . $file['error']; // 错误代码
// 检查上传错误
if ($file['error'] === UPLOAD_ERR_OK) {
$uploadDir = 'uploads/';
$uploadFile = $uploadDir . basename($file['name']);
if (move_uploaded_file($file['tmp_name'], $uploadFile)) {
echo "文件上传成功";
} else {
echo "上传失败";
}
}
}
?>$_ENV 和 $_GLOBALS
php
<?php
// 环境变量
echo $_ENV['PATH'] ?? '路径未设置';
echo $_ENV['HOME'] ?? '主目录未设置';
// 自定义环境变量(来自.env文件或系统)
$dbHost = $_ENV['DB_HOST'] ?? 'localhost';
$dbName = $_ENV['DB_NAME'] ?? 'myapp';
// $GLOBALS包含所有全局变量
$globalVar = "test";
function showGlobals() {
// 访问任何全局变量
echo $GLOBALS['globalVar']; // "test"
// 列出所有全局变量
foreach ($GLOBALS as $key => $value) {
if (!is_array($value) && !is_object($value)) {
echo "$key: $value\n";
}
}
}
?>常量
定义常量
使用 define()
php
<?php
// 基本常量
define('SITE_NAME', '我的网站');
define('VERSION', '1.0.0');
define('MAX_USERS', 1000);
define('PI', 3.14159);
define('DEBUG', true);
// 不区分大小写的常量(PHP 7.3中已废弃)
define('GREETING', '你好', true);
echo greeting; // 可以工作,但不推荐
// 数组常量(PHP 7.0+)
define('FRUITS', ['apple', 'banana', 'orange']);
echo FRUITS[0]; // "apple"
// 带表达式的常量(PHP 5.6+)
define('TIMESTAMP', time());
define('RANDOM_ID', 'ID_' . uniqid());
?>使用 const 关键字
php
<?php
// 类常量
class MathConstants {
const PI = 3.14159;
const E = 2.71828;
const GOLDEN_RATIO = 1.618;
// 常量表达式(PHP 5.6+)
const TWO_PI = self::PI * 2;
// 可见性修饰符(PHP 7.1+)
private const SECRET = 'hidden';
protected const INTERNAL = 'protected';
public const PUBLIC = 'visible';
}
// 命名空间常量
namespace MyApp;
const APP_NAME = '我的应用';
const VERSION = '2.0.0';
// 访问常量
echo MathConstants::PI; // 3.14159
echo MathConstants::TWO_PI; // 6.28318
echo \MyApp\APP_NAME; // "我的应用"
?>魔术常量
php
<?php
// 魔术常量根据上下文变化
echo __LINE__; // 当前行号
echo __FILE__; // 当前文件的完整路径
echo __DIR__; // 当前文件的目录
echo __FUNCTION__; // 当前函数名
echo __CLASS__; // 当前类名
echo __TRAIT__; // 当前Trait名
echo __METHOD__; // 当前方法名
echo __NAMESPACE__; // 当前命名空间
// 实际例子
function debugInfo() {
echo "函数:" . __FUNCTION__ . "\n";
echo "文件:" . __FILE__ . "\n";
echo "行号:" . __LINE__ . "\n";
}
class Logger {
public function log($message) {
$timestamp = date('Y-m-d H:i:s');
$class = __CLASS__;
$method = __METHOD__;
echo "[$timestamp] $class::$method - $message\n";
}
}
// 包含路径助手
require_once __DIR__ . '/config/database.php';
?>预定义常量
php
<?php
// PHP版本常量
echo PHP_VERSION; // PHP版本字符串
echo PHP_MAJOR_VERSION; // 主版本号
echo PHP_MINOR_VERSION; // 次版本号
// 系统常量
echo PHP_OS; // 操作系统
echo PHP_OS_FAMILY; // 操作系统系列(Windows、Linux等)
echo DIRECTORY_SEPARATOR; // / 或 \ 取决于操作系统
echo PATH_SEPARATOR; // : 或 ; 取决于操作系统
// 数学常量
echo M_PI; // 圆周率
echo M_E; // 欧拉数
echo M_LOG2E; // E的以2为底的对数
// 文件常量
echo FILE_APPEND; // file_put_contents()的标志
echo LOCK_EX; // 排他锁标志
// 错误常量
echo E_ERROR; // 致命错误
echo E_WARNING; // 警告
echo E_NOTICE; // 提示
// 布尔常量
echo TRUE; // 1
echo FALSE; // (空)
echo NULL; // (空)
?>常量数组和对象
php
<?php
// 数组常量(PHP 7.0+)
const COLORS = ['red', 'green', 'blue'];
const CONFIG = [
'database' => [
'host' => 'localhost',
'name' => 'myapp'
],
'cache' => [
'driver' => 'redis',
'ttl' => 3600
]
];
echo COLORS[1]; // "green"
echo CONFIG['database']['host']; // "localhost"
// 类常量数组
class AppConfig {
const SUPPORTED_LANGUAGES = ['en', 'es', 'fr', 'de'];
const DEFAULT_SETTINGS = [
'theme' => 'light',
'language' => 'en',
'timezone' => 'UTC'
];
public static function getSetting($key) {
return self::DEFAULT_SETTINGS[$key] ?? null;
}
}
echo AppConfig::SUPPORTED_LANGUAGES[0]; // "en"
echo AppConfig::getSetting('theme'); // "light"
?>变量和常量最佳实践
命名约定
php
<?php
// 变量:驼峰命名或下划线命名
$userName = "john_doe"; // 驼峰命名(推荐)
$user_name = "jane_doe"; // 下划线命名(也可接受)
$isLoggedIn = true;
$has_permission = false;
// 常量:大写字母加下划线
const MAX_LOGIN_ATTEMPTS = 3;
const API_BASE_URL = 'https://api.example.com';
const DEFAULT_TIMEOUT = 30;
// 类常量:大写字母
class UserRole {
const ADMIN = 'admin';
const MODERATOR = 'moderator';
const USER = 'user';
const GUEST = 'guest';
}
// 私有/受保护变量:下划线前缀(可选)
class MyClass {
private $_privateVar;
protected $_protectedVar;
public $publicVar;
}
?>变量初始化
php
<?php
// 始终初始化变量
$counter = 0;
$message = '';
$users = [];
$config = null;
// 使用空合并运算符处理可选值
$page = $_GET['page'] ?? 1;
$limit = $_GET['limit'] ?? 10;
$sort = $_GET['sort'] ?? 'name';
// 正确初始化数组
$errors = [];
$data = [
'users' => [],
'total' => 0,
'page' => 1
];
// 使用适当类型的默认值
function processUser($id, $options = []) {
$defaultOptions = [
'validate' => true,
'cache' => false,
'timeout' => 30
];
$options = array_merge($defaultOptions, $options);
// 使用选项处理用户
}
?>常量组织
php
<?php
// 将相关常量分组
class DatabaseConfig {
const HOST = 'localhost';
const PORT = 3306;
const NAME = 'myapp';
const CHARSET = 'utf8mb4';
}
class CacheConfig {
const DRIVER = 'redis';
const TTL = 3600;
const PREFIX = 'myapp:';
}
// 使用枚举处理相关常量(PHP 8.1+)
enum Status: string {
case PENDING = 'pending';
case APPROVED = 'approved';
case REJECTED = 'rejected';
}
// 配置类
class Config {
const ENVIRONMENTS = ['development', 'testing', 'production'];
private static $config = [];
public static function set($key, $value) {
self::$config[$key] = $value;
}
public static function get($key, $default = null) {
return self::$config[$key] ?? $default;
}
}
?>安全考虑
php
<?php
// 清理用户输入
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
// 转义输出
$safeOutput = htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// 对数据库查询使用预处理语句
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
// 不要在常量中暴露敏感信息
// 不好:const DB_PASSWORD = 'secret123';
// 好:使用环境变量
$dbPassword = $_ENV['DB_PASSWORD'] ?? '';
// 验证和清理超全局变量访问
function getQueryParam($key, $default = null, $filter = FILTER_SANITIZE_STRING) {
return filter_input(INPUT_GET, $key, $filter) ?? $default;
}
$page = getQueryParam('page', 1, FILTER_VALIDATE_INT);
$search = getQueryParam('search', '', FILTER_SANITIZE_STRING);
?>内存管理
php
<?php
// 在完成后释放大型变量
$largeArray = range(1, 1000000);
// ... 使用数组
unset($largeArray); // 释放内存
// 对大型数据结构使用引用
function processLargeArray(&$array) {
// 处理数组而不复制
foreach ($array as &$item) {
$item = strtoupper($item);
}
}
// 小心循环引用
class Parent {
public $children = [];
}
class Child {
public $parent;
}
$parent = new Parent();
$child = new Child();
$parent->children[] = $child;
$child->parent = $parent;
// 破坏循环引用
unset($child->parent);
unset($parent->children);
?>高级变量技术
变量函数
php
<?php
// 变量函数
$functionName = 'strlen';
echo $functionName('Hello'); // 5(调用strlen('Hello'))
$mathOp = 'max';
echo $mathOp(1, 5, 3); // 5(调用max(1, 5, 3))
// 动态方法调用
class Calculator {
public function add($a, $b) {
return $a + $b;
}
public function multiply($a, $b) {
return $a * $b;
}
}
$calc = new Calculator();
$method = 'add';
echo $calc->$method(5, 3); // 8
// 回调数组
$callback = [$calc, 'multiply'];
echo call_user_func($callback, 4, 5); // 20
?>Extract 和 Compact
php
<?php
// 从数组提取变量
$data = [
'name' => 'John',
'age' => 30,
'city' => 'New York'
];
extract($data);
echo $name; // "John"
echo $age; // 30
echo $city; // "New York"
// 将变量压缩到数组
$username = 'alice';
$email = 'alice@example.com';
$active = true;
$user = compact('username', 'email', 'active');
// $user = ['username' => 'alice', 'email' => 'alice@example.com', 'active' => true]
// 带前缀的安全提取
extract($data, EXTR_PREFIX_ALL, 'user');
echo $user_name; // "John"
echo $user_age; // 30
?>下一步
现在您已经了解了变量和常量,让我们在运算符中探讨PHP的运算符。
实践练习
- 使用常量和静态变量创建一个配置系统
- 使用超全局变量构建一个会话管理类
- 实现变量验证和清理函数
- 练习嵌套函数和类的变量作用域
- 创建一个使用魔术常量的调试工具
理解变量和常量对于在PHP应用程序中有效管理数据至关重要!