intvalとint-`(int)X`へのキャストの間に特別な違いはありますか?


219

intvalと(int)の間に特別な違いはありますか?

例:

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

上記の2行のコード間に特別な違いはありますか?

回答:


192

intval()変換元のベース渡すことができます。(int)できません。

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

73
wiki.phpbb.com/Best_Practices:PHPによると、(int)はintval()よりも高速です
Martin Thoma

本日前に述べたように、引数がintまたはfloatの場合、ベース変換は期待どおりに機能しません。
t-dub

1
そのページの状態を示す@moose は赤$i++正しくありません。しかし、それは遅くなるはずです!!
Shiplu Mokaddim、2012

1
私は決して話さなかった$i++。どういう意味ですか?「でも遅いほうがいい!!」何を比較しますか?
マーティントーマ

6
私はideoneでベンチマークを行いました- (int)タイプキャストは2倍高速です! (int)ideone.com/QggNGcintval()ideone.com/6Y8mPN
jave.web

52

(int)and intval():の違いについて注意すべき点の1つは、ベース引数に関係なく、少なくともsとsであるintval()変数を変換する必要がないものとして扱います(少なくともPHP 5.3.5以降)。PHP docページのコメントに記載されているように、この動作は最も明白ではありません。intfloat

$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はないと言うThe base parameter has no effect unless the var parameter is a string.ので、おそらくのが追加されたものということ、そして、再びページは明らかに4日前に更新されました。
オービットのライトネスレース


6
関数が理論的にベース変換を実行できるという事実を考えると、文書化されているかどうかにかかわらず、動作は少し驚くべきものです。それは間違いなく以前に私をつまずきました、しかしおそらくおそらく私はもう少し慎重にRTFMをする必要があります:)
t-dub

7
私はこれが古いスレッドであることを理解しています。まだプログラミングをしているのであれば、これが実際に最も明白な結果である理由を理解していただければ幸いです。baseは文字列表現でのみ使用されるため、intにはbaseがありません。より簡単に言えば、基数10の12のintは、基数99の12のintと同じです。それでも12です。intval(12,8)フォーマットなしの文字列に変換すると、基数8のように見えるという答えを与える期待数が間違っている。intval(12,16)intを作成できないため、何を期待しcますか?
Robert McKee

1
または別の方法で... 1970年1月1日から1523994328ティックがありました。それがMM / DD / YYYYまたはDD / MM / YYYYとして保存されているかどうかを確認しても、どちらの形式でも保存されていないため意味がありません。特定の日付形式ではなく、数値として保存されます。intのベースが何であるかを尋ねるのと同じ方法。値を表示形式から分離することは非常に重要です。
ロバートマッキー

32

ネクロでごめんなさい、PHP7がこの質問に影響するかどうか/どのように影響するのかを見たかっただけです。

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

テスト:

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"

ご覧のとおり、キャストは間違いなくほぼ 100%高速です

しかし、違いがほんの数秒になる前に、ループ数を1億個に増やす必要がありました。これは、ほとんどの場合、実際にパフォーマンスを気にし始める時期です。

したがってintval、キャスティングは現在起こっている言語の魔法のビットなので、関数の使用に固執します。場合であってもintvalバグがあるとしたら、舞台裏キャストの用途は鋳物で発見し、それが修正されることができなかったいくつかの理由(後方互換性?)のために、それらは少なくとも修正で可能性がありintval、それの義務を実行します。

アップデート(PHP 7.1 +追加ケース):

$ 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に最適化されたように見えintval、「1」+ 0がこのスピードコンテストの勝者になりました:) intvalとにかく使い続けます


1
残っている唯一のベンチマーク+0はvarです...ここでの暗黙のキャストが明示的なキャストよりも速いかどうかはわかりません。
SparK 16

2
LOL @ +0勝利...それは非常に汚いハックです
SparK

@SparKあなたのアイデア:)私はそれを信用しませんが、PHPの型キャストルールは完全に最適ではありません
Populus

以下のためにv5.5.34私の結果だった9191.0059452057 ms23307.397127151 ms11483.719110489 msそれぞれ。したがって、PHP 7より前のバージョンでは、キャストが最速です。
GreeKatrina 2016

あまり理解しにくいですが$a = '1' + 0;、私はそのようにすることはほとんど考えていませんでした
マイク

26

少なくとも1つの違いがあると思います:intvalでは、2番目のパラメーターとして使用するベースを指定できます(デフォルトではベース10)。

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

あなたを取得します:

int 123
int 123
int 83

11
:Iそれは信じられないほどの1がベース17数「g」は小数に変換できることを楽しま見つけるintval("2g", 17) = 50 = 2*17 + 16
JSchaefer

1
@JSchaeferさらに試してみたところ36、のように、ベースとして渡すことができる最大値はであることがわかりましたintval("g", 36) //16。36より大きい値は0を返します。これは、カスタムベースに0〜9とa〜zのすべての文字を使用できることを示唆していintval("z",36) //35ます。また、最初のパラメータは大文字と小文字を区別しないことに注意してください。
Jay Dadhania、

17

の便利なプロパティの1つintvalは、これは関数であり、言語構造ではないため、関数を必要とする関数に引数として渡すことができることです。でこれを行うことはできません(int)

たとえば、整数をにIN()渡してSQL 句に含めるために整数を無害化するために使用しましたarray_map。次に例を示します。

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

コールバックとしての匿名関数:array_map(function($n){return (int)$n;}, $_POST['array_of_integers'])
Daniel Omine

@DanielOmineコールバック関数を定義しなくても使用できることを意味しました。
Kodos Johnson、2016

15

アンバーは正しいですし、有用な情報型のキャストを追加する場合(式の前に "(int)"を追加する)は、intvalより300〜600%高速です。したがって、10進数以外の基数を処理することが目的でない場合は、次の使用をお勧めします。 (int) $something


2
あなたが興味深い見つけるかもしれない何か:programmers.stackexchange.com/questions/99445/...
ジェリー

8

intvalの単純なキャストがないというんは、ベースの変換です。

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

ただし、ベースが10の場合はintval、キャストと同じにする必要があります(細心の注意を払い、一方が関数呼び出しを行い、もう一方が呼び出さないことを説明する場合を除きます)。manページに記載されているように:

整数キャストの一般的なルールが適用されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.