Тотальная проверка данных, передаваемых в функцию

1 234
kiowas
На сайте с 06.02.2010
Offline
61
#21

Есть ли возможность защитить от изменения публичное свойство объекта?

подпись
Оптимизайка
На сайте с 11.03.2012
Offline
396
#22
kiowas:
Коллеги, прошу помочь избавить от одной навязчивой привычки

Эта техника, которую Вы используете — неплоха сама по себе, я бы не стал её называть навязчивой привычкой. Называется она - защитное программирование. Т.е. прверяется корректность аргументов функций до и после. С нетипизированными ЯП, такими как PHP, это очень даже полезно на этапе разработки и тестировании.

Обычно такие проверки в релизном коде удаляют (путем #ifdef DEBUG в нормальных ЯП, а в PHP можно пропустить код через какой нить препроцессор).

⭐ BotGuard (https://botguard.net) ⭐ — защита вашего сайта от вредоносных ботов, воровства контента, клонирования, спама и хакерских атак!
F9
На сайте с 13.04.2008
Offline
104
#23
kiowas:
Есть ли возможность защитить от изменения публичное свойство объекта?

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

kiowas
На сайте с 06.02.2010
Offline
61
#24
for93t:
Публичное свойство по определению нельзя защитить от прямых изменений - на то оно и публичное, что каждый может его читать и изменять.

Ок. Переформулирую вопрос. Есть ли возможность создать свойство в объекте, которое будет доступно для чтения из вне, но не доступно для изменения из вне?

---------- Добавлено 07.06.2013 в 13:14 ----------

Коллеги, скажите, пож-та, это нормально, если доступ к свойствам объекта не предоставлять, а возвращать их значения только через методы объекта?

IL
На сайте с 20.04.2007
Offline
435
#25
for93t:
Валидация данных в модели крайне желательна, поскольку с одной и той же моделью может работать несколько контроллеров и в каждом потребуется делать валидацию, если этого не будет делать модель, а это дублирование кода со всеми вытекающими.

Эм.. я как бы про валидацию в модели и говорил. Упор на то, что валидация в конструкторе модели - не всегда уместна... Тем более, в конструкторе может быть неизвестно, какому сценарию должны удовлетворять проверяемые данные.

for93t:
А как был сформирован этот список - через исключения, возвращение false или прямым инжектом в какой-нибудь инстанс-коллектор сообщений - View может, точнее должен, не знать.

Если модель имеет несколько полей, такая валидация в конструкторе накидает несколько исключений? или одно? Где их отлавливать планируется? Не думаю, что во вьюхе.. Контроллер "разрастаться" будет.. Или же сам конструктор модели.. и выноситься.. в отдельные методы (?) Про коллектор сообщений/исключений мысль пока не развиваю, т.к. изначально вообще речь шла про is_int/is_numeric

for93t:
Я привел в пример класс, который реализует паттерн ValueObject.

ValueObject - штука хорошая.. однако, "в реальности" работа с пользовательскими данными (в частности, их изменение/обработка/фильтрация (в модели) и сохранение.. * с валидацией при изменении.. или перед сохранением) требуется гораздо чаще, чем неизменяемый объект...

for93t:
type hint как раз служит валидатором

Type hint - тоже хорошо.. но, опять же, (только мне?) гораздо чаще приходилось сталкиваться с ситуациями, когда требуется именно проверка значения /речь о данных, вводимых пользователем/

for93t:
единая точка ввода, которая гарантирует, что данная переменная всегда будет иметь корректное значение (или не иметь его вовсе, т.е. быть null)

Опять же.. при выборе "бросать exception-ы при установке значения /создании объекта" vs "использовать отдельный метод для валидации" я больше склоняюсь ко второму... по крайней мере "невалидные" данные будут храниться в модели

for93t, на всякий случай.. Подход понимаю, но пытаюсь донести, что /на мой взгляд/ он не всегда является приемлемым и/или оптимальным. Особенно, если речь про работу с данными, получаемыми от пользователя. C ValueObject - Вполне логично, что если хост для подключения к DB указан неверно, то и смысла создавать соединение нет.

kiowas:
Если появляется идея каким-то образом написать функцию или переопределить какую-то другую, так чтобы она была видна из любого куска скрипта и проверяла переменную на целое число положительно, в этом случае как лучше поступить?

Использовать filter_var... В частности для целого положительного - FILTER_VALIDATE_INT + min_range = 1 http://www.php.net/manual/ru/filter.filters.validate.php

---------- Post added 07-06-2013 at 13:17 ----------

kiowas:
Коллеги, скажите, пож-та, это нормально, если доступ к свойствам объекта не предоставлять, а возвращать их значения только через методы объекта?

Про сеттеры-геттеры уже писали. Вполне приемлемо.

Более того, в коде может быть:

 echo $model->name ;

А в реальности вызывается

echo $model->getName();
... :) Облачные серверы от RegRu - промокод 3F85-3D10-806D-7224 ( http://levik.info/regru )
O
На сайте с 29.05.2008
Offline
195
#26


function abc($client_id = null, $email = null) {
if(!$client_id || $client_id != intval($client_id))
return false;
if(!$email || !is_string($email))
return false;
}

Лучше писать так:


function abc($client_id = null, $email = null) {
if (!(isset($client_id) || is_numeric($client_id)))
return false;
if(!isset($email) || empty($email))
return false;
}

Но это уже паранойя.

F9
На сайте с 13.04.2008
Offline
104
#27
kiowas:
Ок. Переформулирую вопрос. Есть ли возможность создать свойство в объекте, которое будет доступно для чтения из вне, но не доступно для изменения из вне?

Да, такое свойство должно иметь модификатор доступа private (или protected, если есть классы-потомки, которые работают с этим свойством) и чтение его значения извне должно осуществляться с помощью public-геттера.

O
На сайте с 29.05.2008
Offline
195
#28

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

F9
На сайте с 13.04.2008
Offline
104
#29
ivan-lev:
for93t, на всякий случай.. Подход понимаю, но пытаюсь донести, что /на мой взгляд/ он не всегда является приемлемым и/или оптимальным. Особенно, если речь про работу с данными, получаемыми от пользователя. C ValueObject - Вполне логично, что если хост для подключения к DB указан неверно, то и смысла создавать соединение нет.

А я и не претендую на то, что озвучил истину во всех инстанциях :) Мой совет по использованию private-свойств относится к конкретной проблеме, которую озвучил ТС:

kiowas:
К тому же если я создаю класс, то в конструкторе уже какие-то свойства класса проверяются и вроде бы этого должно быть достаточно, но нет же... Первый же вызов метода из конструктора и меня опять клонит в этом методе все переменные перепроверить.... А вдруг в конструкторе не проверилось?

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

---------- Добавлено 07.06.2013 в 13:43 ----------

ortegas:
for93t, а еще можно использовать константы, в случае если она задается раз и навсегда.

Боюсь, ТС работает с user input, поэтому константы тут не помогут.

Хотя формально

kiowas:
свойство в объекте, которое будет доступно для чтения из вне, но не доступно для изменения из вне?

и есть определение константы класса.

IL
На сайте с 20.04.2007
Offline
435
#30
for93t:
Боюсь, ТС работает с user input, поэтому константы тут не помогут.

Зачем бояться?.. так и есть ведь.

for93t:
и есть определение константы класса.

Константа - не свойство объекта, а заранее заданное выражение ("захардкожено" до начала выполнения скрипта).. И задать её при инициализации объекта не получится :) даже формально..

---------- Post added 07-06-2013 at 14:08 ----------

kiowas:
Все бы хорошо, но проверки под час становятся громоздкими, тем более когда много параметров.

О, насчёт проверок у ortegas поспрашивайте.. он в нескольких постах свой подход к валидации излагал - в корне отличается от валидации в модели.

1 234

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий