摘要:提供了一些函數(shù)處理操作的內(nèi)置函數(shù),主要有開發(fā)環(huán)境是調(diào)用回調(diào)函數(shù),并把一個數(shù)組作為參數(shù)傳進去作為回調(diào)函數(shù)的參數(shù)也是調(diào)用回調(diào)函數(shù),區(qū)別是并沒有要求把數(shù)組作為參數(shù)傳進回調(diào)函數(shù)做參數(shù)。
說明:Laravel中經(jīng)常使用PHP的Function Handling來設計代碼,本文主要學習PHP的Function Handling特性,來提高寫代碼時的設計質(zhì)量。PHP提供了一些函數(shù)處理操作的內(nèi)置函數(shù),主要有:
call_user_func_array( )
call_user_func( )
func_get_arg( )
func_get_args( )
func_num_args( )
function_exists( )
開發(fā)環(huán)境:Laravel5.3 + PHP7
Function Handling call_user_func_array()/call_user_func()call_user_func_array()是調(diào)用回調(diào)函數(shù),并把一個數(shù)組作為參數(shù)傳進去作為回調(diào)函數(shù)的參數(shù);call_user_func()也是調(diào)用回調(diào)函數(shù),區(qū)別是并沒有要求把數(shù)組作為參數(shù)傳進回調(diào)函數(shù)做參數(shù)。在Laravel中大量使用這兩個內(nèi)置函數(shù)來設計代碼,比如IlluminateFoundationApplication::fireAppCallbacks()的源碼:
/** * Call the booting callbacks for the application. * * @param array $callbacks * @return void */ protected function fireAppCallbacks(array $callbacks) { foreach ($callbacks as $callback) { call_user_func($callback, $this); //執(zhí)行回調(diào)函數(shù),并把Application對象作為參數(shù)傳進去 } }
call_user_func()和call_user_func_array()可以說是PHP設計好代碼的神器,不得不熟悉,這里給下它的PHPUnit測試看看如何使用,爆綠燈:
assertSame("This is a service provider.", $actual); } public function testCallUserFuncArray() { // Arrange $provider = new Provider(); $app = new Application($provider); // Actual $actual = call_user_func_array("MyRightCapitalContainerTestscallUserFunc", [$app]); // Assert $this->assertSame("This is a service provider.", $actual); } } function callUserFunc($app) { return $app->register(); } class Application { private $provider; public function __construct($provider) { $this->provider = $provider; } public function register() { return $this->provider->register(); } } class Provider { public function register() { return "This is a service provider."; } }
call_user_func_array()和call_user_func()真是個非常用的函數(shù),值得在設計自己的代碼里使用。
func_get_arg()/func_get_args()/func_num_args()func_get_arg()是從函數(shù)的參數(shù)列表讀取某個指定的參數(shù),func_get_args()是讀取函數(shù)的整個參數(shù)列表作為數(shù)組返回,func_num_args()是讀取函數(shù)的參數(shù)的個數(shù)。Laravel中的IlluminateFoundationApplication::environment()使用了這三個函數(shù)來設計代碼,很巧妙:
/** * Get or check the current application environment. * * @return string|bool */ public function environment() { // 如果傳入了參數(shù) if (func_num_args() > 0) { // 如果第一個參數(shù)是數(shù)組形式就把該數(shù)組賦值給$patterns;如果不是就把所有參數(shù)作為一個數(shù)組賦值給$patterns $patterns = is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args(); foreach ($patterns as $pattern) { if (Str::is($pattern, $this["env"])) { return true; } } return false; } return $this["env"]; }
看environment()源碼可知道environment()是可以傳入?yún)?shù)的,如果不傳入?yún)?shù)就返回$this["env"]的值即Laravel中的環(huán)境變量APP_ENV值,如App::environment()即為讀取Laravel當前運行環(huán)境變量值;如果傳入?yún)?shù)則判斷該值是否與環(huán)境變量值相等,如App::environment("production","staging", "development")即判斷當前Laravel運行環(huán)境是否是"production","staging", "development"中的一種。很巧妙的設計。
這里寫個PHPUnit測試下,爆綠燈:
class FunctionHandling extends PHPUnit_Framework_TestCase { public function testFuncArgs() { // Arrange $provider = new Provider(); $app = new Application($provider); // Actual $arg_number0 = $app->testFuncArg(); $arg_number1 = $app->testFuncArg("Laravel"); $arg_number2 = $app->testFuncArg(["Laravel", "PHP"]); // Assert $this->assertSame(0, $arg_number0); $this->assertSame(1, $arg_number1); $this->assertSame(2, $arg_number2); } } class Application { private $provider; public function __construct($provider) { $this->provider = $provider; } public function register() { return $this->provider->register(); } public function testFuncArg() { if (func_num_args() > 0) { $patterns = is_array(func_get_arg(0)) ? func_get_arg(0) :func_get_args(); return count($patterns); } return 0; } }function_exists()
function_exists()判斷指定函數(shù)是否已經(jīng)定義,這個函數(shù)在Laravel中大量使用,尤其是造輔助函數(shù)時使用,參考Illuminate/Foundation/helpers.php,
Illuminate/Support/helpers.php。這里做個PHPUnit測試,爆綠燈:
class FunctionHandling extends PHPUnit_Framework_TestCase { public function testFunctionExists() { // Arrange $expected = "Container"; // Actual $actual = functionExists("Container"); // Assert $this->assertSame($expected, $actual); } } if (!function_exists("functionExists")) { function functionExists($container) { return $container; } }
總結(jié):本文主要學習了PHP的Function Handling,這個技術(shù)可以用來提高自己的代碼設計能力,同時Laravel中也大量使用了這個技術(shù)來巧妙設計代碼。下次遇到好的技術(shù)在分享,到時見。
歡迎關(guān)注Laravel-China。
RightCapital招聘Laravel DevOps
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/30473.html
摘要:學習筆記之已經(jīng)聊過使用了來設計,看源碼發(fā)現(xiàn)其巧妙用了和的一些數(shù)組函數(shù)來設計。開發(fā)環(huán)境內(nèi)置函數(shù)和看源碼之前,先看下這幾個內(nèi)置函數(shù)的使用。學習筆記之實例化源碼解析已經(jīng)聊過的實例化,得到中的變量,即的實例化對象。后面再學習下的源碼,到時見。 說明:本文主要學習Laravel的Middleware的源碼設計思想,并將學習心得分享出來,希望對別人有所幫助。Laravel學習筆記之Decorato...
摘要:總結(jié)本文主要學習了啟動時做的七步準備工作環(huán)境檢測配置加載日志配置異常處理注冊注冊啟動。 說明:Laravel在把Request通過管道Pipeline送入中間件Middleware和路由Router之前,還做了程序的啟動Bootstrap工作,本文主要學習相關(guān)源碼,看看Laravel啟動程序做了哪些具體工作,并將個人的研究心得分享出來,希望對別人有所幫助。Laravel在入口index...
說明:本篇主要學習數(shù)據(jù)庫連接階段和編譯SQL語句部分相關(guān)源碼。實際上,上篇已經(jīng)聊到Query Builder通過連接工廠類ConnectionFactory構(gòu)造出了MySqlConnection實例(假設驅(qū)動driver是mysql),在該MySqlConnection中主要有三件利器:IlluminateDatabaseMysqlConnector;IlluminateDatabaseQuery...
摘要:說明本文主要學習的回調(diào)類型通常在使用函數(shù)進行回調(diào)時,如使用進行回調(diào)時,需要傳入回調(diào),實際上有幾種的,在中也大量使用回調(diào),并根據(jù)場景不同傳入不同的回調(diào)類型。開發(fā)環(huán)境是把函數(shù)名作為類型傳進去作為回調(diào)類型,形式如。 說明:本文主要學習PHP的回調(diào)類型callback type,通常在使用函數(shù)進行回調(diào)時,如使用call_user_func($callback, $parameters)進行回調(diào)...
摘要:,看下源碼返回很容易知道返回值是,然后將該值存儲在變量中,這時。看下的源碼去除掉字符后為返回從源碼中可知道返回值為,這時。 說明:本文主要學習下Query Builder編譯Fluent Api為SQL的細節(jié)和執(zhí)行SQL的過程。實際上,上一篇聊到了IlluminateDatabaseQueryBuilder這個非常重要的類,這個類含有三個主要的武器:MySqlConnection, M...
閱讀 3192·2023-04-26 01:39
閱讀 3345·2023-04-25 18:09
閱讀 1612·2021-10-08 10:05
閱讀 3228·2021-09-22 15:45
閱讀 2758·2019-08-30 15:55
閱讀 2393·2019-08-30 15:54
閱讀 3167·2019-08-30 15:53
閱讀 1324·2019-08-29 12:32