PHP函数和变量
PHP中的函数函数解决某个功能的代码段,分为系统函数和自定义函数
系统函数
字符串、数组、数字、日期时间等
- header
- strtolower
- strtoupper
- mt_rand
- range
- current
- array_push
- array_pop
自定义函数
按照具体需求封装的函数
header('content-type:text/html;charset=utf-8');
/**
* 一个函数只完成一个功能
* 函数的执行原理:不调用不执行,当封装完后将其载入内存中,当调用函数时,找到对应的函数,执行函数体。
* 当碰到return语句,或者执行到函数的末尾,再将控制权移交到调用函数的位置上,接着程序继续向下执行。
* function 函数名称([参数名称[=值]]){
* 函数体;
* return 返回值;
* }
* 注意:
* 函数名称不能包含特殊字符,以字母或者下划线开始,跟上数字、字母、下划线
* 函数名称最后以动词开始,最好含义明确,getExt() uploadFile()
* 函数名称遵循驼峰命名法或者下划线
* 函数名称是不区分大小写,但是尽量遵循函数大小写进行调用
* 函数名称不支持重名,如果重名会报致命错误
* 函数可以有参数,也可以没有参数
* 函数可以有返回值,也可以没有返回值
* 在封装函数的时候,平时代码怎么写,现在就怎么写,只不过写完之后,外层套一个架子
* 封装完后需要调用才会执行
*/
// 检测函数名称是否存在的函数
// function_exists($funcName):如果存在返回true,否则返回false
var_dump(function_exists('strtolower')); // true
函数返回值
header('content-type:text/html;charset=utf-8'); // 设置编码
/**
* 测试函数的返回值
* 返回值通过renturn返回值形式
* 函数默认返回null
* 返回值形式可以是任意类型
*/
if(!function_exists('test1')){
function test1(){
echo 'this is test1<br/>';
}
}
var_dump(test1());
function test2(){
return md5('king'); // 加密后的32位字符串
return 1==1; // true
return fopen('index.php', 'r'); // resource
return new stdClass(); // object
return array(32,true, 'king'); // array
return null;
return false;
return 'king';
return 32.3;
}
echo test2();
函数的参数
/**
* 创建M行N列的表格
* 返回值通过renturn返回值形式
* 函数默认返回null
* 返回值形式可以是任意类型
* 必传参数必须再可选参数前面
*/
/**
* 创建特定需求的表格
* @param $rows
* @param $cols
* @param string $color
* @param string $content
* @return string
*/
function createTable($rows, $cols, $color='red',$content='x'){
$table = "<table border='1' color='{$color}' cellpadding='0' width='80%'>";
for($i=1;$i<=$rows;$i++){
$table .= "<tr>";
for($j=1;$j<=$cols;$j++){
$table.="<td>{$content}</td>";
}
$table.="</tr>";
}
$table.="</table>";
return $table;
}
echo createTable(10,5);
header('content-type:text/html;charset=utf-8');
/**
* 获取文件扩展名
* @param string $filename
* @return string
*/
function getExt($filename){
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
return $ext;
}
echo getExt('1.html');
变量的作用域
局部变量
1、函数内部声明的变量为局部变量
2、局部变量分为动态变量和静态变量
- 动态变量
函数执行完毕之后立即释放 - 静态变量
通过static关键字声明的变量为静态变量,当第一次调用函数的时候相当于初始化静态变量,当函数执行完毕之后静态变量没有释放而是保存到静态内存中,当再次调用函数的时候首先从静态内存中取出变量的值接着执行
全局变量
函数体外部声明的变量或者函数体内用global关键字声明的变量
- 如何在函数体内使用全局变量
global关键字或$GLOBALS超全局变量
header('content-type:text/html;charset=utf-8');
$username = 'lxy';
function test(){
//global $m=1; // 报错
global $m;
global $n;
global $i,$j;
$m=$n=$i=$j=1;
}
test();
var_dump($GLOBALS);
var_dump($m,$n);
函数传值和传引用的区别
- 传值
默认情况下,函数参数通过值传递,即时在函数内部改变参数的值,也不会改变函数外部的值 - 传引用
可以通过在参数前添加&符号,代表通过引用传递参数,在参数内部对其进行的操作,影响其本身
header('content-type:text/html;charset=utf-8');
// 传递值
$str = 'King';
$res = strtolower($str);
var_dump($res,$str);
// 传递引用
$arr=array("a","b","c");
array_pop($arr);
var_dump($arr); // array("a","b")
function test($i){
$i+=10;
var_dump($i);
}
$i=2;
test($i);// 12
var_dump($i); //2
// 取变量的地址
function test1(&$j){
$j+=20;
var_dump($j);
}
$m=5;
test1($m); // 25
var_dump($m); // 25
// test1(5); // PHP Fatal error: Only variables can be passed by reference in
PHP中特殊形式的函数
可变函数
在php中如果将函数名称赋予字符串类型的变量,但是在使用该变量时,如果带有小括号,那么php引擎将解析函数
// 可变函数的使用
$funcName = 'md5';
echo $funcName('king');
echo PHP_EOL;
echo md5('king');
echo PHP_EOL;
// 得到所有已经定义的函数,返回数组,包含系统函数和用户自定义函数
print_r(get_defined_functions());
注意:可变函数不能用于像echo print unset() isset() empty() include require以及类似的语言结构,需要自己封装之后实现
回调函数
回调函数就是调用函数的时候将另外一个函数的名称当作参数传递进去,并在函数体中进行调用。
如何调用回调函数?
可以通过可变函数的形式在函数体中进行调用;也可以通过call_user_func()和call_user_func_arrary()进行调用
- 回调函数的例子
// 回调函数的例子
function study(){
echo 'studying……';
}
function play(){
echo 'playing……';
}
function doWhat($functionName){
echo '我正在';
// 通过可变函数的形式进行调用
$functionName();
}
dowhat('study'); // 我正在studying……
- 自定义函数使用回调函数的例子
// 自定义函数使用回调函数的例子
function study($username){
echo $username.' is studying……';
}
function play($username){
echo $username.' is playing……';
}
function doWhat($functionName, $param){
// 通过可变函数的形式进行调用
$functionName($param);
}
dowhat('study', 'king'); // king is studying……
echo PHP_EOL;
function add($x,$y){
return $x+$y;
}
function reduce($x,$y){
return $x-$y;
}
function calc($functionName,$i,$j){
return $functionName($i,$j);
}
echo calc('reduce',5,4); // 1
-
系统函数使用回调函数的例子
array_map(callable array1[,array $...]):array
array_map 为数组的每个元素应用回调函数,返回数组,是为array1每个元素应用callback函数之后的数组。callbak函数形参的数量和传给array_map()数组的数量,两者必须一样。
callback
回调函数,应用到每个数组里的每个元素。
array1
数组,遍历运行 callback 函数。
...
数组列表,每个都遍历运行 callback 函数。
返回数组,包含 callback 函数处理之后 array1 的所有元素。
function test($val){
return $val*2;
}
$arr = [1,2,3,4];
$res = array_map('test', $arr);
print_r($res);
Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 8
)
$config = [
1 => ['title' => '推荐', 'code' => 1],
2 => ['title' => '奇闻1', 'code' => 2],
3 => ['title' => '奇闻2', 'code' => 2],
4 => ['title' => '搞笑', 'code' => 1]
];
/**
* 使用map的时候,在匿名函数里面是没有key值的,而walk是同时存在key val两个值的
*/
array_map(function ($value) use($config) { // & 注意
print_r($value);exit;
/**
* Array
*(
*[title] => 推荐
*[code] => 1
*)
*/
}, $config);
array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
array_walk ( array &callback [, mixed $userdata = NULL ] ) : bool
将用户自定义函数 funcname 应用到 array 数组中的每个单元。
array_walk() 不会受到 array 内部数组指针的影响。array_walk() 会遍历整个数组而不管指针的位置。
array
输入的数组。
callback
典型情况下 callback 接受两个参数。array 参数的值作为第一个,键名作为第二个。
成功时返回 TRUE, 或者在失败时返回 FALSE。
function test(&$val){
$val = $val*2;
return $val;
}
$arr = [1,2,3,4];
$res = array_walk($arr, 'test');
print_r($res); // 1
echo PHP_EOL;
print_r($arr); // 2468
$config = [
1 => ['title' => '推荐', 'code' => 1],
2 => ['title' => '奇闻1', 'code' => 2],
3 => ['title' => '奇闻2', 'code' => 2],
4 => ['title' => '搞笑', 'code' => 1]
];
array_walk($config, function ($value, $key) use (&$config) { // & 注意
if ($value['code'] == 1) {
$config[$key] = $value['title'];
} else {
unset($config[$key]);
}
});
var_dump($config);
array(2) {
[1] =>
string(6) "推荐"
[4] =>
string(6) "搞笑"
}
array_filter — 用回调函数过滤数组中的单元
array_filter ( array callback [, int $flag = 0 ]] ) : array
依次将 array 数组中的每个值传递到 callback 函数。如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。
array要循环的数组
callback使用的回调函数
如果没有提供 callback 函数, 将删除 array 中所有等值为 FALSE 的条目。更多信息见转换为布尔值。
flag决定callback接收的参数形式:
ARRAY_FILTER_USE_KEY - callback接受键名作为的唯一参数
ARRAY_FILTER_USE_BOTH - callback同时接受键名和键值
返回值,返回过滤后的数组
header('content-type:text/html;charset=utf-8');
// 系统函数使用回调函数的例子
function odd($val){
if($val % 2 == 1){
return $val;
}
}
$arr = [1,2,3,4];
$res = array_filter($arr, 'odd');
print_r($res);
Array
(
[0] => 1
[2] => 3
)
call_user_func — 把第一个参数作为回调函数调用
call_user_func ( callable parameter [, mixed $... ]] ) : mixed
第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。
callback将被调用的回调函数(callable)。
parameter0个或以上的参数,被传入回调函数。
返回回调函数的返回值
call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数
说明
call_user_func_array ( callable param_arr ) : mixed
把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。
参数
callback被调用的回调函数。
param_arr要被传入回调函数的数组,这个数组得是索引数组。
返回值
返回回调函数的结果。如果出错的话就返回FALSE
header('content-type:text/html;charset=utf-8');
function add($x,$y){
return $x+$y;
}
echo call_user_func('add',1,2);// 3
echo call_user_func_array('add', array(1,2)); // 3
匿名函数
1、匿名函数,也叫做闭包函数,允许临时创建一个没有指定名称的函数,最经常用作回调函数参数的值。
2、匿名函数也可以作为变量的值使用。
header('content-type:text/html;charset=utf-8');
// 匿名函数定义的第一种形式
$func = function ($username){
return "say hi to {$username}";
};
echo $func('king');
echo PHP_EOL;
// 通过create_function()
$func = create_function('$username','return $username;');
echo PHP_EOL;
echo $func('king');
echo PHP_EOL;
$arr = [1,2,3,4];
$res = array_map(function ($var){return $var*2;}, $arr);
print_r($res);
say hi to king
king
Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 8
)
递归函数
如果函数A需要调用函数B,而发现函数B的代码实现与函数A的完全相同,依次类推,此时就需要封装成递归函数。
想PHP实现目录的遍历,目录的复制、删除费控目录操作必粗通过递归函数来实现
像无限极分类也可以通过递归实现
递归函数:通俗讲就是自己调用自己的函数,通过特定条件结束执行。
header('content-type:text/html;charset=utf-8');
function test($i){
echo $i;
echo PHP_EOL;
if($i>=0){
$func = __FUNCTION__;
$func($i-1);
}
echo PHP_EOL;
echo $i;
echo PHP_EOL;
}
test(3);
exit;
如何使用自定义函数
require require_once include include_once 区别与联系
对于多处使用的自定义函数,使用包含文件方式,可以避免多处写相同的函数
// 通过include/include_once包含文件不存在的时候,会产生两个警告,程序继续执行
/**
* Warning: include(lxy.php): failed to open stream: No such file or directory in D:\learning\test.php on line 10
* Warning: include(): Failed opening 'lxy.php' for inclusion (include_path='D:\xampp\php\PEAR') in D:\learning\test.php on line 10
* include result
*/
include 'lxy.php';
echo 'include result';
echo PHP_EOL;
// 通过require/ require_once包含文件不存在的时候,会产生一个警告和一个致命错误,程序中断执行
/**
* Warning: require(lxy.php): failed to open stream: No such file or directory in D:\learning\test.php on line 14
* Fatal error: require(): Failed opening required 'lxy.php' (include_path='D:\xampp\php\PEAR') in D:\learning\test.php on line 14
*/
require 'lxy.php';
echo 'require result';
/**
* 我是header
* 哈哈哈
* 我是header
*/
require('test.php');
echo '哈哈哈';
echo PHP_EOL;
require('test.php');
/**
* 我是header
* 啦啦啦
*/
require_once('test.php');
echo '啦啦啦';
echo PHP_EOL;
require_once('test.php');
函数实战
通过10种以上的方式截取文件扩展名
// 通过10种以上的方式截取文件扩展名
function getExt($filename){
return strtolower(pathinfo($filename,PATHINFO_EXTENSION));
}
封装简单的计算器
// 封装简单的计算器,传入两个数值,一个操作符,返回结果,默认是加法操作
/**
* 封装简单的计算器,传入两个数值,一个操作符,返回结果,默认是加法操作
* @param number $num1
* @param number $num2
* @param string $op
* @return string
*/
function calc($num1,$num2,$op='+'){
if(!is_numeric($num1) || !is_numeric($num2)){
exit("非数字不能输入");
}
switch ($op){
case '+':
$res = $num1+$num2;
break;
case '-':
$res = $num1-$num2;
break;
case '*':
$res = $num1*$num2;
break;
case '/':
if($num2 !==0){
$res = $num1/$num2;
}else{
exit("除数不能为0");
}
break;
case '%':
$res = $num1%$num2;
break;
}
return "{$num1}{$op}{$num2}={$res}";
}
//echo calc('a','b','+'); // 非数字不能输入
//echo calc(4,0,'/'); // 除数不能为0
echo calc(3,2,'/'); // 3/2=1.5
日期星期封装
/**
* 封装默认2019年12月13日 星期四 可以改变分隔符
* @param string $del1
* @param string $del2
* @param string $del3
* @return string
*/
function dateStr($del1='年',$del2='月',$del3='日'){
$dayArr = ['日','一','二','三','四','五','六'];
$day = date('w'); // 0~6
return date("Y{$del1}m{$del2}d{$del3} 星期").$dayArr[$day];
}
echo dateStr();
echo PHP_EOL;
echo dateStr("/","/",null);
echo PHP_EOL;
echo dateStr("~","~","");
2019年12月23日 星期一
2019/12/23 星期一
2019~12~23 星期一
随机生成验证码
/**
* 默认产生4位数字的验证码,也可以改变验证码的长度
* type=1 数字
* type=2 字母
* type=3 数字+字母
*/