Intereting Posts
PHPUnit утверждает, что не вызывается метод Получение: допустимый объем памяти 33554432 байт исчерпан Невозможно получить доступ к объявленной глобальной переменной в WordPress Выйдите из формы в Laravel Получить версию расширения в php Каков наилучший способ передать HTML-код для встраивания через rss-канал в rss-парсер в php? PHP: Самый безопасный (дешифруемый) метод шифрования? PHP не может инициализировать модуль zorba_api Параметры в выражении выбора DQL (Symfony2 / Doctrine) Как запросить встроенные документы ссылочным документом? Как получить ошибку, если FTP-сервер недействителен.? Включая разрывы строк и маркеры в функции графического сообщения Facebook Что такое PHP как «Персональная домашняя страница» и «Препроцессор гипертекста PHP»? Получение типа mime из имени файла в php Использование mod_rewrite для преобразования путей с хэш-символами в строки запроса

Понимание приведения типа PHP

Я видел эту небольшую часть кода, которая уклоняется от моего понимания:

<?php $a = '0e462097431906509019562988736854'; $b = '0e830400451993494058024219903391'; var_dump($a == $b); 

Что будет выводить:

 bool(true) 

Я понимаю, что при использовании == PHP будет пытаться нечеткое сравнение, без малейшего преобразования между типами для выполнения сравнения. Я не понимаю, почему PHP, похоже, думает, что эти две строки одинаковы. Я бы подумал, так как $a и $b являются строками, что преобразование типа не должно происходить.

Что я не понимаю?

Я думаю, эта статья объясняет это довольно хорошо:

Операторы сравнения типа-принуждения преобразуют числовые строки в числа

Просто процитируем главный вопрос здесь:

Согласно php language.operators.comparison , операторы сравнения типа принуждения будут принуждать оба операнда к float, если они оба выглядят как числа, даже если они оба уже являются строками:

где обе strings используют экспоненциальную нотацию, поэтому рассматриваются как числовые строки, делая свободное сравнение ( == ), принуждая эти strings floats прежде чем фактически «свободно» их сравнивать.

В качестве наилучшей практики и предотвращения неожиданного поведения всегда старайтесь использовать равенство идентичности ( === ), особенно при работе со strings

На самом деле это не ответ, но если вы попробуете:

 $a = '0e4620974319065090195629887368549'; $b = '0e8304004519934940580242199033918'; echo floatval($a) . '<br>' . floatval($b);var_dump($a == $b); 

Вы получаете:

0

0

BOOL (истина)

Теперь, если вы попробуете:

 $a = '0e4620974319065090195629887368549'; $b = '1e8304004519934940580242199033918'; echo floatval($a) . '<br>' . floatval($b);var_dump($a == $b); 

Вы получаете:

0

INF

BOOL (ложь)

Я предполагаю, что PHP преобразует строки в float и дает результат сравнения, используя полученные поплавки, которые в любом случае не верны, но это еще одна история.

В официальной документации проверка равенства между двумя vairiables производится следующим образом:

 $a == $b # Equal TRUE if $a is equal to $b after type juggling. 

Пример :

 $a = 13; # integer type $b = "13"; # string type var_dump($a == $b); # will say TRUE, because juggling was made var_dump($a === $b); # will say FALSE, because PHP will also evaluate the type of variables :) 

PHP пытается преобразовать в тип float, потому что строка начинается с 0. Она останавливается после 0, потому что следующий символ не является числом. То же самое происходит, когда вы используете принуждение типа для преобразования научной нотации в integer:

 $x = (float)"12E-1x"; // $x == 1.2 $x = (int)"12E-1x"; // $x == 12 (stops at E because it's not an integer)