Rumah > Soal Jawab > teks badan
Ditamatkan dalam PHP 8.1 null
作为参数传递给许多核心函数。我的主要问题是 htmlspecialchars(php)
和 trim(php)
等函数,其中 null
tidak lagi secara senyap bertukar kepada rentetan kosong.
Untuk menyelesaikan masalah ini tanpa menggunakan banyak kod, saya cuba menamakan semula fungsi terbina dalam asal dan menggantikannya dengan pembalut yang menukar input daripada null
kepada rentetan (kosong).
Masalah utama pendekatan ini ialah fungsi rename_function(PECL apd)
tidak lagi berfungsi, ia kali terakhir dikemas kini pada tahun 2004 1.
Saya memerlukan beberapa jenis penulisan semula fungsi terbina dalam untuk mengelak daripada menulis semakan nol setiap kali fungsi dipanggil, menjadikan semua kod saya dua kali lebih besar.
Satu-satunya penyelesaian lain yang boleh saya fikirkan ialah dengan hanya menggunakan fungsi tersuai saya, tetapi itu masih memerlukan melalui semua kod dan perpustakaan pihak ketiga yang saya ada.
Dalam PHP 8.1, null tidak lagi ditukar secara senyap kepada rentetan kosong apabila dihantar ke fungsi terbina dalam.
P粉8113290342024-01-11 15:36:30
Saya rasa (dan sebagai nota sampingan, jawapan yang sedia ada mendapat sokongan saya) melukiskan gambaran yang berbeza tentang cara "masalah" tersebut dilihat dan diselesaikan. Ia tidak mengurangkan betul atau salah pendekatan yang digariskan, tetapi sekadar perspektif tambahan yang diharap dapat memberi manfaat bersama. Setiap projek adalah berbeza.
Premis yang diberikan:
Jadi ini pada pandangan saya (pada mulanya) sebagai isu pelaporan. Dengan tidak melaporkan E_DEPRECATED
.
Faedah ini ialah (bukan hanya kod anda) kini mengetahui bahawa kod anda disertakan dengan notis penamatan. Laporan sangat berkesan .
Sebaliknya, menyekat pemberitahuan penamatan boleh menyebabkannya hilang. Jika anda kehilangan pangkalan kod dengan notis penamatan, secara teknikalnya mungkin masih mudah untuk pulih daripada kehilangan (sekali lagi, laporkan notis penamatan), tetapi jika perubahan itu dilanjutkan, ia mungkin menjadi bunyi yang amat menggembirakan (E_TOO_MUCH_NOISE).
Jadi adakah kod tidak senyap sebenarnya adalah perkara yang buruk? Atau bolehkah ia dijadikan manfaat? Saya lebih suka memilih yang terakhir. Walau apa pun, kami sudah memproses maklumat ini.
Jadi, dalam kes ini, idea saya adalah untuk secara amnya tidak menyekat pemberitahuan penamatan, sebaliknya "mendiamkan" panggilan fungsi. Ia mudah, tetapi bodoh dalam kedua-dua cara yang baik dan cara yang buruk:
trim($mixed); #1 -> @trim($mixed); #2
Ini sudah tentu operasi yang boleh digunakan pada pangkalan kod menggunakan alat teks standard. Ia juga menunjukkan kepada anda tempat @
pengendali penindasan telah digunakan pada masa lalu:
@trim($mixed); #3 -> @@trim($mixed); #4
Jika anda seorang pembangun PHP dan melihat kod seperti ini (untuk kes #2-#4) dalam editor, mereka akan serta-merta menjerit kepada anda, dan untuk keempat-empat kes sekurang-kurangnya mendapat perhatian anda ($mixed
).
Terima kasih kerana tidak berdiam diri, kami biarkan tempat ini menjerit, cuma bukan pada masa tayangan 1.
Tidak seperti kaedah pertama berdiam diri dengan tidak melaporkan E_DEPRECATED
来保持沉默的方法不同,这种方法很容易丢失信息,而信息是通过使用所有 @
, di mana maklumat mudah hilang, maklumat disimpan dengan menggunakan semua simbol
@
Adakah ia membantu menyelesaikan masalah bunyi bising? Jika kita berhenti bekerja di sini, itu sama sekali tidak akan berfungsi. Sekarang kami akan melukis simbol p>- pada kod dan memutuskan untuk tidak mengambil tindakan selanjutnya, supaya kami boleh menggunakan penyelesaian pertama (tidak melaporkan mesej penamatan) untuk menyelesaikannya tanpa menyentuh kod.
Jadi apa faedahnya? Nah, walaupun kod sekarang berjalan dengan senyap
, PHP masih menyediakan mesej diagnostik. Iaitu, kini mungkin untuk mendaftarkan pengendali ralat PHP sebagai pendengar (semasa melaksanakan kod).
@
Hanya pada tahap kod, mudah untuk menyemak lokasi ini kerana simbol
Bahagian kedua adalah penting kerana walaupun beberapa tempat mungkin terjejas oleh penamatan, mesti tidak ada satu penyelesaian yang menyelesaikan kesemuanya (saya lebih suka menjauhkan diri daripada 'penyelesaian' "satu saiz untuk semua" jika boleh ), tetapi terutamanya dalam konteks soalan PHP 8.1 telah berubah dan saya boleh bayangkan akan ada keperluan yang berbeza bergantung pada tempat ia digunakan
Sebagai contoh, dalam kod templat (output), jenis konkrit tidak menjadi isu, jadi menukar kepada rentetan kemungkinan besar merupakan penyelesaian pilihan:
@trim($mixed); -> trim((string)$mixed) @@trim($mixed); -> @trim((string)$mixed)
Templat (output) kekal stabil.
Tetapi untuk pengendalian input sebenar, notis penamatan mungkin mendedahkan potensi kelemahan sebenar yang patut diperbaiki, seperti kehilangan nilai lalai (menjadikan perkara terlalu rumit), pengendalian nilai yang tidak jelas (null vs. null, rentetan, boolean vs. nombor ) ) keliru dengan tatasusunan vs. objek dalam PHP) atau hanya $mixed
secara umum.
trim($mixed)
ini mungkin merupakan perlindungan keselamatan yang telah dilupakan selama bertahun-tahun dan tidak pernah dinaik taraf (perlindungan keselamatan yang lebih baik tersedia). Untuk kod seperti ini, saya pasti saya sudah mahu dan memerlukan trim($mixed)
可能是一个被遗忘多年的安全防护,从未进行过升级(有更好的安全防护可用)。对于这样的代码,我很确定我已经想要并要求 $mixed
实际上是 $string
before 我使用 trim ()
sebenarnya $string
trim ()
. Sebabnya sangat mudah, sekurang-kurangnya dua perkara terlintas di fikiran: trim()
a) tidak diperlukan lagi - ia boleh dipadamkan (salah satu pembetulan 李>kegemaran
$mixed 进行修补是完全有效的? ''
如果原始使用是字符串或null
Adakah tampalan menggunakan $mixed sah sepenuhnya? ''
Jika
null
sahaja TypeError
.
@trim($mixed); -> trim($mixed ?? '') @@trim($mixed); -> @trim($mixed ?? '')
Tetapi selain itu, nombor seperti 42, sebagai contoh, akan membuang
dan bukannya mesej penamatan. Ini membezakan antara kod yang sedang berjalan dan kod yang tidak.
@
Jadi masih banyak lagi yang perlu dikekalkan di sini, seperti menyemak lokasi, mengelompokkan lebih lanjut jika boleh, dan kemudian menggunakan pembaikan yang lebih khusus. Ia mungkin mendedahkan ujian atau penegasan yang hilang, mengambil sedikit masa untuk menstabilkan keseluruhan aliran aplikasi, dsb.
Dalam kes ini, selesaikan pemindahan kod, lakukan pengelompokan, kendalikan operator cantum nol dan lakukan kertas kerja yang sesuai untuk pembetulan sebenar. Sebaik sahaja anda selesai menyekat ralat yang tidak jelas menggunakan operator penggabungan nol dan mengalih keluar operator penindasan
, anda mungkin kehilangan maklumat ini jika pelan pembetulan tidak menangkapnya.Saya tidak terkejut apabila saya mendapati diri saya menggaru kepala atau menggosok mata apabila saya kelihatan lebih berpendidikan di bahagian ini. Kemudian saya mengingatkan diri saya bahawa ralat ini bukan disebabkan oleh versi PHP 8.1, perubahan versi hanya menjadikannya muncul (sekali lagi), dan kadang-kadang saya juga mendapat kumpulan ralat lengkap sebagai tangkapan sampingan dengan mengekalkan versi PHP.
🎜Helaian Cheat🎜🎜(string)$mixed
- Tingkah laku sebelumnya $mixed ?? ''
- 仅在 null
上抑制 TypeError
Ralat@
- Penindasan ralat penuh. Anda harus mendokumenkan pangkalan kod anda jika berkenaan. @@
- Jika ini berlaku, ini mungkin tempat yang menarik untuk dilihat. 空($mixed)? '' : xxx($mixed)
- Keluarkan sampah, kelumpuhan udara/kekacauan hibrid biasa, dan cari kelompok, peluang untuk memudahkan asas kod. Berhijrah kepada jenis skalar (PHP 7), memperkenalkan penaipan ketat dari dalam ke luar, menggunakan penaipan "klasik" dan "ketat" PHP jika berkenaan. Pernyataan PHP 7.0 dan mesej penamatan PHP 8.1 menyokong ini dengan baik. Pengendali ralat
Tiada apa-apa yang ajaib tentang pengendalian ralat, ia adalah standard yang didokumenkan pada PHP.net (dengan Contoh #1), yang bertindak sebagai pemerhati untuk peristiwa ralat dan boleh membezakan antara ralat yang ditindas dan tidak ditindas melalui < kod> error_reporting(php)error_reporting(php)
/ error_reporting(php-ini)
至少达到通常需要的级别,如果需要进行区分(在生产环境中,E_DEPRECATED
通常不是报告的一部分)。此示例性处理程序会抛出所有报告的错误,对于弃用事件以及 E_ALL
也会抛出此类错误,因此需要 @
/ < code> error_reporting(php-ini)
biasanya bukan sebahagian daripada report). Pengendali contoh ini membuang semua ralat yang dilaporkan, serta untuk peristiwa penamatan dan E_ALL
, jadi pengendali penindasan
set_error_handler(static function ($type, $message, $file, $line) use (&$deprecations) {
if (!(error_reporting() & $type)) {
// This error code is not included in error_reporting, so let it fall
// through to the standard PHP error handler
// capture E_DEPRECATED
if ($type === E_DEPRECATED) {
$deprecations[] =
['deprecations' => count($deprecations ?: [])]
+ get_defined_vars();
}
return false;
}
// throwing error handler, stand-in for own error reporter
// which may also be `return false;`
throw new ErrorException($message, $type, error_reporting(), $file, $line);
});
Pengendali ralat yang serupa boleh didapati dalam contoh lanjutan E_USER_DEPRECATED
di 3v4l.org, termasuk pada kod yang tidak digunakan untuk dilaporkan.
E_USER_DEPRECATED
结合使用,与上面 E_DEPRECATED
Secara teknikal, operator penindasan ralat boleh digunakan bersama dengan
dengan cara yang sama seperti yang digariskan untuk di atas. E_DEPRECATED
@trigger_error('this. a message.', E_USER_DEPRECATED);
🎜Ia melakukan perkara yang sama: memancarkan peristiwa penamatan tetapi mengecualikannya daripada pelaporan PHP. Melanggan ini boleh menyebabkan anda tenggelam dalam kebisingan. Dengan 🎜 anda sentiasa boleh mendapatkan "baik dan asli" terus daripada PHP. 🎜@
错误抑制运算符的方法并对其进行评论时,IMSoP 立即举起红/黑旗(正确!),很容易将婴儿与洗澡水一起倒掉@
pengendali penindasan. Dalam jawapan saya, tujuannya hanya untuk menyekat pemberitahuan penamatan tetapi hasil daripada penggunaan ialah ia menyekat semua mesej dan ralat diagnostik, malah yang membawa maut dalam beberapa versi PHP, jadi PHP keluar dengan 255, Tiada diagnosis lanjut diperlukan - hanya berhati-hati dan uruskan. Pengendali ini berkuasa. Jejaki penggunaannya dalam pangkalan kod dan sentiasa semak sama ada ia memenuhi garis dasar/jangkaan anda. Untuk situasi undang-undang, pertimbangkan untuk menggunakan penyenyap. Untuk mengalihkan/menyelenggarakan kod, tandakannya dengannya dahulu. Setelah anda selesai mengedit kumpulan, padamkannya sekali lagi. P粉5920854232024-01-11 00:24:47
Pertama, dua perkara yang perlu diingat:
htmlspecialchars($something)
可以替换为 htmlspecialchars($something ?? '')
Seterusnya, beberapa pilihan:
?? ''
atau membetulkan ralat logik, anda tidak mahu batal. nullable_htmlspecialchars
dan cari serta ganti terus dalam kod anda. nullableoverridehtmlspecialchars
;然后在添加 use function nullableoverridehtmlspecialchars;
akan menggunakan fungsi itu dan bukannya fungsi terbina dalam. Ini mesti ditambahkan pada setiap fail, walaupun, jadi anda mungkin memerlukan alat untuk menambahkannya secara automatik. ?? ''
secara automatik pada panggilan fungsi yang sesuai supaya anda tidak perlu mengeditnya secara manual. Malangnya, nampaknya masih belum ada peraturan terbina dalam untuk ini, jadi anda perlu belajar menulis sendiri. ?? ''
pada kes mudah.