眾所周知,當(dāng)我們傳少了參數(shù)到 PHP 函數(shù)的時候,會報 PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function xxx()
的錯誤,比如:
<?php
function hello($name)
{
echo "Hello, {$name}" . PHP_EOL;
}
hello();
// Fatal error: Uncaught ArgumentCountError: Too few arguments to function hello(), 0 passed in D:\tmp\hello.php on line 7 and exactly 1 expected in D:\tmp\hello.php:2
那如果我們將函數(shù)改寫成下面這樣呢?
<?php
function hello()
{
echo "Hello" . PHP_EOL;
}
hello("world");
// Hello
居然不會拋出 Too many arguments to function hello()
的錯誤!難道是 world
這個字符串被扔掉了而沒有傳進去?
將上面的函數(shù)再改一下:
<?php
function hello()
{
foreach (func_get_args() as $arg)
{
echo $arg . PHP_EOL;
}
}
hello("world");
hello("foo", "bar", "baz");
// world
// foo
// bar
// baz
全都已經(jīng)傳進去了呀!帶著好奇心搜了一下,發(fā)現(xiàn) StackOverflow 上已經(jīng)有人問過這個問題了:
https://stackoverflow.com/que...
但是高票回答只是簡簡單單的一句話:
PHP doesn't throw an error on function overload.
然后還從評論區(qū)里翻到了這么一個 bug report:https://bugs.php.net/bug.php?...
官方給出的是 Wont fix
,(not a bug but a feature???)
除了上面兩個鏈接之外,還找到了這個:
http://www.php-internals.com/...
但是看不太懂...
目前我能找到的資料就這些,很好奇但是又不是很清楚是怎么回事,先問幾個問題:
- PHP 的函數(shù)參數(shù)最后是不是有個隱式的
可變長參數(shù)
?- PHP 的函數(shù)傳參是怎么實現(xiàn)的?
- 像代碼段 1,是不是其實正常傳參的時候函數(shù)內(nèi)部已經(jīng)隱式使用
func_get_args()
幫我們把第一個參數(shù)值裝到$name
里面去了?
然后再問一個問題:
像我這種沒多少底層經(jīng)驗的新手,如果想閱讀 PHP 的源碼,該如何讀起?把 php-internals
啃一遍會有幫助嗎?
首先我來說明一下,關(guān)于not a bug but a feature
的意思是不是bug,是PHP的新特性,PHP4,PHP5,PHP7都支持,具體可以看這篇文檔 http://www.php.net/manual/zh/...。
對于一個函數(shù)定義,假設(shè)如下:
function test() {
func_get_args();
}
test(1,2,3,4);
在函數(shù)內(nèi)部通過func_get_args()
函數(shù)就可以取得傳入的參數(shù)。也就是說,這本身就是PHP語法規(guī)則的一部分,假設(shè)調(diào)用PHP的函數(shù)或方法的時候傳遞的參數(shù)個數(shù)為N
,定義方法或函數(shù)的時候的參數(shù)個數(shù)為X
,則有 N >= X;另外,如果在定義方法或函數(shù)的時候?qū)?shù)設(shè)置了默認值,則這個參數(shù)可以不傳。
既然說到這種是PHP本身語法規(guī)則的一部分,我這里告訴你一個PHP本身的函數(shù)就是通過這個原理實現(xiàn)的,那就是compact
函數(shù)。
舉個例子
$a = 'test a';
$b = 'test b';
$c = 'test c';
$d = compact('a','b','c');
此時的$d
為:
$d = [
'a' => 'test a',
'b' => 'test b',
'c' => 'test c'
];
在這種情況下就可以傳無限個參數(shù),然后如果根據(jù)這個參數(shù)判斷存在以這個參數(shù)命名的變量,則把這個變量的值為數(shù)組的value,以參數(shù)名為數(shù)組的key進行打包,然后返回一個數(shù)組。
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團,成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達內(nèi)教育集團成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負責(zé)iOS教學(xué)及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。