Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Собственный фильтр данных
Форумы портала PHP.SU » » Объектно-ориентированное программирование » Собственный фильтр данных

Страниц (2): [1] 2 »
 

1. Psychotech - 07 Июня, 2015 - 08:55:34 - перейти к сообщению
Здравствуйте форумчане. Давно здесь не был, кажись много чего поменялось. В общем взялся писать собственный фильтр вводимых данных, дабы явно дать скрипту понять что полученные данные подозрительны и их стоит обрабатывать более безопасным способом. в общем ничего не предвещало беды пока не появились какие-то непонятки на ровном месте.
Скрипт написал с лету, мунут за пять. отталкивался от ранее написаного, но больно корявого и на линейном программировании. сейчас пишу на ООП. В общем создал класс

CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. class SecuryEnter{
  3.         private $numbermass = array(0,1,2,3,4,5,6,7,8,9);
  4.        
  5.         public function generalTest($stroka, $testmode){
  6.  
  7.                 $resultat = array();
  8.  
  9.                 if($testmode==='num'){
  10.                         for($i=0;$i<strlen($stroka);$i++){
  11.                                 $spectr = substr($stroka,$i,1);
  12.                                 if(!in_array($spectr, $this->numbermass)){
  13.                                         $resultat[0] = false;
  14.                                         $rasultat['denied'] = $spectr;
  15.                                         return $rasultat;
  16.                                         }
  17.                                 }
  18. $resultat[0] = true;
  19.                 return $rasultat;
  20.                         }
  21.  
  22.                 }
  23.        
  24.         public function SecuryEnter(){
  25.  
  26.                
  27.                 }
  28.         }
  29.  
  30.  


(он конечно же получился побольше, но после неудачи решил переписать занового и тестировать на каждом этапе.)

Ну и собственно файл где это все тестируется назовем его test.php
CODE (htmlphp):
скопировать код в буфер обмена
  1. require_once("coreengine/securyenter.php");
  2. $security = new SecuryEnter;
  3. $text = '85445656855';
  4. $test = $security->generalTest($text, 'num');
  5. if($test[0]){
  6.         print "pravda.'<br>'";
  7. }else{
  8.         print "false ".$test["denied"].'<br>';
  9. }


Вот теперь самое интересное. как наверное догадались выводит только false; причем вчера еще сообщал символ на котором произошла остановка, сегодня просто false.

В общем надеюсь на наш коллективный разум. Всю работу задерживает только этот фильтр. Подскажите пока что сейчас не так.
2. Ts.Saltan - 07 Июня, 2015 - 09:01:29 - перейти к сообщению
Psychotech пишет:
rasultat
Psychotech пишет:
resultat
опечатка
3. Psychotech - 07 Июня, 2015 - 09:09:33 - перейти к сообщению
Ts.Saltan пишет:
Psychotech пишет:
rasultat
Psychotech пишет:
resultat
опечатка

О блин мозги засорились за три дня не заметил. Сейчас продолжу полезут дальнейшие ошибки.

