Конвертировать переменную до или после...

Когда нужно конвертировать данные?


  • Всего проголосовало
    7

Yaponchick

Новичок
Здравствуйте.

Уже лет 10 задаюсь этим вопросом:

PHP:
unknownFunction($someDataThatCameFromHell);

function unknownFunction($unknownVariable) {
  print (string) $unknownVariable;
}
versus

PHP:
unknownFunction((string) $someDataThatCameFromHeaven);

function unknownFunction($unknownVariable) {
  print $unknownVariable;
}
Когда нужно конвертировать данные, до или после?

Сам не могу прийти к решению, ибо:
- А вдруг это объект? тогда функция может быть более хитрой проверяя тип объекта
- Если функция ожидает строку, то это упрощает саму функцию...
- и т.д.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
ЗСам не могу прийти к решению, ибо:
- А вдруг это объект? тогда функция может быть более хитрой проверяя тип объекта
- Если функция ожидает строку, то это упрощает саму функцию...
- и т.д.
С объектами как раз все гораздо проще, т.к. для них можно использовать тайп-хинтинг, и главное - проверять на соответствие интерфейсу, а не классу.
Для начала, нужно понять, что это банально зависит от целевого использования функции - не всегда конвертация типа вообще будет иметь какой-то смысл.
Поэтому я так предполагаю, что мы обсуждаем типичный вариант, когда численные данные переданы строками.
Однозначного ответа нет, оба подхода имеют свои за и против.
Мое мнение, в PHP есть смысл в принудительной конвертации при передаче аргумента к типу из-за особенностей реализации в его типичном использовании (все внешные данные (из базы, из параметров запроса) как правило, строки), но она осложнена не всегда ожидаемыми и заранее предсказуемыми эффектами конвертации значений между типами.
В целом, я за вариант, когда в ООП у тебя есть методы, инициализирующие (или заполняющие) объект данными, там делать конвертацию, а в местах использования данных предполагать, что все уже сконвертировано в нужный тип.
 
  • Like
Реакции: WMix

Yaponchick

Новичок
Ну тайпхинтинг уже превращает "момент" где он используется в "жесткотипизированный" )
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Ну тайпхинтинг уже превращает "момент" где он используется в "жесткотипизированный" )
он его превращает в не всегда непредсказуемо типизированный:

PHP:
<?php
function f($argument)
{
    var_dump($argument);
}

$data = '0x555';
f((int)$data); // int(0)
$data = 0x555;
f((int)$data); // int(1365)
$data = '1e6';
f((int)$data); // int(1)
$data = 1e6;
f((int)$data); // int(100000)
 

флоппик

promotor fidei
Команда форума
Партнер клуба
А я думал что TH это:
С объектами как раз все гораздо проще, т.к. для них можно использовать тайп-хинтинг, и главное - проверять на соответствие интерфейсу, а не классу.
Поэтому я так предполагаю, что мы обсуждаем типичный вариант, когда численные данные переданы строками.
Да, я неверно прочел твой комментарий, что не меняет того, что у тебя вопрос-то все равно про конвертацию примитивных типов, а не тайп-хинтинг интерфейсов, где этой проблемы нет
 

AmdY

Пью пиво
Команда форума
Для PHP это не вопрос, однозначно внутри функции, только так можно обеспечить должный уровень безопасности.
 

Yaponchick

Новичок
AmdY, в этом случае мы получаем:
дублёж проверок, и пользователь и родительский класс, и класс третьего программиста будет проверять одно и то же...

С другой стороны, не проверяя внутри мы говорим "программисту": "ну если ты такой лук... сам виноват, учись проверять данные..."
Упрощая жизнь нам и обучая другого ;) Хотя отсюда полезут невидимые баги как вариант...
 

WMix

герр M:)ller
Партнер клуба
Yaponchick, внеси конкретный пример в дискуссию, по мне так '1' и 1 в пхп идентичны и проверять как и кастить тут нечего!
при чтении формы, вероятнее всего лучше сразу закастить (int)string. а так мне ответ AmdY по душе.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Мне нравится вариант AmdY, ибо тогда не надо залить по коду и смотреть, было ли уже преобразование какое или нет.
 

keltanas

marty cats
Уже лет 10 задаюсь этим вопросом:

PHP:
unknownFunction($someDataThatCameFromHell);

function unknownFunction($unknownVariable) {
  print (string) $unknownVariable;
}
Т.е. за 10 лет так и не понял, что функция должна бы возвращать данные, а не печатать их? Или до сих пор тестируешь свои функции через ob_start?

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

Yaponchick

Новичок
keltanas, ха ха... вообще-то в доке указан жесткотипизированный вариант. И если засунуть туда что-то "не то", будет ошибка или он скажет "needle is not string"?
Мой же вопрос относиться как раз к придумыванию варианта документации:

Код:
mixed strpos(mixed needle, mixed haystack)
Тут код будет сам решать, как и что делать...

против

Код:
int strpos(string needle, mixed haystack)
Этот вариант уже подразумевает, что пользователь конвертнул переменную

P.S. а в haystack можно засунуть массив строк?! будет работать?! )))))
P.S.S. А почему в доке стоит int strpos, когда по сути там mixed strpos? )
 

keltanas

marty cats
Yaponchick, на мой взгляд это высосанная из пальца проблема. А высосана она потому, что новички (возможно, люди с определенным складом характера) предпочитают сами додумывать, как и что работает, вместо того, чтобы посмотреть в документацию. А потом удивляются, почему функция работает не так, как они хотели? Данные топик - яркий тому пример.
 

keltanas

marty cats
keltanas, могли бы сразу написать что вы за внешнюю конвертацию... не задевая моих чувств ;)
Я намеренно ничего не писал про внешнюю/внутреннюю конвертацию, потому что
на мой взгляд это высосанная из пальца проблема
т.к. предпочитаю придерживаться принципа "Explicit is better than implicit", чего и вам советую.
 

iceman

говнокодер
ИМХО.
PHP:
function unknownFunction($unknownVariable) {
  return $unknownVariable;
}

print((string) unknownFunction($someDataThatCameFromHeaven));
 
Сверху