函数定义与调用

函数是PHP编程中最重要的概念之一。想象一下,如果每次想要执行相同的操作时都重复编写相同的代码,那将是多么低效和混乱。函数就是为了解决这个问题而诞生的!

什么是函数?

函数是一段可重复使用的代码块,它可以:

  • 接收输入数据(参数)
  • 执行特定的操作
  • 返回结果

把函数想象成一个"机器":你放入原材料(参数),机器处理后输出产品(返回值)。

<?php
// 这就是一个最简单的函数定义
function sayHello() {
    echo "你好,欢迎学习PHP!";
}

// 调用函数
sayHello();  // 输出:你好,欢迎学习PHP!
?>

函数定义的基本语法

基本结构

<?php
function 函数名(参数1, 参数2, ...) {
    // 函数体 - 这里是函数要执行的代码
    // 可以包含变量声明、逻辑处理、返回值等

    return 返回值;  // 可选的返回语句
}
?>

命名规则

函数名称必须遵循以下规则:

  1. 必须以字母或下划线开头
  2. 可以包含字母、数字和下划线
  3. 不区分大小写(这是PHP的特点)
  4. 不能与已有函数重名
<?php
// 正确的函数名
function calculateArea() { }
function get_user_info() { }
function _privateFunction() { }
function calculate123() { }

// 错误的函数名
// function 123calculate() { }     // 数字开头
// function calculate-area() { }   // 包含连字符

// 大小写不敏感 - 这三个函数名实际上是相同的
function myFunction() { }
function MYFUNCTION() { }
function myfunction() { }
// 如果定义了这三个,PHP会报错:函数已存在
?>

基本函数示例

简单的无参数函数

<?php
// 显示欢迎信息
function showWelcome() {
    echo "欢迎来到PHP学习网站!<br>";
    echo "在这里你将掌握Web开发的基础技能。<br>";
}

// 显示当前日期
function showCurrentDate() {
    $currentDate = date('Y年m月d日');
    echo "今天是:" . $currentDate . "<br>";
}

// 调用这些函数
showWelcome();
showCurrentDate();
?>

带参数的函数

<?php
// 个性化的问候函数
function greetUser($name) {
    echo "你好," . $name . "!很高兴见到你!<br>";
}

// 计算两个数的和
function addNumbers($num1, $num2) {
    $sum = $num1 + $num2;
    echo "$num1 + $num2 = $sum<br>";
}

// 显示学生信息
function displayStudentInfo($name, $age, $grade) {
    echo "学生姓名:$name<br>";
    echo "年龄:$age岁<br>";
    echo "年级:$grade<br>";
    echo "-------------------<br>";
}

// 调用带参数的函数
greetUser("张三");
greetUser("李四");

addNumbers(10, 20);
addNumbers(3.5, 2.7);

displayStudentInfo("王小明", 18, "高三");
displayStudentInfo("张小红", 17, "高二");
?>

带返回值的函数

<?php
// 计算圆的面积
function calculateCircleArea($radius) {
    $pi = 3.14159;
    $area = $pi * $radius * $radius;
    return $area;  // 返回计算结果
}

// 判断是否成年
function isAdult($age) {
    if ($age >= 18) {
        return true;   // 返回布尔值
    } else {
        return false;
    }
}

// 获取学生成绩等级
function getGradeLevel($score) {
    if ($score >= 90) {
        return "优秀";
    } elseif ($score >= 80) {
        return "良好";
    } elseif ($score >= 70) {
        return "中等";
    } elseif ($score >= 60) {
        return "及格";
    } else {
        return "不及格";
    }
}

// 使用返回值
$area1 = calculateCircleArea(5);
echo "半径为5的圆的面积是:" . $area1 . "<br>";

$area2 = calculateCircleArea(10);
echo "半径为10的圆的面积是:" . $area2 . "<br>";

$studentAge = 20;
if (isAdult($studentAge)) {
    echo "这个学生已经成年<br>";
} else {
    echo "这个学生还未成年<br>";
}

$score = 85;
$grade = getGradeLevel($score);
echo "学生成绩:$score,等级:$grade<br>";
?>

实际应用示例

简单计算器函数

<?php
// 加法函数
function add($a, $b) {
    return $a + $b;
}

// 减法函数
function subtract($a, $b) {
    return $a - $b;
}

// 乘法函数
function multiply($a, $b) {
    return $a * $b;
}

// 除法函数
function divide($a, $b) {
    if ($b == 0) {
        return "错误:除数不能为0";
    }
    return $a / $b;
}

// 计算器主函数
function calculator($num1, $operator, $num2) {
    switch ($operator) {
        case '+':
            return add($num1, $num2);
        case '-':
            return subtract($num1, $num2);
        case '*':
            return multiply($num1, $num2);
        case '/':
            return divide($num1, $num2);
        default:
            return "错误:不支持的操作符";
    }
}

// 使用计算器
$result1 = calculator(10, '+', 5);   // 15
$result2 = calculator(10, '-', 5);   // 5
$result3 = calculator(10, '*', 5);   // 50
$result4 = calculator(10, '/', 5);   // 2
$result5 = calculator(10, '/', 0);   // 错误信息

echo "计算结果:<br>";
echo "10 + 5 = $result1<br>";
echo "10 - 5 = $result2<br>";
echo "10 * 5 = $result3<br>";
echo "10 / 5 = $result4<br>";
echo "10 / 0 = $result5<br>";
?>

学生成绩管理系统

<?php
// 计算学生总分
function calculateTotal($chinese, $math, $english) {
    return $chinese + $math + $english;
}

// 计算学生平均分
function calculateAverage($total, $subjectCount = 3) {
    return round($total / $subjectCount, 2);
}

// 生成学生报告
function generateStudentReport($name, $chinese, $math, $english) {
    $total = calculateTotal($chinese, $math, $english);
    $average = calculateAverage($total);
    $grade = getGradeLevel($average);

    echo "=== 学生成绩报告 ===<br>";
    echo "姓名:$name<br>";
    echo "语文:$chinese 分<br>";
    echo "数学:$math 分<br>";
    echo "英语:$english 分<br>";
    echo "总分:$total 分<br>";
    echo "平均分:$average 分<br>";
    echo "等级:$grade<br>";
    echo "==================<br><br>";

    return [
        'name' => $name,
        'total' => $total,
        'average' => $average,
        'grade' => $grade
    ];
}

// 批量处理学生成绩
function processClassStudents($students) {
    $classReport = [];

    echo "=== 班级成绩总表 ===<br>";

    foreach ($students as $student) {
        $report = generateStudentReport(
            $student['name'],
            $student['chinese'],
            $student['math'],
            $student['english']
        );
        $classReport[] = $report;
    }

    return $classReport;
}

// 学生数据
$students = [
    ['name' => '张三', 'chinese' => 85, 'math' => 92, 'english' => 88],
    ['name' => '李四', 'chinese' => 76, 'math' => 89, 'english' => 95],
    ['name' => '王五', 'chinese' => 92, 'math' => 96, 'english' => 98],
    ['name' => '赵六', 'chinese' => 68, 'math' => 72, 'english' => 65]
];

// 处理班级成绩
$classData = processClassStudents($students);
?>

电商价格计算器

<?php
// 计算商品折扣价
function calculateDiscountPrice($originalPrice, $discountPercentage) {
    $discount = $originalPrice * ($discountPercentage / 100);
    $finalPrice = $originalPrice - $discount;
    return [
        'original_price' => $originalPrice,
        'discount_percentage' => $discountPercentage,
        'discount_amount' => $discount,
        'final_price' => $finalPrice
    ];
}

