Добавляем Captcha на страницу
Рубрика: Работаем с капчей (captcha)
14 Апр. 2009Эта статья устарела т.к. была написана для yii версии 1.0.х; Если вы используете более новую версию - у вас могут возникнуть ошибки из-за несовместимости. Обычно ответы на все вопросы работы на 1.1.х были описаны в комментариях ниже статьи.
В этом небольшом уроке я хочу рассказать вам как добавить капчу (captcha) сгенерированную с помощью Yii на ваш сайт. Хочу заметить сразу что всё логику валидацию – берет на себя Yii. Давайте начнем…
На готовом примере регистрации своего блога – я продемонстрирую вам как просто добавить капчу на вашу страницу.
И-и-и, раз…
И так что у меня есть для работы.
- UserController.php – мой контроллер который отвечает за регистрацию пользователей. Добавлять капчу мы будем для actionReg()
- user/reg.php – файл отображения который содержит код формы для регистрации
- Users.php – файл модели. Он будет заниматься у нас валидацией капчи и других полей.
В контроллере мы переопределяем метод actions следующим образом:
public function actions()
{
return array(
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xEBF4FB,
),
);
}
Этим мы говорим что в контроллере надо добавить новый экшинс с именем captcha. Данное действие обязательное.
Теперь нам надо создать сам метод регистрации:
public function actionReg()
{
$form = new Users();
# Проверяем были отправлены данные с формы или нет
if (!empty($_POST['Users']))
{
# Если данные отправлены - заполняем атрибуты в моделе
$form->attributes=$_POST['Users'];
# В поле verifyCode передаем значение которое ввёл пользователь
$form->verifyCode = $_POST['Users']['verifyCode'];
# Пробуем пройти валидацию
if($form->validate()) {
exit("Валидация прошла успешно");
# Можем сделать редирект или
# рендер любой страницы.
} else {
# Ошибка в валидации.
# На экран будут отправлены ошибки
}
}
# Выводим страницу с формой на экран
$this->render('reg', array('form' => $form));
}
Логика проста:
- Если мы заходим в user/reg тогда массив $_POST[‘User’] у нас пустой - на экран выводится просто файл reg.php
- Если мы отправили форму – тогда проходит проверка методом validate для модели User. В случае ошибки – в форма не будет сохранена, если ошибки нет – на экране увидим «Валидация прошла успешно».
Теперь в отображении reg.php надо создать примитивную форму:
<?php echo CHtml::form(); ?>
<?php echo CHtml::errorSummary($form); ?>
<?php echo CHtml::activeLabel($form, 'login'); ?>
<?php echo CHtml::activeTextField($form, 'login') ?>
<?php $this->widget('CCaptcha', array('buttonLabel' => '<br>[новый код]')); ?>
<?php echo CHtml::activeTextField($form,'verifyCode'); ?>
<?php echo CHtml::submitButton('Войти'); ?>
<?php echo CHtml::endForm (); ?>
Теперь когда вы войдете на user/reg вы увидите текстовое поле для ввода логина, капчу и поле для ввода капчи на странице.
Идем дальше, в модели (User.php) добавляем правило для валидации капчи:
public $verifyCode;
...
public function rules()
{
return array(
...
array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd')),
...
);
}
Всё! =)
Если хотите опубликовать этот материал у себя - пожалуйста, разместите ссылку на страницу откуда вы его взяли.
- Так получилось что xampp на компе умер. Куча файлов удалилась и только благодаря рестору файлов получилось получить папку "data" ... "Чем открыть файлы frm/MYD/MYI"
- Сегодня на главной странице Yii Framework-а появилось интересное сообщение о возможности быстро опробовать уже установленный Yii 1.0.6 в виде ... "Попробуй Yii как VMware образ"
- Думаю стоит назвать сегодняшний день - Днем Капчи :) В принципе уверен найдется много любителей поизвращяться и превратить капчу ... "Математическая капча"

RSol
Было сказано: Воскресенье, 31 Май 2009
Не все!
Уже наступил на эти грабли!
Еще необходимо не забыть в контроллере прописать соответствующие accessRules.
:)

[guest] xoma
Было сказано: Среда, 03 Июнь 2009
Ты наверное забыл указать, что в модель User необходимо добавить поле 'verifyCode'?? Или оно есть в табличке??

[guest] corpix
Было сказано: Воскресенье, 12 Июль 2009
Хмммм...странно...ругается он у меня на табличку...реально ли без ActiveRecord оформить???Весь инет обгугли(

[adm] zolter
Было сказано: Воскресенье, 12 Июль 2009
Весь инет не надо ) Напишите полностью какую ошибку выдает - и попробуем разобраться вместе.
Вы наверное в файле модели User.php указали не весь код. У меня в статье сокращенный вариант того как должна выглядеть таблица т.к. это просто пример как привязать капчу к любой из страниц.
Вы можете сначала пройти вот этот урок (http://dbhelp.ru/yii-form-validation/page/) который поможет вам создать форму регистрации на странице. и уже потом к тому коду что получиться - учиться прицеплять капчу по этому уроку.

[adm] zolter
Было сказано: Воскресенье, 12 Июль 2009
Скорее всего в моделе у вас не хватает строчек:
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'user';
}

[guest] corpix
Было сказано: Понедельник, 13 Июль 2009
Спасибо, с капчей управился...она требовала наличие поля verifyCode в таблице...с "недосыпа" не разобрался :D

[guest] corpix
Было сказано: Понедельник, 13 Июль 2009
Хмммм...создаётся впечатление, что нажимая F5 я могу постить сколько хочу одинаковых сообщений...пока сессия не закончится
Покачто у себя в контроллере выставил при успешном введении капчи session_destroy(); но это не выход...ведь тогда убьётся, например, сессия авторизированного пользователя

[adm] zolter
Было сказано: Понедельник, 13 Июль 2009
Вы можете в принципе сделать что б при каждом обновлении страницы - код генерировался по новой.

[guest] patison
Было сказано: Понедельник, 20 Июль 2009
Вроде всё сделал как в статье вашей, капча появилась, только вот внезависимости от того какой код я введу (пусть даже не правильный) - Валидация проходит успешно почему-то... :(

[adm] zolter
Было сказано: Понедельник, 20 Июль 2009
Значит забыл в моделе добавить правило:
array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd')),

[guest] patison
Было сказано: Вторник, 21 Июль 2009
Ага, действительно :)
А как сделать если мне например для этой-же модели надо, но для другово действия форму но без капчи. Я её не генерю в html-е формы,
Первое что приходит в голову - помещать в this->verifyCode значение сгенерённое капчей, но как его получить? Нашёл метод getVerifyCode() у класса CCaptchaAction, но чё-то не могу раздуплить как применить его...

[adm] zolter
Было сказано: Вторник, 21 Июль 2009
Всё можно :) Это ж Yii :)
В сэйватрибутес вы можете связать к какому сценарию какие атрибуты относяться. Т.е. делать запись вот такого вида:
public function safeAttributes()
{
return array(
'scen1' => 'username, password',
'scen2' => 'id, username, password',
);
}где login это название сценария. Теперь если вы хотите что б ваша validate действовала по сценарию1 делаете :
$this->validate('scen1')т.е. в сэйв атрибутах будет только "username, password", а айдишка пройдет мимо. А если хотите использовать второй сценарий с id, делаете вот так:
$this->validate('scen2')т.е. внутри validate просто указываете название сценария с которым надо работать.
Так это по поводу сэйв атрибутов и сценариев. А теперь по поводу сценариев и rules.
Каждому из прав (метод rules) вы можете указать в каком сценарии они должны быть задействованы. Это делаеться с помощью параметра "on" => "сценарий". К примеру если мы хотим что бы капча проверялась только для первого сценария мы изменяем немного в моделе правило:
array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd'), 'on' => 'scen1'),т.е. теперь проверка капчи будет работать только для первого сценария. если у правила не указан параметр 'on', тогда оно будет работать для всех сценариев.

[guest] patison
Было сказано: Вторник, 21 Июль 2009
Офигеть! Огромное спасибо. Очень увлекательно =)
зы ща зарегаюсь, я тут видимо задержусь :)))

[guest] me
Было сказано: Четверг, 27 Август 2009
у админа проблемы с падежами? В моделИ, а не в моделЕ. Нет такого условия, чтобы слово Модель при каком-либо условии писалось как МоделЕ.

virus3d
Было сказано: Понедельник, 02 Ноябрь 2009
у меня почемуто не показывает картинку капчи.
вроде работает, показывает что неправильно ввел код в поле. но вот картинки нету.

[adm] zolter
Было сказано: Понедельник, 02 Ноябрь 2009
А сам браузер не может блочить графику?
На хостинге GD включен?

