Автор Тема: Валидация на вх. данни  (Прочетена 1114 пъти)

0 Потребители и 1 Гост преглежда(т) тази тема.

liumbiwe

  • Newbie
  • *
  • Благодарности
  • -Казани: 0
  • -Получени: 0
  • Публикации: 5
Валидация на вх. данни
« -: 21 Юни 2016, 19:07:23 »
  Здравейте ,
нека първо се представя. Казвам се Любо и от един месец работя като стажант php програмист във Варненска фирма ,и съм студент съм 2-ра година.

 Бих искал да ви попитам за някакво леко обяснение за добър начин на валидиране на множество данни от различен тип. Работя с дати , стрингове , файлове [документи , изображения] и т.н. Понеже if след if ми се струва малко претъпкано и нечетливо.
  Съхранявам данните в масив. В момента валидирам с 10-ина метода , връщайки булеви стойности.

Едно псевдо обяснение мн. би ми помогнало.
Благодаря!

catgirl

  • Newbie
  • *
  • Благодарности
  • -Казани: 6
  • -Получени: 2
  • Публикации: 22
Re: Валидация на вх. данни
« Отговор #1 -: 22 Юни 2016, 00:39:35 »
Здравей  :)
Аз ползвам jquery validate plugin - https://jqueryvalidation.org/  и след това, понеже използвам фреймуърк - PHP валидация, която се предлага от съответните класове и методи на фреймуърка.
Пример за jQuery validation:
Код: Javascript
  1. $(document).ready(function() {
  2.     $('#login-form').validate({
  3.         rules: {
  4.             password: "required",
  5.             email: {
  6.                 required: true,
  7.                 email: true
  8.             }
  9.         },
  10.         messages: {
  11.             password: {
  12.                 required: "",
  13.                 minlength: "Your password must be at least 6 characters long"
  14.             },
  15.             email: {
  16.                 required: "",
  17.                 email: "Please enter a valid email address"
  18.             }
  19.         },
  20.        
  21.         submitHandler: function (form) {
  22.            form.submit();
  23.         }
  24.  });
  25. });


За PHP валидация - например аз пиша на Ларавел : https://laravel.com/docs/5.2/validation
Код: PHP
  1. $validator = Validator::make($request->all(), [ 'title' => 'required|unique:posts|max:255', 'body' => 'required', ]);
  2.  
« Последна редакция: 22 Юни 2016, 20:05:37 от Avalanche »

HanKrum

  • Hero Member
  • *****
  • Благодарности
  • -Казани: 120
  • -Получени: 73
  • Публикации: 994
  • Кибик
Re: Валидация на вх. данни
« Отговор #2 -: 22 Юни 2016, 15:55:07 »
Аз не ползвам готови библиотеки и материали, за да държа нещата прости и под контрол.
Винаги преди валидация нормализирам данните, тогава ги мятам на един клас, който ми връща вулева стойност за всичко.
Ако решиш да го видиш на живо как работи, о886 125 11о, и аз съм във Варна ;)
Ако ти хареса идеята, ще го публикувам и другите да го пробват.
"Силата на правителството се крепи на невежеството на народа, и те знаят това и винаги ще се борят против просвещението." Лев Толстой

HD

  • Administrator
  • Hero Member
  • *****
  • Благодарности
  • -Казани: 208
  • -Получени: 165
  • Публикации: 3077
Re: Валидация на вх. данни
« Отговор #3 -: 28 Юни 2016, 08:52:24 »
Здравей и добре дошъл във форума!
Сега на въпроса  ти. Първо въпроса ти е много общо зададен. Процесът на валидация на данни е от две части. Първо имаш нормализация на данните. Тук проверяваш за тип данни. Ако например имаш поле, което записваш някакво число. При валидирането трябва да си сигурен, че данните от полето ще са число.  След това започваш с процеса на валидация. Проверяваш за дължина(mb_strlen), използваш trim, за да премахнеш ненужно празни места(space) преди и след данните  и подготвяш данните за запазване в база данни(htmlspecialchars). Това е най-общо казано.

liumbiwe

  • Newbie
  • *
  • Благодарности
  • -Казани: 0
  • -Получени: 0
  • Публикации: 5
Re: Валидация на вх. данни
« Отговор #4 -: 29 Юни 2016, 15:57:46 »
Тя логиката е ок, ама аз съм наредил 10 if-а един след друг , и ми се струва малко грозно.
Главната цел на въпроса ми е да разбера някакъв общоприет начин на писане на валидатор, който да не го е грижа колко и какви на тип данни влизат в него. В момента имам 5 валидиращи метода за 5 различни форми , което е леко претъпкано според мен , а и някои валидации се повтарят в кода.
Вярно е начинаещ съм , сега би трябвало да мисля как да го накарам да работи ,а не как да се чете по-лесно и да е по-леко/оптимизирано , но и не искам да го правя през пръсти.
Благодарности.

HD

  • Administrator
  • Hero Member
  • *****
  • Благодарности
  • -Казани: 208
  • -Получени: 165
  • Публикации: 3077
Re: Валидация на вх. данни
« Отговор #5 -: 29 Юни 2016, 18:15:12 »
Дай да видим кода.

liumbiwe

  • Newbie
  • *
  • Благодарности
  • -Казани: 0
  • -Получени: 0
  • Публикации: 5
Re: Валидация на вх. данни
« Отговор #6 -: 29 Юни 2016, 18:26:53 »
Код: PHP
  1.  public function validateData($name, $firstcontact, $phonenumber, $pic = NULL, $skype = NULL, $email = NULL, $position = NULL, $startingdate = NULL, $payout = NULL , $file_type =NULL , $doc = NULL) {
  2.         if (!$this->validateLenght($name)) { throw new Exception("The name must be at least 4 characters!"); }
  3.         if (!$this->validateDate($firstcontact)) { throw new Exception("Field 2: Invalid date!"); }
  4.         if (!$this->validatePhone($phonenumber)) { throw new Exception("Invalid phone number!"); }
  5.         if ($pic != NULL) { if (!$this->validatePic($pic)) { throw new Exception("Invalid image format (must be jpeg/bmp)!"); } }
  6.         if ($skype != NULL) { if (!$this->validateSpace($skype OR !$this->validateLenght($skype))) { throw new Exception("Too short skype name / spaces in it!");} }
  7.         if ($email != NULL) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new Exception("Invalid email!"); } }
  8.         if ($position != NULL) { if ($position < 1 OR $position > 13) { throw new Exception("Invalid position!"); } }
  9.         if ($startingdate != NULL) { if (!$this->validateDate($startingdate)) { throw new Exception("Filed 8: Invalid date!"); } }
  10.         if ($payout != NULL) { if (!$this->validateSpace($payout)) { throw new Exception("Avoid spaces in payout!"); } }
  11.         if ($file_type != NULL) { if($file_type < 1 AND $file_type > 3) { throw new Exception("Invalid file type!"); } }
  12.         if ($doc != NULL) { if(!$this->validateDoc($doc)) { throw new Exception("Invalid file format!"); } }
  13.     }
  14.  
  15.     public function validateDataTwo($dateofinterview, $timestart = NULL , $timeend = NULL) {
  16.         if (!$this->validateDate($dateofinterview)) { throw new Exception("Field 1: invalid date!"); }
  17.         if ($timestart != NULL) { if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/', $timestart)) { throw new Exception("Invalid hour format!"); } }
  18.         if ($timeend != NULL) { if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/', $timeend)) { throw new Exception("Invalid hour format!"); } }
  19.     }
  20.  
  21.     public function validateFilter($datefrom = NULL ,$dateto = NULL,$data){
  22.         if ($datefrom != NULL) { if (!$this->validateDate($datefrom)) { throw new Exception("Invalid date!"); } }
  23.         if ($dateto != NULL) { if (!$this->validateDate($dateto)) { throw new Exception("Invalid date!"); } }
  24.         if ($data['position_id'] != '') { if ($data['position_id'] < 1 OR $data['position_id'] > 13) { throw new Exception("Invalid department!"); } }
  25.     }
« Последна редакция: 29 Юни 2016, 21:27:16 от Avalanche »

canon4o

  • Sr. Member
  • ****
  • Благодарности
  • -Казани: 18
  • -Получени: 33
  • Публикации: 324
Re: Валидация на вх. данни
« Отговор #7 -: 29 Юни 2016, 23:17:05 »
О, не! Това изобщо не е добре. Примерно ако искаш да провериш дали имейла само е верен, то трябва да зададеш и останалите 5 аргумента на метода като 3 от тях са задължителни. Трябва да държиш нещата прости. Този метод трябва да го разделиш, като за всеки аргумент на правиш отделен метод, а за някои аргументи можеш да ползваш едни и същи методи. Примерно за имейл трябва да имаш validEmail($email); Като гледам си почнал някои от тях да ги вадиш (validateDate, validatePhone).

Този метод validateData() предполагам го ползваш за валидиране на данните преди запиш, то вместо да предаваш всички полета от формата като аргументи на метода просто логиката от метода я прехвърли в save метода или другия вариант е да предаваш цялата форма като един аргумент на този метод.

liumbiwe

  • Newbie
  • *
  • Благодарности
  • -Казани: 0
  • -Получени: 0
  • Публикации: 5
Re: Валидация на вх. данни
« Отговор #8 -: 30 Юни 2016, 12:33:55 »
Т'ва цялото е в клас "Validate" , който го ползвам преди да пратя данните на Модела отговарящ за записа в базата .Всичко си работи както трябва , има 3 задължителни аргумента , след тях к'вото има такова записва. А и не искам валидацията да ми е в модела.

Не съм сигурен ,че те разбрах.


EDIT: Това добре ли е ?
Код: PHP
  1. <?php
  2.  
  3. class Validate2 {
  4.  
  5.     private $data;
  6.  
  7.     public function __construct($data = array()) {
  8.         $this->data = $data;
  9.         $this->validate();
  10.     }
  11.  
  12.     private function validate() {
  13.         foreach ($this->data as $key => $value) {
  14.             if (!empty($value)) {
  15.                 switch ($key) {
  16.                     case 'name':
  17.                         $this->valName($value);
  18.                         break;
  19.                     case 'firstcontact_date':
  20.                         $this->isDate($value);
  21.                         break;
  22.                     case 'phone_number':
  23.                         $this->isPhone($value);
  24.                         break;
  25.                     case 'picture':
  26.                         $this->valPic($value);
  27.                         break;
  28.                     case 'skype':
  29.                         $this->isSkype($value);
  30.                         break;
  31.                     case 'email':
  32.                         $this->isEmail($value);
  33.                         break;
  34.                     case 'starting_date':
  35.                         $this->isDate($value);
  36.                         break;
  37.                     case 'started_on_date':
  38.                         $this->isDate($value);
  39.                         break;
  40.                     case 'wished_payout':
  41.                         $this->isNumeric($value);
  42.                         break;
  43.                     case 'position_id':
  44.                         $this->valPosition($value);
  45.                         break;
  46.                     case 'date_of_interview':
  47.                         $this->isDate($value);
  48.                         break;
  49.                     case 'time_from':
  50.                         $this->valTime($value);
  51.                         break;
  52.                     case 'time_to':
  53.                         $this->valTime($value);
  54.                         break;
  55.                     case 'next_interview_advice':
  56.                         $this->isDate($value);
  57.                         break;
  58.                     case 'next_interview_details':
  59.                         $this->str_length($value, 1000);
  60.                         break;
  61.                     case 'result':
  62.                         $this->str_length($value, 250);
  63.                         break;
  64.                 }
  65.             }
  66.         }
  67.     }
  68.    
  69.     private function str_length($value , $length) {
  70.         if ($value > $length) {
  71.             throw new Exception('Too long! Max:' . $length . ' characters!');
  72.         }
  73.     }
  74.  
  75.     private function isNumeric($param) {
  76.         if (!is_numeric($param)) {
  77.             throw new Exception('Must be numeric!');
  78.         }
  79.     }
  80.  
  81.     private function isEmail($email) {
  82.         if (!filter_var($email)) {
  83.             throw new Exception("Invalid Email address!");
  84.         }
  85.     }
  86.  
  87.     private function isSkype($skype) {
  88.         if (!preg_match('/^[a-z][a-z0-9\.,\-_]{5,31}$/i', $skype)) {
  89.             throw new Exception('Invalid Skype name!');
  90.         }
  91.     }
  92.  
  93.     private function isPhone($phone) {
  94.         if (!preg_match('/^[0-9]{10}$/', $phone)) {
  95.             throw new Exception('Invalid phone number!');
  96.         }
  97.     }
  98.  
  99.     private function valPosition($position) {
  100.         if ($position < 1 OR $position > 13) {
  101.             throw new Exception('Invalid position!');
  102.         }
  103.     }
  104.  
  105.     private function isDate($date) {
  106.         $year = substr($date, 0, 4);
  107.         $month = substr($date, 5, -3);
  108.         $day = substr($date, 8, 10);
  109.         if (!checkdate($month, $day, $year)) {
  110.             throw new Exception('Invalid date!');
  111.         }
  112.     }
  113.  
  114.     private function valSpace($param) {
  115.         if (preg_match('/\s/', $param)) {
  116.             throw new Exception('Do not use white spaces!');
  117.         }
  118.     }
  119.  
  120.     private function valPic($path) {
  121.         if (exif_imagetype($path)) {
  122.             return TRUE;
  123.         } else if (exif_imagetype($path) != IMAGETYPE_JPEG OR exif_imagetype($path) != IMAGETYPE_BMP OR exif_imagetype($path) != IMAGETYPE_PNG) {
  124.             throw new Exception('Invalid image format!');
  125.         }
  126.     }
  127.  
  128.     private function valTime($time) {
  129.         if (!preg_match("/(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])/", $time)) {
  130.             throw new Exception('Invalid time!');
  131.         }
  132.     }
  133.  
  134.     private function valFileType($type) {
  135.         if ($type < 1 OR $type > 3) {
  136.             throw new Exception('Invalid file type!');
  137.         }
  138.     }
  139.  
  140.     private function valDoc($path) {
  141.         if (mime_content_type($path) == 'application/msword') {
  142.             return TRUE;
  143.         } else if (mime_content_type($path) == 'application/pdf') {
  144.             return TRUE;
  145.         } else {
  146.             throw new Exception('Invalid document format!');
  147.         }
  148.     }
  149.    
  150.     private function valName($name) {
  151.         if (!preg_match('/^([a-zA-Z]{5,20})\s([a-zA-Z]{5,20})$/i', $name)) {
  152.             throw new Exception('Invalid name!');
  153.         }
  154.     }
  155.  
  156. }
  157.  
« Последна редакция: 30 Юни 2016, 17:22:12 от liumbiwe »

canon4o

  • Sr. Member
  • ****
  • Благодарности
  • -Казани: 18
  • -Получени: 33
  • Публикации: 324
Re: Валидация на вх. данни
« Отговор #9 -: 01 Юли 2016, 21:57:21 »
Т'ва цялото е в клас "Validate" , който го ползвам преди да пратя данните на Модела отговарящ за записа в базата .Всичко си работи както трябва , има 3 задължителни аргумента , след тях к'вото има такова записва. А и не искам валидацията да ми е в модела.

Не съм сигурен ,че те разбрах.


EDIT: Това добре ли е ?
Код: PHP
  1. <?php
  2.  
  3. class Validate2 {
  4.  
  5.     private $data;
  6.  
  7.     public function __construct($data = array()) {
  8.         $this->data = $data;
  9.         $this->validate();
  10.     }
  11.  
  12.     private function validate() {
  13.         foreach ($this->data as $key => $value) {
  14.             if (!empty($value)) {
  15.                 switch ($key) {
  16.                     case 'name':
  17.                         $this->valName($value);
  18.                         break;
  19.                     case 'firstcontact_date':
  20.                         $this->isDate($value);
  21.                         break;
  22.                     case 'phone_number':
  23.                         $this->isPhone($value);
  24.                         break;
  25.                     case 'picture':
  26.                         $this->valPic($value);
  27.                         break;
  28.                     case 'skype':
  29.                         $this->isSkype($value);
  30.                         break;
  31.                     case 'email':
  32.                         $this->isEmail($value);
  33.                         break;
  34.                     case 'starting_date':
  35.                         $this->isDate($value);
  36.                         break;
  37.                     case 'started_on_date':
  38.                         $this->isDate($value);
  39.                         break;
  40.                     case 'wished_payout':
  41.                         $this->isNumeric($value);
  42.                         break;
  43.                     case 'position_id':
  44.                         $this->valPosition($value);
  45.                         break;
  46.                     case 'date_of_interview':
  47.                         $this->isDate($value);
  48.                         break;
  49.                     case 'time_from':
  50.                         $this->valTime($value);
  51.                         break;
  52.                     case 'time_to':
  53.                         $this->valTime($value);
  54.                         break;
  55.                     case 'next_interview_advice':
  56.                         $this->isDate($value);
  57.                         break;
  58.                     case 'next_interview_details':
  59.                         $this->str_length($value, 1000);
  60.                         break;
  61.                     case 'result':
  62.                         $this->str_length($value, 250);
  63.                         break;
  64.                 }
  65.             }
  66.         }
  67.     }
  68.    
  69.     private function str_length($value , $length) {
  70.         if ($value > $length) {
  71.             throw new Exception('Too long! Max:' . $length . ' characters!');
  72.         }
  73.     }
  74.  
  75.     private function isNumeric($param) {
  76.         if (!is_numeric($param)) {
  77.             throw new Exception('Must be numeric!');
  78.         }
  79.     }
  80.  
  81.     private function isEmail($email) {
  82.         if (!filter_var($email)) {
  83.             throw new Exception("Invalid Email address!");
  84.         }
  85.     }
  86.  
  87.     private function isSkype($skype) {
  88.         if (!preg_match('/^[a-z][a-z0-9\.,\-_]{5,31}$/i', $skype)) {
  89.             throw new Exception('Invalid Skype name!');
  90.         }
  91.     }
  92.  
  93.     private function isPhone($phone) {
  94.         if (!preg_match('/^[0-9]{10}$/', $phone)) {
  95.             throw new Exception('Invalid phone number!');
  96.         }
  97.     }
  98.  
  99.     private function valPosition($position) {
  100.         if ($position < 1 OR $position > 13) {
  101.             throw new Exception('Invalid position!');
  102.         }
  103.     }
  104.  
  105.     private function isDate($date) {
  106.         $year = substr($date, 0, 4);
  107.         $month = substr($date, 5, -3);
  108.         $day = substr($date, 8, 10);
  109.         if (!checkdate($month, $day, $year)) {
  110.             throw new Exception('Invalid date!');
  111.         }
  112.     }
  113.  
  114.     private function valSpace($param) {
  115.         if (preg_match('/\s/', $param)) {
  116.             throw new Exception('Do not use white spaces!');
  117.         }
  118.     }
  119.  
  120.     private function valPic($path) {
  121.         if (exif_imagetype($path)) {
  122.             return TRUE;
  123.         } else if (exif_imagetype($path) != IMAGETYPE_JPEG OR exif_imagetype($path) != IMAGETYPE_BMP OR exif_imagetype($path) != IMAGETYPE_PNG) {
  124.             throw new Exception('Invalid image format!');
  125.         }
  126.     }
  127.  
  128.     private function valTime($time) {
  129.         if (!preg_match("/(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])/", $time)) {
  130.             throw new Exception('Invalid time!');
  131.         }
  132.     }
  133.  
  134.     private function valFileType($type) {
  135.         if ($type < 1 OR $type > 3) {
  136.             throw new Exception('Invalid file type!');
  137.         }
  138.     }
  139.  
  140.     private function valDoc($path) {
  141.         if (mime_content_type($path) == 'application/msword') {
  142.             return TRUE;
  143.         } else if (mime_content_type($path) == 'application/pdf') {
  144.             return TRUE;
  145.         } else {
  146.             throw new Exception('Invalid document format!');
  147.         }
  148.     }
  149.    
  150.     private function valName($name) {
  151.         if (!preg_match('/^([a-zA-Z]{5,20})\s([a-zA-Z]{5,20})$/i', $name)) {
  152.             throw new Exception('Invalid name!');
  153.         }
  154.     }
  155.  
  156. }
  157.  

Като за сега това е добре, но има още какво да се желае за напред.