All streams
Search
Write a publication
Pull to refresh
63
0.5
Михаил @michael_v89

Программист

Send message
Я не говорил про определение реальных событий. Я говорил про соответствие мыслей человека его словам. Если вы сами осознаете, что вчерашнее яблоко это фантазия, то эту информацию можно будет получить независимо от ваших слов.
Так я имею в виду не определение эмоций, как это делают современные детекторы лжи, а полное чтение мыслей и ассоциаций, которые возникают при вопросе. Чтобы абсолютно правдиво ответит «нет», надо понять сам вопрос, произвести анализ, определить соответствие знакомым понятиям и воспоминаниям, и на основе этого выбрать подходящий ответ. Это как если бы он не просто сказал «нет», а подробно объяснил, почему он так считает — «нет, потому что я был в это время в другом месте» или «нет, потому что я взял деньги у богача, который взял деньги у народа, значит там есть и моя часть».
Мм. Ну вот у вас есть код:
<?= $myStringValue ?>

Можно ли заменить обычный оператор на экранирующий? Может там выше по коду уже была вызвана htmlspecialchars(). Или может у нас в переменной хранится уже проверенный HTML из CKEditor. Если в проекте вообще весь код небезопасный, то можно конечно пройтись поиском с автозаменой, но можно поиском и операторы с запятой найти и поправить их.

P.S. Кстати, а у вас в проектах часто встречается вывод через запятую? Может мне просто такие проекты попадались, где одно значение либо конкатенация.
Это будет доказательством того, говорит ли человек то, о чем думает. То есть, как если бы человек прямо сказал — да, я забрал эту вещь, потому что считаю это справедливым перераспределением благ. Насколько он прав, будет решать не прибор для чтения мыслей. Зато можно полностью избежать неопределенности в случаях, когда человек говорит — я ничего не брал, наоборот это он у меня украл, а хочет на меня все свалить.
А причем здесь автозамена? В рабочем коде там стоит htmlspecialchars(), либо приведение к int, либо то же самое сделано выше по коду. Это другой оператор со своим синтаксисом, он не меняет поведение существующего, нет никакой неоднозначности. И я, пожалуй, ни разу не встречал вывод в этом операторе через запятую. А exception да, он при такой замене будет очень полезен.
И что с того, что токен называется так, а не иначе.

То, что любой внешний контент считается HTML. Значит должен быть оператор корректного вывода в этот HTML, так как это очень частая задача. А T_PAAMAYIM_NEKUDOTAYIM сам по себе оператор, и он тут ни при чем. Ну и да, если у кого-то будут задачи, связанные с ним, он тоже может предложить RFC.

Мое мнение что его нужно убрать совсем

Текущий код никуда не денется, его надо поддерживать, значит и операторы переключения контекста никуда не денутся.

Настолько хорошо, что непонятно зачем еще один вариант

Ну вообще-то это написано далее в предложении, в статье, и в других комментах к ней. Новый оператор либо выведет экранированное значение, либо не выведет никакое. И со стандартным оператором они взаимоисключающие, можно написать либо тот, либо другой, а с функцией опасный вариант это короткое подмножество безопасного.
Основная идея

Оператор имеет следующую форму:
<?* $str ?>
<?* $str, 'html' ?>
<?* $str, 'js | html' ?>

Оба выражения могут быть любого типа, который может быть конвертирован в строку. Второе выражение опционально.
Я изменил знак '~' по причине отсутствия в некоторых раскладках клавиатуры, и потому что он является унарным оператором и распознается в предыдущих версиях PHP с включенными короткими тегами как битовая операция.

Оператор компилируется в следующее AST:

echo PHPEscaper::escape(first_argument, second_argument);


Это сделано аналогично обратным кавычкам и shell_exec().

Есть дефолтная реализация класса PHPEscaper. Он имеет 4 статических метода

PHPEscaper::escape($string, $context = 'html');
PHPEscaper::registerHandler($context, $escaper_function);
PHPEscaper::unregisterHandler($context);
PHPEscaper::getHandlers();


Метод PHPEscaper::escape($string, $context) разбивает строку по символу '|', для всех частей делает trim(), и потом вызывает зарегистрированный обработчик для каждого контекста в цепочке. Контекст по умолчанию 'html', он имеет специальную обработку. Если для него нет обработчика, вызывается htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE)