Большая просьба тему не закрывать пока.
(Добавление)
Ну вот собстенно и пошел процесс который вставляет палки в колеса.
PHP:
скопировать код в буфер обмена
  1.  
  2. class SecuryEnter{
  3.         private $onlywordmass = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","А","Б","В","Г","Д","Е","Ж","З","И","Й","К","Л","М","Н","О","П","Р","С","Т","У","Ф","Х","Ц","Ч","Ш","Щ","Ъ","Ы","Ь","Э","Ю","Я","а","б","в","г","д","е","ж","з","и","й","к","л","м","н","о","п","р","с","т","у","ф","х","ц","ч","ш","щ","ъ","ы","ь","э","ю","я");
  4.         private $mailwordmass = array('-','_','\.','@');
  5.         private $telefonmass = array('+','-', '(',')');
  6.         private $numbermass = array(0,1,2,3,4,5,6,7,8,9);
  7.  
  8.         public function generalTest($stroka, $testmode){
  9.  
  10.                 /*
  11.                 //$stroka - строка которую нужно проверить
  12.                 //$testmode - тип проверяемых данных возможные варианты
  13.                 // str - строка проверять только буквы
  14.                 // mail - проверять буквы и цифры со специальными символами адреса e-mail
  15.                 // tel - проверять телефон
  16.                 // num - только цифры
  17.                 // all - проверять по всем символам  НАХУЯ Я ЭТО СДЕЛАЛ ХУЙ ЕГО ЗНАЕТ
  18.                 //$alertmessage другой вывод строки по умолчанию можно не указывать
  19.                 */
  20.                 $resultat = array();
  21.  
  22.                 if($testmode==='num'){
  23.                         for($i=0;$i<strlen($stroka);$i++){
  24.                                 $spectr[$i] = substr($stroka,$i,1);
  25.                                 if(!in_array($spectr[$i], $this->numbermass)){
  26.                                         $resultat[0] = false;
  27.                                         $resultat['denied'] = $spectr[$i];
  28.                                         return $resultat;
  29.                                         }
  30.                                 }
  31.                         $resultat[0] = true;
  32.                         return $resultat;
  33.                         }
  34.  
  35.                 if($testmode==='tel'){
  36.                         for($i=0;$i<strlen($stroka);$i++){
  37.                                 $spectr[$i] = substr($stroka,$i,1);
  38.                                 if((!in_array($spectr[$i], $this->telefonmass))&&(!in_array($spectr[$i], $this->numbermass))){
  39.                                         $resultat[0] = false;
  40.                                         $resultat['denied'] = $spectr[$i];
  41.                                         return $resultat;
  42.                                         }
  43.                                 }
  44.                         $resultat[0] = true;
  45.                         return $resultat;
  46.                         }
  47.  
  48.  
  49.                 if($testmode==='str'){
  50.                         for($i=0;$i<strlen($stroka);$i++){
  51.                                 $spectr[$i] = substr($stroka,$i,1);
  52.                                 if(!in_array($spectr[$i], $this->onlywordmass)){
  53.                                         $resultat[0] = false;
  54.                                         $resultat['denied'] = $spectr[$i];
  55.                                         return $resultat;
  56.                                         }
  57.                                 }
  58.                         $resultat[0] = true;
  59.                         return $resultat;
  60.                         }
  61.  
  62.  
  63.                 }
  64.  
  65.         public function SecuryEnter(){
  66.  
  67.                 }
  68.         }
  69.  


файл test
PHP:
скопировать код в буфер обмена
  1.  
  2. require_once("coreengine/securyenter.php");
  3. $security = new SecuryEnter;
  4. $text = 'werweыфвфыв';
  5. $test = $security->generalTest($text, 'str');
  6. if($test[0]){
  7.         print "pravda.'<br>'";
  8. }else{
  9.         print "false ".$test["denied"].'<br>';
  10.         echo json_encode($test).'<br>';
  11. }
  12.  
  13.  


вот что я вижу уже три дня и в чем причина понять не могу. догадываюсь что присутствует конфликт кодировки но откуда он взялся понять не могу. ибо вижу вопроc в ромбе на $test["denied"] и естественно возвращает ложь.
(Добавление)
Сервер настроен на "UTF-8"
скрипты в ПХП эксперте на "utf-8 без dom"
4. Psychotech - 07 Июня, 2015 - 11:23:55 - перейти к сообщению
выяснилось что данныая конструкция не работает только с русскими буквами, то есть. все английские попадают под проверку и проходят а кирилица поцему-то убегает.
вот только почему?
PHP:
скопировать код в буфер обмена
  1.  
  2. private $onlywordmass = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","А","Б","В","Г","Д","Е","Ж","З","И","Й","К","Л","М","Н","О","П","Р","С","Т","У","Ф","Х","Ц","Ч","Ш","Щ","Ъ","Ы","Ь","Э","Ю","Я","а","б","в","г","д","е","ж","з","и","й","к","л","м","н","о","п","р","с","т","у","ф","х","ц","ч","ш","щ","ъ","ы","ь","э","ю","я");
  3.        
  4.  
