При избежании нулей в PHP, могу ли я переопределить isset?

#php #null

#php #null

Вопрос:

Я сталкиваюсь с проблемой, с которой, я думаю, все сталкиваются с null: то есть существуют разные виды null. Это может означать «пустой», «без изменений», «сброшенный», «неизвестный» или любое количество вещей. И я дошел до того, что мне нужно как-то различать их.

В принципе, у меня есть часть моей программы, связанная с менеджером баз данных, которая получает объект, представляющий данные, подлежащие обновлению в базе данных, из другой части моей программы, которая отвечает за проверку данных формы и преобразование их в указанный объект (который имеет один из нескольких разных классов с определенными предопределенными свойствами). Мне нужен какой-то способ различать свойство «null» в этом объекте, которое означает «Я действительно хочу, чтобы значение null хранилось в базе данных», и другой тип «null», который означает «Если в базе данных есть существующее значение, не изменяйте его». Из двух, последний будет намного более распространенным случаем, но мне нужен какой-то способ разрешить и первый.

Моя текущая мысль, которая, казалось бы, лучше всего подходит для этой ситуации, заключается в создании нового класса, который представляет каждый «тип» null, например, Unchanged класс стихи SetToNull типа или что-то в этом роде. Тогда я мог бы установить свойство для экземпляра одного из этих классов.

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

Я знаю, что могу сделать что-то вроде этого:

 if (isset($thing->property) amp;amp; !($thing->property instanceof Unchanged || $thing->property instanceof SetToNull)){
    // do whatever
}
  

Однако, это, очевидно, не идеально, потому что это длинный и громоздкий, и я не хочу, чтобы это было везде по всей моей кодовой базе. Я бы предпочел что-то вроде этого:

 if (myCustomIsset($thing->property)){
    // do whatever
}
  

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

Комментарии:

1. Какие два нуля отправляются? Один из них есть null , но что это за второй null , который просто не должен меняться? В чем разница между ними? В принципе, как вы проводите различие между null, который хочет, чтобы значение DB было NULL, или null, который не хочет ничего менять?

2. Для большей части программы разницы нет. Единственное реальное различие заключается в том, что когда я сохраняю данные обратно в базу данных, должен ли я сохранять значение null или мне не следует ничего сохранять и позволить ему сохранить любое существующее значение, которое может быть в базе данных.

Ответ №1:

Лично я бы не стал менять модель. Модель должна представлять данные в базе данных, а значения ее свойств должны совпадать со значениями столбцов, которые представляют эти свойства.

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

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

Комментарии:

1. Вы действительно правильно подметили. К сожалению, в моей ситуации, при том, как у меня работает проверка, это немного сложнее, чем кажется, потому что у средства проверки нет доступа к исходным значениям, поскольку я старался, чтобы эти части моего кода были очень отделены друг от друга. Хотя, возможно, вы правы, и мне придется немного переработать валидатор…

2. Поскольку я думаю об этом немного больше, это, вероятно, то, что я на самом деле собираюсь сделать. Я оставляю Kodos Johnson в качестве принятого ответа, потому что он отвечает на вопрос, который я на самом деле задал, но этот ответ полностью устраняет проблему и является хорошим решением моей основной проблемы.

Ответ №2:

Одна вещь, которая приходит на ум, которую я делал в прошлом, — это два перехода в двух аргументах. Первым аргументом является сам объект. Второй аргумент — это строка, которая содержит имя свойства.

Вот пример:

 function MyCustomIsset($object, $property) {
    return isset($object->$property) amp;amp; !($object->$property instanceof Unchanged || $object->$property instanceof SetToNull);
}
  

И вот как бы вы это использовали:

 if (myCustomIsset($thing, "property")){
    // do whatever
}
  

Поскольку вы не ссылаетесь на свойство объекта при его передаче, PHP не выдаст ошибку. В теле функции вы ссылаетесь на свойство, используя аргумент, переданный в string . Вы можете ссылаться на свойство, используя специальную функцию PHP, называемую variable variables.