[guest] Гость
Было сказано: Четверг, 29 Апрель 2010
как-то не совсем понятно для чего нужно
public function actions()
{
return array(
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xEBF4FB,
),
);
}свойства капчи это не меняет и если этот код удалить, то ошибок не будет.

[guest] zolter
Было сказано: Четверг, 29 Апрель 2010
Просто в Yii экшин может быть не только методом, но и классом, как в данном случае. Вы создаете новый экшин "captcha" за работу которого отвечает класс CCaptchaAction. В данном случае если вы зайдете localhost/you_controller/captcha - то на экране увидите вашу капчу.
п.с. свойство капчи менять должно.

[guest] Гость
Было сказано: Пятница, 01 Октябрь 2010
Если картинки капчи не показываются, надо писать в контроллере что-то вроде
public function accessRules()
{return array(array('allow', 'actions'=>array('index','view','captcha'),
'users'=>array('*'),
то есть добавить действие captcha, в список разрешенных.
В корректности не уверен, т.к сам чайник :)

[guest] Гость
Было сказано: Четверг, 11 Ноябрь 2010
Мне кажется, что формы в ЫЫЫ (Yii) всё же сильно ограничены.
Например, я уверен на 95%, что сделать вашу форму регистрации как составную (модели User, Profile) с использованием Форм Билдера и капчей - не получится.

[guest] zolter
Было сказано: Четверг, 11 Ноябрь 2010
Ну с форм билдером я особо не работал поэтому сказать не могу. Тот кто с этим больше работал - надеюсь подскажет так ли это :)

[guest] Гость
Было сказано: Вторник, 22 Февраль 2011
Если еще кому-то интересно, я поведаю, с какими сложностями столкнулся.
У меня "ручная" сборка пхп+апач+майскуэл так что первая проблема, это было:
GD and FreeType PHP extensions are required.Решилось установкой необходимой библиотеки. На моей федоре, это было очень просто:
yum install php-gdНу, поскольку я использую последнюю версию yii 1.1.6 а так же, потому, что я пытался прикрутить капчу к форме добавления комментариев в демо блоге который идет с этой версией фрейморка, или по иной моей криворукости, после установки php-gd было еще море ошибок, так что я просто оставлю этот тут:
http://www.yiiframework.ru/doc/cookbook/ru/form.captcha
в итоге, с учетом нагугленных материалов в форме получилось такое:
<?if(extension_loaded('gd') && Yii::app()->user->isGuest):?>
<div class="row">
<?=CHtml::activeLabelEx($model,'verifyCode')?>
<?$this->widget('CCaptcha',array('buttonLabel' => '<br>[другой код]<br><br>'))?>
<?=CHtml::activeTextField($model,'verifyCode')?>
<?php echo $form->error($model,'verifyCode');?>
</div>
<?endif?>остальное брал из статьи по ссылке. Там еще несколько нюансов.

[guest] Гость
Было сказано: Четверг, 24 Февраль 2011
Добрый день столкнулся с проблемой действительности капчи.
1. Ввожу данные в форму, специально оставляя не заполненным какое нибудь поле.
2. Срабатывает Ajax валидация.
3. Исправляю данные на корректные, и тут капча устаревает, т.е. вроде бы она есть но она не актуальна.
Как бороться с такой ошибкой не могли бы подсказать.

[guest] Гость
Было сказано: Пятница, 25 Февраль 2011
Вот что написано
public function rules() {
return array(
// Регистрация
array('captcha', 'captcha', 'allowEmpty' => !extension_loaded('gd'),'message'=>'Неверный защитный код', 'on'=>'reg'),
);
}

[guest] zolter
Было сказано: Пятница, 25 Февраль 2011
А 'reg' используете как сценарий ?
например $a= ModelName('reg');
или $a= ModelName();
$a->scenario='reg';
?

[guest] Гость
Было сказано: Пятница, 25 Февраль 2011
как сценарий.
Вот например в контроллере я говорю, что использовать модель
Users, явно указывая по какой схеме валидации проверять.
public function actionRegistration() {
if (Yii::app()->user->isGuest) {
$user = new Users('reg');

[guest] zolter
Было сказано: Пятница, 25 Февраль 2011
Установите что бы капча меняла своё значение к примеру только через 3-5 перезагрузок. Тогда такой проблемы не будет.


