版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
PHP的問題全面闡述PHP網(wǎng)站設(shè)計(jì)的問題前言我的脾氣古怪。我會(huì)抱怨很多東西。這個(gè)星球上大多數(shù)技術(shù)我都不喜歡。PHP不僅使用起來尷尬,還有要嘛我想要的不適合,要嘛不是最令人滿意,要嘛違背我的信仰。我可以告訴你關(guān)于一門語(yǔ)言,所有我想避免的好方式,所有我喜歡的壞方式。來吧,問吧!談話會(huì)很有趣!php是唯一的例外。幾乎php抽象的所有東西都是支離破碎的。包括語(yǔ)言,框架,整個(gè)生態(tài)系統(tǒng)都一塌糊涂。我?guī)缀醪荒軉为?dú)列出咒罵的事情,因?yàn)樗矶級(jí)牧?。每次我打算編輯一堆雜亂如麻的php抱怨清單的時(shí)候,我都被一些瑣事打亂,越深入就越會(huì)發(fā)現(xiàn)其它令人震驚的事情。php讓人難堪。它是如此的破碎,但那些被培訓(xùn)的業(yè)余愛好者,卻對(duì)它稱贊不已。php在做一些徽不足道的挽回措施,但我選擇忘記它。不過我得讓我的系統(tǒng)擺脫這些東西,也就這樣了,這是最后一次嘗試。打個(gè)比喻我只是隨口和Mel抱怨下,而她卻堅(jiān)決讓我發(fā)表出來。我甚至說不出來PHP到底怎么了,因?yàn)椤€好。想想你有一個(gè),嗯,工具箱吧。一堆工具??雌饋磉€好,有標(biāo)準(zhǔn)的東西。你拔除螺絲釘,它怪異的有三個(gè)頭。OK,好吧,這對(duì)你不太有用,但你猜遲早有天會(huì)有用。你拿出榔頭,被震住了,兩邊都有是尖爪。但它仍然能用,我的意思是,你可以用兩頭的中部斜著敲。你拿出老虎鉗,但它們沒有鋸齒面。表面平而光滑。這沒多大用,但依然能用,沒什么。你可以繼續(xù)。工具箱的東西都是怪異和琢磨不定的,但又不能說毫無價(jià)值。整體看沒什么大問題;它的工具都齊全?,F(xiàn)在,想象有很多使用這些工具的木匠,它們和你說:”這些工具有什么問題呢?我們都用過,它們工作都很好??!”。工匠們給你展示他們建的房子,每個(gè)門都是五邊形的而屋頂是癲倒的。你敲前門,它向內(nèi)倒榻了,而他們卻抱怨你打破了他們的門。這就是PHP的問題。立場(chǎng)我認(rèn)為下面的特質(zhì)對(duì)于一門語(yǔ)言的生產(chǎn)力和可用性是重要的,而PHP在大范圍破壞它們。如果你不同意這些,好吧,我無法想像,我們永遠(yuǎn)不會(huì)達(dá)成一致。一門語(yǔ)言必須是可預(yù)見的。它是將人類的思想反映給計(jì)算機(jī)執(zhí)行的媒介,因此它的關(guān)鍵是,人類對(duì)程序的理解實(shí)際要正確。語(yǔ)言必須一致。相似的東西就要看起來相似,不同的就是不同。學(xué)習(xí)了語(yǔ)言的部分知識(shí),就應(yīng)能很容易理解剩下的部分。語(yǔ)言必須簡(jiǎn)潔。新語(yǔ)言應(yīng)該減少繼承舊語(yǔ)言的不好的形式。(我們也可以寫機(jī)器碼。)新語(yǔ)言當(dāng)然應(yīng)努力避免織入新的特有的形式。語(yǔ)言必須是可靠的。語(yǔ)言是解決問題的工具;應(yīng)盡量避免引入新問題。任何”陷阱”都會(huì)大量的分散注意力。語(yǔ)言必須是可調(diào)試的。當(dāng)出錯(cuò)的時(shí)候,程序員必須修正它,我們需要獲得我們想要的幫助。我的立場(chǎng)是:PHP到處處充滿驚奇:mysql_real_escape_string,E_ACTUALLY_ALLPHP不一致:strpos,str_rot13PHP需要特別形式:error-checkingaroundCAPIcalls,===PHP古怪:==。for($fooas&$bar)PHP晦澀:默認(rèn)無棧跟蹤或fatals,復(fù)雜的錯(cuò)誤報(bào)告我不能就單個(gè)問題解釋為什么它歸為這些類,否則將會(huì)沒完沒了。我相信讀者自己會(huì)思考。不要再和我扯這些東西了我知道很多有利的論點(diǎn)。我也聽到很多反駁的論點(diǎn)。這些都只能讓談話立即停止。不要再跟我扯這些東西了,求你了。不要和我說”好的開發(fā)者能用任何語(yǔ)言寫出好的代碼”,或者壞開發(fā)者。.吧啦吧啦。這毫無意義。好的工匠可以用石頭或錘子駕馭釘子,但你見過有多少工匠用石頭的?成為一個(gè)好開發(fā)者的標(biāo)準(zhǔn)之一就是善于選擇工具。不要和我說熟記上千個(gè)例外和古怪行為是開發(fā)者的職責(zé)。是的,這在任何系統(tǒng)中都是必要的,因?yàn)殡娔X是傻的。這不意味著,系統(tǒng)能瘋狂的接受而沒有上限。PHP有的只是異常,這是不行的,一旦和語(yǔ)言摔角決斗,你實(shí)際編寫程序就要花費(fèi)更多的努力。我的工具不能為我創(chuàng)建應(yīng)用產(chǎn)生積極作用。不要和我說“那就是CAPI的工作方式”。這星球上高級(jí)語(yǔ)言存在的目的是什么,它們能提供的一切僅僅是一些字符串助手函數(shù)和一堆C的包裝器?如果是這樣,那就用C!這里,甚至還有為它準(zhǔn)備的CGI庫(kù)。不要和我扯“搞出奇怪的事,是你活該”。如果存在兩個(gè)特性,總有一天,某些人會(huì)找到一起使用它們的理由。再次強(qiáng)調(diào),這不是C;這里沒有規(guī)范,這里不需要“未定義行為”。不要再和我扯Facebook和Wikipedia就用的PHP.我早知道了!它們也能用Brainfuck寫,但只要他們足夠陪明,不斷折騰這些事情,他們總能克服平臺(tái)的問題。眾所周知,如果使用其它語(yǔ)言編寫,開發(fā)時(shí)間可能會(huì)減少一半或加倍;單獨(dú)拿出這些數(shù)據(jù)毫無意義。上帝保佑,不要再和我扯任何東西了!如果列出的沒有傷害你的PHP的觀點(diǎn),無所謂,因此請(qǐng)停止在網(wǎng)上做無意義的爭(zhēng)論,繼續(xù)開發(fā)高帥富酷的站點(diǎn)來證明我是錯(cuò)的。偷偷告訴你:我非常喜歡Python.我也很樂意對(duì)它說些你不愛聽的話,如果你真想的話。我并不要求它完美;我只是想揚(yáng)長(zhǎng)避短,總結(jié)我想要的最佳東西。PHP語(yǔ)言核心CPAN被稱為“Perl的標(biāo)準(zhǔn)庫(kù)”。這并沒有對(duì)Perl的標(biāo)準(zhǔn)庫(kù)做過多說明,但它蘊(yùn)含了健壯的核心可以構(gòu)建強(qiáng)大的東西的思想?;驹瓌tPHP最初很明確的是為非程序員設(shè)計(jì)的(言外之意,非專業(yè)程序);根源已經(jīng)很難脫離。從PHP2.0文檔中挑選出來的對(duì)話:一旦你開始為每個(gè)類型區(qū)分不同的操作符,你就開始使用語(yǔ)言變得復(fù)雜了。例如,你不能為strings使用‘==’,你現(xiàn)在必須用‘eq’。我沒看出這點(diǎn)來,特別是那些類似PHP的腳本語(yǔ)言,它們大多數(shù)相當(dāng)簡(jiǎn)單而多數(shù)情況下,作為非程序員,只想要一門包含少量基本邏輯語(yǔ)法的語(yǔ)言,而不想付出過多學(xué)習(xí)曲線。PHP為保持前進(jìn)不惜代價(jià)。什么都有比沒有好。這不是個(gè)正確的設(shè)計(jì)原則。早期的PHP受Perl影響;大量的標(biāo)準(zhǔn)庫(kù)參考C使用“out”參數(shù);OO部分的設(shè)計(jì)像C++和Java.PHP從其它語(yǔ)言中引入大量的靈感,但對(duì)那些熟知其它語(yǔ)言的人,仍然難以理解。(int)看起來像C,但是int并不存在。命名空間使用\。新的數(shù)組語(yǔ)法使用[key=>value],不同于任何其它語(yǔ)言定義hash字面量的形式。弱類型(例如,默默的自動(dòng)在strings/mumbers/等間轉(zhuǎn)換)是如此的復(fù)雜。少量的新特性以新語(yǔ)法實(shí)現(xiàn);大多數(shù)工作通過函數(shù)或者看起來像函數(shù)的東西完成。除了類的支持,這理所當(dāng)然的需要新的操作符和關(guān)鍵字。本頁(yè)列出的問題都有官方解決方案—如果你想資助Zend修復(fù)它們的開源編程語(yǔ)言的話。路漫漫,其修遠(yuǎn)。思考下面的代碼,從PHP文檔的某地方挑出來的。@fopen('/not-existing-file','r');它將做什么?如果PHP使用–disable-url-fopen-wrapper編譯,它將不工作。(文檔沒有說,“不工作”是什么意思;返回null,拋出異常?)注意這點(diǎn)已在PHP5.2.5中移除。如果allow_url_fopen在php.ini中禁用,也將不工作。(為什么?無從得知。)由于@,non-existentfile的警告將不打印。但如果在php.ini中設(shè)置了scream.enabled,它又將打印?;蛘呷绻胕ni_set手動(dòng)設(shè)置scream.enabled.但,如果error_reporting級(jí)別沒設(shè)置,又不同。如果打印出來了,精確去向依賴于display_errors,再一次還是在php.ini.或者ini_set中。我無法告訴你這個(gè)函數(shù)調(diào)用的行為,如果沒有查看編譯時(shí)標(biāo)志,服務(wù)器端配置,和我的程序中的配置的話。這些都是內(nèi)建行為。該語(yǔ)言充滿了全局和隱似狀態(tài)。mbstring使用全局字符編碼。func_get_arg之類的看起來像正常的函數(shù),但是只對(duì)當(dāng)前正在執(zhí)行的函數(shù)操作。Error/exception處理默認(rèn)是全局的。register_tick_function設(shè)置了一個(gè)全局函數(shù)去運(yùn)行每個(gè)tick(鉤子?)—-什么?!沒有任何線程支持。(不奇怪,因?yàn)樯厦嬉呀o出。)加之缺乏內(nèi)建的fork(下面提到),使得并行編程極其困難。PHP的某些部分在實(shí)踐中會(huì)產(chǎn)生錯(cuò)誤代碼。json_decode對(duì)不正確的輸入返回null,盡管null也是一個(gè)JSON解碼的合法對(duì)象—該函數(shù)極不可靠,除非你每次使用后都調(diào)用json_last_error.如果在位置0處找到,array_search,strpos,和其它類似的函數(shù)返回0,但如果都沒有找到的話。會(huì)返回false讓我們稍稍展開最后一部分。在C中,函數(shù)如strpos返回-1,如果未找到。如果你沒檢查這種情況,卻試著以下標(biāo)使用它,那將可能命中垃圾內(nèi)存,程序會(huì)崩潰。(也許吧,這是C.誰(shuí)泥馬知道。我確定至少有工具處理它)話說,Python中,等效的.index方法將拋出一個(gè)異常,如果元素沒找到的話。如果你不檢查該情形,程序?qū)⒈罎?。在PHP中,該函數(shù)返回false.如果你把FALSE作為下標(biāo)使用,或者用它做其他事情,PHP會(huì)默默的將它轉(zhuǎn)成0,但除了用于===比較。程序是不會(huì)崩潰的;它將執(zhí)行錯(cuò)誤的邏輯,且無任何警告,除非你記得在每個(gè)使用strpos和其它類似函數(shù)的地方包含正確的樣版處理代碼。這真是糟透了!編程語(yǔ)言只是工具;它們是為我服務(wù)的。這里,PHP給我布下了陷阱,等著我跳進(jìn)去,而我不得不時(shí)刻警惕這些無聊的字符串操作和相等比較。PHP是個(gè)雷區(qū)。我已經(jīng)聽過很多關(guān)于PHP解析器的故事,它的開發(fā)者來自世界各地。有從事PHP核心開發(fā)工作的人,有調(diào)試PHP核心的人,也有和核心開發(fā)者交流過的人。沒有一個(gè)故事是贊賞的。因此不得不在這里插入一句,因?yàn)樗档弥貜?fù):PHP是個(gè)業(yè)余愛好者的社區(qū)。極少數(shù)人設(shè)計(jì),為它工作,或極少有人知道他們?cè)谧鍪裁?。(哦,親愛的讀者,你當(dāng)然是個(gè)極品例外?。┠切┏砷L(zhǎng)了,想轉(zhuǎn)投其它平臺(tái)的人,使整個(gè)社區(qū)的平均水平下降。這個(gè),就是這里,是PHP的最大問題:絕對(duì)的盲目領(lǐng)導(dǎo)盲目。好了,回來面對(duì)現(xiàn)實(shí)吧。操作符==不中用。"foo"==TRUE,和"foo"==0…但,當(dāng)然TRUE!=0。==會(huì)將兩邊轉(zhuǎn)成數(shù)字,如果可能的話,這意味著它將轉(zhuǎn)成floats如果可能。所以大的16進(jìn)制字符串(如,passwordhashes)可能偶然會(huì)比較成true,盡管它們不一樣。就連JavaScript都不會(huì)這樣做。由于某些原因,"6"=="6","4.2"=="4.20",和"133"=="0133"。但注意133!=0133,因?yàn)?133是八進(jìn)制的。===比較值和類型…除了對(duì)象,只有兩邊實(shí)際上是同一對(duì)象才為true!對(duì)于對(duì)象,==比較值(或每個(gè)屬性)和類型,這又是===比較任何非對(duì)象類型的行為。好玩嗎?比較大小也好不到哪去。甚至行為都不一致:NULL<-1,而NULL==0。排序也因此不確定;它依賴于在排序中比較元素的算法的順序。比較操作符嘗試排序數(shù)組,以兩種不同的方式:首先按長(zhǎng)度,然后按元素。如果它們有相同數(shù)量的元素但不同的keys,它們是不可比的。對(duì)象比較比其它比較做得更多…除了那些即不小于也不大于的對(duì)象。為了類型更安全的==比較,我們有===。為了類型更安全的<比較,我們有…什么也沒有。"123"<"0124",通常,不管你怎么做。類型轉(zhuǎn)換也無濟(jì)于事。盡管上面的舉動(dòng)很瘋狂,但卻明確拒絕Perl’s的字符串paris和算術(shù)運(yùn)行符,PHP沒有重載+.+就是通常的+,而。是通常的連接符。[]下標(biāo)操作符也可以拼寫成{}。[]可以用于任何變量,不光是字符串和數(shù)組。它返回null,無錯(cuò)誤警告。[]僅能獲取單個(gè)元素。foo()[0]是個(gè)語(yǔ)法錯(cuò)誤。(已在PHP5.4中修復(fù))不像(從字面上看)任何其它語(yǔ)言都有的類似的操作符,?:是左結(jié)合的。因此:$arg
='T';$vehicle
=((
$arg
=='B')?'bus':(
$arg
=='A')?'airplane':(
$arg
=='T')?'train':(
$arg
=='C')?'car':(
$arg
=='H')?'horse':'feet');echo
$vehicle;打印horse.變量無法聲明變量。當(dāng)?shù)谝淮问褂脮r(shí),不存在的變量會(huì)被創(chuàng)建為null值。全局變量在使用前,需要global聲明。這是根據(jù)上面得出的自然結(jié)果,因此這是個(gè)完美的理由,但,如果沒有顯示的聲明,全局變量甚至無法讀取—PHP將悄悄的創(chuàng)建一個(gè)局部同名變量取代它。我還沒見過其它語(yǔ)言使用類似的方法處理范圍問題。沒有引用。PHP所謂的引用是個(gè)真正的別名;這無疑是一種倒退,不像Perl的引用,也沒有像Python那樣的對(duì)象標(biāo)識(shí)傳遞。沒有明顯的方式檢測(cè)和取消引用?!币谩笔棺兞吭谡Z(yǔ)言中與眾不同。PHP是動(dòng)態(tài)類型的,因此變量通常無類型…除了引用,它修飾函數(shù)定義,變量語(yǔ)法,和賦值。一旦變量被引用(可在任何地方發(fā)生),它就一直是個(gè)引用。沒有明顯的方法探測(cè)和解引用需要的變量值。好吧,我說謊了。有些”SPLtypes”也作用于變量:$x=newSplBool(true);$x="foo";將失敗。這有點(diǎn)像靜態(tài)類型,自己看看。Areferencecanbetakentoakeythatdoesn’texistwithinanundefinedvariable(whichbecomesanarray)。Usinganon-existentarraynormallyissuesanotice,butthisdoesnot.通過函數(shù)定義的常量稱為takingastring;這之前,它們不存在。(這可能實(shí)際上是復(fù)制Perl使用常量的行為。)變量名是大小寫敏感的。函數(shù)和類名不是。使得方法使用駝峰式命名會(huì)很奇怪。結(jié)構(gòu)array()和幾個(gè)類似的結(jié)構(gòu)不是函數(shù)。$func="array";$func();不工作。數(shù)組拆包可以使用list($a,$b)=…操作完成。list()是類函數(shù)語(yǔ)法,就像數(shù)組那樣。我不知道為什么不給一個(gè)真正的專用語(yǔ)法,也不知道為什么名字如些的讓人迷惑。(int)很顯然的被設(shè)計(jì)成類似C,但它不是單獨(dú)的標(biāo)記;在語(yǔ)言中,沒有東西被稱為int.試試看:var_dump(int)不工作,它會(huì)拋出一個(gè)解析錯(cuò)誤,因?yàn)閰?shù)看起來像是強(qiáng)制轉(zhuǎn)操作符。(integer)是(int)的別名。也有(bool)/(boolean)和(float)/(double)/(real)。有個(gè)(array)操作符用來轉(zhuǎn)成數(shù)組和(object)用來轉(zhuǎn)成對(duì)象。這聽起來很貼心,但常常有個(gè)用例:你可以用(array)使得某個(gè)函數(shù)參數(shù),既可以是單個(gè)元素,也可以是列表,相同對(duì)待。但這樣做不可靠,因?yàn)槿绻橙藗鬟f了單個(gè)對(duì)象,把它轉(zhuǎn)換成數(shù)組將實(shí)際上生成了一個(gè)包含對(duì)象屬性的數(shù)組。(轉(zhuǎn)換成對(duì)象執(zhí)行了反轉(zhuǎn)操作。)include()這類的函數(shù)基本上就是C的#include:他們將其它的文件源碼轉(zhuǎn)存到你的文件中。沒有模塊系統(tǒng),甚至對(duì)PHP代碼也一樣。沒有類似嵌套或者局部范圍的函數(shù)或類。它們都是全局的。include某文件,它的變量導(dǎo)入到當(dāng)前函數(shù)范圍中(給了文件訪問你的變量的能力),但是函數(shù)和類存入全局范圍中。追加數(shù)組使用$foo[]=$bar.echo不是函數(shù)。empty($var)是如此極端,對(duì)于任何其它東西不表現(xiàn)為函數(shù),除了變量,e.g.empty($var||$var2),是個(gè)解析錯(cuò)誤。為什么地球上有這種東西,解析器為什么需要了解empty?還有些冗余的語(yǔ)法塊:if(…):…endif;,等等。錯(cuò)誤處理PHP的一個(gè)獨(dú)特操作符是@(實(shí)際上從DOS借用過來的),它隱藏錯(cuò)誤。PHP錯(cuò)誤不提供棧軌跡。你不得不安裝一個(gè)處理器生成它們。(但fatalerrors不行—見下文。)PHP的解析錯(cuò)誤通常只拋出解析的狀態(tài),沒其它東西了,使得調(diào)試很糟糕。PHP的解析器所指的例如。::內(nèi)部作為T_PAAMAYIM_NEKUDOTAYIM,而<<操作符作為T_SL.我說“內(nèi)部的”,但像上面說的,給程序員顯示的::或<<出現(xiàn)在了錯(cuò)誤的位置。大多數(shù)錯(cuò)誤處理打印給服務(wù)器日志打印一行錯(cuò)誤日志,沒人看到而一直進(jìn)行。E_STRICT看起來像那么回事,但它實(shí)際上沒多少保護(hù),沒有文檔顯示它實(shí)際上是做什么的。E_ALL包含了所有的錯(cuò)誤類別—除了E_STRICT.關(guān)于什么允許而什么不允許是古怪而不一致的。我不知道E_STRICT是怎樣適用于這里的,但這些卻是正確的:試圖訪問不存在的對(duì)象屬性,如,$foo->x.(warning)使用變量做為函數(shù)名,或者變量名,或者類名。(silent)試圖使用未定義常量。(notice)試圖訪問非對(duì)象類型的屬性。(notice)試圖使用不存在的變量名。(notice)2<“foo”(隱藏)foreach(2as$foo);(warning)而下面這些不行:試圖訪問不存在的類常量,如$foo::x.(fatalerror)使用字符串常量作為函數(shù)名,或變量名,或類名。(parseerror)試圖調(diào)用一個(gè)示定義函數(shù)。(fatalerror)Leavingoffasemicolononthelaststatementinablockorfile.(parseerror)使用list和其它準(zhǔn)內(nèi)建宏作為方法名。(parseerror)用下標(biāo)訪問函數(shù)的返回值,如:foo()[0]。(parseerror;已在5.4中修復(fù))在列表的其他地方也有幾個(gè)關(guān)于其它怪異解析錯(cuò)誤的好例子__toString方法不能拋出異常。如果你嘗試,PHP將…呃,拋出一個(gè)異常。(實(shí)際上是個(gè)fatalerror,可以被通過的,除了…)PHP錯(cuò)誤和PHP異常是完全不同的物種。它們不能相互作用。PHP錯(cuò)誤(內(nèi)部,稱為trigger_error)不能被try/catch捕獲。同樣,異常不能通過set_error_handler安裝的錯(cuò)誤處理器觸發(fā)錯(cuò)誤。作為替代,有一個(gè)單獨(dú)的set_exception_handler可以處理未捕獲的異常,因?yàn)橛胻ry塊包裝你程序入口在mod_pho模塊中是不可能的。Fatal錯(cuò)誤(例如,newClassDoesntExist())不能被任何東西捕獲。大量的完全無害的操作會(huì)拋出fatal錯(cuò)誤,由于一些有爭(zhēng)議的原因被迫終結(jié)你的程序。關(guān)閉函數(shù)仍然運(yùn)行,但它們無法獲取棧軌跡(它們運(yùn)行在上層),它們很難告知該程序是由一個(gè)錯(cuò)誤還是程序的正常運(yùn)行結(jié)束。沒有finally結(jié)構(gòu),使得包裝代碼(注冊(cè)處理器,運(yùn)行代碼,注銷處理器;monkeypatch,運(yùn)行測(cè)試,unmonkeypatch)很難看,很難寫。盡管OO和異常大量的復(fù)制了Java的模式,這是故意的,因?yàn)閒inally“在PHP上下文中,只得其形不得其神”.Huh?函數(shù)函數(shù)調(diào)用似乎相當(dāng)昂貴。一些內(nèi)建函數(shù)與reference-returning函數(shù)交互,呃,一種奇怪的方式。正如在別處提到的,很多看起來像函數(shù)或者看起來它們應(yīng)該是函數(shù)的東西實(shí)際上是語(yǔ)言的構(gòu)成部分,因此無法像正常函數(shù)一樣的工作。函數(shù)參數(shù)可以具有“類型提示”,基本上只是靜態(tài)類型。你不能要求某個(gè)參數(shù)是int或是string或是對(duì)象或其它“核心”類型,即使每個(gè)內(nèi)建函數(shù)使用這種類型,可能因?yàn)閕nt在PHP中不是個(gè)東西吧。(查看上面關(guān)于(int)的討論)。你也不能使用特殊的被大量?jī)?nèi)建函數(shù)使用的偽類型裝飾:mixed,number,orcallback.因此,下面:functionfoo(string
$s){}foo("helloworld");產(chǎn)生錯(cuò)誤theerror:PHPCatchablefatalerror:Argument1passedtofoo()mustbeaninstanceofstring,stringgiven,calledin…你可能會(huì)注意到“類型提示”實(shí)際上并不存在;在程序中沒有string類。如果你試圖使用ReflectionParameter::getClass()動(dòng)態(tài)測(cè)試類型提示,將會(huì)得到類型不存在,使得實(shí)際上不可能取得該類型名。函數(shù)的返回值不能被推斷將當(dāng)前函數(shù)的參數(shù)傳給另一個(gè)函數(shù)(分派,不罕見)通過call_user_func_array(‘other_function’,func_get_args())完成。但func_get_args在運(yùn)行時(shí)拋出一個(gè)fatal錯(cuò)誤,抱怨它不能作為函數(shù)參數(shù)。為什么為什么這是個(gè)類型錯(cuò)誤?(已在PHP5.3中修復(fù))閉包需要顯示的命名每個(gè)變量為closed-over.為什么解析器不想辦法解決?(Okay,it’sbecauseusingavariableever,atall,createsitunlessexplicitlytoldotherwise.)Closed-over變量,通過和其它函數(shù)參數(shù)相同的語(yǔ)義”傳遞”。這樣的話,數(shù)組和字符串等等,將以傳值方式傳給閉包。除非使用&.因?yàn)殚]包變量會(huì)自動(dòng)傳遞參數(shù),沒有嵌套范圍,閉包不能指向私有方法,不管是否定義在類中。(可能在5.4中修復(fù)?不清楚。)函數(shù)沒有命名參數(shù)。實(shí)際上被devs顯示拒絕,因?yàn)樗皶?huì)導(dǎo)致代碼臭味”。Functionargumentswithdefaultscanappearbeforefunctionargumentswithout,eventhoughthedocumentationpointsoutthatthisisbothweirdanduseless.(Sowhyallowit?)向函數(shù)傳遞額外的參數(shù)會(huì)被忽略(除了內(nèi)建函數(shù),會(huì)拋出異常)。丟失的參數(shù)被假定為null.”可變”函數(shù)需要func_num_args,func_get_arg,和func_get_args.這類事情沒有語(yǔ)法。OOPHP的函數(shù)部分被設(shè)計(jì)成類似C,但面向?qū)ο螅╤oho)被設(shè)計(jì)成類似Java.我不想過分強(qiáng)調(diào)這有多不合諧。我還沒有發(fā)現(xiàn)一個(gè)有大寫字母的全局函數(shù),重要的內(nèi)建類使用駝峰式方法命名,并有g(shù)etFoo的Java風(fēng)格的屬性訪問器。這是門動(dòng)態(tài)語(yǔ)言,對(duì)嗎?Perl,Python,和Ruby都有一些通過代碼訪問”屬性”的概念;PHP僅僅有笨重的__get之類的東西。類型系統(tǒng)圍繞著低層的Java語(yǔ)言設(shè)計(jì),Java和PHP’s處一時(shí)代,Java有意的做了更多限制,照搬Java,我百思不得其解。類不是對(duì)象。元編程不得不通過字符串名指向它們,就像函數(shù)一樣。內(nèi)建的類型不是對(duì)象,(不像Perl)也無法使得看起來像對(duì)象。instanceof是個(gè)操作符,盡管很晚才增加進(jìn)來,而大多數(shù)語(yǔ)言都建有專門的函數(shù)和語(yǔ)法。受Java影響嗎?類不是第一類?(我不知道它們是不是。)但有一個(gè)is_a函數(shù)。它有個(gè)可選參數(shù)指定是否允許對(duì)象實(shí)際是一個(gè)字符串命名的類。get_class是函數(shù);沒有typeof操作符。同樣有is_subclass_of.然而,這對(duì)于內(nèi)建類型無法工作,(再一次,int不是個(gè)東西)。這樣,你需要is_int等等。右值必須是變量或字面量;不能是表達(dá)式。不然會(huì)導(dǎo)致…一個(gè)解析錯(cuò)誤。clone是一個(gè)操作符?!OO的設(shè)計(jì)是一只混合Perl和Java的怪物。對(duì)象屬性通過$obj->foo,但類屬性是$obj::foo.我沒見過任何其它語(yǔ)言這樣做,或者這樣做有什么用。而,實(shí)例方法仍然能通過靜態(tài)的(Class::method)調(diào)用。如果從其它方法中這么調(diào)用,會(huì)在當(dāng)前$this上被看成常規(guī)的方法調(diào)用。我認(rèn)為吧。new,private,public,protected,static,等等。試圖虜獲Java開發(fā)者的芳心?我知道這更多是個(gè)人的品位,但我不知道為什么這些東西在一門動(dòng)態(tài)語(yǔ)言中是必要的—在C++中,它們中的大多數(shù)是有關(guān)匯編和編譯時(shí)的命名決議。子類不能覆蓋private方法。子類覆蓋的公共方法也不可見,單獨(dú)調(diào)用,超類的私有方法。會(huì)有問題,如在測(cè)試mocks對(duì)象時(shí)。方法無法命名為,例如“l(fā)ist”,因?yàn)閘ist()是特殊的語(yǔ)法(不是個(gè)函數(shù)),而解析器會(huì)被搞暈。如此曖昧的原因無從得知,而類工作得就很好。($foo->list()不是語(yǔ)法錯(cuò)誤。)如果當(dāng)解析構(gòu)造函數(shù)參數(shù)時(shí)拋出異常(如,newFoo(bar())而bar()拋出),構(gòu)造函數(shù)不會(huì)被調(diào)用,但析構(gòu)函數(shù)會(huì)。(已在PHP5.3中修復(fù))在__autoload和解析函數(shù)中的異常會(huì)導(dǎo)致fatal錯(cuò)誤。沒有構(gòu)造器或析構(gòu)器。__construct是個(gè)初始化函數(shù),像Python的__init__.無法通過調(diào)用類申請(qǐng)內(nèi)存和創(chuàng)建對(duì)象。沒有默認(rèn)的初始化函數(shù)。調(diào)用parent::__construct()的時(shí)候,如果父類沒定義它自己的__construct方法會(huì)導(dǎo)致fatal錯(cuò)誤。OO帶來了個(gè)迭代器接口,是語(yǔ)言規(guī)范的部分(如…as…),但該接口實(shí)際上沒有內(nèi)建實(shí)現(xiàn)(如數(shù)組)。如果你想要個(gè)數(shù)組迭代器,你必須用ArrayIterator包裝它。沒有內(nèi)建方式能夠讓迭代器將其作為第一類對(duì)像工作。類可以重載它們轉(zhuǎn)化成字符串的方式,但不能重載怎樣轉(zhuǎn)換成數(shù)字或任何其它內(nèi)建類型的方式。字符串,數(shù)字,和數(shù)組都有字符串轉(zhuǎn)換方式;語(yǔ)言很依賴于此。函數(shù)和類都是字符串。然而,如果沒定義__toString,試圖將換內(nèi)建或自定義對(duì)像(甚至于一個(gè)閉包)轉(zhuǎn)換成字符串會(huì)導(dǎo)致錯(cuò)誤,甚至連echo都可能出錯(cuò)。無法重載相等或比較操作。實(shí)例方法中的靜態(tài)變量是全局的;它們的值跨越該類的多個(gè)實(shí)例共享。標(biāo)準(zhǔn)庫(kù)Perl“某些需要匯編”。Python是“batteriesincluded”。PHP是“廚房水槽,它來自加拿大,但所有的水龍頭用C貼牌”。概括沒有類型系統(tǒng)。你可以編譯PHP,但必須通過php.ini指定要加載什么,選項(xiàng)因擴(kuò)展部分存在(將它們的內(nèi)容注入到全局名稱空間中)或不存在。因?yàn)槊Q空間是最近才有的特性,標(biāo)準(zhǔn)庫(kù)一點(diǎn)沒被打亂。在全局名稱空間中有上千個(gè)函數(shù)。庫(kù)的某些部分很不一致。下劃線對(duì)無下劃線:strpos/str_rot13,php_uname/phpversion,base64_encode/urlencode,gettype/get_class“to”對(duì)2:ascii2ebcdic,bin2hex,deg2rad,strtolower,strtotimeObject+verb對(duì)verb+object:base64_decode,str_shuffle,var_dumpversuscreate_function,recode_string參數(shù)順序:array_filter($input,$callback)versusarray_map($callback,$input),strpos($haystack,$needle)versusarray_search($needle,$haystack)前綴混亂:usleepvsmicrotimeCaseinsensitivefunctionsvaryonwheretheigoesinthename.大概一半的數(shù)組函數(shù)以array_開頭。剩下的不是。廚房水槽。庫(kù)包括:綁定ImageMagick,綁定GraphicsMagick(ImageMagick的派生),少量的幾個(gè)函數(shù)能檢測(cè)EXIF數(shù)據(jù)(其中ImageMagick已經(jīng)可以做到)解析bbcode的函數(shù),一些非常特殊的標(biāo)記,被幾個(gè)少量的論壇包使用。太多XML包。DOM(OO),DOMXML(not),libxml,SimpleXML,“XMLParser”,XMLReader/XMLWriter,和一大砣我不能認(rèn)出的東西就省略了。當(dāng)然會(huì)有些不同,你可以自由的弄清晰它們的區(qū)別。綁定了兩個(gè)特別的信用卡處理器,SPPLUS和MCVE.什么?三種訪問MySQL數(shù)據(jù)庫(kù)的方式:mysql,mysqli,和PDO抽象的一些東西。C影響它需要擁有的自己的符號(hào)。PHP是個(gè)高層的,動(dòng)態(tài)類型的語(yǔ)言。然后大量的標(biāo)準(zhǔn)庫(kù)的部分仍然只是圍繞CAPIS的薄層封裝,伴隨著下面的東西:”O(jiān)ut”參數(shù),盡管PHP可以返回ad-hoc哈?;蚝敛毁M(fèi)力的返回多參數(shù)。至少一打的函數(shù)是為了獲取某子系統(tǒng)的最近一次錯(cuò)誤(見下文),盡管PHP已存存異常處理功能8年了。有個(gè)mysql_real_escape_string,盡管已有個(gè)具有相同參數(shù)的mysql_escape_string,僅僅因?yàn)樗荕ySQLCAPI的一部分。全局行為卻是非全局功能的(如MySQL)。使用多個(gè)MySQL連接需要顯示的對(duì)每個(gè)函數(shù)調(diào)用傳遞連接句柄。包裝器真的,真的,真的很薄。例如,調(diào)用了dba_nextkey而沒調(diào)用dba_firstkey將出現(xiàn)段錯(cuò)誤。有一堆的ctype_*函數(shù)(如ctype_alnum)映射類似名稱的C字符函數(shù),而不是如,isupper.Genericism如果函數(shù)相做兩件略有不同的事,PHP就搞出兩個(gè)函數(shù)。你怎樣反向排序?在Perl中,你可以用{$b<=>$a}。在Python中,你可能用.sort(reverse=True)。在PHP中,有個(gè)特別的函數(shù)叫rsort()。那些看起來像Cerror的函數(shù):curl_error,json_last_error,openssl_error_string,imap_errors,mysql_error,xml_get_error_code,bzerror,date_get_last_errors,還有其它的嗎?排序函數(shù):array_multisort,arsort,asort,ksort,krsort,natsort,natcasesort,sort,rsort,uasort,uksort,usort文本檢索函數(shù):ereg,eregi,mb_ereg,mb_eregi,preg_match,strstr,strchr,stristr,strrchr,strpos,stripos,strrpos,strripos,mb_strpos,mb_strrpos,plusthevariationsthatdoreplacements有大量的別名:strstr/strchr,is_int/is_integer/is_long,is_float/is_double,pos/current,sizeof/count,chop/rtrim,implode/join,die/exit,trigger_error/user_error…scandir返回一個(gè)當(dāng)前給出目錄的文件列表。而不是(可能有益)按返回目錄順序返回,函數(shù)返回一個(gè)已排序的文件列表。有個(gè)可選的參數(shù)可以按字母逆順返回。這些用于排序很顯然很不夠。str_split將字符串拆成等長(zhǎng)的塊。chunk_split將字符串拆成等長(zhǎng)的塊,然后用個(gè)分隔符連接。讀取壓縮文件需要一套單獨(dú)的函數(shù),取決于格式。有六套函數(shù),它們的API都不同,如bzip2,LZF,phar,rar,zip,和gzip/zlib因?yàn)槭褂脜?shù)數(shù)組調(diào)用函數(shù)是如此的別扭(call_user_func_array),所以有些配套的像printf/vprintf和sprintf/vsprintf.它們做相同的事,但一個(gè)帶多個(gè)參數(shù),另一個(gè)帶參數(shù)數(shù)組。文本preg_replace帶/e(eval)標(biāo)志的將用待替換的字符串替換匹配的部分,然后eval它。strtok的設(shè)計(jì)顯然是和C函數(shù)等效的,由于很多原因,已被認(rèn)為是個(gè)壞注意。PHP可以輕易的返回一個(gè)數(shù)組(而這在C中別扭),很多的hackstrtok(3)用法(修改字符串某處),在這里不能使用。parse_str解析查詢字符串,從函數(shù)名看不出任何跡象。而它會(huì)register_globals并轉(zhuǎn)存查詢字符串到本地范圍變量中,除非你傳遞一個(gè)數(shù)組來填充。(當(dāng)然,什么也不返回)碰到空分隔符,explode會(huì)拒絕分割。每個(gè)其它的字符串拆分實(shí)現(xiàn)采取這種作法的意思應(yīng)該是把字符串應(yīng)拆分成字符;PHP有一個(gè)拆分函數(shù),令人迷惑的稱為str_split而卻描述為“將字符串轉(zhuǎn)成數(shù)組”。格式化日期,有strftime,像CAPI處理本地語(yǔ)言環(huán)境一樣。當(dāng)然也有date,完全不同的語(yǔ)法而僅用于English.”gzgetss—獲取gz文件的行指針并去除HTML標(biāo)記?!敝懒诉@一系列函數(shù)的概念,讓我去死吧。mbstring都是關(guān)于“multi-byte”,解決字符集的問題。仍然處理的是普通字符串。有個(gè)單一的全局”默認(rèn)”的字符集。一些函數(shù)允許指定字符集,但它依賴于所有的參數(shù)和返回值。提供了ereg_*函數(shù),但這些都被廢棄了。preg_*很幸運(yùn),用一些PCRE-specific標(biāo)記,它們能理解UTF-8.系統(tǒng)和反射有一大堆的函數(shù),聚焦于文本和變量。壓縮和提取僅是冰山一角。有幾種方式讓PHP動(dòng)態(tài),咋一看沒有什么明顯的不同或相對(duì)好處。類工具不能修改自定義類;運(yùn)行時(shí)工具取代了它并能修改自定義的任何東西;Reflection*類能反射語(yǔ)言的大部分東西;有很多獨(dú)特的函數(shù)是為了報(bào)告函數(shù)和類的屬性的。這些子系統(tǒng)是獨(dú)立,相關(guān),多余的嗎?get_class($obj)返回對(duì)象的類名稱。get_class()返回被調(diào)用函數(shù)中的類的名稱。撇開這些不說,同一個(gè)函數(shù)會(huì)做完全不同的事情:get_class(null)…行為象后者。因此面對(duì)一個(gè)隨機(jī)的變量,你不能信任它。驚訝吧!stream_*類允許實(shí)現(xiàn)自定義的流對(duì)象給fopen和其它的內(nèi)建的類似文件處理的東西使用。由于幾個(gè)內(nèi)部原因,“通知”不能被實(shí)現(xiàn)。register_tick_function能接受閉包對(duì)象。unregister_tick_function不行;相反,它會(huì)拋出錯(cuò)誤,抱怨閉包不能轉(zhuǎn)換成字符串。php_uname告知你當(dāng)前操作系統(tǒng)相關(guān)東西。fork和exec不是內(nèi)建的。它們來自pcntl擴(kuò)展,但默認(rèn)不包含。popen不提供pid文件。session_decode用于讀取任意的PHPsession字符串,但僅當(dāng)有個(gè)活躍的session時(shí)才工作。它轉(zhuǎn)存結(jié)果到$_SESSION中,而不是返回它的值。雜項(xiàng)curl_multi_exec不改變curl_error當(dāng)出錯(cuò)的時(shí)候,但它改變curl_error.mktime的參數(shù)是有順序的:hour,minute,second,month,day,year數(shù)據(jù)操縱程序什么都不是,除了咀嚼和吐出數(shù)據(jù)以外。大量的語(yǔ)言圍繞著數(shù)據(jù)操縱設(shè)計(jì),從awk到Prolog到C.如果語(yǔ)言無法操縱數(shù)據(jù),它就無法做任何事。數(shù)字Integers在32位平臺(tái)是是有符號(hào)32位數(shù)。不像PHP的同時(shí)代者,沒有自動(dòng)bigint提升。因此你的數(shù)學(xué)運(yùn)算可能會(huì)由于CPU體系結(jié)構(gòu)結(jié)果不一樣。你唯一選擇大整數(shù)的方式是使用GMP或BC包裝函數(shù)。(開發(fā)者可能已經(jīng)建義加入新的,單獨(dú)的,64位類型。這真是瘋了。)PHP支持八進(jìn)制數(shù)語(yǔ)法,以0開頭,因此如012是10.然而,08變成了0.8(或9)和任何接下來的數(shù)字消失了。01c是個(gè)語(yǔ)法錯(cuò)誤。pi是個(gè)函數(shù)?;蛘哂袀€(gè)常量,M_PI.沒有冪操作符,只有pow函數(shù)。文本無Unicode支持。只有ASCII工作是可靠的,真的。有個(gè)mbstring擴(kuò)展,上面提過的,但會(huì)稍被打擊。這意味著使用內(nèi)建的string函數(shù)處理UTF-8文本會(huì)有風(fēng)險(xiǎn)。相似的,在ASCII外,也沒有什么大小寫比較概念。盡管有擴(kuò)展版本的大小寫敏感的函數(shù),但它們不會(huì)認(rèn)為é等于é。你不能在變量中內(nèi)插keys,如,“$foo[‘key’]“是個(gè)語(yǔ)法錯(cuò)誤。你也不能unquoteit(這樣會(huì)產(chǎn)生警告,無論什么地方?。蚴褂?{…}/{$…}”${foo[0]}”是對(duì)的?!?{foo[0][0]}”是個(gè)語(yǔ)法錯(cuò)誤。糟糕的拷貝類似Perl的語(yǔ)法(兩個(gè)根本不同的語(yǔ)議)?數(shù)組嘔,騷年。這家伙扮演list數(shù)據(jù)類型,操作hash,和排序set,解析list,偶爾會(huì)有些奇怪的組合。它是怎樣執(zhí)行的?以何種方式使用內(nèi)存?誰(shuí)知道?不喜歡,反正我還有其它的選擇。=>不是操作符。它是個(gè)特別的結(jié)構(gòu),僅僅存在于array(…)和foreach結(jié)構(gòu)中。負(fù)值索引不工作,盡管-1也是個(gè)和0一樣的合法鍵值。盡管這是語(yǔ)言級(jí)的數(shù)據(jù)結(jié)構(gòu),但沒有簡(jiǎn)短語(yǔ)法;array(…)是簡(jiǎn)短語(yǔ)法。(PHP5.4帶來了”literals”,[。..]。)=>結(jié)構(gòu)是基于Perl,Perl允許foo=>1而不用引號(hào)。在PHP中,你這么做會(huì)得到警告;沒有無需引號(hào)創(chuàng)建hash字符串鍵值的方式。數(shù)組處理函數(shù)常常讓人迷惑或有不確定行為,因?yàn)樗鼈儾坏貌粚?duì)lists,hashes,或可能兩者的結(jié)合體做運(yùn)算??紤]array分組,“計(jì)算arrays的不同部分”。$first=
array("foo"=>123,"bar"=>456);$second=
array("foo"=>456,"bar"=>123);echovar_dump(array_diff($first,$second));這段代碼將做什么?如果array_diff將參數(shù)以hashes看待,它們明顯是不同的;相同的keys有不同的值。如果以list看待,它們?nèi)匀皇遣煌?值的順序不同。事實(shí)上array_diff認(rèn)為它們相等,因?yàn)樗詓ets對(duì)待:僅僅比較值,忽略順序。同樣,array_rand隨機(jī)選擇keys時(shí),也有奇怪的行為,這對(duì)大多數(shù)需要從列表中挑出東西的用例沒什么幫助。盡管大量PHP代碼依賴key的順序:array("foo","bar")!=
array("bar","foo")array("foo"=>1,"bar"=>2)==
array("bar"=>2,"foo"=>1)如果兩個(gè)數(shù)組混合的話,會(huì)發(fā)生什么?我留給讀者自己弄清楚。(我不知道)array_fill不能創(chuàng)建0長(zhǎng)度的數(shù)組;相反它會(huì)發(fā)出警告并返回false.所有的(很多的…)排序函數(shù)就地操作而什么都不返回。想新建一個(gè)已排序數(shù)組的拷貝,沒門;你不得不自己拷貝數(shù)組,然后排序,然后再使用數(shù)組。但array_reverse返回一個(gè)新數(shù)組。一堆被排序的東西和一些鍵值對(duì)聽起來像是個(gè)某種強(qiáng)大的處理函數(shù)參數(shù)的方式,但,沒門。非數(shù)組標(biāo)準(zhǔn)庫(kù)包含“快速哈?!?,“特定的強(qiáng)類型”的hash結(jié)構(gòu)OO實(shí)現(xiàn)。然,深入它,有4類,每種處理不同的鍵值對(duì)類型組合。不清楚為什么內(nèi)建的數(shù)組實(shí)現(xiàn)不能優(yōu)化這些極其普通情況,也不清楚它相對(duì)的性能怎樣。有個(gè)ArrayObject類(實(shí)現(xiàn)了4個(gè)不同的接口),它包裝數(shù)組讓它看起來像對(duì)象。自定義類可以實(shí)現(xiàn)同樣的接口。但只有限的幾個(gè)方法,其中有一半不像內(nèi)建的數(shù)組函數(shù),而內(nèi)建的數(shù)組函數(shù)不知道怎樣對(duì)ArrayObject或其它的類數(shù)組的類型操作。函數(shù)函數(shù)不是數(shù)據(jù)。閉包實(shí)際上是對(duì)象,但普通的函數(shù)不是。你甚至不能通過它們裸名稱引用它們;var_dump(strstr)會(huì)發(fā)出警告并猜測(cè)你的意思是字符串字面量,“strstr”。想辨別出字符串還是”函數(shù)”引用,沒門。create_function基本上是個(gè)eval的包裝者。它用普通的名字創(chuàng)建函數(shù)并在全局范圍安裝它(因此永遠(yuǎn)不會(huì)被垃圾回收—不要在循環(huán)中使用!)。它實(shí)際上對(duì)當(dāng)前上下文一無所知,因?yàn)樗皇情]包。名字包含一個(gè)NUL字節(jié),因此永遠(yuǎn)不會(huì)與普通函數(shù)沖突(因?yàn)槿绻谖募娜魏蔚胤接蠳UL的話,PHP的解析器會(huì)失?。?。Declaringafunctionnamed__lambda_funcwillbreakcreate_function—theactualimplementationistoeval-createthefunctionnamed__lambda_func,theninternallyrenameittothebrokenname.If__lambda_funcalreadyexists,wafatalerror.其它對(duì)NULL使用(++)生成1.對(duì)NULL用(–)生成NULL.沒有生成器。Web框架執(zhí)行環(huán)境一個(gè)單一共享文件php.ini,控制了PHP的大部分功能并織入了復(fù)雜的針對(duì)覆蓋什么與何時(shí)覆蓋的規(guī)則。PHP軟件能部署在任意的機(jī)器上,因此必須覆蓋一些設(shè)置使環(huán)境正常,這在很大程序上會(huì)違背像php.ini這樣的機(jī)制的使用。PHP基本上以CGI運(yùn)行。每次頁(yè)面被點(diǎn)擊,PHP在執(zhí)行前,重編譯整個(gè)環(huán)境。就連Python的玩具框架的開發(fā)環(huán)境都不會(huì)這樣。這就導(dǎo)致了整個(gè)“PHP加速器”市場(chǎng)的形成,僅僅編譯一次,就能加速PHP,就像其它的語(yǔ)言一樣。Zend,PHP的幕后公司,將這個(gè)做為它們的商業(yè)模式。很長(zhǎng)時(shí)間以來,PHP的錯(cuò)誤默認(rèn)輸出給客戶端—我猜是為開發(fā)環(huán)境提供幫助。我不認(rèn)為這是真相,但我仍然看到偶爾會(huì)有mysql錯(cuò)誤出現(xiàn)在頁(yè)面的頂部。在<?php…?>標(biāo)簽外的空白,甚至在庫(kù)中,PHP以文本對(duì)待并解析給響應(yīng)(或者導(dǎo)致“headersalreadysent”錯(cuò)誤)。一個(gè)流行的做法是忽略?>關(guān)閉標(biāo)簽。部署部署方式常常被引述為PHP的最高級(jí)部分:直接部署文件就可以了。是的,這比需要啟動(dòng)整個(gè)進(jìn)程的Python或Rury或Perl要容易。但PHP留下了許多待改進(jìn)的地方。我很樂意以應(yīng)用服務(wù)器的方式運(yùn)行Web應(yīng)用程序并反向代理它們。這樣的代價(jià)最小,而好處多多:你可以單獨(dú)管理服務(wù)器和應(yīng)用程序,你可以按機(jī)器的多或少運(yùn)行運(yùn)行多個(gè)或少量應(yīng)用進(jìn)程,而不需要多個(gè)web服務(wù)器,你可以用不同的用戶運(yùn)行應(yīng)用,你可以選擇web服務(wù)器,你可以拆下應(yīng)用而無需驚動(dòng)web服務(wù)器,你可以無縫部署應(yīng)用等等。將應(yīng)用與web服務(wù)器直接焊接是荒謬的,沒有什么好的理由支持你這么做。每個(gè)PHP應(yīng)用程序都使用php.ini。但只有一個(gè)php.ini文件,它是全局的;如果你在一個(gè)共享的服務(wù)器上,需要修改它,或者如果你運(yùn)行兩個(gè)應(yīng)用需要不同的設(shè)置,你就不走運(yùn)了;你不得不向組織申請(qǐng)所有必須的設(shè)置并放在應(yīng)用程序,如使用ini_set或在Apache的配置文件或在.htaccess設(shè)置。如果你能做的話??赡躻ow,你有大量的地方需要檢查以找出怎樣獲取已設(shè)置的值。類似的,“隔離”PHP應(yīng)用的方法也不容易,它依賴于系統(tǒng)的其它部分。想運(yùn)行兩個(gè)應(yīng)用程序,想要不同的庫(kù)版本,或不同的PHP版本本身?開始構(gòu)建另一人Apache的拷貝吧?!币欢盐募狈桨?,除了使路由像只病重的笨驢外,還意味著你不得不小心處理白名單或黑名單,以控制什么東西可訪問,這是因?yàn)槟愕腢RL層次也就是你的代碼樹的層次。配置文件和其它的”局部模塊”需要C之類的東西守護(hù)以避免直接加載。版本控制系統(tǒng)的文件(如.svn)需要保護(hù)。使用mod_php,使得文件系統(tǒng)的所有東西都是潛在的入口;使用應(yīng)用服務(wù)器,僅有一個(gè)入口,并且僅通過URL控制調(diào)用與否。你不能無縫的升級(jí)那堆以CGI-style運(yùn)行的文件,除非你想要應(yīng)用崩潰和出現(xiàn)未定義行為,當(dāng)用戶在升級(jí)的間歇期點(diǎn)擊你的站點(diǎn)時(shí)。盡管配置Apache運(yùn)行PHP很”簡(jiǎn)單”,仍然會(huì)有一些陷阱。而PHP文檔建議使用SetHandler使得.php文件以PHP方式運(yùn)行,AddHandler看起來運(yùn)行良好,然而事實(shí)上會(huì)有問題。當(dāng)你使用AddHandler,你在告知Apache“以php執(zhí)行它”,這是一個(gè)可能的處理.php文件的方式。但!Apache對(duì)文件的擴(kuò)展名不這樣認(rèn)為。它被設(shè)計(jì)為能支持如,index.html.en這樣的文件。對(duì)于Apache
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026四川雅安市老干部活動(dòng)中心招聘1人筆試備考題庫(kù)及答案解析
- 2026浙江金華市武義縣城鄉(xiāng)環(huán)境服務(wù)有限公司招聘1人筆試備考題庫(kù)及答案解析
- 2026湖南永州市廉潔征兵筆試參考題庫(kù)及答案解析
- 2025年多媒體應(yīng)用設(shè)計(jì)師筆試及答案
- 2025年大學(xué)高校財(cái)務(wù)管理崗筆試及答案
- 2025年boss心理測(cè)試筆試及答案
- 2025年達(dá)州鋼鐵集團(tuán)筆試及答案
- 2025年建筑集團(tuán)招聘筆試題庫(kù)及答案
- 2025年內(nèi)蒙古教招英語(yǔ)筆試及答案
- 2025年醫(yī)院會(huì)計(jì)事業(yè)編考試真題及答案
- 殘疾人服務(wù)與權(quán)益保護(hù)手冊(cè)(標(biāo)準(zhǔn)版)
- 車隊(duì)春節(jié)前安全培訓(xùn)內(nèi)容課件
- 2025年溫州肯恩三位一體筆試英語(yǔ)真題及答案
- 云南師大附中2026屆高三高考適應(yīng)性月考卷(六)歷史試卷(含答案及解析)
- PCR技術(shù)在食品中的應(yīng)用
- 輸液滲漏處理課件
- 教育培訓(xùn)行業(yè)發(fā)展趨勢(shì)與機(jī)遇分析
- 物業(yè)與商戶裝修協(xié)議書
- 湖南鐵道職業(yè)技術(shù)學(xué)院2025年單招職業(yè)技能測(cè)試題
- GB/T 46318-2025塑料酚醛樹脂分類和試驗(yàn)方法
評(píng)論
0/150
提交評(píng)論