Berhijrah ke PHP 8.1 - Bagaimana untuk membetulkan ralat lulus nol kepada parameter yang tidak digunakan - Namakan semula fungsi bina dalam
P粉420868294
P粉420868294 2024-01-10 16:21:21
0
2
496

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.


  1. https://pecl.php.net/package/apd

P粉420868294
P粉420868294

membalas semua(2)
P粉811329034

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

(biasanya) mudah dikesan dalam kod juga. 🎜

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

sebelum
    saya menggunakan trim (). Sebabnya sangat mudah, sekurang-kurangnya dua perkara terlintas di fikiran:
  • trim() a) tidak diperlukan lagi - ia boleh dipadamkan (salah satu pembetulan 李>kegemaran
  • saya: padamkan kod!) - atau - b) Ia
  • sedang
melakukan kerja rentetan, maka saya menghadapi masalah kerana saya tidak mahu apa-apa bukan rentetan hadir. Masalahnya ialah ia secara amnya tidak berfungsi dengan pendekatan senapang patah (Gießkanne sesiapa?).

$mixed 进行修补是完全有效的? ''如果原始使用是字符串或null Adakah tampalan menggunakan $mixed sah sepenuhnya? ''Jika

penggunaan asal ialah rentetan atau 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 error_reporting(php)error_reporting(php) / error_reporting(php-ini) 至少达到通常需要的级别,如果需要进行区分(在生产环境中,E_DEPRECATED 通常不是报告的一部分)。此示例性处理程序会抛出所有报告的错误,对于弃用事件以及 E_ALL 也会抛出此类错误,因此需要 @ / error_reporting(php-ini)

Sekurang-kurangnya ke tahap yang biasanya diperlukan, jika pembezaan diperlukan (dalam persekitaran pengeluaran,

biasanya bukan sebahagian daripada report). Pengendali contoh ini membuang semua ralat yang dilaporkan, serta untuk peristiwa penamatan dan E_ALL, jadi pengendali penindasan

dikehendaki untuk tidak membuang:

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

Walau bagaimanapun, kurang kawalan ke atasnya 🎜 dan 🎜 ia mungkin sudah digunakan oleh kod pihak ketiga yang sudah berada dalam kebergantungan projek. Kod seperti berikut tidak jarang berlaku: 🎜
@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. 🎜
  1. Apabila mempertimbangkan untuk menggunakan @ 错误抑制运算符的方法并对其进行评论时,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粉592085423

Pertama, dua perkara yang perlu diingat:

  1. PHP 8.1 ditamatkan panggilan ini, yang tidak menjadikannya ralat. Tujuan penamatan adalah untuk memberikan notis awal kepada pengarang untuk membetulkan kod mereka, jadi anda dan pengarang perpustakaan yang anda gunakan boleh membetulkan isu sebelum PHP 9.0 dikeluarkan. Oleh itu, jangan panik kerana tidak semua isu boleh diselesaikan dengan segera dan bersabar dengan penyelenggara perpustakaan yang akan menyelesaikan masalah itu pada masa mereka sendiri.
  2. Pembetulan pantas dalam kebanyakan kes ialah menggunakan pengendali penyatuan null untuk memberikan nilai lalai yang sesuai supaya anda tidak memerlukan semakan nol yang panjang setiap kali anda menggunakannya. Contohnya, htmlspecialchars($something) 可以替换为 htmlspecialchars($something ?? '')

Seterusnya, beberapa pilihan:

  • Bergantung pada bilangan kes anda, anda mungkin boleh membetulkan beberapa isu secara manual sekaligus, atau menambah ?? '' atau membetulkan ralat logik, anda tidak mahu batal.
  • Buat fungsi tersuai seperti nullable_htmlspecialchars dan cari serta ganti terus dalam kod anda.
  • Mana-mana fail yang mencipta fungsi ruang nama tersuai seperti 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.
  • Gunakan Rektor untuk menambah ?? '' 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.
  • Mungkin lebih mudah, bergantung pada kemahiran anda, untuk menggunakan ungkapan biasa cari dan ganti untuk menambah ?? '' pada kes mudah.
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan