php單例怎么操作 總是有人在黑php,這是怎樣的一群人?
總是有人在黑php,這是怎樣的一群人?PHP現(xiàn)在名聲不好,因?yàn)樗?jīng)是 "可怕 "。這篇文章試圖回答一些關(guān)于PHP的常見論斷,以便向非技術(shù)人員說明PHP并沒有很多人說的那么差。1.它是否鼓勵(lì)不良做法?
總是有人在黑php,這是怎樣的一群人?
PHP現(xiàn)在名聲不好,因?yàn)樗?jīng)是 "可怕 "。
這篇文章試圖回答一些關(guān)于PHP的常見論斷,以便向非技術(shù)人員說明PHP并沒有很多人說的那么差。
1.它是否鼓勵(lì)不良做法?
不再是了。以前很多開發(fā)者都是被書本教會(huì)了非常不好的做法,所以PHP代碼質(zhì)量非常差。PHP曾經(jīng)允許你做一些非常奇怪的事情,這使得構(gòu)建非常容易,但是維護(hù)起來卻是一場(chǎng)噩夢(mèng)。
這些不再是常見的問題。隨著高質(zhì)量學(xué)習(xí)資料的引入,這些資料很容易學(xué)習(xí)和獲取,一個(gè)新的開發(fā)者可以用正確的方法學(xué)習(xí)PHP。這可以防止初級(jí)開發(fā)人員編寫一些維護(hù)起來非常痛苦的代碼,因?yàn)樗麄儧]有 我不知道建造東西的正確方法。
隨著框架的引入,大部分導(dǎo)致許多糟糕體驗(yàn)的常見代碼現(xiàn)在都自動(dòng)完成了;所以開發(fā)者只需要使用框架,框架就能正確編碼。
而且這些年來,一些不好的做法都是因?yàn)槿笔Я颂匦?,?dǎo)致了一些不應(yīng)該被允許的事情?,F(xiàn)在大多數(shù)情況下,甚至無法意識(shí)到之前寫的東西會(huì)導(dǎo)致這個(gè)名聲。
總結(jié)
它不再鼓勵(lì)不良行為...
使用框架可以避免不好的實(shí)踐。
現(xiàn)在有很多關(guān)于語言特性的討論。不再支持不好的功能。
PHP添加了其他語言中存在的大部分(如果不是全部)功能。
2.它的安全性差嗎?
過去,PHP應(yīng)用程序的安全性通常很差,因?yàn)檎Z言允許這樣做。這些東西已經(jīng)不用了,因?yàn)楝F(xiàn)在PHP應(yīng)用的開發(fā)已經(jīng)完全不同了。
通過使用自動(dòng)加載器來包含文件,而不是動(dòng)態(tài)地包含文件,遠(yuǎn)程和本地文件包含(PHP從原始地址以外的其他地址讀取文件)。
通過廣泛使用模板系統(tǒng)(可以自動(dòng)處理顯示動(dòng)態(tài)內(nèi)容的轉(zhuǎn)義和安全問題),避免了在PHP中直接使用HTML(一個(gè)用戶將JavaScript腳本添加到要顯示給另一個(gè)用戶的地方)導(dǎo)致的跨站腳本攻擊。
通過在SQL中使用預(yù)處理語句,可以避免SQL注入攻擊(這是由于需要構(gòu)建SQL查詢并一起發(fā)送查詢和數(shù)據(jù),用戶可以在查詢中添加額外的SQL命令)。另外,ORM的應(yīng)用也很廣泛,它保證了用戶數(shù)據(jù)和查詢是分開發(fā)送的,SQL不能把它當(dāng)成一個(gè)單獨(dú)的命令。
通過廣泛使用nonce系統(tǒng)的表單庫(kù),可以避免跨站點(diǎn)請(qǐng)求偽造(其中用戶可以被誘騙在您的站點(diǎn)上執(zhí)行某些操作)。
總結(jié)
通過使用自動(dòng)加載器(所有主流框架),避免包含遠(yuǎn)程和本地文件。
通過使用模板語言作為標(biāo)準(zhǔn)或前端框架(如React),可以避免跨站點(diǎn)腳本(XSS)攻擊。
通過使用ORM和廣泛使用預(yù)準(zhǔn)備語句來避免SQL注入。
通過使用nonce令牌(所有主流框架都自動(dòng)支持),可以避免跨站點(diǎn)請(qǐng)求偽造(CRSF)攻擊。
3.真的很慢嗎?
那要看你拿它和什么比了。如果拿PHP和Java,C或者Go比,就慢一些。但是如果你拿PHP和Python,Ruby之類的比較,并不慢。PHP是同類語言中速度最快的語言之一,而且它還在不斷提高自己的性能。
在大多數(shù)情況下,您的應(yīng)用程序很慢是因?yàn)榉?wù)器過載或數(shù)據(jù)庫(kù)查詢很慢。這些問題在任何語言中都會(huì)存在。
總結(jié)
PHP比編譯語言慢。
PHP比其他腳本語言更快。
網(wǎng)站慢通常不是因?yàn)闆]有快速語言,而是服務(wù)器或數(shù)據(jù)庫(kù)造成的性能問題。
4.它的擴(kuò)展性真的很差嗎?
事實(shí)上,任何語言都是可以縮放的。編譯語言(如Go、C或Rust)的擴(kuò)展成本比腳本語言(如PHP)低。但是,它們不是為同一任務(wù)而設(shè)計(jì)的。其實(shí)都一樣;這僅僅取決于您使用的服務(wù)器數(shù)量。如果您使用足夠多的服務(wù)器,您可以擴(kuò)展任何應(yīng)用程序。PHP比其他腳本語言的擴(kuò)展成本更低,因?yàn)樗鼏?dòng)運(yùn)行需要的資源更少,可以運(yùn)行在CPU更多內(nèi)存更小的服務(wù)器上。
此外,對(duì)于可伸縮性,數(shù)據(jù)庫(kù)很重要。如果可以擴(kuò)展數(shù)據(jù)庫(kù),就可以擴(kuò)展應(yīng)用程序。數(shù)據(jù)庫(kù)比應(yīng)用服務(wù)器更難擴(kuò)展。很容易添加另一個(gè)讀取數(shù)據(jù)庫(kù)的客戶機(jī);然而,使數(shù)據(jù)庫(kù)快速運(yùn)行要困難得多。
總結(jié)
任何語言都可以是可擴(kuò)展的;這取決于您使用多少臺(tái)服務(wù)器。
擴(kuò)展的真正問題是數(shù)據(jù)庫(kù),而不是使用的應(yīng)用程序語言。
如果你能擴(kuò)展你的數(shù)據(jù),你就能擴(kuò)展你的應(yīng)用。
5.我應(yīng)該一直用它嗎?
不是。每種編程語言都有自己的專業(yè)領(lǐng)域。PHP非常適合Web應(yīng)用。你應(yīng)該用它來構(gòu)建網(wǎng)站和API。
如果您正在構(gòu)建一個(gè)系統(tǒng)應(yīng)用程序,其中每一毫秒都很重要,請(qǐng)使用Rust或c。
如果你正在構(gòu)建一個(gè)人工智能應(yīng)用,Python是一個(gè)很好的選擇。
如果您正在構(gòu)建一個(gè)SaaS應(yīng)用程序,PHP是一個(gè)不錯(cuò)的選擇。
如果您正在構(gòu)建一個(gè)Android應(yīng)用程序,Kotlin是一個(gè)不錯(cuò)的選擇。
如果你正在建造Java是構(gòu)建在多種平臺(tái)上運(yùn)行的應(yīng)用程序的好選擇。
總結(jié)
每種語言都有其最佳用例。
PHP的最佳用例是Web應(yīng)用程序。
Go,Rust,c適合系統(tǒng)應(yīng)用。
Python適合人工智能。
Kotlin適用于Android應(yīng)用程序。
Java適合于平臺(tái)無關(guān)的應(yīng)用程序。
6.結(jié)論
每年都講php,但是你的PHP現(xiàn)在是不是過期了?很多關(guān)于PHP的說法已經(jīng)過時(shí)10年了。在我看來,如果有人給你一個(gè)過期10年的技術(shù)主題的信息,那么這個(gè)人可能不是你想要信任的技術(shù)專家。
PHP是創(chuàng)建W
set nx函數(shù)用法?
在Redis中,所謂的SETNX是 "如果不存在則設(shè)置 ",也就是只有在不存在的時(shí)候才能設(shè)置,用它來達(dá)到鎖定的效果,但是很多人都沒有意識(shí)到SETNX有陷阱!
比如一個(gè)查詢數(shù)據(jù)庫(kù)的接口,調(diào)用量很大,所以增加一個(gè)緩存,設(shè)置緩存過期后刷新。問題是,當(dāng)并發(fā)量較大時(shí),如果沒有鎖機(jī)制,大量并發(fā)請(qǐng)求會(huì)在緩存過期的瞬間穿透緩存,直接查詢數(shù)據(jù)庫(kù),產(chǎn)生雪崩效應(yīng)。如果有鎖機(jī)制,那么只能控制一個(gè)請(qǐng)求來更新緩存,其他請(qǐng)求可以等待,也可以根據(jù)需要使用過期的緩存。
讓 下面以PHP社區(qū)中最流行的PHPRedis擴(kuò)展為例,實(shí)現(xiàn)一個(gè)演示代碼:
服務(wù)器端編程語言(Professional Hypertext Preprocessor的縮寫)
$ok $redis-setNX($key,$ value);
如果($ok) {
$ cache-update();
$ redis-del($ key);
}
當(dāng)緩存過期時(shí),通過SetNX獲得鎖。如果成功,更新緩存并刪除鎖。看起來邏輯很簡(jiǎn)單,但很遺憾有一個(gè)問題:如果請(qǐng)求執(zhí)行因?yàn)槟撤N原因意外退出,導(dǎo)致創(chuàng)建了鎖但沒有刪除鎖,那么這個(gè)鎖就一直存在,這樣以后緩存就永遠(yuǎn)不會(huì)更新了。因此,我們需要為鎖添加一個(gè)到期時(shí)間,以防發(fā)生某些情況:
服務(wù)器端編程語言(Professional Hypertext Preprocessor的縮寫)
$ redis-multi();
$redis-setNX($key,$ value);
$redis-expire($key,$ TTL);
$ redis-exec();
因?yàn)镾etNX沒有設(shè)置過期時(shí)間的功能,所以我們需要借助Expire來設(shè)置,需要用Multi/Exec來包裝它們,保證請(qǐng)求的原子性,防止SetNX過期成功。e失敗了。不幸的是,仍然存在問題:當(dāng)多個(gè)請(qǐng)求到達(dá)時(shí),盡管只有一個(gè)請(qǐng)求 s SetNX可以成功,任何要求 s Expire可以成功,這意味著即使不能獲得鎖,也可以刷新到期時(shí)間。如果請(qǐng)求密集,過期時(shí)間將一直刷新,導(dǎo)致鎖一直有效。所以我們需要有條件地執(zhí)行Expire,同時(shí)確保原子性,然后我們有下面的Lua代碼:
本地關(guān)鍵碼[1]
本地值鍵[2]
本地ttl密鑰[3]
本地ok (setnx,key,value)
如果ok 1,則
(過期,密鑰,ttl)
結(jié)束
返回ok
我沒有。;t指望用Lua腳本實(shí)現(xiàn)一個(gè)看似簡(jiǎn)單的功能,真的很麻煩。事實(shí)上,Redis考慮了每個(gè)人 苦難。從2.6.12開始,SET已經(jīng)涵蓋了SETEX的功能,SET本身也已經(jīng)包含了設(shè)置到期時(shí)間的功能,也就是說我們之前需要的功能,只有SET才能實(shí)現(xiàn)。
服務(wù)器端編程語言(Professional Hypertext Preprocessor的縮寫)
$ok $redis-set($key,$value,array(nx,ex $ TTL));
如果($ok) {
$ cache-update();
$ redis-del($ key);
}
上面的代碼完美嗎?答案是差不多!想象一下,如果一個(gè)請(qǐng)求更新緩存需要很長(zhǎng)時(shí)間,甚至比鎖的有效期還要長(zhǎng),那么在緩存更新過程中鎖就會(huì)失效,此時(shí)另一個(gè)請(qǐng)求就會(huì)獲得鎖。但是如果之前的請(qǐng)求在緩存更新完成后直接刪除鎖,那么其他請(qǐng)求創(chuàng)建的鎖也會(huì)被誤刪除,所以我們需要在創(chuàng)建鎖的時(shí)候引入一個(gè)隨機(jī)值:
服務(wù)器端編程語言(Professional Hypertext Preprocessor的縮寫)
$ok $redis-set($key,$random,array(nx,ex $ TTL));
如果($ok) {
$ cache-update();
if ($redis-get($key) $random) {
$ redis-del($ key);
}
}