5. Ts.Saltan - 07 Июня, 2015 - 11:29:40 - перейти к сообщению
mb_substr, mb_strlen
Русские символы занимают больше одного байта, поэтому нужны мультибайтовые функции для работы со строками
6. Psychotech - 07 Июня, 2015 - 11:29:57 - перейти к сообщению
не спасает. хотя я установил что символы в функцию передаются именно в windows-1251. конвертировал с разных сторон и на вхождении в функцию и внутри неё причем как ввод так и проверочный массив. ничего не помогает. У кого какие идеи?
(Добавление)
Ts.Saltan пишет:
mb_substr, mb_strlen
Русские символы занимают больше одного байта, поэтому нужны мультибайтовые функции для работы со строками

так так все заработало. А где инфу взять про это чтобы на будущее предугадывать подобное? или может сами в двух словах обьясните почему просто substr не подходит?
(Добавление)
странно прочитал описание mb_string но понять не могу. русские же символы в utf-8 входят в диапозон 0-255;
7. Ts.Saltan - 07 Июня, 2015 - 11:42:16 - перейти к сообщению
Psychotech пишет:
почему просто substr не подходит?

Вот например две строки
$a = "hello";
$b = "привет";

Английский символ занимает 1 байт, русский - 2, китайский и прочие - 4, 8 и т.д.
Т.к. substr вырезает по одному байту, он вернёт «половину» русского символа, но полный английский.
По аналогии
echo $a[0] //h
echo $b[0] //?
8. LIME - 07 Июня, 2015 - 12:36:06 - перейти к сообщению
Psychotech пишет:
русские же символы в utf-8 входят в диапозон 0-255;
нет не входят
Фильтр станет гораздо удобнее писать если освоить регулярки
9. Мелкий - 07 Июня, 2015 - 12:49:06 - перейти к сообщению
Psychotech пишет:
русские же символы в utf-8 входят в диапозон 0-255;

Не входят. С чего вы это взяли?
Кириллица в UTF8 живёт в диапазоне 0xD090 .. 0xD18F, плюс 0xD001 и 0xD191 для Ёё. Весьма и весьма далеко от 0x00-0xFF

Ts.Saltan пишет:
китайский и прочие - 4, 8 и т.д.

Никакого т.д. В UTF8 только 1, 2, 3 или 4 байта на символ. При том 4 байт тот же mysql не умеет хранить вовсе.

Psychotech пишет:
А где инфу взять про это чтобы на будущее предугадывать подобное?

Использовать только mb_*, для других функций проверять, умеет ли та иногобайтовые кодировки.
10. Psychotech - 07 Июня, 2015 - 13:31:44 - перейти к сообщению
Мелкий пишет:
Psychotech пишет:
русские же символы в utf-8 входят в диапозон 0-255;

Не входят. С чего вы это взяли?
Кириллица в UTF8 живёт в диапазоне 0xD090 .. 0xD18F, плюс 0xD001 и 0xD191 для Ёё. Весьма и весьма далеко от 0x00-0xFF


не это в принципе доходчиво, только я имел ввиду

насколько я понял это имелось ввиду в описании мультибайтовых функций. У меня почему-то шло расхождение именно здесь. Если быть точнее то когда я вводил к примеру "Ы" то функция ставила в игнор при этом код ошибки выдавала там где "Ы" только писало знак вопроса в ромбе
PHP:
скопировать код в буфер обмена
  1. $resultat['denied'] = $spectr[$i];

а при
PHP:
скопировать код в буфер обмена
  1. $resultat['char'] = ord($spectr[$i]);
ставило код другой буквы (помоему "Р" русской)
0xD090 - это хекс код в 16-ой кодировке где здесь диапозон 0-255. в хексе диапозон 0-255 кажется только 0х00 - 0хFF чтобы было понятнее тем кто не знаком понятнее обьяснить на цветах, то есть RGB можно выразить как цвет красного ,зеленого и синего в диапозоне 0-255 то есть белый это 255,255,255 соответственно диапозон символов, которые попадают под функцию char() тоже лежат в диапозоне от 0-255 при выводе char() со всеми значениями начиная с 192 по 255 выводятся кирилица, разве нет?
По крайней мере я так понял назначение функции char() и описание мультибайтовых функций.
Еще такой вопрос вертится в голове. почему при кодировке windows-1251 таких проблем не возникает,как сейчас. в кодировке windows получается кирилица входит в вышеупомянутый диапозон и strlen и прочие функции работают нормально.
11. Psychotech - 09 Июня, 2015 - 00:45:07 - перейти к сообщению
у меня уже крыша едет. Код из первого поста перестал работать все время выдает "правду"
12. Мелкий - 09 Июня, 2015 - 11:21:07 - перейти к сообщению
Psychotech пишет:
$spectr[$i];

