Есть ли какая - то особая разница между intval и приведением к int - `(int) X`?
есть ли какая-то особая разница между intval и (int)?
пример:
$product_id = intval($_GET['pid']);
$product_id = (int) $_GET['pid'];
есть ли какая-либо особая разница между двумя строками кода выше?
7 ответов
intval()
может быть прошел базовый из чего конвертировать. (int)
не может.
int intval( mixed $var [, int $base = 10 ] )
одна вещь, чтобы отметить о разнице между (int)
и intval()
: intval()
обрабатывает переменные, которые уже int
s и float
s как не нуждающийся в преобразовании, независимо от базового аргумента (по крайней мере, с PHP 5.3.5). Это поведение не является самым очевидным, как отмечено в комментарии на странице PHP doc и бесстыдно повторил здесь:
$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 + дополнительный случай):
$ 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.
Поэтому, если ваша цель-не иметь дело с другими базами, кроме decimal, я рекомендую использовать:
(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
должно совпадать с приведением (если вы не собираетесь быть придирчивым и упомянуть, что один делает вызов функции, а другой нет). Как отмечено на man page:
применяются общие правила целочисленного литья.