Можно использовать это так:
<?php
    // где-нибудь в приложении, устанавливается 1 раз
    PHPEscaper::registerHandler('html', function($str) {
        return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5 | ENT_DISALLOWED | ENT_SUBSTITUTE);
    });
    PHPEscaper::registerHandler('js', [MyEscaper, 'escapeJs']);
?>
<?* $str, 'js | html' ?>


И даже больше.
В AST название PHPEscaper регистрируется как not fully qualified name (ZEND_NAME_NOT_FQ).
Это позволяет использовать пространства имен и автолоадинг.
<?php use MyEscaper as PHPEscaper; ?>
<?* $str, 'js | html' ?>

Будет вызвано MyEscaper::escape($str, 'js | html').

Таким образом, мы можем иметь автолоадинг, разные контексты, HTML экранирование по умолчанию, и полный контроль и кастомизацию.
Ссылки:

RFC: https://wiki.php.net/rfc/escaping_operator
Коммит с изменениями: github
Первоначальное обсуждение: http://marc.info/?t=146619199100001
Обсуждение RFC: http://marc.info/?t=146868366400003
Попробовал реализовать. Пара мыслей вдогонку.

— В языке не место таким операторам.
Таким операторам не место в C++, или в C#, или в Java. А в самом популярном языке для веб-программирования ему самое место. Даже в исходниках PHP текст вне тегов PHP обозначается T_INLINE_HTML, а не просто T_EXTERNAL_CONTENT.
zend_language_scanner.l

Если бы в PHP не было оператора переключения контекста <?php ?>, то экранирующий оператор тоже был бы не нужен. Но именно это сделало PHP таким, какой он есть. Надо или убрать операторы переключения контекста совсем, или улучшить их использование.

— Зачем в языке нужен оператор для вызова конкретной функции?
Это не оператор для отдельной функции. Это и оператор и функция для часто встречающегося случая.
Кстати, вы не забыли, что в PHP уже есть специальный оператор для вызова конкретной функции?) Обратные кавычки и shell_exec().
zend_language_parser.y

— Зачем делать оператор, чтобы сэкономить пару нажатий на клавиши.
Проблема не в том, сколько клавиш нажимать, а в том, что очень легко сделать неправильно. Варианты <?= h($something) ?> и <?= $something ?> оба работают хорошо, небезопасный вариант работает точно так же, как и безопасный, до тех пор, пока мы не получим небезопасные данные.
Нельзя отрицать, что проблема существует. Это видно по количеству обсуждений этой темы.

— Если делать такой оператор, то нужно сделать работу с разными контекстами
Мне кажется, такой проблемы нет. Потому что — а кто об этом просит?) Нет ни одного фиче-реквеста про специальный оператор для json_encode(), зато есть куча реквестов для htmlspecialchars(). Они тянутся чуть ли не с самого появления PHP.

С другой стороны, все равно нужна возможность задавать разные флаги для html-экранирования. Заодно можно и работу с контекстами добавить. И у меня есть идея, как это можно сделать.
Если будет возможность напрямую читать реакции всех нервных клеток, то, думаю, гипноз ничего не даст. Потому что он не имеет влияния на каждую клетку отдельно, многие связи все равно останутся. Вот если будет возможность напрямую записать, тогда да. Но техническая возможность прочитать мысли и узнать, соответствует ли им то, что человек говорит, от этого не меняется.
Во-первых, мысли и ассоциативные связи все равно возникают. Чтобы они не возникали, нужно, чтобы человек действительно не понимал, о чем его спрашивают (например, если спрашивают на неизвестном ему языке). Во-вторых, обычные детекторы лжи основаны на реакциях тела и кожных покровов, поэтому они считаются только косвенным доказательством. В-третьих, я имел в виду не настоящее время и не ученика в школе, а будущее и раскрытие настоящих преступлений. Думаете, если будет возможность точно узнать, как все было, кто виновен, и избежать риска наказать невиновного, то не сделают соответствующие изменения в законе?

P.S. Разве я где-то предлагал не использовать его ни для чего другого? Узнать правду — это прямое применение чтения мыслей. А бессмертие тут вообще ни при чем. Ну сделаете вы копию вашего сознания в теле робота, что для вас изменится? Да ничего. Если вы порежете палец, больно будет вам, а не копии.
нанороботы, взаимодействуя с корой головного мозга, смогут подключать наше сознание к сети интернет