Обращение к конкретному байту, не символу.

ord - Возвращает ASCII код символа.
ASCII - вообще 7-битная кодировка, кириллицы там нет никакой. То, что функция возвращает в принципе значение любого байта - так исторически сложилось.

Psychotech пишет:
RGB можно выразить как цвет красного ,зеленого и синего в диапозоне 0-255

TrueColor. 8 бит на цвет, угу. Хм, откуда вы в этих девяностых нашли UTF8?
Уже в конце девяностых появился какой-нибудь OpenEXR, 16 бит на цвет и редкоиспользуемые профили аж до 32 бит на каждый цвет.
Ныне всякие Hi10P и прочие HDR.
Ну, по графике - это не ко мне, но верить, что 16млн цветов хватит всем?..

Psychotech пишет:
0xD090 - это хекс код в 16-ой кодировке где здесь диапозон 0-255. в хексе диапозон 0-255 кажется только 0х00 - 0хFF

А хто сказал, что это одно значение? Вроде уже давно вам говорят "многобайтовая кодировка". Это два байта, 0xD0 и 0x90.
Своими побайтовыми операциями вы читаете первый байт и отчего-то удивляетесь, что он не соответствует многобайтовому символу.
Ну вот для архаичной CP1251 0xD0 кириллической букве Р и соответствует.

Psychotech пишет:
при кодировке windows-1251 таких проблем не возникает

Потому что в ASCII заняты 7 бит. И в туеву кучу голов разом пришла мысль, что в оставшийся бит можно понапихать всякой фигни, несовместимой друг с другом, разумеется. Вот так получилась известная эпоха веба с попытками угадать кодировку страницы и до сих пор сохраняется стандарт на именование передаваемых файлов только в латинице. И куча таких же костылей в других протоколах.
Повезло ещё, что ASCII-несовместимые кодировки почти не встречаются. А то и такие были.
Но весь этот ворох кодировок остался умещающимся в 1 байт.
13. Psychotech - 09 Июня, 2015 - 12:51:49 - перейти к сообщению
С приципами кодировки уже вроде разобрались пора возвращаться к насущным проблемам. почему скрипт, который после достижения рабочего состояния не меняли перестал адекватно реагировать.
PHP:
скопировать код в буфер обмена
  1. if($testmode==='num'){
  2.                         for($i=0;$i<strlen($stroka);$i++){
  3.                                 $spectr[$i] = substr($stroka,$i,1);
  4.                                 if(!in_array($spectr[$i], $this->numbermass)){
  5.                                         return false;
  6.                                         }
  7.                                 }
  8.                         return true;
  9.                         }
  10. //где private $numbermass = array(0,1,2,3,4,5,6,7,8,9);

Скрипт проверки
PHP:
скопировать код в буфер обмена
  1.  
  2. require_once("coreengine/securyenter.php");
  3. $security = new SecuryEnter;
  4. $text = '12221d';
  5. $test = $security->generalTest($text, 'num');
  6. if($security->generalTest($text, 'num')){
  7.         print "pravda<br> $text<br>";
  8. }else{
  9.         print "false <br> $text<br>";
  10. }
14. Мелкий - 09 Июня, 2015 - 13:16:51 - перейти к сообщению
Значит меняли тестовые входные данные.

В конкретно-взятом случае проблема растёт от классических граблей динамической типизации PHP, 'd' == 0 -> true
Пользовательский ввод надо проверять через http://php.net/manual/en/function.filter-var.php или регулярками - компактнее и нагляднее. Но по граблям походить тоже надо, главное, чтобы в реальный проект этот велосипед не шёл.
15. Psychotech - 09 Июня, 2015 - 13:26:07 - перейти к сообщению
Мелкий пишет:
http://php.net/manual/en/function.filter-var.php или регулярками - компактнее и нагляднее

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

 

Powered by ExBB FM 1.0 RC1