php не выдает ошибку, а просто уведомляет, когда я обращаюсь к неопределенному свойству объекта/массива

поэтому javascript (ajax) отправляет строковый объект JSON в php, который получает json_decoded, а затем я ссылаюсь на свойства объекта, чтобы сохранить их в базе данных.

$Name = $Person->Name;
$Surname = $Person->Surname;

Теперь клиент может быть вредоносным, и он мог переименовать некоторые имена свойств Person перед отправкой JSON на сервер, и я хотел бы избежать этого условия.

Таким образом, клиент мог бы переименовать свойство «Имя» в «Имя555», поэтому, когда я пытаюсь получить $Person->Name, я думал, это вызовет ошибку, но, к сожалению, это не так, вместо этого я получаю назад к клиенту только уведомление о:

Notice: Undefined property: stdClass::$Name in /home/aaa/public_html/saveperson.php on line 38

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

заранее спасибо.


person MirrorMirror    schedule 19.09.2013    source источник
comment
вы можете попробовать с помощью try catch, поместите возврат ошибки в catch   -  person Pranay Bhardwaj    schedule 19.09.2013


Ответы (2)


Уже выдает ошибку. Если вы полны решимости действовать немедленно, вы можете установить собственный обработчик ошибок с помощью set_error_handler.

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

if (!isset($Person->Name)) {
    // do something here
}
person Jon    schedule 19.09.2013
comment
Я хотел бы избежать isset() всех 20 свойств, потому что это может вызвать проблемы с производительностью, особенно у многих пользователей, поэтому я подумал, что решение для выдачи ошибок будет лучше, чем наличие 20 issset() в коде. возможно, я ошибаюсь, и isset() не имеет серьезного наказания, сделает тест. - person MirrorMirror; 20.09.2013
comment
@MIrrorMirror: вы никогда не пишете 20 вызовов одной и той же функции. Вместо этого напишите цикл, который повторяется 20 раз. Или преобразуйте в массив вместо объекта и используйте простое добавление массива или array_merge_recursive (в зависимости от того, какую структуру данные должны иметь), чтобы заполнить все пустыми значениями (с которыми вам все равно придется иметь дело). Вариантов много, лучший выбор зависит от специфики. - person Jon; 20.09.2013
comment
Спасибо за ваш комментарий. Я не уверен, что понял, что вы имели в виду, говоря, что нет необходимости в 20 вызовах isset. Если у объекта есть 20 свойств (фамилия, имя, возраст и т. д.), не нужно ли мне !isset(person-›surname) || !isset(человек-›имя и т. д. и т. д. и т. д., что составит 20 вызовов? - person MirrorMirror; 20.09.2013
comment
@MIrrorMirror: вы должны создать массив с именами 20 свойств, а затем запустить цикл: foreach ($properties as $name) if (!isset($Person->$property)) .... - person Jon; 20.09.2013
comment
ах, теперь я понял, но все равно это 20 вызовов, у меня не было проблем с ручным вводом, но с вероятным падением производительности, вызванным этим - person MirrorMirror; 20.09.2013
comment
@MIrrorMirror: я не понимаю, почему вы должны беспокоиться об этом, если вы не Твиттер. - person Jon; 20.09.2013

Мое выражение try/catch было неверным, но с

if(!isset(@Person->Name)){ throw new Exception... }

должно сработать.

person Mario.Hydrant    schedule 19.09.2013
comment
isset не будет генерировать исключение, он просто вернет FALSE, если свойство не существует. - person George Marques; 20.09.2013
comment
как указывает @GeorgeMarques, это не приведет к возникновению исключения, поэтому попытка ничего не поймает. Однако вы можете: if(!isset(@Person->Name)){ throw new Exception... } - person siva.k; 20.09.2013
comment
Спасибо, ребята, читая источник, я предположил, что оператор в блоке try нужен только для возврата false, чтобы отключить блок catch. - person Mario.Hydrant; 20.09.2013