// 计算运费
function calculateShipping($weight, $distance) {
    // 基础运费计算
    $baseFee = 10;  // 基础费用10元
    $weightFee = $weight * 2;  // 每公斤2元
    $distanceFee = $distance * 0.1;  // 每公里0.1元

    $totalShipping = $baseFee + $weightFee + $distanceFee;

    // 最低运费5元,最高不超过100元
    if ($totalShipping < 5) {
        $totalShipping = 5;
    } elseif ($totalShipping > 100) {
        $totalShipping = 100;
    }

    return round($totalShipping, 2);
}

// 生成商品价格报告
function generatePriceReport($productName, $originalPrice, $discount, $weight, $distance) {
    echo "=== 商品价格计算报告 ===<br>";
    echo "商品名称:$productName<br>";

    // 计算折扣价格
    $priceInfo = calculateDiscountPrice($originalPrice, $discount);
    echo "原价:¥{$priceInfo['original_price']}<br>";
    echo "折扣:{$priceInfo['discount_percentage']}%<br>";
    echo "折扣金额:¥{$priceInfo['discount_amount']}<br>";
    echo "折后价:¥{$priceInfo['final_price']}<br>";

    // 计算运费
    $shipping = calculateShipping($weight, $distance);
    echo "商品重量:{$weight}kg<br>";
    echo "配送距离:{$distance}km<br>";
    echo "运费:¥$shipping<br>";

    // 计算总价
    $totalPrice = $priceInfo['final_price'] + $shipping;
    echo "总计:¥" . number_format($totalPrice, 2) . "<br>";
    echo "======================<br><br>";

    return [
        'product_name' => $productName,
        'original_price' => $priceInfo['original_price'],
        'final_price' => $priceInfo['final_price'],
        'shipping' => $shipping,
        'total_price' => $totalPrice
    ];
}

// 示例商品
generatePriceReport("智能手机", 2999, 15, 0.5, 20);
generatePriceReport("笔记本电脑", 5999, 10, 2.5, 50);
generatePriceReport("运动鞋", 399, 20, 1.2, 10);
?>

函数调用方式

直接调用

<?php
function showMessage($message) {
    echo $message;
}

// 直接调用
showMessage("Hello PHP!");
?>

通过变量调用(可变函数)

<?php
function hello() {
    echo "Hello!<br>";
}

function goodbye() {
    echo "Goodbye!<br>";
}

$funcName = "hello";
$funcName();  // 调用hello()函数

$funcName = "goodbye";
$funcName();  // 调用goodbye()函数
?>

在表达式中调用

<?php
function square($number) {
    return $number * $number;
}

// 在表达式中使用函数
$result = square(5) + square(3);  // 25 + 9 = 34
echo "5² + 3² = $result<br>";

// 在条件语句中使用
if (square(4) > 15) {
    echo "4的平方大于15<br>";
}
?>

最佳实践

1. 函数应该只做一件事

<?php
// 好的做法:函数职责单一
function calculateArea($width, $height) {
    return $width * $height;
}

function displayArea($area) {
    echo "面积是:$area";
}

// 不好的做法:函数做多件事
function calculateAndDisplayArea($width, $height) {
    $area = $width * $height;
    echo "面积是:$area";
    return $area;
}
?>

2. 使用有意义的函数名

<?php
// 好的命名
function calculateRectangleArea($width, $height) { }
function validateEmailAddress($email) { }
function connectToDatabase($host, $username, $password) { }

// 不好的命名
function ca($w, $h) { }
function chk($e) { }
function conn($h, $u, $p) { }
?>

3. 函数应该简洁

<?php
// 好的做法:简洁明了
function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

// 不好的做法:过于复杂
function checkEmail($email) {
    $email = trim($email);
    if (empty($email)) {
        return false;
    }

    if (!preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/', $email)) {
        return false;
    }

    if (strlen($email) > 254) {
        return false;
    }

    return true;
}
?>

常见错误和解决方案

1. 函数未定义错误

<?php
// 错误示例:调用不存在的函数
// myUndefinedFunction();  // 会报错:Call to undefined function

// 解决方案:先定义再调用
function myFunction() {
    echo "函数已定义";
}

myFunction();  // 正确调用
?>

2. 函数名冲突

