Как это !(true || false) === true?

Какие-то чудеса начались сегодня. Запускаю проект на Symfony через app_dev.php, а мне пишет:
You are not allowed to access this file. Check app_dev.php for more information.


Смотрю: написано:

if (isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || !(in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1']) || PHP_SAPI === 'cli-server')
) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}


Запускаю дебаггер, проверяю каждое выражение в условии - везде false, но в тело if заходит. Ладно, добавляю дамп:
var_dump(
    isset($_SERVER['HTTP_CLIENT_IP']),
    isset($_SERVER['HTTP_X_FORWARDED_FOR']),
    !(in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1']) || PHP_SAPI === 'cli-server'));


Выдаёт:

E:\Program Files\Apache24\htdocs\organizer.local\web\app_dev.php:16:boolean false
E:\Program Files\Apache24\htdocs\organizer.local\web\app_dev.php:16:boolean false
E:\Program Files\Apache24\htdocs\organizer.local\web\app_dev.php:16:boolean true
You are not allowed to access this file. Check app_dev.php for more information.


Ок, разбираюсь с компонентами третьего условия, которое с инверсией вернуло true:
var_dump(in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1']), PHP_SAPI === 'cli-server');


Пишет:

E:\Program Files\Apache24\htdocs\organizer.local\web\app_dev.php:15:boolean true
E:\Program Files\Apache24\htdocs\organizer.local\web\app_dev.php:15:boolean false
You are not allowed to access this file. Check app_dev.php for more information.


Странно, не правда ли? !(true or false) должно вернуть false.

Проверяем:

var_dump(in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1']), PHP_SAPI === 'cli-server');
var_dump(!(in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1']) || PHP_SAPI === 'cli-server'));


E:\Program Files\Apache24\htdocs\organizer.local\web\app_dev.php:15:boolean true
E:\Program Files\Apache24\htdocs\organizer.local\web\app_dev.php:15:boolean false
E:\Program Files\Apache24\htdocs\organizer.local\web\app_dev.php:16:boolean true


Опа! Неожиданный результат. Причем в дебаггере он не воспроизводится (с помощью evaluate expression).

Что за чертовщина, товарищи??

P.S. Чуть покопавшись, заметил, что после изменения скрипта при первом запуске всё работает как надо, а без Opcache такой ерунды вообще не происходит. Что бы это значило?

Apache 2.4.27 x64/PHP 7.2.0b1 x64 TS @ Windows 10 x64
  • Вопрос задан
  • 316 просмотров
Решения вопроса 3
alexey-m-ukolov
@alexey-m-ukolov Куратор тега PHP
isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || !(in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1']) || PHP_SAPI === 'cli-server')


false
    || false
    || !(false || false)


false
    || false
    || !false


false
    || false
    || true


true

P.S. А дебажили вы неправильно - почему вдруг в var_dump !in_array() появилось, если выражение оригинальное другое совсем.
Ответ написан
Audiophile
@Audiophile Автор вопроса
Оказался баг PHP Opcache. Уже исправили в 7.2.0-dev
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы