Saya memiliki potongan kode berikut:
$item['price'] = 0;
/* Code to get item information goes in here */
if($item['price'] == 'e') {
$item['price'] = -1;
}
Ini dimaksudkan untuk menginisialisasi harga item ke 0 dan kemudian mendapatkan informasi tentangnya. Jika harga diinformasikan sebagai 'e' itu berarti pertukaran, bukan penjualan, yang disimpan dalam database sebagai angka negatif.
Ada juga kemungkinan untuk meninggalkan harga sebagai 0, baik karena item tersebut adalah bonus atau karena harga akan ditetapkan nanti.
Namun, setiap kali harga tidak disetel, yang meninggalkannya dengan nilai awal 0, if
loop yang ditunjukkan di atas mengevaluasi sebagai benar dan harga disetel ke -1. Artinya, ia menganggap 0 sama dengan 'e'.
Bagaimana ini bisa dijelaskan?
Jika harga diberikan sebagai 0 (setelah inisialisasi), perilakunya tidak menentu: terkadang if dievaluasi sebagai benar, terkadang dievaluasi sebagai salah. *
if((string)$item['price'] == 'e')
memperbaiki perilaku aneh. Lihat stackoverflow.com/a/48912540/1579327 untuk lebih jelasnyaJawaban:
Anda melakukan
==
yang memilah jenis untuk Anda.0
adalah int, jadi dalam hal ini akan dilemparkan'e'
ke int. Yang tidak dapat diuraikan menjadi satu dan akan menjadi0
. Sebuah string'0e'
akan menjadi0
dan akan cocok!Menggunakan
===
sumber
Ini karena bagaimana PHP melakukan operasi
==
perbandingan yang ditunjukkan oleh operator pembanding :Karena operan pertama adalah angka (
0
) dan yang kedua adalah string ('e'
), string juga diubah menjadi angka (lihat juga Tabel Perbandingan dengan Berbagai Jenis ). Halaman manual pada tipe data string mendefinisikan bagaimana konversi string ke angka dilakukan:Dalam hal ini string adalah
'e'
dan karenanya akan dievaluasi sebagai pelampung:Karena
'e'
tidak dimulai dengan data numerik yang valid, ia mengevaluasi ke float0
.sumber
mengevaluasi
true
karena pertama"ABC"
diubah menjadi bilangan bulat dan menjadi0
kemudian dibandingkan dengan0
.Ini adalah perilaku aneh dari bahasa PHP: biasanya seseorang diharapkan
0
untuk dipromosikan menjadi string"0"
dan kemudian dibandingkan"ABC"
dengan hasilfalse
. Mungkin itulah yang terjadi dalam bahasa lain seperti JavaScript di mana"ABC" == 0
evaluasi perbandingan lemahfalse
.Melakukan perbandingan yang ketat menyelesaikan masalah:
mengevaluasi
false
.Tetapi bagaimana jika saya perlu membandingkan angka sebagai string dengan angka?
mengevaluasi
false
karena suku kiri dan kanan memiliki tipe yang berbeda.Apa yang sebenarnya dibutuhkan adalah perbandingan yang lemah tanpa perangkap juggling tipe PHP.
Solusinya adalah dengan mempromosikan istilah secara eksplisit menjadi string dan kemudian melakukan perbandingan (ketat atau lemah tidak masalah lagi).
adalah
true
sementara
adalah
false
Diterapkan ke kode asli:
sumber
Operator == akan mencoba mencocokkan nilai meskipun nilainya berbeda. Misalnya:
Jika Anda juga membutuhkan perbandingan jenis, gunakan operator ===:
sumber
Masalah Anda adalah operator yang sama ganda, yang akan mengetikkan anggota kanan ke jenis kiri. Gunakan yang ketat jika Anda mau.
Mari kembali ke kode Anda (disalin di atas). Dalam kasus ini, dalam banyak kasus, $ item ['price'] adalah integer (kecuali jika sama dengan e, tentunya). Dengan demikian, berdasarkan hukum PHP, PHP akan melakukan typecast
"e"
ke integer, yang menghasilkanint(0)
. (Jangan percaya padaku?<?php $i="e"; echo (int)$i; ?>
).Untuk dengan mudah lolos dari ini, gunakan operator triple equal (perbandingan tepat), yang akan memeriksa jenis dan tidak akan typecast secara implisit.
PS: fakta menyenangkan PHP:
a == b
tidak menyiratkan itub == a
. Ambil contoh Anda dan balikkan:if ("e" == $item['price'])
tidak akan pernah benar-benar terpenuhi asalkan $ item ['price'] selalu berupa bilangan bulat.sumber
Ada metode yang agak berguna dalam PHP untuk memvalidasi campuran "0", "false", "off" as == false dan "1", "on", "true" as == true yang sering diabaikan. Ini sangat berguna untuk mengurai argumen GET / POST:
Ini tidak sepenuhnya relevan dengan kasus penggunaan ini, tetapi mengingat kesamaan dan fakta ini adalah hasil pencarian yang cenderung ditemukan ketika mengajukan pertanyaan untuk memvalidasi (string) "0" sebagai salah, saya pikir itu akan membantu orang lain.
http://www.php.net/manual/en/filter.filters.validate.php
sumber
Anda harus menggunakan
===
bukan==
, karena operator biasa tidak membandingkan tipe. Sebaliknya itu akan mencoba untuk mengetikan item.Sementara itu
===
mempertimbangkan jenis barang.===
berarti "sama dengan",==
artinya "eeeeh .. agak mirip"sumber
if((string)$item['price']=='e'){ $item['price'] = -1; }
===
operatorSaya pikir yang terbaik adalah menunjukkan dengan contoh yang saya lakukan, sambil mengalami perilaku aneh yang sama. Lihat kasus pengujian saya dan semoga ini akan membantu Anda memahami perilakunya dengan lebih baik:
sumber
Pada dasarnya, selalu gunakan
===
operator, untuk menjamin keamanan tipe.sumber