PHP 函数学习笔记

1. 函数声明与调用

  • 命名函数
  • 匿名函数

函数的语法
function 函数名(类型限定 参数列表): 返回值类型
{
函数体
return 返回值;
}

  1. // 1. 命名函数
  2. // 自动提升到脚本的顶部,在全局的任何地方都可以调用到
  3. function demo1()
  4. {
  5. return 'Hello';
  6. }
  7. // 按名访问
  8. echo demo1(), '<br>';
  9. // 2. 匿名函数
  10. $demo2 = function () {
  11. return 'word';
  12. };
  13. echo $demo2();

2. 函数的参数

  • 必选参数
  • 可选参数
  • 不定参数
  • 引用参数
  1. // 1. 必选参数
  2. function demo1(string $name): string
  3. {
  4. return "hello $name ";
  5. }
  6. echo demo1('TJ'), '<br>';
  7. // 将标量(单值)自动转换为字符串
  8. echo demo1(123), '<br>';
  9. echo demo1(true), '<br>';
  10. // echo demo1([]), '<br>';
  11. // echo demo1(new class
  12. // {
  13. // }), '<br>';
  14. // echo demo1(); //错误
  15. // 2. 可选参数
  16. function demo2(string $email, string $name = 'TJ'): string
  17. {
  18. return "hello $name ,$email";
  19. }
  20. // echo demo2(), '<br>';
  21. echo demo2('T。。。'), '<br>';
  22. // 当有多个参数时,可选参数必须放在后面
  23. // 必填参数是必须要求有的,如果将可选参数放到首位会有逻辑冲突,既要求必须填,还允许不填。
  24. // 3. 不定参数
  25. function demo3(float $a, float $b, float $c): float
  26. {
  27. return $a + $b + $c;
  28. }
  29. echo demo3(1, 2, 3), '<br>';
  30. //如果有更多的参数,怎么才能更高级和优雅
  31. function demo4()
  32. {
  33. // 通过函数中内置的三个函数获取到参数的全部信息
  34. // 1. 参数个数
  35. $n = func_num_args();
  36. // 2. 参数组成的数组
  37. // func_get_args()
  38. $args = '[' . implode(',', func_get_args()) . ']';
  39. // 3.获取某一个参数
  40. // $arg = func_get_args()[1];
  41. //等价与
  42. $arg = func_get_arg(1);
  43. printf('参数数量:%d<br> 参数数组: %s <br> 第二个参数: %s <br>', $n, $args, $arg);
  44. // 求和
  45. echo '和:', array_sum(func_get_args());
  46. }
  47. demo4(1, 2, 3);
  48. //js中有 ...rest 语法,剩余参数
  49. function demo5(...$args)
  50. {
  51. // print_r($args);
  52. $n = count($args);
  53. $arg = $args[1];
  54. printf('参数数量:%d<br> 参数数组: [%s] <br> 第二个参数: %s <br>', $n, implode(',', $args), $arg);
  55. }
  56. demo5(1, 2, 3, 4);
  57. //实战: 数据表查询
  58. echo '<hr>';
  59. function connect(...$args)
  60. {
  61. print_r($args);
  62. return new PDO($args[0], $args[1], $args[2]);
  63. }
  64. //
  65. $pdo = connect('mysql:dbname=mysql', 'root', 'root');
  66. if ($pdo) echo '<h3>连接成功</h3>';
  67. // 4. 引用参数
  68. echo '<hr>';
  69. //js函数只支持值传递
  70. // php支持“值传递”和“引用传递”
  71. //默认是值传递
  72. //引用传递(引用传参)
  73. //在函数内部对参数的任何更新都会映射到外部的参数中
  74. //在函数的参数前面使用:&
  75. $name = 'TJ';
  76. function demo6(string &$name)
  77. {
  78. $name = '新参数';
  79. }
  80. echo "\$name = $name <br>";
  81. demo6($name);
  82. echo "\$name = $name <br>";

3. 函数的返回值(多值)

  • 数组
  • 对象
  • 序列化字符串
  1. // 函数值允许有一个返回值
  2. // 原则:单值返回
  3. // 返回多值怎么办?
  4. // 1. 数组
  5. function demo1(): array
  6. {
  7. return ['status' => 1, 'message' => '验证成功'];
  8. }
  9. $res = demo1();
  10. var_dump($res);
  11. echo '<br>';
  12. echo $res['status'] === 1 ? $res['message'] : '验证失败', '<br>';
  13. // 2. 对象
  14. function demo2(): object
  15. {
  16. // 匿名类
  17. return new class()
  18. {
  19. public $name = 'admin';
  20. public $email = 'admin@php.cn';
  21. };
  22. }
  23. $user = demo2();
  24. // var_dump($user);
  25. printf('name = %s <br>email = %s<hr>', $user->name, $user->email);
  26. // 3. 序列化的字符串
  27. // 3.1 php 内置的序列号函数
  28. // 如果有一些数据需要进行网络传输或者保存到文件或者数据表中的时候需要用到他
  29. // 如果这个序列化的数据只在php程序中使用,应该使用php内置的方法
  30. function demo3(): string
  31. {
  32. return serialize(['status' => 1, 'message' => '验证成功']);
  33. }
  34. $str = demo3();
  35. echo $str;
  36. // file_put_contents('file.txt', $str . "\\n ", FILE_APPEND | LOCK_EX);
  37. $arr = unserialize($str);
  38. echo '<br>';
  39. var_dump($arr);
  40. echo '<br>';
  41. // 3.2 转为json格式的字符串
  42. // 这样就可以与其它编程语言进行数据交换,例如与js,java,python
  43. function demo4(): string
  44. {
  45. // return json_encode(['status' => 1, 'message' => '验证成功'], JSON_UNESCAPED_UNICODE);
  46. // 等效于
  47. return json_encode(['status' => 1, 'message' => '验证成功'], 256);
  48. // 还可以用320:JSON_UNESCAPED_SLASHES + JSON_UNESCAPED_UNICODE => 64 + 256: 不编码,不转义
  49. //448=64+128+256 64即不转换\ 128 不转换\n \r \t之类的空白 256中文输出
  50. }
  51. $str = demo4();
  52. echo ' json_encode => ', $str, '<br>';
  53. // 常量的整数表示
  54. // JSON_HEX_TAG => 1
  55. // JSON_HEX_AMP => 2
  56. // JSON_HEX_APOS => 4
  57. // JSON_HEX_QUOT => 8
  58. // JSON_FORCE_OBJECT => 16
  59. // JSON_NUMERIC_CHECK => 32
  60. // JSON_UNESCAPED_SLASHES => 64
  61. // JSON_PRETTY_PRINT => 128
  62. // JSON_UNESCAPED_UNICODE => 256
  63. // JSON_PARTIAL_OUTPUT_ON_ERROR => 512
  64. // JSON_PRESERVE_ZERO_FRACTION => 1024
  65. // 如果当前脚本接收一个前端或者其它接口发送过来的json 格式的数据,可以进行解析
  66. // 解析的目的是将外部的json还原成php能够处理的数据类型
  67. $res = json_decode($str);
  68. var_dump($res);
  69. echo '<br>';
  70. //默认将外部的json解析为object对象类型
  71. printf('status = %d message = %s<hr>', $res->status, $res->message);
  72. // 如果不喜欢对象方式访问,也可以使用数组方式
  73. // json_decode()传入第二个参数:true;
  74. $res = json_decode($str, true);
  75. var_dump($res);
  76. echo '<br>';
  77. printf('status = %d message = %s<hr>', $res['status'], $res['message']);

4. 作用域与闭包

  • 函数作用域
  • 匿名函数与闭包
  1. // js:函数作用域,块作用域(es6+)
  2. // php:函数作用域
  3. //声明在函数外部的成员,默认就是全局成员
  4. $name = 'TJ';
  5. $email = 'TJ@tj.com';
  6. function demo1(): string
  7. {
  8. // 函数作用域:只有调用它的时候才会创建
  9. $res = '';
  10. // 如果想在函数内部访问全局 / 外部的成员
  11. // 有两种方式可以在函数内部访问外部成员
  12. // 1. global
  13. global $name;
  14. $res = 'name =>' . $name . '<br>';
  15. // 2. $GLOBALS 超全局数组不受作用域限制,声明的所有全局变量都存在这个数组中
  16. $res .= 'email =>' . $GLOBALS['email'] . '<br>';
  17. // 函数内部声明的变量:外部不可见
  18. $salary = 9988;
  19. $res .= 'salary =>' . $salary . '<br>';
  20. return $res;
  21. }
  22. echo demo1();
  23. // 2. 闭包:匿名函数
  24. // 可以访问函数外部的自由变量
  25. echo '<hr>';
  26. $demo2 = function () use ($name, $email) {
  27. return sprintf('name = %s<br> email = %s <br>', $name, $email);
  28. };
  29. echo $demo2();
  30. //闭包支持引用传参(经常用,
  31. echo '<hr>';
  32. echo '当前:name = ' . $name . '<br>';
  33. $demo3 = function ($myname) use (&$name) {
  34. $name = $myname;
  35. };
  36. echo $demo3('TM TJ');
  37. echo '现在:name = ' . $name . '<br>';
  38. // use 禁止使用已下三种参数
  39. // 1. 超全局不能用: $_GET
  40. // 2. $this
  41. // 3. 与当前参数重名不能用
  42. // 闭包经常用作函数的返回值
  43. function demo4($site)
  44. {
  45. //返回一个函数,闭包的最佳使用场景
  46. return function ($color) use ($site) {
  47. return sprintf('<h3 style="color:%s">%s</h3>', $color, $site);
  48. };
  49. };
  50. // var_dump(demo4('php'));
  51. echo '<hr>';
  52. $cl = demo4('php');
  53. echo $cl('red');
  54. // 高阶函数 : 柯里化
  55. echo '<hr>';
  56. echo demo4('php.cn')('red');

