使用简单函数
<?php
//打印文字为粗体函数
function printBold($text)
{
print("<b>$text</b>");
}
print("这一行不是粗体<br>\n");
printBold("这一行是粗体");
print("<br>\n");
print("这一行不是粗体");
?>
系统(内置)函数
PHP有很多标准的内置函数,这些函数分为两部分,一部分是核心函数,例如字符串和变量函数,还有一些函数需要和特定的PHP扩展模块一起安装,否则在使用它们的时候就会得到一个致命的“未定义函数”错误。例如,要使用图像函数imagecreateturecolor(),需要在安装PHP的时候加上GD(一个图像处理库)的支持。或者,要使用MySQL数据库的连接函数mysql_connect(),就需要在安装PHP的时候加上MySQL数据库的支持。要知道当前使用的PHP有哪些函数,可以调用phpinfo()函数或者get_loaded_extensions()函数得到PHP加载了哪些扩展库。
<?php
phpinfo();
?>
自定义函数
<?php
//调用etc函数
etc();
//定义foo函数
function foo()
{
echo "我是函数foo\n";
//定义bar函数
function bar()
{
echo "我是函数bar\n";
}
}
//定义etc函数
function etc()
{
echo "我是函数etc\n";
}
//调用foo函数
foo();
//调用bar函数
bar();
?>
在目前的PHP版本中,函数具有全局属性,也就是定义一个函数后,可以在程序的任何地方使用,定义函数的位置可以在程序的任何地方,甚至可以在另有一个函数内部。
上述代码分析:代码第四行调用etc函数,而etc函数是在第19-22行定义的,由此可见PHP中,函数可以定义在需要调用代码之后。第7-16行定义了foo函数,在foo函数中又定义了bar函数,这叫函数中的函数,在实际项目中很少又这样的定义。最后的几行中调用了foo函数和bar函数,运行正常,再次证明了PHP函数可以定义在任何地方,且在任何地方均可调用。
由于PHP函数具有全局特性,造成了函数不能重名。
函数参数
函数的参数是用来和函数沟通的途径,参数以逗号作为分隔符。
调用函数时,需要给参数传值,传值有3种方式:
1.按值传递:函数默认按值传递,相当于将值赋给了参数,以下是例子
<?php
$n = 3; //初始化一个变量‘
//定义函数
function byvalue($num)
{
$num = $num + 1; //改变参数的值
echo $num;
}
byvalue($n);
echo "<br>"; //换行
echo $n;
?>
代码分析:第三行初始化了变量 n 的 值 为 3 , 第 6 − 9 行 定 义 了 函 数 b y v a l u e , 实 现 的 功 能 是 将 收 到 的 参 数 值 加 1 操 作 , 第 11 行 调 用 函 数 b y v a l u e , 给 参 数 n的值为3,第6-9行定义了函数byvalue,实现的功能是将收到的参数值加1操作,第11行调用函数byvalue,给参数 n的值为3,第6−9行定义了函数byvalue,实现的功能是将收到的参数值加1操作,第11行调用函数byvalue,给参数num的值为 n ( 3 ) , 函 数 b y v a l u e 实 现 了 n(3),函数byvalue实现了 n(3),函数byvalue实现了num++,并打印出结果4,完成函数调用。
2.引用传递:引用传递和C语言的传值类似,传值时一个拷贝,引用传递是传递了一个别名,而不是拷贝一个值。
<?php
$n = 3; //初始化一个变量
//定义函数
function byvalue(&$num) //参数前多了一个&符号
{
$num = $num + 1; //改变参数的值
echo $num;
}
byvalue($n);
echo '<br>';
echo $n;
?>
在按值传递种,$n的值是3,现在的结果是4,这就是引用传递。如果希望允许函数修改它的参数值,必须引用传递参数。
3.默认值:函数的参数可以设置一个默认值
<?php
$n = 3; //初始化一个变量
//定义函数
function byvalue($num=1)
{
$num = $num + 1; //改变参数的值
echo $num;
}
byvalue($n);
echo '<br>';
byvalue();
?>
代码分析:这次修改是在参数
n
u
m
后
面
添
加
了
一
个
默
认
值
,
第
12
和
14
行
各
调
用
了
一
次
b
y
v
a
l
u
e
函
数
,
不
同
的
是
第
12
行
调
用
给
了
参
数
值
num后面添加了一个默认值,第12和14行各调用了一次byvalue函数,不同的是第12行调用给了参数值
num后面添加了一个默认值,第12和14行各调用了一次byvalue函数,不同的是第12行调用给了参数值n,第14行调用时没有给参数,结果显示给了没有给参数的结果为2,这说明当函数参数有默认值的时候,调用函数时没有给参数,那么函数使用默认值。
注意:默认值必须是常量表达式,不是变量、类成员、或者函数调用等
在函数参数使用默认值时,如果有多个参数,那么需要将有默认值参数放在任何非默认值参数的右边。
<?php
function hello($name = 'leo', $time)
{
return '你好, ' . $name . '。 现在的时间是: ' . $time;
}
echo hello('9点');
?>
运行结果将会有警告且,不是预期结果
<?php
function hello($time, $name = 'leo')
{
return '你好, ' . $name . '。 现在的时间是: ' . $time;
}
echo hello('9点');
?>
返回值
函数值通过使用可选的返回语句返回。通常使用return语句,任何类型都可以返回,其中包括列表和对象。在return语句在函数中,那么执行后将立即停止该函数运行,并且将控制权传递会它被调用的行,函数不能返回多个值,但可以返回一个数组得到多个值。同样,函数也可以返回一个引用,这和变量的引用类似,只需要在函数前加上符号"&"。
<?php
function &returnReference()
{
$someReference = "leo";
return $someReference;
}
$reference =&returnReference();
?>
变量$reference是函数returnReference返回的一个引用。
动态调用函数
假设一个状况,在一个项目中,客户要求自己设置字符串转换成大写或小写。
<?php
/*
设置字符转换方式,小写strtolower,大写strtoupper
*/
$functionName = 'strtolower'; //设置为小写
$string = 'LEO'; //要处理的字符
//判断用户设置
if ($functionName == 'strtolower')
{
//调用函数处理
$string = strtolower($string);
}
?>
改进:
<?php
/*
设置字符转换方式,小写strtolower,大写strtoupper
*/
$functionName = 'strtolower'; //设置为小写
$string = 'LEO'; //要处理的字符
//判断用户设置
$functionName($string);
?>
这就是PHP中动态调用函数
注意:动态调用函数不能用于语言结构,例如echo(),print(),unset(),isset(),empty(),include(),require()及类似语句,除非将这些语言结构冲重新用自定义函数包装起来,然后使用包装函数调用
作用域
问题:在PHP代码中,变量和函数产生后,其有效期有多长,在哪些结构里面起作用,这就有关作用域了
1.局部作用域:
局部作用域即只是在某一个区间有效。
<?php
function text()
{
$abc = 123;
}
echo $abc;
?>
此代码将会报错;因为变量$abc在text函数外是无效的。
<?php
$abc = 123;
function text()
{
echo $abc;
}
text();
?>
此代码也会报错。
如果函数内需要使用函数外定义的变量该如果做呢?
<?php
$abc = 123;
function text()
{
global $abc;
echo $abc;
}
text();
?>
这次将不会报错
代码分析:这次修改在函数中加入了关键字"global",后面是变量$abc,这样函数内就可以使用函数外的变量了,如果有多个变量,那么就使用逗号隔开,依然是分号结束。
<?php
$abc = 123;
$def = 456;
function text()
{
global $abc,$def;
echo $abc . $def;
}
text();
?>
2.全局作用域:
之前提到,函数具有全局作用域,也就是定义一个函数,那么该函数可以在程序中的任何地方使用。
在PHP中,虽然直接在文件开头定义的变量是全局变量,但是在函数中却需要加入关键字global才可以使用,
但如果有必要可以将变量定义在预定义变量中,因为PHP预定义变量是超全局变量,
超全局变量是可以在PHP中任何地方使用的,这个特性和函数一样。
<?php
$text = 'leo';
function printvar()
{
echo '在函数printvar内显示的$globals[\'text\']: ' . $GLOBALS['text'];
echo "<br>";
}
printvar();
echo '直接显示的$globals[\'text\']: ' . $GLOBALS['text'];
echo "<br>";
echo '直接显示的$text: ' . $text;
?>
代码分析:第四行定义变量 t e x t , 值 为 l e o , 第 6 − 10 行 定 义 函 数 p r i n t v a r , 函 数 作 用 是 打 印 text,值为leo,第6-10行定义函数printvar,函数作用是打印 text,值为leo,第6−10行定义函数printvar,函数作用是打印GLOBALS[‘text’]这个变量,第12行调用函数printvar,此时得到第一个结果,第13行打印字符串“直接显示…”后面是一个字符串运算符" . ",是将“直接显示…”与后面“$GLOBALS[‘text’]"的值。
加入反斜杠是因为打印的这个字符串含有变量,如果使用双引号将不会显示“ G L O B A L S [ ′ t e x t ′ ] ” , 而 是 显 示 “ GLOBALS['text']”,而是显示“ GLOBALS[′text′]”,而是显示“GLOBLAS[‘text’]”的值。使用单引号是为了让这个变量以字符串输出,但是使用单引号就会和“$ GLOBALS[‘text’]”冲突,此时使用两个反斜杠来转义这两个单引号,这样就准确地输出了字符串“$GLOBALS[‘text’]”。
只要定义的变量具有全局属性,那么该变量都可以用“$GLOBLAS[‘定义的变量名字’]”来访问,不论在何时何地。具有全局属性的变量通常指没有在任何条件或一些结构下定义的变量。
<?php
$text = 'leo';
function printcvar()
{
$wahaha = 'wahaha';
}
echo '显示的$GLOBALS[\'text\']: ' . $GLOBALS['text'];
echo '<br>';
echo '显示的$GLOBALS[\'wahaha\']: ' . $GLOBALS['wahaha'];
?>
发现wahaha后面没有显示。
代码分析:定义$text变量没有在任何函数内或foreach等结构内,所以具有全局属性,这些变量可以用超全局变量访问,反之,在函数printvar内定义的变量wahaha则具有局部属性,只是在函数printvar中有效,所以不能用超全局变量访问到。
生存期
<?php
function text()
{
$a = 0;
echo $a;
$a++;
}
text();
text();
?>
结果输出00.函数内的变量 a 是 一 个 局 部 作 用 域 变 量 , 每 次 调 用 时 都 会 将 a是一个局部作用域变量,每次调用时都会将 a是一个局部作用域变量,每次调用时都会将a的值设为0并输出0。将变量自加1的 a + + 没 有 作 用 , 因 为 一 旦 退 出 本 函 数 变 量 a++没有作用,因为一旦退出本函数变量 a++没有作用,因为一旦退出本函数变量a就不存在了。
那么,要将函数内的变量保留下来,除了return 之外,还可以使用静态变量。
<?php
function text()
{
static $a = 0;
echo $a;
$a++;
}
text();
text();
?>
结果为01,这说明情况发生改变了,变量
a
的
生
存
期
不
仅
仅
因
为
第
一
次
函
数
t
e
x
t
的
调
用
结
束
而
结
束
,
当
第
二
次
调
用
函
数
时
,
变
量
a的生存期不仅仅因为第一次函数text的调用结束而结束,当第二次调用函数时,变量
a的生存期不仅仅因为第一次函数text的调用结束而结束,当第二次调用函数时,变量a的值还存在。
现在来看一下函数的生存期,先前提到函数是具有全局域的,无论在哪都能使用,但下面这个例子会出现一些例外。
<?php
function math()
{
echo 'math is amazing';
function code()
{
echo 'code is amazing';
}
}
code();
?>
结果会出现错误。这是因为没有运行math函数,code函数就没有定义。
修改:
<?php
function math()
{
echo 'math is amazing';
function code()
{
echo 'code is amazing';
}
}
math();
code();
?>
结果运行正常。
修改:
<?php
function math()
{
echo 'math is amazing';
function code()
{
echo 'code is amazing';
}
}
math();
math();
code();
?>
发现有区别,因为第一次调用math函数时,定义了code,第二次调用就出现了错误,这就是为什么不推荐在函数中定义函数,因为定义了函数中的函数,那么上层函数就只能调用一次。