compact() 函数是PHP中用于快速创建包含变量名和对应值的数组的实用函数。它可以将当前作用域中的变量打包成关联数组,极大简化了数据传递和处理的流程。
compact() 函数接受一个或多个参数(变量名的字符串或包含变量名的数组),并在当前符号表中查找这些变量名,返回一个包含变量名和对应值的关联数组。
compact(var1, var2, ...);
| 参数 | 描述 |
|---|---|
| var1 | 必需。可以是带有变量名的字符串,或者是包含变量名的数组。 |
| var2,... | 可选。可以是带有变量名的字符串,或者是包含变量名的数组。允许多个参数。 |
演示如何使用 compact() 将多个变量打包成数组。
<?php
// 定义一些变量
$firstname = "张";
$lastname = "三";
$age = 25;
$city = "北京";
$country = "中国";
echo "当前作用域中的变量:\n";
echo "firstname: $firstname\n";
echo "lastname: $lastname\n";
echo "age: $age\n";
echo "city: $city\n";
echo "country: $country\n\n";
// 使用 compact() 创建数组
$result = compact('firstname', 'lastname', 'age', 'city', 'country');
echo "compact() 创建的数组:";
print_r($result);
// 输出:
// Array ( [firstname] => 张 [lastname] => 三 [age] => 25 [city] => 北京 [country] => 中国 )
?>
演示 compact() 如何处理不存在的变量名。
<?php
// 定义一些变量
$username = "john_doe";
$email = "john@example.com";
// 尝试打包存在的和不存在的变量
$result = compact('username', 'email', 'nonexistent', 'another_missing');
echo "compact() 结果(不存在的变量被忽略):";
print_r($result);
// 输出:
// Array ( [username] => john_doe [email] => john@example.com )
// 注意: nonexistent 和 another_missing 变量不存在,被忽略
// 检查哪些变量被成功打包
$variables_to_check = array('username', 'email', 'nonexistent', 'another_missing');
$available_variables = array();
foreach($variables_to_check as $var_name) {
if(isset($$var_name)) {
$available_variables[] = $var_name;
}
}
echo "可用的变量: ";
print_r($available_variables);
$safe_result = compact($available_variables);
echo "安全打包的结果:";
print_r($safe_result);
?>
演示如何在MVC框架中使用 compact() 向视图传递数据。
<?php
// 模拟从数据库获取的数据
$user_id = 101;
$username = "zhangsan";
$user_email = "zhangsan@example.com";
$user_role = "admin";
$last_login = "2023-10-15 14:30:00";
// 页面元数据
$page_title = "用户管理 - 张三";
$page_description = "张三的用户详细信息页面";
$page_keywords = "用户,管理,详细信息";
// 使用 compact() 打包所有视图数据
$view_data = compact(
'user_id',
'username',
'user_email',
'user_role',
'last_login',
'page_title',
'page_description',
'page_keywords'
);
echo "视图数据数组:";
print_r($view_data);
// 模拟视图渲染函数
function render_view($view_name, $data = array()) {
echo "=== 渲染视图: {$view_name} ===\n";
echo "传递的数据:\n";
print_r($data);
// 在实际的MVC框架中,这里会包含视图文件并提取数据
// extract($data);
// include "views/{$view_name}.php";
}
// 使用 compact() 传递数据给视图
render_view('user_profile', $view_data);
// 另一种方式:直接在函数调用中使用 compact()
render_view('user_profile', compact(
'user_id', 'username', 'user_email', 'user_role', 'last_login'
));
// 在实际的框架中,可能这样使用:
// return view('user.profile', compact('user', 'page_title', 'page_description'));
?>
演示如何使用 compact() 构建结构化的API响应。
<?php
// API处理函数
function api_response($success, $data = null, $message = '', $code = 200) {
$response = compact('success', 'data', 'message', 'code');
header('Content-Type: application/json');
return json_encode($response, JSON_PRETTY_PRINT);
}
// 用户数据查询模拟
function get_user_data($user_id) {
// 模拟数据库查询
if($user_id == 101) {
$user_id = 101;
$username = "李四";
$email = "lisi@example.com";
$created_at = "2023-01-15";
$is_active = true;
return compact('user_id', 'username', 'email', 'created_at', 'is_active');
}
return null;
}
// 处理API请求
$user_id = isset($_GET['user_id']) ? intval($_GET['user_id']) : 0;
$user_data = get_user_data($user_id);
if($user_data) {
$success = true;
$data = $user_data;
$message = "用户数据获取成功";
$code = 200;
} else {
$success = false;
$data = null;
$message = "用户不存在";
$code = 404;
}
// 构建并输出API响应
echo "API响应:\n";
echo api_response($success, $data, $message, $code);
// 更复杂的API响应构建
function build_api_response($data, $pagination = null, $metadata = null) {
$success = true;
$message = "请求成功";
$code = 200;
$base_response = compact('success', 'message', 'code', 'data');
if($pagination) {
$base_response['pagination'] = $pagination;
}
if($metadata) {
$base_response['metadata'] = $metadata;
}
return $base_response;
}
// 使用示例
$users = array(
array('id' => 1, 'name' => '用户1'),
array('id' => 2, 'name' => '用户2'),
array('id' => 3, 'name' => '用户3')
);
$pagination = array(
'current_page' => 1,
'per_page' => 10,
'total' => 3,
'total_pages' => 1
);
$metadata = array(
'version' => '1.0',
'timestamp' => time(),
'request_id' => uniqid()
);
$api_response = build_api_response($users, $pagination, $metadata);
echo "\n复杂API响应:\n";
print_r($api_response);
?>
演示如何使用 compact() 处理表单数据和验证错误。
<?php
// 模拟表单提交数据
$_POST = array(
'username' => 'john_doe',
'email' => 'john@example.com',
'password' => 'secret123',
'confirm_password' => 'secret123',
'age' => '25'
);
// 提取表单数据到变量
extract($_POST, EXTR_SKIP);
// 验证数据
$errors = array();
if(empty($username)) {
$errors['username'] = '用户名不能为空';
} elseif(strlen($username) < 3) {
$errors['username'] = '用户名至少需要3个字符';
}
if(empty($email)) {
$errors['email'] = '邮箱不能为空';
} elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = '邮箱格式不正确';
}
if(empty($password)) {
$errors['password'] = '密码不能为空';
} elseif(strlen($password) < 6) {
$errors['password'] = '密码至少需要6个字符';
} elseif($password !== $confirm_password) {
$errors['confirm_password'] = '密码确认不匹配';
}
if(empty($age)) {
$errors['age'] = '年龄不能为空';
} elseif(!is_numeric($age) || $age < 1 || $age > 150) {
$errors['age'] = '年龄必须是1-150之间的数字';
}
// 准备返回给视图的数据
$form_data = compact('username', 'email', 'age');
$has_errors = !empty($errors);
if($has_errors) {
$success = false;
$message = "表单验证失败";
} else {
$success = true;
$message = "表单验证成功";
// 这里可以处理数据保存等操作
// save_user_data(compact('username', 'email', 'password', 'age'));
}
// 构建完整的响应数据
$response_data = compact('success', 'message', 'form_data', 'errors', 'has_errors');
echo "表单处理结果:";
print_r($response_data);
// 模拟重显示表单的函数
function show_form($data) {
extract($data);
echo "=== 显示表单 ===\n";
echo "成功: " . ($success ? '是' : '否') . "\n";
echo "消息: {$message}\n";
if($has_errors) {
echo "错误信息:\n";
print_r($errors);
}
echo "表单数据:\n";
print_r($form_data);
}
// 显示表单结果
show_form($response_data);
?>
演示 compact() 和 extract() 如何配合工作。
<?php
// compact() 和 extract() 是互补函数
// 示例1: 数据打包和解包
$name = "王五";
$age = 30;
$city = "上海";
echo "原始变量:\n";
echo "name: $name, age: $age, city: $city\n\n";
// 使用 compact() 打包变量
$data = compact('name', 'age', 'city');
echo "打包后的数组:";
print_r($data);
// 修改数组
$data['name'] = "赵六";
$data['age'] = 35;
// 使用 extract() 解包回变量
extract($data);
echo "解包后的变量:\n";
echo "name: $name, age: $age, city: $city\n\n";
// 示例2: 函数间数据传递
function process_user_data() {
$user_id = 1001;
$username = "test_user";
$status = "active";
// 打包数据返回
return compact('user_id', 'username', 'status');
}
function display_user_data($data) {
// 解包数据到当前作用域
extract($data);
echo "用户ID: $user_id\n";
echo "用户名: $username\n";
echo "状态: $status\n";
}
$user_data = process_user_data();
display_user_data($user_data);
// 示例3: 配置管理
class Config {
private static $data = array();
public static function set($key, $value) {
self::$data[$key] = $value;
}
public static function get($key, $default = null) {
return isset(self::$data[$key]) ? self::$data[$key] : $default;
}
public static function load($config_array) {
self::$data = array_merge(self::$data, $config_array);
}
public static function export() {
return self::$data;
}
}
// 设置配置
$db_host = 'localhost';
$db_user = 'root';
$db_pass = 'password';
$app_name = '我的应用';
$debug_mode = true;
// 使用 compact() 打包配置
$config = compact('db_host', 'db_user', 'db_pass', 'app_name', 'debug_mode');
Config::load($config);
echo "配置数据:";
print_r(Config::export());
// 验证配置
echo "数据库主机: " . Config::get('db_host') . "\n";
echo "应用名称: " . Config::get('app_name') . "\n";
?>
演示如何使用 compact() 进行动态变量处理。
<?php
// 动态创建变量并打包
$fields = array('title', 'content', 'author', 'category', 'tags');
foreach($fields as $field) {
// 动态创建变量
${$field} = "示例{$field}";
}
echo "动态创建的变量:\n";
foreach($fields as $field) {
echo "{$field}: " . ${$field} . "\n";
}
// 使用 compact() 打包动态变量
$article_data = compact($fields);
echo "\n打包后的文章数据:";
print_r($article_data);
// 从数据库结果动态创建变量
function get_dynamic_data() {
// 模拟数据库字段
$db_fields = array('product_id', 'product_name', 'price', 'stock', 'category');
$db_values = array(101, '智能手机', 2999, 50, '电子产品');
// 动态创建变量
foreach($db_fields as $index => $field) {
${$field} = $db_values[$index];
}
// 返回打包的数据
return compact($db_fields);
}
$product_data = get_dynamic_data();
echo "产品数据:";
print_r($product_data);
// 条件变量打包
function build_conditional_data($include_user = true, $include_settings = false) {
$user_id = 1001;
$username = "user123";
$settings_theme = "dark";
$settings_language = "zh-CN";
$app_version = "1.0.0";
$data = compact('app_version');
if($include_user) {
$user_data = compact('user_id', 'username');
$data = array_merge($data, $user_data);
}
if($include_settings) {
$settings_data = compact('settings_theme', 'settings_language');
$data = array_merge($data, $settings_data);
}
return $data;
}
echo "条件数据构建:\n";
$data1 = build_conditional_data(true, false);
echo "包含用户数据:";
print_r($data1);
$data2 = build_conditional_data(true, true);
echo "包含用户和设置数据:";
print_r($data2);
?>
| 返回值: | 返回带有所有变量名和它们的值的数组。任何没有对应变量的字符串都会被忽略。 |
|---|---|
| PHP 版本: | 4+ |
| 更新日志: |
|
<?php
/**
* 安全的 compact 函数,验证变量存在性
*/
function safe_compact($variables) {
if(!is_array($variables)) {
$variables = func_get_args();
}
$result = array();
foreach($variables as $var_name) {
if(isset($GLOBALS[$var_name])) {
$result[$var_name] = $GLOBALS[$var_name];
} elseif(isset($$var_name)) {
$result[$var_name] = $$var_name;
}
// 如果变量不存在,跳过(保持与 compact() 一致的行为)
}
return $result;
}
/**
* 严格的 compact 函数,要求所有变量都存在
*/
function strict_compact($variables) {
if(!is_array($variables)) {
$variables = func_get_args();
}
$result = array();
$missing = array();
foreach($variables as $var_name) {
if(isset($$var_name)) {
$result[$var_name] = $$var_name;
} else {
$missing[] = $var_name;
}
}
if(!empty($missing)) {
throw new InvalidArgumentException("以下变量不存在: " . implode(', ', $missing));
}
return $result;
}
// 测试安全函数
$existing_var = "存在的变量";
$another_var = "另一个变量";
echo "安全 compact 测试:\n";
try {
$safe_result = safe_compact('existing_var', 'another_var', 'nonexistent_var');
echo "安全打包结果:";
print_r($safe_result);
$strict_result = strict_compact('existing_var', 'another_var');
echo "严格打包结果:";
print_r($strict_result);
// 这会抛出异常
// $strict_error = strict_compact('existing_var', 'nonexistent_var');
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
/**
* 批量变量管理类
*/
class VariableManager {
private $variables = array();
public function set($name, $value) {
$this->variables[$name] = $value;
return $this;
}
public function get($name, $default = null) {
return isset($this->variables[$name]) ? $this->variables[$name] : $default;
}
public function compact($names) {
if(!is_array($names)) {
$names = func_get_args();
}
$result = array();
foreach($names as $name) {
if(array_key_exists($name, $this->variables)) {
$result[$name] = $this->variables[$name];
}
}
return $result;
}
public function export() {
return $this->variables;
}
}
// 使用变量管理器
$vm = new VariableManager();
$vm->set('app_name', '我的应用')
->set('version', '1.0.0')
->set('debug', true)
->set('environment', 'production');
$exported = $vm->compact('app_name', 'version', 'debug');
echo "变量管理器导出:";
print_r($exported);
?>