最近在開(kāi)發(fā)一個(gè)Discuz!插件,今天遇到一個(gè)問(wèn)題,我在后臺(tái)的一個(gè)函數(shù)中調(diào)用插件的變量數(shù)據(jù)時(shí)返回空值,測(cè)試幾次無(wú)果后突然想起應(yīng)該是沒(méi)有加載緩存導(dǎo)致的,于是加入了loadcache('plugin')加載插件緩存,可是問(wèn)題依舊。
分析一下問(wèn)題,需要調(diào)用到到數(shù)據(jù)的是一個(gè)函數(shù)(暫且稱(chēng)為函數(shù)A),已經(jīng)執(zhí)行了global $_G;以調(diào)用全局變量,而且通過(guò)print_r輸出$_G也證實(shí)$_G中是有數(shù)據(jù)的,缺失的是插件緩存。而函數(shù)A在前臺(tái)也要調(diào)用,因?yàn)榍芭_(tái)套了plugin.php的外殼,已經(jīng)加載插件緩存,不需要執(zhí)行l(wèi)oadcache('plugin'),因此在函數(shù)中執(zhí)行l(wèi)oadcache('plugin')操作對(duì)執(zhí)行效率有影響。
再次分析問(wèn)題,后臺(tái)調(diào)用函數(shù)A的代碼則在另一個(gè)函數(shù)中(暫且稱(chēng)為函數(shù)B),突然在想,會(huì)不會(huì)要在這個(gè)函數(shù)里執(zhí)行一次global $_G;好讓后臺(tái)加載的變量?jī)?nèi)容由函數(shù)B傳遞給函數(shù)A?
抱著試一試的態(tài)度,我在函數(shù)B中也添加了global $_G;,結(jié)果成功了!
這引申出了一個(gè)global作用域的作用范圍的問(wèn)題。在我這次調(diào)試中,函數(shù)A因?yàn)橛珊瘮?shù)B調(diào)用,因此后臺(tái)中調(diào)用的loadcache('plugin');所生成的新$_G只在后臺(tái)部分有效,而函數(shù)B中由于沒(méi)有使用global $_G,因此并未獲取到最新的$_G。而函數(shù)A的文件引用(require)我寫(xiě)在了函數(shù)B中,函數(shù)A成了函數(shù)B的一個(gè)子集,后臺(tái)代碼中運(yùn)行過(guò)loadcache的全局變量對(duì)函數(shù)A無(wú)效,函數(shù)A中的global取得的$_G值繞開(kāi)了我所寫(xiě)的loadcache。因此需要在函數(shù)B中運(yùn)行一次global獲得最新的$_G值才能在函數(shù)A中生效。
下面是一個(gè)使用“global”關(guān)鍵字的演示例子:
正如你在上面的例子中看到的一樣,“global”關(guān)鍵字是用來(lái)導(dǎo)入全局變量的,看起來(lái)它工作的很好,而且很簡(jiǎn)單,那么為什么我們還要擔(dān)心使用“global”關(guān)鍵字來(lái)定義全局?jǐn)?shù)據(jù)呢?
我來(lái)給處入行的人講解一下全局變量global的使用,”全局變量“,這個(gè)名詞中的全局兩個(gè)字已經(jīng)告訴我們這個(gè)變量在各個(gè)地方都能用,先看一個(gè)實(shí)例:
結(jié)果: 3
如果沒(méi)有全局變量global在方法內(nèi)是不能獲得$a,$b值的,所以在方法里面想用外面的變量就需要先聲明這個(gè)變量為全局變量,這樣就可以使用了,很方便吧,代碼如下:
以上腳本的輸出將是“3”,在函數(shù)中申明了全局變量 $w3sky 和 $w3sky2,任何變量的所有引用變量都會(huì)指向到全局變量.