5. 回调函数

  • call_user_func()
  • call_user_func_array()
  1. // 回调执行
  2. function demo1(string $name): string
  3. {
  4. return "Hello $name !";
  5. }
  6. // 传统方式
  7. echo demo1('TJ'), '<hr>';
  8. // php 单线程,同步执行,如果遇到耗时函数会发生阻塞,应该将它改为异步回调执行
  9. //call_user_func(函数,参数列表)
  10. echo call_user_func('demo1', 'callBack'), '<hr>';
  11. //call_user_func_array(函数,参数列表)
  12. echo call_user_func_array('demo1', ['callBackToo']), '<hr>';
  13. $sql = 'SELECT * FROM `db` LIMIT 1';
  14. $demo2 = function ($dsn, $username, $password) use ($sql) {
  15. $pdo = new PDO($dsn, $username, $password);
  16. $stmt = $pdo->prepare($sql);
  17. $stmt->execute();
  18. return $stmt->fetchAll(PDO::FETCH_ASSOC);
  19. };
  20. $res = call_user_func_array($demo2, ['mysql:dbname=mysql', 'root', 'root']);
  21. print_r($res);
  22. // 这两个函数还可以异步的调用对象方法
  23. class User
  24. {
  25. // 实例方法
  26. public function hello(string $name): string
  27. {
  28. return "hello $name !";
  29. }
  30. //静态方法:;类调用
  31. public static function say(string $site): string
  32. {
  33. return "欢迎来 $site !";
  34. }
  35. }
  36. // 实例方法
  37. $res = call_user_func_array([new User, 'hello'], ['TJ']);
  38. echo $res, '<br>';
  39. // 静态方法
  40. // $res = call_user_func_array(['User', 'say'], ['o-o']);
  41. // 等价于
  42. $res = call_user_func_array('User::say', ['o-o']);
  43. echo $res, '<br>';

6. 静态变量

  • static
  1. // 静态变量
  2. function demo1()
  3. {
  4. //静态话的变量不会消除
  5. //函数中的静态变量不会随着函数调用解释而消失。自动进入下一次的函数调用中
  6. // 可以实现在函数的多次调用过程中: 共享数据 / 数据通信
  7. static $i = 1;
  8. echo $i, '<br>';
  9. $i++;
  10. }
  11. echo demo1();
  12. echo demo1();
  13. echo demo1();
  14. echo demo1();

注意:call_user_func_array() 会用的比较多
个人感觉,静态方法调用
$res = call_user_func_array('类::方法', ['参数']);
$res = call_user_func_array(['类', '方法'], ['参数']);
好理解。
总结:
为了和实例方法调用一起记忆还是统一比较好记。
实列调用:$res = call_user_func_array([new 类, '方法'], ['参数']);
静态调用:$res = call_user_func_array(['类', '方法'], ['参数']);

更多相关文章

  1. 手把手教你如何用DolphinDB进行机器学习
  2. Java Lambda 表达式
  3. Vue3 系统入门与项目实战
  4. c语言学习打卡 自定义函数
  5. Excel按区间查询,大咖有句悄悄话
  6. 用函数公式制作旋风图,75.42%的人没想到!
  7. 工作中最常用的十个函数公式,看看哪个还不熟?
  8. Flink特异的迭代操作-bulkIteration
  9. spring boot 获得 http请求url中的参数

随机推荐

  1. 利用keepalived构建高可用MySQL-HA
  2. MySQL表格查询基本语句2
  3. 组织这种结构的最佳方式?
  4. mysql添加外键语句
  5. lucene 4.10 检索mysql数据库
  6. mysql必知必会 - LIMIT
  7. 高级MySQL:查找轮询响应之间的相关性
  8. mysql 根据select结果进行循环操作,并写入
  9. Linux下,配置WordPress时出现“您的PHP似
  10. MySQL可视化软件Work Bench导出导入数据