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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Собственный фильтр данных

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Описание: Хочу написать собственный фильтр вводамых данных, но что-то не так
Psychotech
Отправлено: 07 Июня, 2015 - 08:55:34
Post Id


Новичок


Покинул форум
Сообщений всего: 32
Дата рег-ции: Июнь 2015  


Помог: 0 раз(а)




Здравствуйте форумчане. Давно здесь не был, кажись много чего поменялось. В общем взялся писать собственный фильтр вводимых данных, дабы явно дать скрипту понять что полученные данные подозрительны и их стоит обрабатывать более безопасным способом. в общем ничего не предвещало беды пока не появились какие-то непонятки на ровном месте.
Скрипт написал с лету, мунут за пять. отталкивался от ранее написаного, но больно корявого и на линейном программировании. сейчас пишу на ООП. В общем создал класс

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.

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



Посетитель


Покинул форум
Сообщений всего: 384
Дата рег-ции: Дек. 2013  
Откуда: Belarus


Помог: 22 раз(а)




Psychotech пишет:
rasultat
Psychotech пишет:
resultat
опечатка
 
 Top
Psychotech
Отправлено: 07 Июня, 2015 - 09:09:33
Post Id


Новичок


Покинул форум
Сообщений всего: 32
Дата рег-ции: Июнь 2015  


Помог: 0 раз(а)




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"
Прикреплено изображение
v53ScqF[1].png

(Отредактировано автором: 07 Июня, 2015 - 09:24:29)

 
 Top
Psychotech
Отправлено: 07 Июня, 2015 - 11:23:55
Post Id


Новичок


Покинул форум
Сообщений всего: 32
Дата рег-ции: Июнь 2015  


Помог: 0 раз(а)




выяснилось что данныая конструкция не работает только с русскими буквами, то есть. все английские попадают под проверку и проходят а кирилица поцему-то убегает.
вот только почему?
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.  
 
 Top
Ts.Saltan
Отправлено: 07 Июня, 2015 - 11:29:40
Post Id



Посетитель


Покинул форум
Сообщений всего: 384
Дата рег-ции: Дек. 2013  
Откуда: Belarus


Помог: 22 раз(а)




mb_substr, mb_strlen
Русские символы занимают больше одного байта, поэтому нужны мультибайтовые функции для работы со строками
 
 Top
Psychotech
Отправлено: 07 Июня, 2015 - 11:29:57
Post Id


Новичок


Покинул форум
Сообщений всего: 32
Дата рег-ции: Июнь 2015  


Помог: 0 раз(а)




не спасает. хотя я установил что символы в функцию передаются именно в windows-1251. конвертировал с разных сторон и на вхождении в функцию и внутри неё причем как ввод так и проверочный массив. ничего не помогает. У кого какие идеи?
(Добавление)
Ts.Saltan пишет:
mb_substr, mb_strlen
Русские символы занимают больше одного байта, поэтому нужны мультибайтовые функции для работы со строками

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



Посетитель


Покинул форум
Сообщений всего: 384
Дата рег-ции: Дек. 2013  
Откуда: Belarus


Помог: 22 раз(а)




Psychotech пишет:
почему просто substr не подходит?

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

Английский символ занимает 1 байт, русский - 2, китайский и прочие - 4, 8 и т.д.
Т.к. substr вырезает по одному байту, он вернёт «половину» русского символа, но полный английский.
По аналогии
echo $a[0] //h
echo $b[0] //?
 
 Top
LIME
Отправлено: 07 Июня, 2015 - 12:36:06
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




Psychotech пишет:
русские же символы в utf-8 входят в диапозон 0-255;
нет не входят
Фильтр станет гораздо удобнее писать если освоить регулярки
 
 Top
Мелкий Супермодератор
Отправлено: 07 Июня, 2015 - 12:49:06
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




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_*, для других функций проверять, умеет ли та иногобайтовые кодировки.


-----
PostgreSQL DBA
 
 Top
Psychotech
Отправлено: 07 Июня, 2015 - 13:31:44
Post Id


Новичок


Покинул форум
Сообщений всего: 32
Дата рег-ции: Июнь 2015  


Помог: 0 раз(а)




Мелкий пишет:
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 и прочие функции работают нормально.
 
 Top
Psychotech
Отправлено: 09 Июня, 2015 - 00:45:07
Post Id


Новичок


Покинул форум
Сообщений всего: 32
Дата рег-ции: Июнь 2015  


Помог: 0 раз(а)




у меня уже крыша едет. Код из первого поста перестал работать все время выдает "правду"
 
 Top
Мелкий Супермодератор
Отправлено: 09 Июня, 2015 - 11:21:07
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




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 байт.


-----
PostgreSQL DBA
 
 Top
Psychotech
Отправлено: 09 Июня, 2015 - 12:51:49
Post Id


Новичок


Покинул форум
Сообщений всего: 32
Дата рег-ции: Июнь 2015  


Помог: 0 раз(а)




С приципами кодировки уже вроде разобрались пора возвращаться к насущным проблемам. почему скрипт, который после достижения рабочего состояния не меняли перестал адекватно реагировать.
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. }
 
 Top
Мелкий Супермодератор
Отправлено: 09 Июня, 2015 - 13:16:51
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Значит меняли тестовые входные данные.

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


-----
PostgreSQL DBA
 
 Top
Psychotech
Отправлено: 09 Июня, 2015 - 13:26:07
Post Id


Новичок


Покинул форум
Сообщений всего: 32
Дата рег-ции: Июнь 2015  


Помог: 0 раз(а)




Мелкий пишет:
http://php.net/manual/en/function.filter-var.php или регулярками - компактнее и нагляднее

за совет конечно огромное спасибо, но хотелось бы найти причину в конкретном случае почему скрипт "живет своей жизнь" хочет работает правильно хочет перестает, причем совершенно не менялось ничего. для наглядности вечером все работало, утром встал и... слов нет по крайней мере приличных.
 
 Top
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB