Apakah ada perbedaan khusus antara intval dan casting ke int - `(int) X`?

219

Apakah ada perbedaan khusus antara intval dan (int)?

Contoh:

$product_id = intval($_GET['pid']);
$product_id = (int) $_GET['pid'];

Apakah ada perbedaan khusus antara dua baris kode di atas?

Sarfraz
sumber

Jawaban:

192

intval()dapat melewati basis yang akan dikonversi. (int)tidak bisa.

int intval( mixed $var  [, int $base = 10  ] )
Amber
sumber
73
(int) lebih cepat daripada intval (), menurut wiki.phpbb.com/Best_Practices:PHP
Martin Thoma
Seperti yang saya catat di bawah sebelumnya hari ini, konversi basis tidak berfungsi seperti yang diharapkan jika argumennya int atau float
t-dub
1
@ begitu, status halaman $i++itu salah dalam warna merah. Tapi itu harus lebih lambat !!
Shiplu Mokaddim
1
Saya tidak pernah berbicara tentang $i++. Maksud kamu apa? Ketika Anda mengatakan "Tapi itu harus lebih lambat !!" apa yang kamu bandingkan
Martin Thoma
6
Saya melakukan benchmarking pada ideone - (int)typecast lebih cepat x 2! (int): Ideone.com/QggNGc , intval(): ideone.com/6Y8mPN
jave.web
52

Satu hal yang perlu diperhatikan tentang perbedaan antara (int)dan intval(): intval()memperlakukan variabel yang sudah intdan floattidak memerlukan konversi, terlepas dari argumen dasar (setidaknya untuk PHP 5.3.5). Perilaku ini bukan yang paling jelas, seperti yang tercantum dalam komentar di halaman PHP doc dan tanpa malu-malu mengulangi di sini:

$test_int    = 12;
$test_string = "12";
$test_float  = 12.8;

echo (int) $test_int;         // 12
echo (int) $test_string;      // 12
echo (int) $test_float;       // 12

echo intval($test_int, 8);    // 12 <-- WOAH!
echo intval($test_string, 8); // 10
echo intval($test_float, 8)   // 12 <-- HUH?
t-dub
sumber
13
Dokter itu mengatakan The base parameter has no effect unless the var parameter is a string.Kemudian lagi halaman itu tampaknya diperbarui empat hari yang lalu, jadi mungkin itulah yang ditambahkan.
Lightness Races di Orbit
3
Hmm, tidak. Ini telah didokumentasikan dengan jelas selama hampir 11 tahun .
Lightness Races dalam Orbit
6
Didokumentasikan dengan jelas atau tidak, perilaku ini sedikit mengejutkan mengingat fakta bahwa fungsi tersebut secara teoritis dapat melakukan konversi basis. Itu benar-benar membuat saya tersandung sebelumnya, tapi mungkin saya hanya perlu RTFM sedikit lebih hati-hati :)
t-dub
7
Saya menyadari ini adalah utas lama, dan jika Anda masih pemrograman, maka saya harap Anda sekarang melihat mengapa ini sebenarnya hasil yang paling jelas. Int tidak memiliki basis karena basis hanya digunakan dalam representasi string. Atau lebih tepatnya, int 12 di basis 10 sama dengan int 12 di basis 99. Masih 12. Harapan yang intval(12,8)akan memberikan jawaban bahwa ketika dikonversi ke string tanpa format akan terlihat seperti basis 8 jumlahnya salah. Apa yang Anda harapkan dari intval(12,16)karena tidak bisa membuat int c?
Robert McKee
1
Atau dengan cara lain ... Ada 1523994328 kutu sejak 1 Januari 1970. Bertanya apakah itu disimpan sebagai MM / DD / YYYY atau DD / MM / YYYY tidak masuk akal karena tidak disimpan dalam salah satu format tersebut. Ini disimpan sebagai angka, bukan dalam format tanggal tertentu. Cara yang sama seperti bertanya apa dasar sebuah int. Memisahkan nilai dari format yang ditampilkannya cukup penting.
Robert McKee
32

Maaf untuk necroing, saya hanya ingin melihat apakah / bagaimana PHP7 berpengaruh pada pertanyaan ini:

$ php -v
PHP 7.0.4-5+deb.sury.org~trusty+1 (cli) ( NTS )

Ujian:

