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

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

Пример:

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

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

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

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

Одна вещь, чтобы отметить разницу между (int) и intval() : intval() обрабатывает переменные, которые уже являются int s и float s, которые не нуждаются в преобразовании, независимо от базового аргумента (по крайней мере, от 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? 

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

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

вы получите:

 int 123 int 123 int 83 

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

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

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

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

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

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

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

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

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