Есть ли какая-то особая разница между intval и приведением к int - `(int) X`? - PullRequest
203 голосов
/ 16 декабря 2009

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

Пример:

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

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

Ответы [ 7 ]

177 голосов
/ 16 декабря 2009

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

int intval( mixed $var  [, int $base = 10  ] )
48 голосов
/ 19 октября 2011

Следует обратить внимание на разницу между (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?
24 голосов
/ 16 декабря 2009

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

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

даст вам:

int 123
int 123
int 83
23 голосов
/ 11 марта 2016

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

14 голосов
/ 18 августа 2011

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

12 голосов
/ 11 августа 2016

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

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

$ids = implode(",", array_map('intval', $_POST['array_of_integers']));
$sql = "SELECT * FROM table WHERE ids IN ($ids)";
8 голосов
/ 16 декабря 2009

То, что intval делает, чего не делает простое приведение, - это базовое преобразование:

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...