php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = (int) '1'; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "3279.1121006012 ms"
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = intval('1'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "5379.3351650238 ms"

Seperti yang Anda lihat, casting jelas lebih cepat, hampir 100%

Tetapi saya harus meningkatkan jumlah loop menjadi 100 juta sebelum perbedaannya hanya dalam hitungan detik, yaitu ketika saya akan benar-benar mulai memperhatikan kinerja, dalam banyak kasus.

Jadi saya akan tetap menggunakan intvalfungsi, karena casting adalah sedikit keajaiban bahasa yang terjadi. Bahkan jika intvalmenggunakan casting di belakang layar, jika ada bug yang ditemukan dengan casting, dan untuk beberapa alasan itu tidak bisa diperbaiki (kompatibilitas mundur?), Maka mereka setidaknya bisa memperbaiki intvaluntuk melakukan tugasnya.

Pembaruan (PHP 7.1 + Kasing ekstra):

$ php -v
PHP 7.1.0RC6 (cli) (built: Nov  9 2016 04:45:59) ( NTS )
$ php -a
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = (int) '1'; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "3583.9052200317 ms"
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = intval('1'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "3569.0960884094 ms"
php > $start_ts = microtime(true); for($i = 0; $i < 100000000; $i++) { $a = '1' + 0; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "1641.7920589447 ms"

Tampak seperti 7.1 dioptimalkan intval, dan '1' + 0 sekarang pemenang kontes kecepatan ini :) aku masih tetap menggunakan intvalpula

Populus
sumber
1
satu-satunya tolok ukur yang tersisa adalah ke +0var ... tidak yakin apakah pemeran implisit di sini lebih cepat daripada yang eksplisit.
SparK
2
LOL @ +0menang ... itu hack sangat kotor
SparK
@Taruh ide Anda :) Saya tidak akan mempercayainya, aturan ketik casting PHP bukan yang terbaik
Populus
Untuk v5.5.34hasil saya berada 9191.0059452057 ms, 23307.397127151 msdan 11483.719110489 msmasing-masing. Jadi sebelum PHP 7, casting adalah yang tercepat.
GreeKatrina
Meskipun itu jauh kurang dimengerti saya suka $a = '1' + 0;dan saya yakin paling tidak pernah berpikir untuk melakukannya seperti itu
mic
26

Saya pikir setidaknya ada satu perbedaan: dengan intval , Anda dapat menentukan basis mana yang harus digunakan sebagai parameter kedua (basis 10 secara default):

var_dump((int)"0123", intval("0123"), intval("0123", 8));

akan membuat Anda:

int 123
int 123
int 83
Pascal MARTIN
sumber
11
Saya merasa sangat lucu bahwa seseorang dapat mengubah basis nomor 17 "g" menjadi desimal:intval("2g", 17) = 50 = 2*17 + 16
JSchaefer
1
@ JSchaefer Saya mengambilnya lebih jauh, dan menemukan bahwa maksimum yang saya bisa lewati sebagai pangkalan adalah 36, seperti di intval("g", 36) //16. Nilai apa pun yang lebih besar dari 36 menghasilkan 0. Itu menunjukkan bahwa kami dapat menggunakan semua 0-9 plus karakter az untuk basis kustom kami, seperti intval("z",36) //35. Juga, perlu dicatat bahwa parameter pertama adalah case-insensitive .
Jay Dadhania
17

Salah satu properti yang berguna intvaladalah bahwa - karena ini adalah fungsi dan bukan konstruksi bahasa - dapat dilewatkan sebagai argumen ke fungsi yang mengharapkan fungsi. Anda tidak dapat melakukan ini dengan (int).

Sebagai contoh, saya telah menggunakannya untuk membersihkan integer untuk dimasukkan ke dalam IN()klausa SQL dengan meneruskannya ke array_map. Berikut ini sebuah contoh:

$ids = implode(",", array_map('intval', $_POST['array_of_integers']));
$sql = "SELECT * FROM table WHERE ids IN ($ids)";
Kodos Johnson
sumber
anonim berfungsi sebagai callback:array_map(function($n){return (int)$n;}, $_POST['array_of_integers'])
Daniel Omine
@DanielOmine Maksud saya Anda dapat menggunakannya tanpa harus mendefinisikan fungsi panggilan balik.
Kodos Johnson
15

Kuning benar dan jika saya dapat menambahkan jenis informasi yang berguna casting (menambahkan "(int)" sebelum ekspresi Anda) adalah 300 hingga 600% lebih cepat dari intval. Jadi, jika tujuan Anda bukan untuk berurusan dengan basis selain desimal, saya sarankan menggunakan: (int) $something

user900469
sumber
2
Sesuatu yang mungkin menarik bagi Anda: programmers.stackexchange.com/questions/99445/…
Gerry
8

Hal yang intvaltidak dilakukan oleh pemeran sederhana adalah konversi basis:

int intval ( mixed $var [, int $base = 10 ] )

Jika basisnya 10, intvalharus sama dengan gips (kecuali Anda akan menjadi nitpicky dan menyebutkan bahwa satu membuat panggilan fungsi sementara yang lain tidak). Seperti yang tercantum pada halaman manual :

Aturan umum dari integer casting berlaku.

menipu
sumber