<?php
// 如果定义了同名函数,PHP会报致命错误
// function test() { echo "第一个函数"; }
// function test() { echo "第二个函数"; }  // 报错

// 解决方案:使用不同的函数名
function testUser() { echo "用户测试"; }
function testAdmin() { echo "管理员测试"; }
?>

3. 参数数量错误

<?php
function greet($name) {
    echo "你好,$name!";
}

// greet();  // 警告:缺少参数
greet("张三");  // 正确
?>

4. 忘记返回值

<?php
function add($a, $b) {
    $sum = $a + $b;
    // 忘记return $sum;
}

$result = add(5, 3);
var_dump($result);  // 输出:NULL

// 解决方案:添加return语句
function addFixed($a, $b) {
    $sum = $a + $b;
    return $sum;
}

$result = addFixed(5, 3);
var_dump($result);  // 输出:int(8)
?>

练习题

基础练习

  1. 创建问候函数

    <?php
    // 创建一个函数personalGreeting,接收姓名和年龄两个参数
    // 输出个性化的问候信息
    
    // 你的代码
    
    // 测试
    personalGreeting("小明", 18);  // 应该输出:18岁的小明,你好!
    ?>
    
  2. 温度转换函数

    <?php
    // 创建函数celsiusToFahrenheit,将摄氏度转换为华氏度
    // 公式:华氏度 = 摄氏度 × 9/5 + 32
    
    // 你的代码
    
    // 测试
    echo celsiusToFahrenheit(0);    // 应该输出:32
    echo celsiusToFahrenheit(100);  // 应该输出:212
    ?>
    
  3. 判断奇偶数

    <?php
    // 创建函数isEven,判断一个数是否为偶数
    // 返回true或false
    
    // 你的代码
    
    // 测试
    var_dump(isEven(4));   // 应该输出:bool(true)
    var_dump(isEven(7));   // 应该输出:bool(false)
    ?>
    

进阶练习

  1. 创建计算器类函数

    <?php
    // 创建一个高级计算器函数,支持多种运算
    // 支持:+、-、*、/、^(幂运算)
    
    // 你的代码
    
    // 测试
    echo advancedCalculator(2, '^', 3);  // 应该输出:8
    echo advancedCalculator(10, '/', 2); // 应该输出:5
    ?>
    
  2. 学生成绩统计

    <?php
    // 创建一个函数,接收学生成绩数组
    // 返回最高分、最低分、平均分、及格率的统计信息
    
    // 你的代码
    
    $scores = [85, 92, 78, 65, 88, 95, 72, 58];
    $stats = analyzeScores($scores);
    print_r($stats);
    ?>
    

实战练习

  1. 商品库存管理系统

    <?php
    // 创建一套商品库存管理函数
    // 包含:添加库存、减少库存、检查库存、生成库存报告
    
    // 需要实现的函数:
    // addStock($product, $quantity)
    // reduceStock($product, $quantity)
    // checkStock($product)
    // generateInventoryReport()
    
    // 你的代码
    
    // 测试你的系统
    ?>
    
  2. 简单的用户认证系统

    <?php
    // 创建用户认证相关函数
    // 包含:注册用户、验证登录、生成用户信息
    
    // 需要实现的函数:
    // registerUser($username, $password, $email)
    // loginUser($username, $password)
    // getUserProfile($username)
    
    // 你的代码
    
    // 测试你的认证系统
    ?>
    

总结

函数是PHP编程的核心概念,掌握函数的定义和调用是成为优秀PHP开发者的基础。通过本章的学习,你应该能够:

  1. 理解函数的概念和作用
  2. 掌握函数定义的基本语法
  3. 学会创建带参数和返回值的函数
  4. 能够在实际项目中应用函数
  5. 遵循函数编写的最佳实践

记住,编写好的函数需要多加练习。在实际开发中,合理使用函数可以让代码更加清晰、可维护和可重用。

下一章我们将学习函数的高级特性,包括参数传递、返回值处理、变量作用域等更多有趣的内容。