Pull to refresh

Comments 42

Тогда уж
$var = $_REQUEST[$var]; // перед присваиванием нужно прогнать через фильтр
Мне кажется стоит реализовать ArrayAccess в Request, т.е будет обычный доступ типа $request['var1'], можно будет проверить на isset, а также встроить проверки.
Либо через магические методы __get и __set. Чтоб было $request->var1
Так обычно и делают, дело в том что я решил сделать более универсальный метод. В котором не нужно париться с этими инициализациями (при условии использования классов). Мы скормили объект класса в в метод инициализации и всё, получили свойства с значениями (желательно что бы эти свойства уже были обьявленны в классе да бы избежать нотисов и ерорров).
Поясню :) чтоб все поняли :)
Приведенные примеры — это дичайшие антипаттерны. Это примеры того, как ни в коем случае нельзя писать, если конечно вы пишете не для врагов.

ps: register_globals is back, ага ))

Какие трудности или опасность Вы видите в моём минипатерне? Или я чего то просто не недопонимаю. В чем трабл?
Здесь столько всего плохого, даже не знаю с чего начать. Какой-то винегрет из костылей.
Ладно, знаю что всё сыро и убого)) Но вкратце пожалуйста перечислите костыли и подводные камушки! Так как я наивен и до сих пор думаю что это хорошее решение…
Получение данных из реквеста. Надо разделять GET POST и COOKIE
Использование переменных переменных. Метапрограммирование зло.
Инициализация свойств объекта через паблик-свойства, торчащие наружу… жуть-жуть.

Ну, пока хватит
> Метапрограммирование зло.
Вот это не правда
В приведенных примерах — однозначно зло.
Вот, точно, но не только #data_filtering, но и все остальное
Ну фильтры я уже не добавлял, просто в строке где присваивание, коментами предупредил о необходимости отфильтровать данные. Кстати спасибо data_filtering.
<code=php>
$v = $r[ $i ];
$obj->$v = $r[ $k[ $i ] ];

Я бы за такое руки отрывал.
Что за $k?
Что за $r?
Что за $v???
Что за получение индекса из массива по индексу?
extract() хорошая функция, но мы не контролируем инициализацию, то есть в моём случае, перед инициализацией, мы можем прогнать данные через фильтры проверки данных и очистки
то есть нужно еще создавать класс или конфиг для Request что бы он знал что фильтровать и как фильтровать.
И более чем уверен, что там будет куча лишних циклов, которые можно избежать воспользовашись геттерами и сеттерами.
Да, вы правы, это будет как отдельный класс, и он фильтрует только то, что находиться в супглоб массиве и присвоит эти значения свойствам класса.
extract(array_map(function ($item, $val) {}, array_keys($_REQUEST), $_REQUEST));

Примерно так. Но это дичь, тем более, использовать $_REQUEST я бы не рекомендовал, лучше отдельные $_POST, $_COOKIE.
А ещё можно присвоить $_REQUEST объект на основе ArrayAccess, передав ему в конструктор $_REQUEST, но это не менее странно.
а вообще для таких целей лучше использовать магию или еще лучше — геттеры и сеттеры.
К примеру если перемнной нету — будет notice. И вы никак знать не будете, какой именно перемнной не будет в массиве, что бы например добавить значение null.
То есть ошибка ошибка не избежна (если не добавлять магию в класс VarsVar, который Вы в вашем примере передаете для заполнения) и о дефолтных значениях тоже можно забыть.
для минусующих поясню: имелось ввиду не то, что эта функция хороша и стоить её использовать, а то, что зачем писать кусок кода, если есть функция, которая сама это делает. А по поводу топика хорошо сказано комментарием выше
Какая красота. По пунктам.

1. Можно использовать foreach вместо for
2. А ещё лучше использовать extract
3. А ещё лучше не использовать такой подход в принципе. Можно переписать существующие переменные (свойства). Можно не найти концов при отладке, когда переменные таким неявным способом инициализируются.

PS. register_globals в своё время пилили-пилили и выпилили, а тут прямо-таки «назад в будущее», вернее сказать «вперёд в прошлое».
1. foeach работает немного медленнее с одномерными ассоциативными массивами, и на порядок медленнее с двумерными
2. ещё рас повторюсь, extract() не безопасен, он возобновляет давно похороненный register_globals!
3. очень даже легко отлаживать. я же в примере сделал выводы и реквеста и переменных, которые он создал. Если у Вас при отладке нет таких переменных или свойства не переприсвоены, просто проеверяем есть ли оное в супглоб массиве и всё.

register_globals тут даже и не пахнет, я же не зря упомянул, что будут инициализированы только public свойства класса, весь остальной мусор можно отфильтровать…
1. А еще, пост-инкремент тянет за собой несколько лишних операций, в отличие от пре-инкремента, повсеместное использование объектов — тоже медленней, чем просто функций со структурами данных, ну и вообще пхп довольно медленный в сравнении с, скажем, Си.
2. То что тут описано делает ровно то же самое.

Вообще для таких штук делают такое разделение:
Есть объект Request-а, у которого вы можете попросить св-ва запроса (в т.ч. POST,GET,etc).
Есть компонент, который занимается валидацией и биндингом данных. (Его тоже конечно можно разделить на два)
Есть собственно сам объект, в который надо инжектить данные.

А то что тут описано — только слепо биндит данные на паблик св-ва объекта с какого-либо массива, валидация теряется
1. Это диагноз, который называется «echo быстрее, чем print».
2. extract безопаснее Вашего первого способа, там можно указать некоторые настройки. Что касается объектов. Тут нельзя будет использовать extract. Опять же можно всяким мусором заполнить объект. И если все объекты для конфигурирования будут показывать свои свойства всем, то, скажем так, это открывает слишком много секретов, которые должны быть скрыты. Не будет интерфейсов, потому что все свойства будут открыты. Передал один объект он заполнился, передал другой объект, он точно так же заполнился и даже не поперхнулся.
3. Заполнение переменных и объектов будет зависеть не от программы, а от внешних факторов. Т.е. не так как хочет программист, а как повезёт. Передал/не передал, строка/массив. Конечно, можно фильтровать, но объектам не нужны одинаково отфильтрованные данные. Кому-то нужен массив, кому-то числовая строка, а кому-то любая строка подойдёт. Как место_где_распихиываются_данные_по_объектам узнает какому объекту что и в каком формате надо?
Кто-то постигает пхп:)
Только не надо такие статьи на хабре писать, помимо того, что все это довольно очевидно, в итоге это еще и не удобно и может привести к «не безопасно»
Постигаем, постигаем))
Но всё же не понятно, почему это не удобно и где кроется опасность?
Как вы определите где данные пришли из $_GET и $_POST? Это для начала.
$_REQUEST я взял для примера, конечно же нужно разделять на гет, пост и кукис
Ок.
echo '<br />var1 - '.$obj->var1; // вывод: "var1 - VAR1"
Если юзер не пришлет, например $_GET['var1'], то у вас будет ошибка. Значит вы будете проверять, чем-то вида if(!empty($obj->var1)){}. Вопрос: зачем прослойка из класса если можно сразу if(!empty($_GET['var1'])){}

Это я к тому, что вы вместо foreach используете for (чем уменьшаете читаемость кода) для экономия ресурсов, но при этом создаете класс, в котором нужны-то и нет.
Всё же не могу понять вашей встревоженности. Но так и не услышал ни одного 100%-го факта, что бы я убился головой об стенку и забыл про этот бред
Кстати, реализация рэйс кондишена через АПЦ… ВНЕЗАПНО привела к устойчивой нагрузке в 53% на CPU… после чего всё пришлось откатить обратно. (весь один скрипт в 30строк (+5 строчек про апц))

Amazon EC2 Debian 5.0.3 lenny + Apache/2.2.16 + PHP 5.3.3-7 with Suhosin-Patch + apc 3.1.3p1

Вначале обновлюсь, а потом еще раз попробую.
Ошибка: в методе GetVarRequest() класса Request не инициализирована переменная $k. И метапрограммированием здесь не пахнет, Вы уж извините.
Обшибку исправил, спасибо.
В вашем топике вы динамически создаете методы с помощью каррирования. Примеры можно найти. Я же создаю переменные и свойства на основе пришедших данных, и чем это не метапрограммирование?

Кстати, пока писал этот коммент, пришло озарение где мой велосипед вроде бы уже используется и что пример с супглоб масивами был, мягко говоря, не очень. Так как многим из вас это напомнило register_globals.

Если это подтвердится, надеюсь вы поменяете своё мнение об этом подходе, или расстреляете меня до конца!))
Я не просто создаю методы, я реализую частичное их использование. А на счет вашего топика… Возможно вам стоит посмотреть в сторону фрэймворков и разобраться в реализации чего-то подобного там. Например Zend Framework, посмотрите как реализован Zend_Form.
Вот через mass-assignment в рельсах гитхаб недавно и ломали: habrahabr.ru/post/139399/

Ваш пример с заполнением объекта из $_REQUEST ничем принципиально не отличается.
Егор молодца, что тут сказать. Он их предупреждал "… мейнтейнеры Rails игнорировали баг… Егор теперь решил протестировать его"))
Вот и я хочу этим топиком узнать все + и — донного подхода.
И у рельс кстати есть два метода для настройки фильтрации attr_protected и attr_accessible. Слабенькая гибкость, но всё же.
Вы бы про ПХП почитали, а не углублялись в нюансы Рельс.
Sign up to leave a comment.

Articles