İntval ve int - `(int) X` e döküm arasında belirli bir fark var mı?


219

İntval ve (int) arasında belirli bir fark var mı?

Misal:

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

Yukarıdaki iki kod satırı arasında belirli bir fark var mı?

Yanıtlar:


192

intval()edilebilir bir baz geçirilen dönüştürmek için. (int)olumsuz.

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

73
(int) 'e göre, daha hızlı) (intval daha wiki.phpbb.com/Best_Practices:PHP
Martin Thoma

Ben şöyle aşağıda belirtildiği bugün erken, temel dönüşüm argüman bir int veya şamandıra ise beklendiği gibi çalışmaz.
t-dub

1
Bu sayfa durumlarını @moose $i++olduğu yanlış kırmızı. Ama daha yavaş olmalı !!
Shiplu Mokaddim

1
Hiç konuşmadım $i++. Ne demek istiyorsun? "Ama daha yavaş olmalı!" neyi karşılaştırıyorsun
Martin Thoma

6
Ben ideone üzerinde kıyaslama yaptım - (int)typecast daha hızlı x 2! (int): İdeone.com/QggNGc , intval(): ideone.com/6Y8mPN
jave.web

52

Arasındaki fark hakkında nota bir şey (int)ve intval(): intval()davranır zaten değişkenler ints ve float(en azından PHP 5.3.5 itibariyle) bakılmaksızın taban argümanının, hiçbir dönüşüm ihtiyacı olarak bu. Bu davranış, PHP doc sayfasındaki yorumlarda belirtildiği ve burada utanmadan tekrarlandığı gibi en bariz değildir :

$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?

13
Doc diyor ki The base parameter has no effect unless the var parameter is a string.Sonra tekrar sayfa dört gün önce güncellendi, bu yüzden belki de bu eklendi.
Orbit'te Hafiflik Yarışları


6
Belirgin bir şekilde belgelenmiş olsun ya da olmasın, fonksiyonun teorik olarak temel dönüşüm yapabileceği göz önüne alındığında, davranış biraz şaşırtıcıdır. Kesinlikle beni daha önce açtı, ama belki de sadece biraz daha dikkatli RTFM gerekiyor :)
t-dub

7
Bunun eski bir iş parçacığı olduğunu anlıyorum ve hala programlama yapıyorsanız, umarım şimdi bunun neden en açık sonuç olduğunu görüyorsunuz. Bir int'in tabanı yoktur, çünkü base yalnızca string gösterimlerinde kullanılır. Veya daha basit bir şekilde, taban 10'daki 12'lik bir int, taban 99'daki 12'lik bir int ile aynıdır. Hala 12'dir. intval(12,8)Biçimlendirmesi olmayan bir dizgiye dönüştürüldüğünde taban 8'e benzeyeceği beklentisi. sayı sadece yanlış. Ne umuyorsunuz intval(12,16)çünkü bir int a yapamıyor c?
Robert McKee

1
Ya da başka bir yol ... 1 Ocak 1970'ten beri 1523994328 keneler oldu. Bunun MM / DD / YYYY veya DD / MM / YYYY olarak depolanıp depolanmadığını sormak mantıklı değil çünkü bu formatların hiçbirinde saklanmadı. Herhangi bir tarih biçiminde değil, sayı olarak saklanır. Bir int'in tabanının ne olduğunu sormakla aynı şekilde. Değerleri görüntülendikleri formattan ayırmak oldukça önemlidir.
Robert McKee

32

Necroing için üzgünüm, sadece PHP7 bu soru üzerinde bir etkisi olup olmadığını görmek istedim:

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

Test:

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"

Gördüğünüz gibi, döküm yoluyla, kesinlikle hızlıdır neredeyse % 100

Ancak, fark saniye cinsinden dönmeden önce döngü sayısını 100 milyona yükseltmek zorunda kaldım, bu da çoğu durumda performansla ilgilenmeye ne zaman başlayacağım.

Bu yüzden intvalişlevi kullanmaya devam edeceğim , çünkü döküm biraz dil büyüsü oluyor. intvalPerde arkasında döküm kullansa bile , dökümde bir hata bulunsaydı ve bir nedenden dolayı düzeltilemedi (geriye uyumluluk?), O zaman en azından intvalgörevini yerine getirmek için düzeltebilirlerdi .

Güncelleme (PHP 7.1 + Ekstra durum):

$ 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"

7.1 optimize edilmiş gibi görünüyor intvalve '1' + 0 şimdi bu hız yarışmasının galibi :) intvalYine de kullanmaya devam ediyorum


1
geriye kalan tek kriter +0var ... Buradaki örtük almanın açık olandan daha hızlı olup olmadığından emin değil.
SparK

2
LOL @ +0kazanıyor ... bu çok kirli bir
saldırı

@ Fikrinizi bozun :) Yine de güvenmezdim, PHP'nin tür döküm kuralları tam olarak en iyisi değil
Populus

For v5.5.34my sonuçları vardı 9191.0059452057 ms, 23307.397127151 msve 11483.719110489 mssırasıyla. PHP 7'den önce döküm en hızlısıdır.
GreeKatrina

Ben çok daha az anlaşılır olmasına rağmen $a = '1' + 0;ve ben en çok böyle yapmayı hiç düşünmemiştim
mic

26

En az bir fark olduğunu düşünüyorum: intval ile , ikinci bir parametre (varsayılan olarak temel 10) olarak hangi bazın kullanılması gerektiğini belirtebilirsiniz:

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

Seni alacak :

int 123
int 123
int 83

11
Ben bir temel 17 sayı "g" ondalık dönüştürmek inanılmaz eğlenceli buluyorum:intval("2g", 17) = 50 = 2*17 + 16
JSchaefer

1
@JSchaefer Daha da ileri götürdüm ve baz olarak geçebileceğim maksimumun 36, olduğu gibi olduğunu buldum intval("g", 36) //16. 36'dan büyük herhangi bir değer 0 döndürür. Bu, özel tabanımız için 0-9 artı az karakterinin tümünü kullanabileceğimizi gösterir intval("z",36) //35. Ayrıca, ilk parametrenin büyük / küçük harfe duyarlı olmadığı da belirtilmelidir .
Jay Dadhania

17

Kullanışlı bir özelliği intval- bir dil yapısı değil, bir işlev olduğu için - bir işlev bekleyen bir işleve argüman olarak aktarılabilmesidir. Bunu ile yapamazsın (int).

Örneğin, bir SQL IN()yan tümcesine dahil etmek için tamsayıları sterilize etmek için kullandım array_map. İşte bir örnek:

$ids = implode(",", array_map('intval', $_POST['array_of_integers']));
$sql = "SELECT * FROM table WHERE ids IN ($ids)";

Geri arama olarak anonim işlev:array_map(function($n){return (int)$n;}, $_POST['array_of_integers'])
Daniel Omine

@DanielOmine Geri arama işlevini tanımlamak zorunda kalmadan kullanabileceğinizi kastediyorum.
Kodos Johnson

15

Amber haklı ve yararlı bir bilgi türü ekleyebilirsem (ifadenizden önce "(int)" eklemek) aralıktan% 300 ila 600 daha hızlıdır. Amacınız ondalık sayının dışında başka üslerle uğraşmak değilse, şunları kullanmanızı öneririm: (int) $something


2
İlginç bulabileceğiniz bir şey: programmers.stackexchange.com/questions/99445/…
Gerry

8

Şey intvalbasit bir döküm yok bunu yapmaz baz dönüşüm:

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

Tabanı 10 ise, intvalbir döküm ile aynı olmalıdır (eğer nitpicky olmayacak ve biri değilken bir işlev çağrısı yapmak söz sürece). Üzerinde belirtildiği gibi adam sayfası :

Ortak tamsayı döküm kuralları geçerlidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.