Есть ли какая-то особая разница между intval и casting для int - `(int) X`?

Существует ли какая-либо особенность между intval и (int)?

Пример:

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

Есть ли какое-либо конкретное отличие между двумя строками кода?

Ответ 1

intval() может передать базу, из которой можно преобразовать. (int) не может.

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

Ответ 2

Одно замечание о различии между (int) и intval(): intval() обрабатывает переменные, которые уже int и float не нуждаются в преобразовании, независимо от базового аргумента (как и PHP 5.3. 5 по крайней мере). Это поведение не является наиболее очевидным, как отмечено в комментариях на странице документа PHP и бесстыдно повторено здесь:

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

Ответ 3

Я думаю, что существует по крайней мере одно различие: с intval вы можете указать, какая база должна использоваться как второй параметр (базовый 10 по умолчанию):

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

вы получите:

int 123
int 123
int 83

Ответ 4

Извините за некроз, мне просто хотелось узнать, влияет ли 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%

Но мне пришлось увеличить количество циклов до 100 миллионов, прежде чем разница была в считанные секунды, а это касается того, когда я действительно начну заботиться о производительности в большинстве случаев.

Поэтому я буду придерживаться функции intval, потому что кастинг - это немного языковая магия, которая происходит. Даже если intval использует кастинг за кулисами, если есть ошибка, обнаруженная при кастинге, и по какой-то причине она не может быть исправлена ​​(обратная совместимость?), Тогда они могли бы по крайней мере исправить intval для выполнения этой обязанности.

Обновление (PHP 7.1 + Extra case):

$ 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 в любом случае

Ответ 5

Янтарь прав, и если я могу добавить полезную информацию (добавление "(int)" перед вашим выражением) на 300-600% быстрее, чем intval. Поэтому, если ваша цель состоит не в том, чтобы иметь дело с другими базами, а с десятичной точкой, я рекомендую использовать:  (int) $something

Ответ 6

Одно полезное свойство intval заключается в том, что - поскольку это функция, а не языковая конструкция, ее можно передать в качестве аргумента функции, ожидающей функции. Вы не можете сделать это с помощью (int).

Например, я использовал его для дезинфекции целых чисел для включения в предложение SQL IN(), передав его в array_map. Вот пример:

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

Ответ 7

Вещь, которая intval делает, что простой актер не является базовым преобразованием:

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

Если база равна 10, то intval должна быть такой же, как и приведение (если вы не будете nitpicky и укажите, что один делает вызов функции, а другой - нет). Как указано на странице :

Применяются общие правила применения целых чисел.