Тоже думал о таком варианте, только в контексте того, что это можно использовать как универсальный детектор лжи. Позадавали несколько вопросов, проверили мысли, которые при этом возникают, и точно узнали, что это двоечник Вася украл 100 р. из сумочки учительницы, а не отличник Коля, как говорит Вася.
Вы не поняли. Человек написал комментарий по поводу «ощущаю разницу в реакции организма на ночные бдения сейчас и 10 лет назад». Потому и ощущаете, что из-за компьютера не вылазите последние 10 лет.
У меня тоже так бывает, да и думаю у многих. У меня даже есть теория, почему так происходит.
Когда занимаешься задачей, новые данные находятся в оперативной памяти, весь фокус внимания направлен на их восприятие и на текущий вариант решения (обычно на понимание того, как оно работает, или на поиск причины, почему не работает). А когда отвлекся (пошел прогуляться, или просто чай поставить и в окно посмотреть), то информация начинает переходить из оперативной памяти в долговременную, и появляются ассоциативные связи с уже известными понятиями и между новыми.
Ассоциативные сигналы, кончено, возникают постоянно, но когда внимание направлено на новую информацию, воспринимаются только наиболее сильные. Поэтому когда появляется знакомая задача, то и решение можно найти быстро.
ActiveCustomers — отдельное

И абсолютно не связанное с InactiveCustomers и просто Customers? Иначе зачем вам его от них отделять?

Active — это отдельная характеристика, она не образует новых сущностей, а ограничивает подмножество существующих. То есть используется как фильтр. И так как в бизнес-требованиях фильтры могут комбинироваться (активные + юридические лица + из региона Урал), логично выделить их в отдельные методы и аналогично комбинировать в коде.

Так что да, специализированный Query Builder как вариант, а All заканчивает построение и вычисляет результат. А еще иногда бывают нужны не все, а только часть (первые 10 с самыми большими контрактами).
Я, возможно, чего-то не понимаю, но разве AllActiveCustomers — это отдельное самостоятельное бизнес-понятие?
Customer — это бизнес-сущность, Active — это ее бизнес-характеристика, All вообще связано с количеством и применяется уже к результату. Соответственно, наиболее близким к бизнес-логике будет какой-то такой вариант:
CustomerRepository.Find().Active().All()

Active() содержит бизнес-логику кого считать активным — у кого статус «активнен», или у кого активные контракты есть, или что-то еще. А в какую последовательность SQL-команд она потом превращается, это уже детали реализации.
Что мешало вам сразу написать подробную статью?
Немного капитанская статья, мне кажется. Если действительно хочешь исправить ошибку (или не хочешь, но надо), то обычно так и делаешь — сначала наиболее вероятные места, потом менее вероятные, потом остается только проверить всё оставшееся по очереди, в отладчике либо убирая из кода.
Я бы еще добавил, что если во время поиска ошибки вы обнаружили, что что-то работает, хотя не должно, то тоже надо найти причину. Возможно, эта ошибка компенсируется другой ошибкой. И наоборот, иногда полезно проверять предположения типа «если я тут сделаю вот так, то там должна возникнуть такая-то ошибка».
Я не говорил, что нельзя. Я сказал, что это не одно и то же, и воспринимаются они по-разному.
Впрочем, это уже оффтоп, я изначально говорил о том, что новичкам понятнее, когда границы блока явно обозначены, а не зависят от количества невидимых символов.
Я бы сказал, это смысл комментов в другом. То, что вы повысили точность, не означает, что она стала достаточной. Не знаю, почему вы считаете, что разные разрядные сетки что-то доказывают. Нельзя получить 1 в выражении 1000000000877 — 876 — 1000000000000, если разрядная сетка 1, 2, 4, или 8 знаков, и младшие разряды в первом числе превращаются в 0. Смысл не в количестве разрядов, а в том, помещается ли туда результат.

Поэтому фраза
Но откуда знать, что при дальнейшем увеличении точности не произойдет еще какого-либо скачка
технически абсолютно неграмотна. Оттуда и знать, что точность теперь достаточная. Почему достаточная? Потому что порядок множителей меньше или равен 10^36.

Information

Rating
1,964-th
Location
Россия
Registered
Activity