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