Интернет списание на летен жител. Направи си сам градина и зеленчукова градина

Лудо валидиране на php. Валидиране и почистване на данни с помощта на PHP. Случвания и изключения


В предишна статия обещах да напиша сравнение на собствената си библиотека с други налични решения, така че днес ще разгледаме валидирането с помощта на Aura.Filter, Respect Validation, Sirius Validation и Valitron.


Нека си представим, че имаме определена обществена услуга в процес на разработка, която изисква потребителите да се регистрират за пълен достъп до всички функции. По този начин формулярът за регистрация ще съдържа следните полета:

  • име. Трябва да съдържа точно две думи, като първата е собственото име на потребителя, а втората е фамилията.
  • Влизам. Ако се подаде стойност, тя трябва да съдържа само латински букви, тирета и долна черта.
  • електронна поща. Трябва да съдържа валиден имейл адрес.
  • парола. Трябва да бъде зададено и да е с дължина не повече от 64 знака.
  • съгласен. Типично квадратче за отметка, което потребителят трябва да постави, за да потвърди, че приема условията на услугата.
  • И така, имаме пет полета, които потребителят трябва да попълни, за да се регистрира в нашата въображаема услуга. Нека си представим, че сме получили напълно невалидни данни като вход:


    $data = [ "name" => "Albert", // Трябва да има две думи "login" => "@lbert", // "Забранен" символ @ "email" => "нещо не е наред", / / ​​Трябва да има бъде имейл "парола" => Aura.Filter

    Валидирането с помощта на Aura.Filter започва с фабрика за филтри. Трябва да създадем така наречения „филтър за тема“, тъй като ще валидираме масив, а не индивидуална стойност.

    Ние дефинираме правилата, използвайки Aura\Filter\FilterFactory; $filter = (нова FilterFactory)->newSubjectFilter(); $filter->validate("name") ->isNotBlank() ->is("two_words") ->setMessage("Името трябва да е от две думи."); $filter->validate("login") ->isBlankOr("alnum") ->setMessage("Ако посочите логин, той трябва да съдържа само латински знаци."); $filter->validate("email") ->isNotBlank() ->is("email") ->setMessage("Моля, въведете валиден имейл адрес."); $filter->validate("password") ->isNotBlank() ->is("strlenMax", 64) ->setMessage("Моля, напишете вашата парола."); $filter->validate("agreed") ->is("callback", function($subject, $field) ( return $subject->($field) === true; ))->setMessage("Имате нужда съгласете се с условията на услугата.");

    Както можете да видите, описанието на правилата е доста просто. Aura.Filter предоставя цял набор от полезни правила извън кутията и някои от тях бяха използвани в примера по-горе:

  • isNotBlank метод. Указва, че полето не може да има нулева стойност.
  • алнум. Това правило позволява само латински букви.
  • електронна поща. И е толкова ясно :)
  • strlenMax. Указва, че полето не може да надвишава дължината, зададена от втория аргумент на метода is.
  • обратно повикване. Този тип правило е подобно на затварянията от Kontrolio. Позволява ви да дефинирате правило под формата на затваряне. Към това затваряне Aura.Filter предава „темата“, нашия масив от данни от формуляра и поле, в този случай съгласувано.
  • Вероятно сте забелязали, че не съм посочил правилото за две_думи. Естествено, в Aura.Filter няма такова правило, така че трябва да създадем такова. Както се казва в документацията, това се прави с помощта на отделен клас за правилото:


    /** * Правило, което валидира потребителското име. * Потребителското име се състои от две думи: собствено и фамилно име, разделени с един интервал. */ class UserNameRule ( /** * Валидира потребителското име. * * @param object|array $subject * @param string $field * @param int $max * * @return bool */ public function __invoke($subject, $field , $max = null) ( $value = $subject->($field); if (! is_scalar($value)) ( return false; ) return (bool) preg_match("/^+\s+$/u", $стойност);

    Втората стъпка е да уведомим фабриката за филтри за нашето ново правило. Това става чрез предаване на първия аргумент като масив от правила към фабриката за филтриране:


    Следващата стъпка е да уведомим Aura.Filter, че сме създали ново правило и искаме да го използваме. Това се прави чрез предаване на масив от правила към първия аргумент на фабриката:


    използвайте Aura\Filter\FilterFactory; $rules = [ "two_words" => function() (връща ново UserNameRule; ) ]; $filter = (нова FilterFactory($rules))->newSubjectFilter();

    Сега нашето правило за две_думи може да се използва по същия начин като всяко друго стандартно правило.

    Обратна връзка

    Както си спомняте, входящите данни, които проверяваме, са напълно невалидни, тъй като всяко поле съдържа неправилна стойност или изобщо не я съдържа. Следователно се предполага, че в резултат на валидирането ще получим грешки и съответните съобщения за тях.


    Ние валидираме с Aura.Filter, както следва:


    $valid = $filter->apply($data); if (! $valid) ( $failures = $filter->getFailures(); $messages = $failures->getMessages(); )

    IN $ съобщениясе записва масив, така че за показване на съобщения се нуждаем от две вложени foreach:


    Уважавайте валидирането

    Втората библиотека, която използвах в сравнението, е сравнително популярно решение, наречено Respect Validation. Тъй като хората й вярват, мисля, че има какво да се види там.


    За чистотата на експеримента, когато сравняваме библиотеки, ще използваме същия набор от данни, дефиниран в началото:


    използвайте Respect\Validation\Validator като v; $data = [ "name" => "Albert", // Трябва да има две думи "login" => "@lbert", // "Забранен" знак @ "email" => "нещо не е наред", / / ​​Трябва да има бъде имейл тук "password" => "" // Паролата изобщо не е посочена // "agreed" не е в масива, защото потребителят не е поставил отметка в квадратчето ]; Определяне на правилата

    Както при Aura.Filter, имаме нужда от собствено правило за валидиране на потребителското име, така че нека започнем оттук:


    пространство от имена MyNamespace; използвайте Respect\Validation\Rules\AbstractRule; клас UserNameRule разширява AbstractRule (публична функция validate($input) ( return (bool) preg_match("/^+\s+$/u", $input); ))

    API за външни правила е почти идентичен с Aura.Filter, само методът validate() се използва вместо магията __invoke(). Струваше ми се, че този API е по-прост и по-разбираем. Е, по-близо е до Kontrolio :)


    Не намерих никакво споменаване на това в документацията, но в допълнение към самото правило трябва да създадете свой собствен тип изключение за него. Името на класа на изключение трябва да се състои от името на класа на правилото и постфикс Изключение.


    използвайте Respect\Validation\Exceptions\NestedValidationException; клас UserNameRuleException разширява NestedValidationException ( // )

    Е, най-накрая можем да потвърдим нашите данни. Първо предаваме нашето ново правило на валидатора, така че той да знае за него и да можем да го използваме в бъдеще. В Respect Validation това става чрез извикване на метода with(), като се предава пространството от имена, в което се намират нестандартните правила.


    v::with("MyNamespace\\");

    Сега всички нестандартни правила се намират в пространството от имена MyNamespace, ще бъдат „разпознати“ от валидатора. Следващата стъпка е да опишем необходимите правила и да извършим валидиране.


    v::attribute("name", v::userNameRule()) ->attribute("login", v::alnum("-_")) ->attribute("email", v::email()) ->attribute("password", v::notEmpty()->stringType()->length(null, 64)) ->attribute("agreed", v::trueVal()) ->assert((object) $данни);

    Забележете как прилагаме нашето правило към атрибута име. Тук името на класа на правилото е трансформирано в името на метода на валидатора. Останалите правила като цяло са интуитивни.


    Струва си да споменем отделно защо предоставяме масива $данникъм обекта. Факт е, че Respect Validation приема обекти, а не масиви като вход. Това трябва да се вземе предвид при разработването с помощта на тази библиотека.

    Обратна връзка

    За разлика от Aura.Filter, валидаторът Respect хвърля изключение, когато валидирането е неуспешно. И това изключение съдържа съобщения за грешка при валидиране. Следователно примерът, който току-що беше показан, трябва да бъде написан по следния начин:


    опитайте ( v::with("RespectValidationExample\\"); v::attribute("name", v::userNameRule()) ->attribute("login", v::alnum("-_")) - >attribute("email", v::email()) ->attribute("password", v::notEmpty()->stringType()->length(null, 64)) ->attribute("agreed", v::trueVal()) ->assert((object) $data ) catch (NestedValidationException $ex) ( $messages = $ex->getMessages(); )

    Използвайки getMessages(), ще получим плосък масив от всички съобщения, събрани от валидатора по време на процеса на валидиране. Като изхвърлим масива, получаваме нещо подобно:


    array(5) ( => string(29) „Неуспешна проверка на данните за %s“ => string(60) „входът трябва да съдържа само букви (a-z), цифри (0–9) и „-_““ => низ (25) „имейлът трябва да е валиден имейл“ => низ (26) „паролата не трябва да е празна“ => низ (32) „Трябва да присъства съгласуван атрибут“ )

    Можете да промените съобщенията на свои. Може би по някакъв начин съм разбрал погрешно тази библиотека, но този процес не ми се стори толкова очевиден: трябва да използвате метода findMessages() за обработено изключение, в което дефинирате съобщения не за атрибути, а за правила.


    $ex->findMessages([ "userNameRule" => "Потребителското име трябва да се състои от две думи.", "alnum" => "Не харесваме вашето влизане.", "email" => "Очевидно не харесвате искате да ни дадете вашия имейл.", "notEmpty" => "Е, къде е вашата парола?", "agreed" => "Жалко, че не сте съгласни." ]);

    Не знам какво не е наред, но има няколко неща, които все още не разбирам. Ето какво получаваме, като дефинираме правилата по горния начин:


    array(5) ( => string(40) “Потребителското име трябва да е от две думи.” => string(31) “Не харесваме вашето име.” => string(25) “имейлът трябва да е валиден имейл” = > string(5) „Е, къде е вашата парола?“ => string(9) „Жалко, че не сте съгласни.“

    Както можете да видите, съобщението за имейл полето не беше приложено, остана стандартното. Но съобщението на индекс 4 е обратното! И това въпреки факта, че не използвах името на правилото, а името на полето. Докато ако бях използвал името на правилото (trueVal), съобщението ми щеше да се изгуби някъде. Коментарите от опитни потребители на тази библиотека са добре дошли.

    Проверка на Сириус

    Добре, нека преминем към следващата библиотека и да видим как се справя с подобни задачи.

    Определяне на правилата

    Отново трябва да дефинираме правило за потребителското име. Ще го напишем нещо подобно:


    class UserNameRule extends AbstractRule ( // Съобщения за грешка const MESSAGE = "Потребителското име трябва да е две думи."; const LABELED_MESSAGE = "(етикетът) трябва да е две думи."; публична функция validate($value, $valueIdentifier = null) ( return (bool) preg_match("/^+\s+$/u", $value ) )

    Моля, обърнете внимание на разликата в подходите в сравнение с вече обсъдените библиотеки. Ние дефинираме два вида съобщения в константи, вместо да използваме свойства, методи или аргументи на правило.


    Сега нека опишем логиката на валидиране:


    $validator = нов валидатор; $validator ->add("name", "required | MyApp\Validation\Rule\UserNameRule") ->add("login", "required | alphanumhyphen", null, "Login може да съдържа само латински букви, тирета и долни черти. ") ->add("имейл", "задължително | имейл", null, "Моля, въведете правилен имейл.") ->add("парола", "задължително | maxlength(64)", null, "Вашият парола, сър.") ->add("съгласен", "задължително | равно(вярно)", null, "Защо не се съгласихте?");

    Както можете да видите, наборът от правила е много прост и разбираем. За описание използваме имена, разделени с хоризонтални ленти. Този подход е подобен на този, използван в Laravel и Kontrolio.


    Четвъртият аргумент на метода add() описва съобщението за грешка при валидиране, което Sirius ще използва, ако валидирането е неуспешно. Защо не добавихме съобщение за нашето ново правило? UserNameRule?


    $validator->add("име", "задължително | MyApp\Validation\Rule\UserNameRule")

    Това е така, защото съобщенията вече са описани в константите на класа:


    class UserNameRule extends AbstractRule ( // Съобщения за грешка const MESSAGE = "Потребителското име трябва да е от две думи."; ...

    Друг вариант е да използвате метода addMessage() на самия валидатор:


    $validator->addMessage("имейл", "Моля, въведете валиден имейл.");

    Моля, обърнете внимание, че персонализираните правила се идентифицират с пълното име на техния клас, докато в Kontrolio можете да посочите псевдоним/псевдоним.

    Обратна връзка

    За да извършим валидиране, ние извикваме метода на валидатора validate(), като му предаваме данни:


    $data = [ "name" => "Albert", // Трябва да има две думи "login" => "@lbert", // "Забранен" знак @ "email" => "нещо не е наред", / / ​​Трябва да има бъде имейл тук "password" => "" // Паролата изобщо не е посочена // "agreed" не е в масива, защото потребителят не е поставил отметка в квадратчето ]; $валидатор->валидиране($данни);

    За разлика от Respect, Sirius няма да направи изключение, а просто ще се върне невярно. Съобщенията за грешка при валидиране могат да бъдат получени чрез метода на валидатора getMessages(). Той връща грешки, групирани по атрибути, така че имаме нужда от два цикъла foreach, за да преминем през грешките:


    foreach ($validator->getMessages() as $attribute => $messages) ( foreach ($messages as $message) ( echo $message->getTemplate() . "\n"; ) )

    Тук $message е обект от клас Sirius\Validation\ErrorMessage, който има метод getTemplate(), който връща точното съобщение, от което се нуждаем.

    Valitron Дефиниране на правилата

    Първата разлика: за да добавите ново правило, не е необходимо да създавате отделен клас. Можете просто да използвате затваряне, което връща булев резултат.


    За добавяне на персонализирани правила Valitron има статичен метод addRule(), в който първите два аргумента са задължителни, а третият е незадължителен. Хареса ми този метод, тъй като показва идентификатора на правилото, логиката и съобщението за грешка на едно място.


    използвайте Valitron\Validator; Validator::addRule("two_words", function($field, $value) ( ​​​​return (bool) preg_match("/^+\s+$/u", $value); ), "Потребителското име трябва да се състои точно от две думи ");

    Втората разлика е как правилата се прилагат към атрибутите. Във всички предишни случаи видяхме, че атрибутът е, така да се каже, основно нещо.


    Valitron пое по различен път и постави на първо място правилата за валидиране. Като описвате правила, изглежда, че прилагате атрибути към тези правила, а не обратното.


    $валидатор = нов валидатор($данни); $validator ->rule("two_words", "name")->label("") ->rule("required", [ "name", "login", "email", "password", "agreed" ] ) ->rule("slug", "login") ->rule("email", "email") ->rule("accepted", "agreed");

    Както може да се види от примера, в метода rule() първо пишем името на правилото и едва след това посочваме атрибутите, които трябва да съответстват на това правило. По-ясен пример е задължителното правило, което показва как атрибутите „принадлежат“ на това правило.


    Valitron (подобно на други решения, които сме прегледали) предоставя стандартни съобщения за грешки. Ако просто ги използвате, ще видите, че всяко съобщение започва с името на съответния атрибут.


    Valitron замества имена на атрибути в текста на съобщението дори когато се използват нестандартни съобщения за грешка. Ето защо използвахме метода label() с празен низ, за ​​да премахнем името на атрибута.


    $validator->rule("two_words", "name")->label("") Обратна връзка

    Конкретно по отношение на валидирането, API на библиотеката Valitron практически не се различава от това, което вече видяхме в статията. За да извършим валидиране, ние извикваме метода на валидатора validate():


    $validator->validate();

    Съобщенията за грешка при валидиране могат да бъдат извлечени с помощта на метода getErrors():


    $валидатор->грешки();

    Съобщенията тук са групирани по атрибути по същия начин, както при Sirius Validation, с изключение на това, че няма отделен клас за съобщението и получаваме обикновен многоизмерен масив.


    foreach ($validator->errors() as $attribute => $messages) ( foreach ($messages as $message) ( echo $message . "\n"; ) ) Kontrolio

    И накрая, последната библиотека за днес е моята собствена разработка, наречена Kontrolio.

    Определяне на правилата

    Отново, за пети път, ще създадем правило за валидиране на потребителското име. Всичко е сравнително просто и стандартно:


    пространство от имена MyProject\Validation\Rules; използвайте Kontrolio\Rules\AbstractRule; class TwoWords разширява Kontrolio\Rules\AbstractRule ( публична функция isValid($input = null) ( return (bool) preg_match("/^+\s+$/u", $input); ))

    Сега създаваме фабрика и регистрираме правило с нея, използвайки метода extend():


    пространство от имена MyProject; използвайте Kontrolio\Factory; използвайте MyProject\Validation\Rules\TwoWords; $factory = Kontrolio\Factory::getInstance()->extend();

    След като регистрираме правилото, можем да го използваме, включително и по име - two_words. Нека създадем валидатор:


    $data = [ "name" => "Albert", // Трябва да има две думи "login" => "@lbert", // "Забранен" знак @ "email" => "нещо не е наред", / / ​​Трябва да има бъде имейл тук "password" => "" // Паролата изобщо не е посочена // "agreed" не е в масива, защото потребителят не е поставил отметка в квадратчето ]; $rules = [ "name" => "two_words", "login" => "sometimes|alphadash", "email" => "email", "password" => "length:1.64", "agreed" = > " прието" ]; $messages = [ "name" => "Потребителското име трябва да се състои от две думи.", "login" => "Не ни харесва вашето име за вход.", "email" => "Очевидно не искате да дадете ни вашия имейл .", "password" => "Е, къде е вашата парола?", "agreed" => "Жалко, че не сте съгласни." ]; $validator = $factory->make($data, $rules, $messages);

    Описахме правилата, използвайки синтаксис, подобен на този, използван в Laravel, въпреки че можехме да използваме по-подробна версия:


    $rules = [ "name" => new TwoWords, "login" => , "email" => new Email, "password" => new Length(1, 64), "agreed" => new Accepted ]; Обратна връзка

    Валидирането се стартира с помощта на същия метод validate():


    $validator->validate();

    Сега можем да получаваме съобщения за грешки, като използваме един от методите getErrors() или getErrorsList(). Първият метод позволява по-сложно извеждане на грешки, докато вторият връща плосък масив. Използвайки getErrors(), можем да изведем съобщения нещо подобно:



    И с getErrorsList() можете да направите по-опростен списък от съобщения:


    Долен ред

    В тази статия показах примери за използване на следните библиотеки:

  • Аура. Филтър
  • Уважавайте валидирането
  • Проверка на Сириус
  • Валитрон
  • контрол
  • „Пример от реалния свят“ може да изглежда твърде прост. Трябва да се съглася, тъй като наистина някои възможности на библиотеката бяха пропуснати от статията. По принцип, ако ви интересува, можете сами да проучите техните характеристики.


    Всяка от библиотеките предлага свои собствени функции и има своите тъмни страни, така че мисля, че е въпрос на вкус и предизвикателство да изберете тази.


    Благодаря за четенето. Направете правилния избор.

    Тагове: Добавете тагове

    Много е важно входът във вашия формуляр да бъде валидиран, преди да вземете данните за подаване на формуляра за по-нататъшна обработка. Когато във формуляра има много полета, скриптът за проверка на PHP става твърде сложен. Освен това, тъй като правите същото или подобно валидиране за повечето формуляри, които правите, твърде много дублирани усилия се изразходват за валидиране на формуляри.

    Относно този общ PHP скрипт за валидиране на формуляр

    Този общ PHP скрипт за валидиране на формуляри прави много лесно добавянето на валидации към вашия формуляр.

    Ние създаваме и свързваме набор от „дескриптори за валидиране“ с всеки елемент във формуляра. „Дескрипторът за валидиране“ е низ, указващ вида на валидирането, което трябва да се извърши. Например „req“ означава задължително, „alpha“ означава разрешаване само на букви и т.н.

    Всяко поле във формуляра може да има нула, една или повече проверки. Например въведеното не трябва да е празно, трябва да е по-малко от 25 знака, трябва да е буквено-цифрено и т.н.

    Можете да асоциирате набор от валидиращи дескриптори за всяко поле за въвеждане във формуляра.

    Изтеглете PHP скрипта за валидиране на формуляр

    Можете да изтеглите PHP скрипта за валидиране на формуляр по-долу:
    Zip файлът съдържа скрипта за валидиране на формуляр formvalidator.php, документация и примери за използване.

    Използване на PHP скрипт за валидиране на формуляр
  • Включете formvalidator.php във вашия скрипт за обработка на формуляри
  • require_once "formvalidator.php"
  • Създайте обект FormValidator и добавете дескрипторите за валидиране на формуляра.
  • $валидатор = нов FormValidator(); $validator->addValidation("Име","req","Моля, попълнете име"); $validator->addValidation("Имейл","имейл", "Входът за имейл трябва да бъде валидна имейл стойност"); $validator->addValidation("Имейл","req","Моля, попълнете имейл");

    Първият аргумент е името на полето за въвеждане във формата. Вторият аргумент е дескрипторът за валидиране, който казва типа на изискваното валидиране. Третият аргумент е съобщението за грешка, което трябва да се покаже, ако проверката е неуспешна.

  • Валидирайте формуляра, като извикате функцията ValidateForm().
  • if(!$validator->ValidateForm()) ( echo "Грешки при валидиране:"; $error_hash = $validator->GetErrors(); foreach($error_hash as $inpname => $inp_err) ( echo "

    $inpname: $inp_err

    \n"; ) ) Пример

    Примерът по-долу ще направи идеята по-ясна

    Име: Имейл:

    Добавяне на персонализирано валидиране

    Ако искате да добавите персонализирано валидиране, което не е предоставено от дескрипторите за валидиране, можете да го направите. Ето стъпките:

  • Създайте клас за персонализираното валидиране и заменете функцията DoValidate().
  • клас MyValidator разширява CustomValidator ( функция DoValidate(&$formars,&$error_hash) ( if(stristr($formars["Comments"],"http://")) ( $error_hash["Comments"]="Няма разрешени URL адреси в коментарите"; return false; ) return true; ) )

  • Добавете персонализирания обект за валидиране
  • $валидатор = нов FormValidator(); $validator->addValidation("Име","req","Моля, попълнете име"); $validator->addValidation("Имейл","имейл", "Входът за имейл трябва да бъде валидна имейл стойност"); $validator->addValidation("Имейл","req","Моля, попълнете имейл"); $custom_validator = нов MyValidator(); $validator->AddCustomValidator($custom_validator);

    Персонализираната функция за валидиране ще бъде извикана автоматично след други валидации.

    Таблица с дескриптори за валидиране

    Ето списъка с всички дескриптори за валидиране:

    Дескриптор за валидиранеИзползване
    изискванеПолето не трябва да е празно
    макслен=???проверява максималната дължина на въведените данни. Например, ако максималният разрешен размер е 25, дайте дескриптора за валидиране като „maxlen=25“
    минлен=???проверява дължината на въведения низ до необходимия минимум. пример „minlen=5“
    алнумПроверете данните дали съдържат други знаци, различни от букви или цифри
    alnum_sПозволява само букви, цифри и интервали
    брПроверете цифровите данни
    алфаПроверете данните по азбучен ред.
    alpha_sПроверете данните по азбучен ред и позволете интервали.
    електронна пощаПолето е поле за имейл и проверете валидността на данните.
    lt=???
    по-малко=???
    Проверете дали данните са по-малки от предадената стойност. Валидно само за числови полета.
    пример: ако стойността трябва да е по-малка от 1000, дайте описание за валидиране като „lt=1000“
    gt=???
    по-голямо=???
    Уверете се, че данните са по-големи от предадената стойност. Валидно само за числови полета.
    пример: ако стойността трябва да е по-голяма от 10, дайте описание за валидиране като „gt=10“
    regexp=???Проверете с регулярен израз стойността трябва да съвпада с регулярния израз.
    пример: “regexp=^(1.20)$” позволява до 20 азбучни знака.
    dontselect=??Този дескриптор за валидиране е за избрани входни елементи (списъци). Обикновено полетата със списък за избор ще имат един елемент, казващ „Изберете един“. Потребителят трябва да избере опция, различна от тази опция. Ако стойността на тази опция е „Изберете едно“, описанието за валидиране трябва да бъде „dontselect=Изберете едно“
    dontselectchkТози валидиращ дескриптор е за квадратчета за отметка. Потребителят не трябва да поставя отметка в даденото поле. Въведете стойността на квадратчето за отметка вместо ??
    Например dontselectchk=on
    shouldselchkТози валидиращ дескриптор е за квадратчета за отметка. Потребителят трябва да постави отметка в даденото квадратче. Въведете стойността на квадратчето за отметка вместо ??
    Например, shouldselchk=on
    dontselectradioТози валидиращ дескриптор е за радио бутони. Потребителят не трябва да избира дадения радио бутон. Въведете стойността на бутона за избор вместо ??
    Например dontselectradio=NO
    изберете радиоТози валидиращ дескриптор е за радио бутони. Потребителят трябва да избере дадения радио бутон. Въведете стойността на бутона за избор вместо ??
    Например selectradio=yes
    селмин=??Изберете поне n на брой квадратчета за отметка от група квадратчета за отметка.
    Например: selmin=3
    СамотенПрави задължителна радиогрупа. Потребителят трябва да избере поне един елемент от радиогрупата.
    eqelmnt=???сравнете два елемента във формуляра и се уверете, че стойностите са еднакви, например „парола“ и „потвърдете парола“. Заменете ??? с името на другия входен елемент.
    Например: eqelmnt=confirm_pwd

    Reg.ru: домейни и хостинг

    Най-големият регистратор и хостинг доставчик в Русия.

    Повече от 2 милиона имена на домейни в услуга.

    Промоция, домейн поща, бизнес решения.

    Повече от 700 хиляди клиенти по света вече са направили своя избор.

    *Задръжте мишката, за да спрете превъртането на пауза.

    Назад напред

    Валидиране и почистване на данни с помощта на PHP

    Сигурността на данните е много важен момент, който често се подценява както от разработчиците, така и от клиентите. Започвайки с PHP 5.2.0, почистването и валидирането на данни (проверка за съответствие с определени критерии) стана по-лесно с въвеждането на филтриране на данни. Днес ще разгледаме техниките за филтриране, как да използваме филтри и ще създадем някои персонализирани функции.

    Въведение

    Винаги съм смятал, че писането на код в PHP е лесно, а още по-лесно е да пишете лош код в PHP. Широкото използване на PHP в областта на уеб разработката е улеснено от много проекти с отворен код като WordPress, Drupal, Magento. Освен това това са уеб приложения като Facebook и т.н. При такова широко разпространено използване на PHP (динамични уебсайтове, платформи за блогове, системи за управление на съдържание, използване в приложения за електронна търговия и т.н.), вероятността да се натъкнете на мръсна информация и несигурни системи е много голяма. Този урок ще ви покаже някои методи за почистване и валидиране на данни с помощта на PHP. Ще се съсредоточим върху няколко типа въвеждане и как да използваме PHP филтри и персонализирани функции.

    Защо да почиствате и проверявате?

    В това ръководство ще се съсредоточим върху информация, която идва директно от потребители, както и от други външни източници. Това означава, че нямаме контрол върху информацията, която получаваме. Всичко, което можем да направим, е да контролираме какво ще се прави с тази получена информация. Почти всички видове заплахи идват от информация, предадена от потребители или други трети страни.

    Сред основните:

    - XSS (Cross-Site Scripting)

    Това е метод за инжектиране на код, при който скрипт се инжектира в страница на атакувания уебсайт от напълно различен сайт на различен сървър. Тази уязвимост се счита за една от най-често срещаните в мрежата.

    - SQL инжекция

    Следващата популярна уязвимост е друга форма на инжектиране на код, която позволява различни видове злонамерено поведение, включително неоторизиран достъп до информация, промяна на информацията в базата данни или по друг начин нарушаване на нормалното функциониране на уеб приложение. Тази атака се извършва чрез инжектиране на произволен SQL код в заявката, предназначен да взаимодейства с базата данни.

    - CSRF/XSRF (Cross-Site Request Forgery)

    Тази уязвимост е по-рядко срещана от предишните. Обикновено този вид уязвимости възникват при работа със сесии и бисквитки и по-рядко при лошо проверени и изчистени данни. CSRF може да се използва, за да позволи на даден сайт да прави всякакви заявки без знанието на потребителя. Един от известните начини за реализиране на тази атака е използването на неправилно образуван атрибут srcна картината, което води до изпълнение на някакъв скрипт, а не до показване на картината.

    - Некоректна информация

    Неправилната информация сама по себе си не е „уязвимост“. Подобна информация обаче в много случаи води до редица проблеми както за собственика на сайта, така и за администратора на базата данни. Често неправилната по структура информация води до смущения в работата, особено ако сайтът е реализиран на любителско ниво, не по стандарти, както и до сривове в работата на автоматизирани системи, които очакват ясно структурирани данни в определен формат за обработка.


    Превод на диалога към картината:

    Здравейте, това е училището на сина ви, което ви притеснява. Тук имаме проблеми с компютрите.

    О, Боже, счупи ли нещо?

    Истинското име на сина ви е Робърт"); DROP TABLE ученици;?

    О, да, викаме го Малки маси Боби

    Разбирате ли, загубихме всички записи за тазгодишните ученици. Надявам се да сте доволни.

    И се надявам да се научите да проверявате информацията, въведена в базата данни.

    За нашите цели ще се съсредоточим само върху използването на техники от страна на сървъра за подобряване на информационната сигурност, така че нека да разгледаме как се дефинират термините „дезинфекция“ и „валидиране“, когато се прилагат към PHP. Нека да разгледаме ръководството за PHP:

    „Валидирането се използва, за да се провери дали информацията, която се проверява, отговаря на определени изисквания. Например, използвайки FILTER_VALIDATE_EMAIL, ние определяме дали информацията е валиден (т.е. структурно правилен) имейл адрес, но не променяме тези данни.

    Почистването предполага възможна промяна в проверяваната информация, например премахване на нежелани знаци. Например, когато използвате FILTER_SANITIZE_EMAIL, знаците, които не трябва да се съдържат в имейл адреса, ще бъдат премахнати. Тези. В този случай няма проверка на коректността на адреса (т.е. валидиране), но очевидно неподходящите знаци се премахват - нищо повече."

    По същество, ако мислите за сайта си като за нощен клуб, в който всеки иска да отиде, проверката е задачата да се провери дали даден гост е в списъка с гости, дезинфекцията е отбивачът, който държи нежеланите елементи извън клуба. така.

    Какви филтри имам?

    Всички PHP инсталации не могат да бъдат идентични. Въпреки че филтрите бяха въведени в PHP 5.2.0, не всички инсталации имат еднакъв набор от филтри. В повечето случаи всички филтри, за които ще говорим, вече ще бъдат включени в PHP, инсталиран на вашия сървър, но за да ви помогнем да научите малко повече за филтрите, ще разгледаме какво е налично на вашия сървър конкретно. Файлът с изходния код е прикачен getfilters.php, който след като бъде инсталиран и стартиран на сървъра, ще покаже списък с всички ваши филтри (като информационните филтри, достъпни чрез функцията filter_varи поточно предаване, достъпно чрез stream_filter_append)

    Echo "Филтри за данни\n

    \н \n"; ехо " \n"; ехо " \н"; foreach(filter_list() as $id =>$filter) ( ехо " \n"; ) ехо "
    ИД на филтъраИме на филтъра
    $филтър".filter_id($filter)."
    \н";

    Първо получаваме масив, съдържащ списък на всички налични филтри, използващи функцията филтър_списък, след което преминаваме през масива, показвайки името на филтъра и неговия идентификатор.

    Как да използвам филтъра?

    PHP филтрите за валидиране и пречистване се активират чрез предаване на функция filter_varпоне два параметъра. Като пример, нека приложим филтър за изчистване към цяло число:

    $стойност = "123abc456def"; echo filter_var($value, FILTER_SANITIZE_NUMBER_INT); !}

    В този пример имаме променлива стойност, което предаваме на функцията filter_varот PHP Filters Extension с помощта на филтъра FILTER_SANITIZE_NUMBER_INT. В резултат ще получим:

    Филтърът за почистване на цели числа премахва всички знаци, които не са цели числа, като ни дава "чисто" цяло число. В източниците можете да опитате различни входове и към тях ще бъдат приложени редица общи филтри. Архивът включва различни низове, които можете сами да използвате като тестов материал.

    Какво правят различните филтри?

    Списъкът по-долу не е пълен, но съдържа повечето от филтрите, които идват със стандартна инсталация на PHP 5.2.0+.

    FILTER_VALIDATE_BOOLEAN: Проверява дали предадената информация е булева стойност TRUE или FALSE. Ако предадената стойност не е булева стойност, тогава се връща FALSE. Скриптът по-долу ще отпечата TRUE за примера на променливата стойност1 стойност02:

    $стойност01 = ВЯРНО; if(filter_var($value01,FILTER_VALIDATE_BOOLEAN)) ( echo "TRUE"; ) else ( echo "FALSE"; ) echo "

    " $value02 = FALSE; if(filter_var($value02,FILTER_VALIDATE_BOOLEAN)) ( echo "TRUE"; ) else ( echo "FALSE"; )

    FILTER_VALIDATE_EMAIL: Проверява дали предадената информация е валиден имейл адрес по отношение на структурата. Не се проверява дали този адрес действително съществува, а само валидността на адреса, т.е. правилността на неговата структура. Скриптът по-долу ще отпечата TRUE за примера на променливата стойност01и FALSE за примера на променливата стойност02(тъй като задължителната част със знака @ липсва):

    $value01 = " [имейл защитен]"; if(filter_var($value01,FILTER_VALIDATE_EMAIL)) ( echo "TRUE"; ) else ( echo "FALSE"; ) echo "

    " $value02 = "nettuts"; if(filter_var($value02,FILTER_VALIDATE_EMAIL)) ( echo "TRUE"; ) else ( echo "FALSE"; )

    FILTER_VALIDATE_FLOAT: Проверява дали предадената стойност е число с плаваща запетая. Скриптът по-долу ще отпечата TRUE за примера на променливата стойност01и FALSE за примера на променливата стойност02(тъй като разделянето "," не е разрешено в числа с плаваща запетая):

    $value01 = "1,234"; if(filter_var($value01,FILTER_VALIDATE_FLOAT)) ( echo "TRUE"; ) else ( echo "FALSE"; ) echo "

    " $value02 = "1,234"; if(filter_var($value02,FILTER_VALIDATE_FLOAT)) ( echo "TRUE"; ) else ( echo "FALSE"; )

    FILTER_VALIDATE_INT: Проверява дали предадената стойност е цяло число. Скриптът по-долу ще отпечата TRUE за примера на променливата стойност01и FALSE за примера на променливата стойност02(десетичните числа не са цели числа):

    $value01 = "123456"; if(filter_var($value01,FILTER_VALIDATE_INT)) ( echo "TRUE"; ) else ( echo "FALSE"; ) echo "

    " $value02 = "123.456"; if(filter_var($value02,FILTER_VALIDATE_INT)) ( echo "TRUE"; ) else ( echo "FALSE"; )

    FILTER_VALIDATE_IP: Проверява дали предадената стойност е валиден IP адрес. Той не проверява дали има отговор от този адрес, а само дали прехвърлената стойност по своята структура е IP адрес. Скриптът по-долу ще отпечата TRUE за примера на променливата стойност01и FALSE за примера на променливата стойност02:

    $value01 = "192.168.0.1"; if(filter_var($value01,FILTER_VALIDATE_IP)) ( echo "TRUE"; ) else ( echo "FALSE"; ) echo "

    " $value02 = "1.2.3.4.5.6.7.8.9"; if(filter_var($value02,FILTER_VALIDATE_IP)) ( echo "TRUE"; ) else ( echo "FALSE"; )

    FILTER_VALIDATE_URL: Проверява дали подадената стойност е валиден URL. Не проверява, не проверява дали ресурсът е достъпен, а само дали се следва URL структурата. Скриптът по-долу ще отпечата TRUE за примера на променливата стойност01и FALSE за примера на променливата стойност02:

    $value01 = "http://net.tutsplus.com"; if(filter_var($value01,FILTER_VALIDATE_URL)) ( echo "TRUE"; ) else ( echo "FALSE"; ) echo "

    " $value02 = "nettuts"; if(filter_var($value02,FILTER_VALIDATE_URL)) ( echo "TRUE"; ) else ( echo "FALSE"; )

    FILTER_SANITIZE_STRING: По подразбиране този филтър премахва невалидна или неоторизирана информация в низ. Например, той ще премахне всички HTML тагове като или от входния низ:

    $value = "alert("TROUBLE HERE");"; echo filter_var($value, FILTER_SANITIZE_STRING); !}

    Този скрипт ще премахне таговете и ще върне следното:

    Предупреждение ("ПРОБЛЕМА ТУК");

    FILTER_SANITIZE_ENCODED: Много програмисти използват функцията urlencode(). Този филтър по същество изпълнява същите функции. Например, следният пример ще кодира всички специални знаци и интервали във входния низ:

    $value = "alert("TROUBLE HERE");"; echo filter_var($value, FILTER_SANITIZE_ENCODED); !}

    Скриптът ще кодира пунктуация, интервали, скоби и ще върне следното:

    %3Cscript%3Ealert%28%27TROUBLE%20HERE%27%29%3B%3C%2Fscript%3E

    FILTER_SANITIZE_SPECIAL_CHARS: Този филтър по подразбиране е HTML кодиране на специални знаци като кавички, амперсанд и скоби. Тъй като демонстрационната страница не може да покаже това изрично (тъй като HTML-кодираните специални знаци ще бъдат интерпретирани от браузъра и показани), можете да го видите, ако погледнете изходния код:

    $value = "alert("TROUBLE HERE");"; echo filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS); !}

    Специалните знаци ще бъдат преобразувани в техните HTML обекти:

    FILTER_SANITIZE_EMAIL: Този филтър прави точно това, което всички си мислеха, че ще направи. Той премахва знаци от адреса, които не трябва да присъстват в адреса (кръгли и квадратни скоби, двоеточие и т.н.) Да приемем, че случайно сте добавили скоби около буква към вашия адрес (не ме питайте как, използвайте въображението си :) )

    $стойност = "t(e) [имейл защитен]"; echo filter_var($value, FILTER_SANITIZE_EMAIL);

    Скобите ще бъдат премахнати и ще получите своя чист и красив имейл:

    [имейл защитен]

    Това е отличен филтър, който може да се използва в имейл формуляри, особено когато се сдвоява с FILTER_VALIDATE_EMAIL, което ще намали потребителските грешки и ще предотврати XSS атаки.

    FILTER_SANITIZE_URL: Този филтър е подобен на предишния. Той премахва всички знаци, които не са разрешени в URL адреса. Например, да приемем, че в адреса случайно имаше знак "®". Отново, как е попаднал там е пълна мистерия.

    $value = "http://net.tuts®plus.com"; echo filter_var($value, FILTER_SANITIZE_URL); !}

    По този начин ще премахнем ненужния знак "®" и ще получим нормален адрес:

    http://net.tutsplus.com

    FILTER_SANITIZE_NUMBER_INT: Този филтър е подобен на FILTER_VALIDATE_INT, но вместо просто да проверява дали дадено число е цяло число, той също премахва всичко, което не е цяло число. Отлично нещо, особено срещу досадните спам ботове и измамници, които се опитват да въведат някакви глупости в полето:

    $value01 = "123abc456def"; echo filter_var($value01, FILTER_SANITIZE_NUMBER_INT); ехо "
    "; $value02 = "1.2.3.4.5.6.7.8.9"; echo filter_var($value02, FILTER_SANITIZE_NUMBER_INT);

    123456 123456789

    FILTER_SANITIZE_NUMBER_FLOAT: Подобно на FILTER_VALIDATE_INT. Освен това ви позволява да постигнете подобен ефект:

    $value01 = "123abc456def"; echo filter_var($value01, FILTER_SANITIZE_NUMBER_FLOAT); ехо "
    "; $value02 = "1.2.3.4.5.6.7.8.9"; echo filter_var($value02, FILTER_SANITIZE_NUMBER_FLOAT);

    И двата набора знаци се преобразуват и изходът е следният:

    123456 123456789

    $стойност = "1,23"; echo filter_var($стойност, FILTER_SANITIZE_NUMBER_FLOAT);

    Точката ще бъде премахната и стойността ще бъде върната:

    Една от основните причини филтрите FILTER_SANITIZE_NUMBER_FLOAT и FILTER_SANITIZE_INT да са разделени е възможността да се използва специалният флаг FILTER_FLAG_ALLOW_FRACTION, който идва като трети параметър, предаден на функцията filter_var:

    $стойност = "1,23"; echo filter_var($стойност, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

    Опции, флагове и контролни масиви - Mein Gott!

    Флагът, използван в предишния пример, е само един от начините за по-подробен контрол върху типовете данни, които ще бъдат изчистени, дефинициите на разделителите, как масивите се обработват от филтри и т.н. Можете да научите повече за флаговете и функциите, използвани във връзка с използването на филтри в ръководството за PHP, в частта, посветена на филтрите - php.net/manual/en/book.filter.php.

    Други методи за изчистване на информация чрез PHP

    Сега ще разгледаме няколко ключови техники за почистване на данни, за да предотвратим атака срещу вашето приложение. Те са особено подходящи за тези приложения, които все още работят на PHP4, както се появиха с неговото пускане.

    htmlspecialchars: Тази PHP функция преобразува 5 специални знака в съответните HTML обекти.

    На трансформация подлежат:

    & (амперсанд)
    " (двойни кавички), когато флагът ENT_NOQUOTES не е зададен
    ’ (единични кавички) само когато флагът ENT_QUOTES е зададен
    < (меньше, чем)
    > (повече от)

    Тази функция се използва по същия начин като всяка друга в PHP:

    Echo htmlspecialchars("$string");

    htmlentities: Подобно на функция htmlspecialcharsтази функция преобразува специални знаци в техните HTML обекти. Единствената разлика е, че в този случай всички специални символи, които могат да бъдат конвертирани, се конвертират. Това е доста често срещан метод за прикриване на имейл адреси от спам ботове, тъй като не всички от тях са конфигурирани да четат html обекти:

    Echo htmlentities("$string");

    mysql_real_escape_string: Това е функция на MySQL, която помага за защита срещу атаки чрез SQL инжектиране. Счита се за добра практика (и всъщност необходимост) цялата информация, предадена на SQL заявката, да се предава през тази функция. Избягва всички опасни специални символи, които могат да причинят проблеми и да причинят малки маси Бобище унищожи друга таблица в училищната база данни.

    $query = "SELECT * FROM table WHERE value=".mysql_real_escape_string("$string")." LIMIT 1,1"; $runQuery = mysql_query($query); !}

    Персонализирани функции

    За много хора вградените функции и филтри може да не са достатъчни. Често може да се изисква по-стриктно и по-тясно валидиране или пречистване. За да постигнат желаните резултати, много хора сами пишат функции за валидиране на данни. Пример е опцията за търсене в база данни за стойности от определен тип, като:

    Функция checkZipCode($value) ( ​​​​$zipcheck = "SELECT COUNT(*) FROM `database`.`zipcodes` WHERE value="".filter_var(mysql_real_escape_string($value),FILTER_SANITIZE_NUMBER_INT)."""; $count = mysql_query($zipcheck); if($count==1) (връща TRUE;) else (връща FALSE;))

    Други потребителски функции може да не са директно свързани с базата данни, но подготвят информация, преди да я вмъкнат в базата данни:

    Функция cleanString($string) ( $detagged = strip_tags($string); if(get_magic_quotes_gpc()) ( $stripped = stripslashes($detagged); $escaped = mysql_real_escape_string($stripped); ) else ( $escaped = mysql_real_escape_string($) detagged); връща $escaped;

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

    Хареса ли ви материала и искате да ми благодарите?
    Просто споделете с вашите приятели и колеги!


    Ще говорим за валидирането на POST или GET данни, въпреки че по принцип това може да се приложи и към данни, получени чрез други методи, като бисквитки. Когато разработвате каквото и да е уеб приложение, трябва да напишете интерфейс за взаимодействие с потребителите и естествено да създадете различни форми за потребителите, за да изпращат данни към сървъра. например, това могат да бъдат коментари. Мисля, че за всички е ясно и очевидно, че получените данни трябва да бъдат проверени дали отговарят на типа, размера и посочения диапазон. На първо място, това е необходимо за сигурността на системата, уебсайта или базата данни, защото... Неправилно предадени данни или умишлено лошо оформена заявка могат да отворят достъп до нападател.

    Второ, непроверените данни, ако са неправилни, могат да причинят нестабилна работа на скрипта, системата или целия сървър. Следователно всички данни трябва да бъдат проверени и препроверени; може би някой ще каже, че няма нужда от излишна параноя, но аз смятам, че в случая тя просто не може да бъде излишна.

    Не се доверявайте на данните, получени от потребителите, под никакъв предлог, при никакви обстоятелства. Случва се просто да ни мързи да напишем код, който проверява отново получените данни, или се надяваме, че съществуващите методи за проверка са достатъчни, в резултат на което правим отстъпки за себе си.

    Малко отклонение от темата:
    Работата по проекти, разработването и програмирането на уебсайтове, скриптове и други системи заема почти цялото ми свободно време (освен работното време), с други думи, върша тази работа за максимално възможния брой часове на ден. От време на време има нужда да тествате нещо, за забавление или просто от любопитство. В резултат на това сайтове, направени набързо, използвайки домашно приготвени машини или CMS от древни версии, се превръщат в подобни тестови лабораторни плъхове. Разбира се, всичко по-горе страда от криво написан код, липса на контрол на данните и просто гъмжи от различни грешки. Всъщност в повечето случаи за един час мои експерименти на такива сайтове успявам да намеря няколко сериозни уязвимости и повечето от тях се крият в недостатъчна валидация на входящите данни. Напоследък това често се среща в скриптове, които обработват POST данни, получени от JavaScript + Ajax.

    Очевидно програмистите, които са написали тези скриптове с помощта на Ajax, смятат, че тъй като всички заявки се извършват във фонов режим, без знанието на потребителя или просто без презареждане на страницата, тогава данните не трябва да бъдат специално проверявани.

    Като правило, доста от тези скриптове се оказват толкова пълни с дупки, че без много усилия успяват да направят по-голяма дупка и да наводнят черупката си. разбира се, само с цел експериментиране и нищо повече (администрацията на такива сайтове винаги е информирана за съществуващите уязвимости).

    Мисля, че важността на валидирането е ясна за всички. Дълго време всеки път пишех едно и също парче код, след което използвах собствените си функции за проверка на данни, много от които бяха много примитивни и като правило разпръснати в различни части на (включени) файлове. Скоро започнах да се запознавам с PHP рамките Zend, CI, Kohana, всяка от които имплементира собствен клас за валидиране на данни, които заех за моите проекти. В крайна сметка реших да пригодя един от CI класовете според моите нужди, но се оказа, че авторът на един от блоговете за програмиране вече се е погрижил за това. След това споделям неговите произведения, а именно модифицираната библиотека CodeIgniter.

    Нека да разгледаме следния код:

    Вижте кода PHP

    require_once "validator.class.php" ; $валидатор = нов валидатор() ; $валидатор -> set_rules ("име" , "Вашето име" , масив ("задължително" => , "алфа" => ) ) ; $validator -> set_rules ("email" , "Вашият имейл" , array ("required" => "Поле %s е задължително" , "valid_email" => ) ) ; if ($validator -> run () ) ( echo "Проверката беше успешна" ; ) else ( echo $validator -> get_string_errors () ; )

    Както можете да видите от примера, в първия ред включваме файла на класа validator.calss.phpкъм нашия скрипт. След това създаваме екземпляр на класа и запазваме обекта в променлива $валидатор.
    След това с помощта на метода $validator->set_rules($field, $label, $rules)задайте полетата за проверка.

    Този метод приема 3 параметъра:

  • $поле- име на полето за проверка (стойността на атрибута name в тага)
  • $етикет- име на полето за проверка, ще бъде вмъкнато в съобщенията за грешка
  • $правила- масив от правила за валидиране, в който правилото за валидиране се използва като ключ, а съобщението за грешка за това правило се използва като стойност
  • След като всички полета за валидиране са зададени, стартираме валидатора чрез метода $validator->run(). Ако проверката е успешна, този метод ще върне стойността ВЯРНО, в противен случай, ако има някакви грешки, ще се върне НЕВЯРНО.

    Има три метода за получаване на съобщения за грешка:

  • get_string_errors()- връща всички съобщения за грешка като низ
  • get_array_errors()— връща всички съобщения като масив, където името на полето се използва като ключ, а описанието на грешката за това поле се използва като стойност.
  • грешка_на_формата($поле)- връща съобщение за грешка за полето, предадено като параметър $field
  • По подразбиране съобщенията за грешка са обвити в таг . За да зададете своя дизайн, използвайте метода set_error_delimiters($префикс, $суфикс). Например така:

    Сега съобщенията за грешка ще се превърнат в дивс класа "грешка"

    Както можете да видите, всичко е много просто.

    Вижте кода PHP

    $validator -> set_error_delimiters ( " ", " " );

    За да зададете правила за валидиране, можете да използвате метода set_rules($fields)предават многомерен асоциативен масив. Да разгледаме един пример:

    Вижте кода PHP

    $rules = array ( array ( "field" => "name" , "label" => "Вашето име" , "rules" => array ( "required" => "Поле %s е задължително" , "alpha" = > "Полето %s трябва да съдържа само букви" ) , array ( "field" => "email" , "label" => "Вашият имейл" , "rules" => array ( "required" => "Полето % s е задължително" , "valid_email" => "Поле %s трябва да съдържа валиден имейл адрес" ) ) ) ; $validator -> set_rules ($rules ) ;

    Както можете да видите, записах същите правила за валидиране като в първия пример, само под формата на многомерен асоциативен масив. Можете да използвате всеки от методите, които ви подхождат най-добре в дадена ситуация.

    И така, какви правила за валидиране поддържа този клас?

    Донесох в този клас най-често срещаните правила за валидиране, с които всеки се сблъсква. Ето пълен списък на тези правила:

    изисква сеВръща FALSE, ако полето е празно
    цяло числоВръща FALSE, ако стойността не е цяло число
    плавамВръща FALSE, ако стойността не е числова стойност
    valid_urlВръща FALSE, ако стойността не е валиден URL адрес
    валиден имейлВръща FALSE, ако стойността не е валиден имейл адрес
    valid_ipВръща FALSE, ако IP адресът не е валиден
    мачовеВръща FALSE, ако елементът не съответства на стойността на друг елемент на полето
    алфаВръща FALSE, ако елементът съдържа повече от букви
    valid_captchaВръща FALSE, ако стойността в полето на сесията не е равна на стойността на полето на формуляра
    валидна датаВръща FALSE, ако елементът съдържа невалидна дата

    Повечето от тези правила използват филтри, които станаха достъпни в PHP 5.

    Ако желаете, винаги можете да разширите набора от правила за валидиране, като добавите необходимите функции към класа Validator.

    За да получите стойността на обработените POST данни, използвайте следния метод:

    Вижте кода PHP

    Обикновено този метод се извиква за изчистване на формуляра при успешна обработка на формуляра.

    Валидирането на данни е фундаментално важен аспект на CRUD приложение. Трябва да сте сигурни, че данните, които клиентът ви изпраща, са това, което очаквате. Това не е само от съображения за сигурност, защита на вашите данни от злоупотреба и умишлена корупция, но и просто от неволни грешки при изпращането на данни. Низове, ограничени до определена дължина, дати в конкретен формат и задължителни полета са общи употреби на валидиране на данни.

    PHP библиотеките на редактора предоставят два различни метода за проверка:

    • Базирано на поле, където всяка отделна подадена стойност се валидира независимо: Field->validator() .
    • Глобално валидиране, при което данните, изпратени от страна на клиента, могат да бъдат валидирани като цяло: Editor->validator() .
    Наследена информация (v1.6-)

    Моля, обърнете внимание, че валидирането на PHP в Editor 1.6 и по-стари беше малко по-различно. По-старата форма на валидиране все още ще работи с библиотеките 1.7+ и нейната документация остава достъпна, но за нови проекти използвайте стила на валидиране, обсъден тук.

    Валидирането на полето е това, с което най-често ще работите - например проверка дали поле за имейл адрес действително съдържа имейл адрес, а Редакторът предоставя редица готови за използване валидатори за най-често срещаните типове данни, както и способност да посочите своя собствена. Глобалното валидиране може да бъде полезно при проверка на зависимости между полета и конфликти в съществуващия набор от данни.

    Валидиране на полето

    PHP библиотеките на редактора предоставят метод validator() за класа Field и редица предварително изградени методи за валидиране в класа Validate. Всеки от тези методи за валидиране връща функция, която се изпълнява при необходимост за валидиране на изпратените данни.

    Разгледайте следния пример - функцията Validate::minNum() е конфигурирана с число и връща функция, която може да се използва за валидатора на полето.

    Field::inst("age") ->validator(Validate::minNum(16));

    Моля, вижте по-долу за по-подробни примери.

    Опции за валидиране

    Всеки метод за валидиране, осигурен от класа Validation, може по избор да приема параметри, за да му каже как да валидира данните (например методът minLen ще приеме цяло число, за да посочи минималната дължина на приемлив низ), но всички по избор приемат екземпляр на клас ValidateOptions. Този клас дефинира редица опции, които се споделят между всички методи за валидиране.

    Класът ValidateOptions е конструиран с ValidateOptions::inst() (или нов ValidateOptions() в PHP 5.4+), подобно на другите класове на редактора. Той има три метода, които могат да се използват за промяна на поведението на валидиране:

    • ->allowEmpty(boolean) : Как да обработваме празни данни (т.е. низ с нулева дължина):
      • вярно (по подразбиране) - Позволява въвеждането на полето да бъде с нулева дължина
      • false - Забранява въвеждането на нулева дължина
    • ->message(string) : съобщението за грешка, което да се покаже, ако проверката е неуспешна. Това просто е „Въведеното не е валидно“ по подразбиране, така че вероятно ще искате да го персонализирате, за да отговаря на вашите нужди.
    • ->optional(boolean) : Изискване полето да бъде изпратено или не. Тази опция може да бъде особено полезна в Редактор, тъй като Редакторът няма да зададе стойност за полета, които не са подадени - давайки възможност за подаване само на частичен списък от опции.
      • true (по подразбиране) - Не е необходимо полето да е в списъка с параметри, изпратен от клиента.
      • false - Полето трябва да бъде включено в подадените от клиента данни.
    Пример - задаване на персонализирано съобщение за грешка Field::inst("stock_name") ->validator(Validate::minNum(10, new ValidateOptions::inst() ->message("Името на акциите трябва да е дълго поне 10 знака") )); Множество валидатори

    Често може да бъде полезно да използвате няколко валидатора заедно, например за да потвърдите, че въведен низ е по-малък от определен брой знаци и също така, че е уникален в базата данни. Множество валидатори могат да бъдат добавени към поле просто чрез извикване на метода Field->validator() няколко пъти. Вместо да презапише предишния валидатор, той всъщност ще ги добави заедно. Те се изпълняват в последователността, в която са добавени, и всички валидатори трябва да преминат, за да бъдат данните приети за валидни.

    Като пример разгледайте следния код, който ще провери минималната и максималната дължина на данните, както и че е уникален:

    Field::inst("stock_name") ->validator(Validate::minLen(10)) ->validator(Validate::maxLen(12)) ->validator(Validate::unique());

    Готови за използване полеви валидатори

    Класът Validate в PHP библиотеките на Editor има редица методи, които могат да се използват за извършване на валидиране много бързо и лесно. Това са:

    Основен
    • none(ValidateOptions $cfg=null) - Не се извършва проверка
    • basic(ValidateOptions $cfg=null) - Основно валидиране - извършва се само валидирането, предоставено от ValidateOptions
    • required(ValidateOptions $cfg=null) - Полето трябва да бъде изпратено и данните не трябва да са с нулева дължина. Обърнете внимание, че Редакторът има опцията да не изпраща всички полета (например при вградено редактиране), така че валидаторът notEmpty() се препоръчва вместо този.
    • notEmpty(ValidateOptions $cfg=null) - Полето не трябва да се изпраща, но ако е, не може да съдържа данни с нулева дължина
    • boolean(ValidateOptions $cfg=null) - Проверете дали са изпратени булеви данни (включително 1, вярно включено, да, 0, невярно, изключено и не)
    Числа
    • numeric(string $decimalChar=".", ValidateOptions $cfg=null) - Проверете дали всеки вход е числов.
    • minNum(цяло число $min, низ $decimalChar=".", ValidateOptions $cfg=null) - Числовият вход е по-голям или равен на даденото число
    • maxNum(integer $max, string $decimalChar=".", ValidateOptions $cfg=null) - Числовият вход е по-малък или равен на даденото число
    • minMaxNum(integer $min, integer $max, string $decimalChar=".", ValidateOptions $cfg=null) - Числовият вход е в дадения диапазон (включително)
    струни
    • email(ValidateOptions $cfg=null) - Валидирайте въведеното като имейл адрес.
    • ip(ValidateOptions $cfg=null) - Валидирайте като IP адрес.
    • minLen(integer $min, ValidateOptions $cfg=null) - Уверете се, че низът има минимална дължина.
    • maxLen(integer $max, ValidateOptions $cfg=null) - Уверете се, че низ не надвишава максимална дължина.
    • minMaxLen(integer $min, integer $max, ValidateOptions $cfg=null) - Уверете се, че низ има дадена дължина в диапазон
    • noTags(ValidateOptions $cfg=null) - Не позволявайте HTML тагове
    • url(ValidateOptions $cfg=null) - Валидирайте като URL адрес.
    • values(array $values, ValidateOptions $cfg=null) - Позволява само стойности, които са посочени в масив от опции (първият параметър). Това може да бъде полезно, ако желаете да имате вход в свободна форма или да създадете списък за избор и искате да потвърдите, че изпратената стойност е в рамките на даден набор от данни (вижте също метода dbValues(), ако валидни стойности се съхраняват в база данни) . Обърнете внимание, че стойностите, дадени в масива от стойности, се проверяват спрямо подадените данни като данни, които са чувствителни към регистър (т.е. „A“ != „a“).
    • xss(ValidateOptions $cfg=null) - Проверете дали входът може да съдържа XSS атака. Това използва функцията за форматиране XSS на полето, за да определи дали въведеният низ трябва да бъде форматиран или не.
    Време за среща
    • dateFormat(string $format, ValidateOptions $cfg=null) - Проверете дали е въведена валидна дата. Форматът се дефинира от метода date() на PHP, който се използва за анализиране на низ от дата и час.
    База данни
    • dbValues(ValidateOptions $cfg=null, string $column=null, string $table=null, Database $db=null, array $valid=null) - Позволява само стойност, която присъства в колона на база данни. Това е специално проектирано за използване с обединени таблици (т.е. уверете се, че референтният ред присъства, преди да го използвате), но потенциално може да се използва и в други ситуации, където се изисква референтна цялост.
    • unique(ValidateOptions $cfg=null, string $column=null, string $table=null, array $db=null) - Уверете се, че изпратените данни са уникални в колоната на таблицата.
    Един към много (Mjoin)

    Обърнете внимание, че тези методи са за използване с метода Mjoin->validator() (Редактор 1.9 и по-нова). Моля, вижте документацията на Mjoin за повече подробности.

    • mjoinMinCount($minimum, ValidateOptions $cfg=null) - Изискване поне дадения брой опции/стойности да бъдат изпратени за присъединяване един към много.
    • mjoinMaxCount($maximum, ValidateOptions $cfg=null) - Изискване тези много или по-малко опции / стойности да бъдат изпратени за присъединяване един към много.
    Персонализирани валидатори на полета

    Ако предоставените методи по-горе не отговарят на типа валидиране, което търсите, е абсолютно възможно да предоставите персонализирани методи за валидиране. Методът validator() Field ще приеме функция, която връща true или низ и приема следния вход параметри:

  • стойност - Стойността, която трябва да бъде валидирана
  • данни – Съвкупността от данни за въпросния ред
  • field - Екземплярът на хост Field
  • хост - Информация за екземпляра на редактора на хоста
  • Върнатата стойност трябва да е истина, за да покаже, че валидирането е преминало, или низ, който съдържа съобщение за грешка, ако валидирането е неуспешно.

    Следният прост пример показва как може да се приложи проверка на низ maxLen с персонализиран метод за валидиране:

    Field::inst("last_name") ->validator(function ($val, $data, $field, $host) ( return strlen($val) > 50 ? "Дължината на името трябва да бъде 50 знака или по-малко" : true; ));

    Примери за валидиране на полета

    Използвайте метода Validation.minNum(), за да потвърдите вход като число и по-голямо или равно на дадено число (не са посочени опции за валидиране, така че се използват стойностите по подразбиране):

    // Обикновено непразно поле Field::inst("age") ->validator(Validate::minNum(16))

    Както по-горе, но с ValidateOptions, използвани за задаване на съобщението за грешка:

    // Проверка на диапазона на номера с персонализирано съобщение за грешка Field::inst("range") ->validator(Validate::minNum(16, ValidateOptions::inst() ->message("Minimum age is 16")));

    Този път валидиране на имейл адрес, който не може да бъде празен и трябва да бъде изпратен:

    Field::inst("email") ->validator(Validate::email(ValidateOptions::inst() ->allowEmpty(false) ->optional(false)));

    Съединение с dbValues ​​​​което ще приеме празна стойност, която се съхранява като null в базата данни:

    Field::inst("users.site") ->options(Options::inst() ->table("sites") ->value("id") ->label("name")) ->validator( Валидиране::dbValues()),

    Разрешете изпращането само на определени стойности:

    Field::inst("group") ->validator(Validate::values(array("CSM", "FTA", "KFVC"))))

    Следното показва пълен пример на редактор с приложени методи за валидиране:

    Ditor::inst($db, "staff") ->fields(Field::inst("first_name") ->validator(Validate::notEmpty(ValidateOptions::inst() ->message("Изисква се собствено име "))), Field::inst("last_name") ->validator(Validate::notEmpty(ValidateOptions::inst() ->message("Изисква се фамилно име"))), Field::inst(" позиция"), Field::inst("имейл") ->validator(Validate::email(ValidateOptions::inst() ->message("Моля, въведете имейл адрес"), Field::inst( "office"), Field::inst("extn"), Field::inst("age") ->validator(Validate::numeric()) ->setFormatter(Format::ifEmpty(null)), Field: :inst("salary") ->validator(Validate::numeric()) ->setFormatter(Format::ifEmpty(null)), Field::inst("start_date") ->validator(Validate::dateFormat(" Y-m-d")) ->getFormatter(Format::dateSqlToFormat("Y-m-d")) ->setFormatter(Format::dateFormatToSql("Y-m-d"))) ->process($_POST) ->json();

    Глобални валидатори

    Може също да намерите за полезно да можете да дефинирате глобален валидатор, който да се изпълнява всеки път, когато се направи заявка към сървъра и се изпълни методът Editor->process(). Този метод може да се използва за осигуряване на ограничения на достъпа за сигурност, валидиране на входните данни като цяло или дори за проверка дали даден потребител е влязъл преди обработка на заявката.

    функция

    Функцията, която се дава на метода Editor->validator() има следния подпис:

  • $editor - Екземплярът на редактора, за който се изпълнява функцията.
  • $action - Действието, което се извършва - това ще бъде едно от:
    • Editor::ACTION_READ - Четене / получаване на данни
    • Editor::ACTION_CREATE - Създаване на нов запис
    • Editor::ACTION_EDIT - Редактиране на съществуващи данни
    • Редактор::ACTION_DELETE - Изтриване на съществуващ ред(ове)
    • Editor::ACTION_UPLOAD - Качване на файл.
  • $data - Данните, предоставени от клиента.
  • Върнатата стойност от функцията трябва да бъде низ, ако проверката е неуспешна, където върнатият низ е съобщението за грешка, което да се покаже на крайния потребител. Ако проверката премине, върнете празен низ, нула или просто няма оператор за връщане.

    Имайте предвид, че тази функция се изпълнява само веднъж, когато се извика методът Editor->process(), а не веднъж на изпратен ред. Освен това, считано от Editor 1.9, е възможно да се добавят множество функции за валидиране чрез извикване на Editor->validator() няколко пъти, точно както при валидаторите на полета. Дадените валидатори ще се изпълняват последователно.

    Примери // Разрешаване на достъп само за четене въз основа на променлива на сесия Editor::inst($db, "table") ->fields(...) ->validator(function ($editor, $action, $data) ( if ( $action !== Editor::ACTION_READ && $_SESSION["read_only"]) (връщане "Не може да се променят данни"; ) )) ->process($_POST) ->json(); // Създаване и редактиране със зависимо валидиране Editor::inst($db, "table") ->fields(...) ->validator(function ($editor, $action, $data) ( if ($action == = Editor::ACTION_CREATE ||. $action === Editor::ACTION_EDIT) ( foreach ($data["data"] as $pkey => $values) ( if ($values["country"] === "САЩ " && $values["location"] === "London UK") ( return "London UK не е в САЩ"; ) ) ) )) ->process($_POST) ->json(); Документация за PHP API

    Документацията за разработчици на PHP API за PHP класовете на редактора е достъпна за подробна и техническа дискусия относно методите и класовете, обсъдени по-горе.

    Свързани публикации