函數(shù)
函數(shù):function,是一種語(yǔ)法結(jié)構(gòu),將實(shí)現(xiàn)某一個(gè)功能的代碼塊(多行代碼)封裝到一個(gè)結(jié)構(gòu)中,從而實(shí)現(xiàn)代碼的重復(fù)利用(復(fù)用)。
定義&使用
function 函數(shù)名(參數(shù)){
//函數(shù)體
//返回值:return 結(jié)果;
}
定義函數(shù)的目的:是為了實(shí)現(xiàn)代碼的重復(fù)利用,一個(gè)功能一個(gè)函數(shù)(簡(jiǎn)單明了)
函數(shù)的使用:通過(guò) 函數(shù)名()
的方式進(jìn)行函數(shù)訪問(wèn)
注意:
- 如果函數(shù)在定義的過(guò)程中有參數(shù),那么在調(diào)用的時(shí)候就必須傳入對(duì)應(yīng)的參數(shù):函數(shù)是一種結(jié)構(gòu)不會(huì)自動(dòng)運(yùn)行,必須通過(guò)調(diào)用才會(huì)執(zhí)行
- 函數(shù)是在代碼執(zhí)行階段,碰到函數(shù)名字的時(shí)候才會(huì)調(diào)用,不是在編譯階段。
- 函數(shù)的調(diào)用特點(diǎn):只要系統(tǒng)在內(nèi)存中能夠找到對(duì)應(yīng)的函數(shù),就可以執(zhí)行(函數(shù)的調(diào)用可以在函數(shù)定義之前)
display(20); //20hello Mango
function display($val)
{
echo $val;
echo "hello Mango";
}
命名規(guī)則
命名規(guī)范:由字母、數(shù)字和下劃線(xiàn)組成,但是不能以數(shù)字開(kāi)頭
函數(shù)作為一種常用的結(jié)構(gòu),一般遵循以下規(guī)則:函數(shù)通常名字代表著函數(shù)的功能,而有些功能會(huì)比較復(fù)雜,可能一個(gè)單詞不足以表達(dá),需要多個(gè)組合。
1.駝峰法:除了左邊第一個(gè)單詞外,后面所有的單詞首字母都大寫(xiě):showParentInfo()
2.下劃線(xiàn)法:單詞之間通過(guò)下劃線(xiàn)連接,單詞都是小寫(xiě):show_parent_info()
函數(shù)名字:在一個(gè)腳本周期中,不允許出現(xiàn)同名函數(shù)(通常在一個(gè)系統(tǒng)開(kāi)發(fā)中都不會(huì)使用同名函數(shù))
參數(shù)種類(lèi)
函數(shù)的參數(shù)分為兩種:形參和實(shí)參
- 形參:形式參數(shù),不具有實(shí)際意義的參數(shù),是在函數(shù)定義時(shí)使用的參數(shù)
- 實(shí)參:實(shí)際參數(shù),具有實(shí)際數(shù)據(jù)意義的參數(shù),是在函數(shù)調(diào)用時(shí)使用的參數(shù)
形參是實(shí)參的載體:實(shí)參在調(diào)用時(shí)通常是需要傳入到函數(shù)內(nèi)部參與計(jì)算(運(yùn)算),那么需要在函數(shù)內(nèi)部去找到實(shí)際數(shù)據(jù)所在的位置才能找到數(shù)據(jù)本身:需要實(shí)際調(diào)用的時(shí)候,將數(shù)據(jù)以實(shí)參的形式傳遞給形參:給形參賦值,從而使得函數(shù)內(nèi)部可以用到外部數(shù)據(jù)。
例子:
注意:
1.在PHP中允許實(shí)參多于形參(個(gè)數(shù)):函數(shù)內(nèi)部不用而已
2.在PHP中理論上形參個(gè)數(shù)沒(méi)有限制(實(shí)際開(kāi)發(fā)不會(huì)太多)
3.實(shí)參不能少于形參個(gè)數(shù)
默認(rèn)值
默認(rèn)值指的是形參的默認(rèn)值,在函數(shù)定義的時(shí)候,就給形參進(jìn)行一個(gè)初始賦值:如果實(shí)際調(diào)用傳入的參數(shù)(實(shí)參)沒(méi)有提供,那么形參就會(huì)使用定義時(shí)的值來(lái)進(jìn)入函數(shù)內(nèi)部參與運(yùn)算。
通常默認(rèn)值是用在一些一定會(huì)有某個(gè)數(shù)據(jù)參與,但是可能通常是某個(gè)我們知道的值。
注意事項(xiàng):
1.默認(rèn)值的定義是放在最右邊的(多個(gè)),不能左邊形參有默認(rèn)值,但是右邊沒(méi)有 (必須從右往左缺省,而且要連續(xù))
2.函數(shù)外部定義的變量名字與函數(shù)定義的形參名字沖突(同名)是沒(méi)有任何關(guān)聯(lián)關(guān)系的,如果多個(gè)函數(shù)使用同樣的形參名字也不沖突。
引用傳遞
實(shí)參在調(diào)用時(shí)會(huì)將值賦值給形參,那么實(shí)際上使用的方式就是一種簡(jiǎn)單的值傳遞:將實(shí)參(如果是變量或者常量或者其他表達(dá)式)的結(jié)果(值)取出來(lái)賦值給形參:形參與外部實(shí)際傳入的參數(shù)本身沒(méi)有任何關(guān)聯(lián)關(guān)系:只是結(jié)果一樣。
如果希望在函數(shù)內(nèi)部拿到的外部數(shù)據(jù),能夠在函數(shù)內(nèi)部改變,那么就需要明確告知函數(shù)(定義時(shí)),函數(shù)才會(huì)在調(diào)用的時(shí)候去主動(dòng)獲取外部數(shù)據(jù)的內(nèi)存地址。以上這種定義形式參數(shù)的方式叫作引用傳值。
function 函數(shù)名(形參1,&形參2){ //此時(shí)形參1是值傳遞 形參2是引用傳遞
//函數(shù)體
}
在調(diào)用的時(shí)候,必須給引用傳值的參數(shù)位置傳入實(shí)際參數(shù),而且參數(shù)本身必須是變量。(變量才有指向的數(shù)據(jù)的內(nèi)存地址)
$a = 1;
$b = 1;
function AddMyself($a,&$b)
{
$a++;
$b++;
}
AddMyself($a,$b);
echo $a,'<br/>',$b; // 1 2
引用傳值注意事項(xiàng):在傳入實(shí)參的時(shí)候,必須傳入變量
函數(shù)返回值
返回值:return,指的是將函數(shù)實(shí)現(xiàn)的結(jié)果,通過(guò)return關(guān)鍵字,返回給函數(shù)外部(函數(shù)調(diào)用處):在PHP中所有的函數(shù)都有返回值。(如果沒(méi)有明確return使用,那么系統(tǒng)默認(rèn)返回NULL)
function display()
{
echo "hello world";
}
var_dump(display()); //NULL
函數(shù)的返回值可以是任意數(shù)據(jù)類(lèi)型
return關(guān)鍵字
- return在函數(shù)內(nèi)部存在的價(jià)值:返回當(dāng)前函數(shù)的結(jié)果(當(dāng)前函數(shù)運(yùn)行結(jié)束,后續(xù)return的代碼不會(huì)執(zhí)行)
- return還可以在文件中直接使用(不在函數(shù)里面):代表文件將結(jié)果return后面跟的內(nèi)容,轉(zhuǎn)交給包含當(dāng)前文件的位置。(通常在系統(tǒng)配置文件中使用較多),在文件中也代表中終止文件后面的代碼:return之后的內(nèi)容不會(huì)執(zhí)行
$res = include_once 'func.hpp'; //假設(shè)該文件return 'hello world'
echo $res;//hello world
作用域
作用域:變量(常量)能夠被訪問(wèn)的區(qū)域
1.變量可以在普通代碼中定義
2.變量也可以在函數(shù)內(nèi)部定義
在PHP中作用域嚴(yán)格來(lái)說(shuō)分為兩種:但是PHP內(nèi)部還定義一些在嚴(yán)格意義之外的一種,所以總共算三種:
1.全局變量:就是用戶(hù)普通定義的變量(函數(shù)外部定義)
- 所屬全局空間:在PHP中只允許在全局空間使用:理論上函數(shù)內(nèi)部不可訪問(wèn)
- 腳本周期:直到腳本運(yùn)行結(jié)束(最后一行代碼執(zhí)行完)
$glo = 'global area';
function func()
{
$inner = __FUNCTION__;
echo $glo;//err,函數(shù)內(nèi)部不可訪問(wèn)外部全局變量
}
2.局部變量:就是在函數(shù)內(nèi)部定義的變量
- 所屬當(dāng)前函數(shù)空間:在PHP中只允許在當(dāng)前函數(shù)自己內(nèi)部使用
- 函數(shù)周期:函數(shù)執(zhí)行結(jié)束(函數(shù)是在棧區(qū)中開(kāi)辟獨(dú)立內(nèi)存空間運(yùn)行)
3.超全局變量:系統(tǒng)定義的變量(預(yù)定義變量:$_SERVER、$_POST等)
- 所屬超全局空間:沒(méi)有訪問(wèn)限制(函數(shù)內(nèi)外都可以訪問(wèn))
超全局變量會(huì)將全局變量自動(dòng)納入到$GLOBALS里面,而$GLOBALS沒(méi)有作用域限制,所以能夠幫助局部去訪問(wèn)全局變量:但是必須使用數(shù)組方式
$glo = 'global area';
function func()
{
echo $GLOBALS['glo'];
}
func(); //global area
echo '<hr/>';
echo $glo; //global area
如果想函數(shù)內(nèi)部使用外部變量:除了$GLOBALS之外,通過(guò)參數(shù)傳值(如果要統(tǒng)一戰(zhàn)線(xiàn)還可以使用引用傳值)。
global關(guān)鍵字
在PHP中,其實(shí)還有一種方式,能夠?qū)崿F(xiàn)全局訪問(wèn)局部,同時(shí)局部也可以訪問(wèn)全局:global關(guān)鍵字
global關(guān)鍵字:是一種在函數(shù)里面定義變量的一種方式
1、 如果使用global定義的變量名在外部存在(全局變量),那么系統(tǒng)在函數(shù)內(nèi)部定義的變量直接指向外部全局變量所指向的內(nèi)存空間(同一個(gè)變量);
2、 如果使用global定義的變量名在外部不存在(全局變量),系統(tǒng)會(huì)自動(dòng)在全局空間(外部)定義一個(gè)與局部變量同名的全局變量
本質(zhì)的形式:在函數(shù)的內(nèi)部和外部,對(duì)一個(gè)同名變量(全局和局部)使用同一塊內(nèi)存地址保存數(shù)據(jù),從而實(shí)現(xiàn)共同擁有。
語(yǔ)法規(guī)則
global 變量名;//不能賦值
$變量名 = 值;
例子:
$global = 'global area';
function func()
{
//外部存在同名的global變量
//函數(shù)內(nèi)部定義的變量直接指向外部全局變量所指向的內(nèi)存空間
global $global;
echo $global;
//定義全局不存在變量
global $local;
$local = 'inner func';
}
func(); //global area
echo '<hr/>';
echo $local;//訪問(wèn)"局部"變量 inner func
以上方式可以實(shí)現(xiàn)局部與全局的互訪,但是通常不會(huì)這么用。一般如果會(huì)存在特殊使用,也會(huì)使用參數(shù)的形式來(lái)訪問(wèn)。(還可以使用常量:define定義的常量)
define('PI', 3.14);
function func()
{
echo PI;
}
func(); //3.14
echo PI;//3.14
靜態(tài)變量
靜態(tài)變量:static,是在函數(shù)內(nèi)部定義的變量,使用static關(guān)鍵字修飾,用來(lái)實(shí)現(xiàn)跨函數(shù)共享數(shù)據(jù)的變量:函數(shù)運(yùn)行結(jié)束所有局部變量都會(huì)清空,如果重新運(yùn)行一下函數(shù),所有的局部變量又會(huì)重新初始化,而靜態(tài)變量不會(huì)
語(yǔ)法
function 函數(shù)名(){
//定義變量
static $變量名 = 值; //通常會(huì)在定義的時(shí)候就直接賦值
}
例子
function func()
{
$local = 0;
static $count = 0;
$count++;
$local++;
echo $local," ",$count;
}
func(); echo '<hr/>';//1 1
func(); echo '<hr/>';//1 2
func(); echo '<hr/>';//1 3
靜態(tài)變量的作用是為了跨函數(shù)共享數(shù)據(jù)(同一個(gè)函數(shù)被多次調(diào)用)
使用
1、 為了統(tǒng)計(jì):當(dāng)前函數(shù)被調(diào)用的次數(shù)
2、 為了統(tǒng)籌函數(shù)多次調(diào)用得到的不同結(jié)果(遞歸思想)
可變函數(shù)
可變函數(shù):當(dāng)前有一個(gè)變量所保存到值,剛好是一個(gè)函數(shù)的名字,那么就可以使用$變量()
來(lái)充當(dāng)函數(shù)名使用
- 該變量相當(dāng)于是C語(yǔ)言當(dāng)中的函數(shù)指針
語(yǔ)法
$變量名 = '函數(shù)名'
function 函數(shù)名(函數(shù)參數(shù)){
//...
}
$變量名(函數(shù)參數(shù))
使用例子
$func = 'display';
function display()
{
echo "hell I am function display()" ;
}
$func();//hell I am function display()
可變函數(shù)在系統(tǒng)使用的過(guò)程中還是比較多的,尤其是使用很多系統(tǒng)函數(shù)的時(shí)候:需要用戶(hù)在外部定義一個(gè)自定義函數(shù),但是是需要傳入到系統(tǒng)函數(shù)內(nèi)部使用 (回調(diào)函數(shù))
//假設(shè)是系統(tǒng)函數(shù) -求第二個(gè)參數(shù)的4次方
function sys_func($arg1,$arg2)
{
return $arg1($arg2);//user_func($agr2)
}
function user_func($num)
{
return pow($num,4);
}
echo sys_func('user_func',10);//求10^4 ==> 10000
匿名函數(shù)
匿名函數(shù)==>沒(méi)有名字的函數(shù)
基本語(yǔ)法
變量名 = function(函數(shù)參數(shù)){
//函數(shù)體
}
使用一個(gè)變量保存匿名函數(shù),本質(zhì)該變量是一個(gè)對(duì)象(Closure)
使用例子
$func = function(){
echo "hello world";
};
$func();//hello world
var_dump($func);//object(Closure)#1 (0) { }
閉包
簡(jiǎn)單來(lái)說(shuō):函數(shù)內(nèi)部有一些局部變量在函數(shù)執(zhí)行之后沒(méi)有被釋放,是因?yàn)樵诤瘮?shù)內(nèi)部還有對(duì)應(yīng)的函數(shù)在引用(函數(shù)的內(nèi)部函數(shù):匿名函數(shù))
證明:函數(shù)內(nèi)部的局部變量在函數(shù)使用完之后沒(méi)有被釋放
1、 使用內(nèi)部匿名函數(shù);
2、 匿名函數(shù)使用外部局部變量:use;
3、 匿名函數(shù)被返回給外部使用
function func()
{
$name = "HELLO WORLD";
//定義匿名函數(shù)
//use就是將外部局部變量保留給內(nèi)部使用
$innerFunction = function() use($name)
{
echo $name;
}; //注意分號(hào)!
return $innerFunction;//返回內(nèi)部匿名函數(shù)
}
$get = func(); //$get = $innerFunction
$get();//HELLO WORLD
常用系統(tǒng)函數(shù)
輸出函數(shù)
print()
:類(lèi)似于echo輸出提供的內(nèi)容,本質(zhì)是一種結(jié)構(gòu)(不是函數(shù)),但是有返回值,始終返回1,可以不需要使用括號(hào)
print_r()
:類(lèi)似于var_dump,但是比var_dump簡(jiǎn)單,不會(huì)輸出數(shù)據(jù)的類(lèi)型,只會(huì)輸出值(數(shù)組打印使用比較多)
時(shí)間函數(shù)
date():按照指定格式對(duì)對(duì)應(yīng)的時(shí)間戳(從1970年格林威治時(shí)間開(kāi)始計(jì)算的秒數(shù)),如果沒(méi)有指定特定的時(shí)間戳,那么就是默認(rèn)解釋當(dāng)前時(shí)間戳
time():獲取當(dāng)前時(shí)間對(duì)應(yīng)的時(shí)間戳
microtime():獲取微秒級(jí)別的時(shí)間
strtotime():按照規(guī)定格式的字符串轉(zhuǎn)換成時(shí)間戳
echo time(),'<br/>';
echo microtime(),'<br/>';
echo strtotime('tomorrow 10 hours');
數(shù)學(xué)函數(shù)
max():指定參數(shù)中最大的值
min():比較兩個(gè)數(shù)中較小的值
rand():得到一個(gè)隨機(jī)數(shù),指定區(qū)間的隨機(jī)整數(shù)
mt_rand():與rand一樣,只是底層結(jié)構(gòu)不一樣,效率比rand高(建議使用)
round():四舍五入
ceil():向上取整
floor():向下取整
pow():求指定數(shù)字的指定指數(shù)次結(jié)果:pow(2,8) == 2^8 == 256
abs():絕對(duì)值
sqrt():求平方根
與函數(shù)相關(guān)函數(shù)
function_exists():判斷指定的函數(shù)名字是否在內(nèi)存中存在(幫助用戶(hù)不去使用一個(gè)不存在的函數(shù),讓代碼安全性更高)
func_get_arg():在自定義函數(shù)中去獲取指定數(shù)值對(duì)應(yīng)的參數(shù)
func_get_args():在自定義函數(shù)中獲取所有的參數(shù)(以數(shù)組形式返回)
func_num_args():獲取當(dāng)前自定義函數(shù)的參數(shù)數(shù)量(個(gè)數(shù))
function testFunc($a,$b)
{
//獲取指定參數(shù) --獲取第一個(gè)參數(shù)
var_dump(func_get_arg(1));
//獲取所有參數(shù)
var_dump(func_get_args());
//獲取參數(shù)數(shù)量
var_dump(func_num_args());
}
echo '<pre>';
//短路運(yùn)算,該函數(shù)存在才調(diào)用
function_exists('testFunc') && testFunc(1,'2',3.14);
輸出:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-672172.html
string(1) "2"
array(3) {
[0]=>
int(1)
[1]=>
string(1) "2"
[2]=>
float(3.14)
}
int(3)
注意:參數(shù)的標(biāo)識(shí)是從0開(kāi)始的,func_get_args和func_num_args都是統(tǒng)計(jì)的對(duì)應(yīng)實(shí)參的數(shù)量文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-672172.html
到了這里,關(guān)于【PHP】函數(shù)-作用域&可變函數(shù)&匿名函數(shù)&閉包&常用系統(tǒng)函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!