|
本帖最后由 baiyuxiong 于 2010-1-25 15:18 编辑
从头学CodeIgniter和Doctrine 第三天 用户注册【翻译】下
英文原文:http://www.phpandstuff.com/articles/codeigniter-doctrine-scratch-day-3-user-signup-form翻译:http://baiyuxiong.com/article/123.htm
超过字数限制了,只好发两篇。
接上篇:http://codeigniter.org.cn/forums/thread-4632-1-1.html
表单辅助函数
我们已经载入了表单辅助函数,现在来使用它。
编辑: system/application/views/signup_form.php
HTML复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Signup Form </title>
</head>
<body>
<div id="signup_form">
<p class="heading">New User Signup </p>
<?php echo form_open('signup/submit'); ?>
<p>
<label for="username">Username: </label>
<?php echo form_input('username'); ?>
</p>
<p>
<label for="password">assword: </label>
<?php echo form_password('password'); ?>
</p>
<p>
<label for="passconf">Confirm Password: </label>
<?php echo form_password('passconf'); ?>
</p>
<p>
<label for="email">E-mail: </label>
<?php echo form_input('email'); ?>
</p>
<p>
<?php echo form_submit('submit','Create my account'); ?>
</p>
<?php echo form_close(); ?>
</div>
</body>
</html>
复制代码
我突出显示了调用的不同函数。这些函数为我们的表单标签和元素创建html。
打开http://localhost/ci_doctrine/signup
在浏览器上查看源文件:
HTML复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Signup Form </title>
</head>
<body>
<div id="signup_form">
<p class="heading">New User Signup </p>
<form action="http://localhost/ci_doctrine/signup/submit" method="post">
<p>
<label for="username">Username: </label>
<input type="text" name="username" value="" /> </p>
<p>
<label for="password">Password: </label>
<input type="password" name="password" value="" /> </p>
<p>
<label for="passconf">Confirm Password: </label>
<input type="password" name="passconf" value="" /> </p>
<p>
<label for="email">E-mail: </label>
<input type="text" name="email" value="" /> </p>
<p>
<input type="submit" name="submit" value="Create my account" /> </p>
</form>
</div>
</body>
</html>
复制代码
给它设计一下样式。
在工程目录ci_doctrine下创建一个名为css的目录。
创建文件: css/style.css
CSS复制代码
body {
font-family: "Trebuchet MS",Arial;
font-size: 14px;
background-color: #212426;
color: #11151E;
}
input, textarea, select {
font-family:inherit;
font-size:inherit;
font-weight:inherit;
}
#signup_form {
margin-left: auto;
margin-right: auto;
width: 360px;
font-size: 16px;
}
#signup_form .heading {
text-align: center;
font-size: 22px;
font-weight: bold;
color: #B9AA81;
}
#signup_form form {
background-color: #B9AA81;
padding: 10px;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
}
#signup_form form label {
font-weight: bold;
}
#signup_form form input[type=text],input[type=password] {
width: 316px;
font-weight: bold;
padding: 8px;
border: 1px solid #FFF;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
#signup_form form input[type=submit] {
display: block;
margin: auto;
width: 200px;
font-size: 18px;
background-color: #FFF;
border: 1px solid #BBB;
}
#signup_form form input[type=submit]:hover {
border-color: #000;
}
#signup_form .error {
font-size: 13px;
color: #690C07;
font-style: italic;
}
复制代码
这个教程不是关于CSS的,所以这里不做太多解释。
再次编辑:system/application/views/signup_form.php
添加高亮显示的行:
HTML复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Signup Form </title>
<link rel="stylesheet" href="<?php echo base_url(); ?>css/style.css"
type="text/css" media="all">
</head>
<body> 复制代码
我们调用了base_url()函数,在这个例子中,返回http://localhost/ci_doctrine/ 。这个函数是辅助函数的一部分。
访问: http://localhost/ci_doctrine/signup, 看到:
表单验证
如果你现在点击submit按钮,你将收到一个404错误:
因为submit() 方法不存在.
编辑: system/application/controllers/signup.php
PHP复制代码
<?php
class Signup extends Controller {
public function __construct () {
parent ::Controller();
$this->load->helper(array('form','url'));
$this->load->library('form_validation');
}
public function index () {
$this->load->view('signup_form');
}
public function submit () {
if ($this->_submit_validate () === FALSE) {
$this->index();
return;
}
$this->load->view('submit_success');
}
private function _submit_validate () {
// validation rules
$this->form_validation->set_rules('username', 'Username',
'required|alpha_numeric|min_length[6]|max_length[12]');
$this->form_validation->set_rules('password', 'Password',
'required|min_length[6]|max_length[12]');
$this->form_validation->set_rules('passconf', 'Confirm Password',
'required|matches[password]');
$this->form_validation->set_rules('email', 'E-mail',
'required|valid_email');
return $this->form_validation->run();
}
}
复制代码
解释一下我刚添加的代码:
- 我添加了2个方法:submit()和_submit_validate()。
- 表单提交的时候调用submit()方法。
- 首先它验证输入。如果验证失败,调用index()方法再次显示注册表单。
- 如果没有错误,我们载入名为submit_success的view。我们一会儿再创建这个view。
- _submit_validate()是我创建的一个私有函数。包含表单验证的内容。
- 返回验证的结果(true or false)。
我们来看看表单验证是如何工作的。
当我们一开始载入表单验证类库时,
首先设置规则:
PHP复制代码
$this->form_validation->set_rules('username', 'Username','required|alpha_numeric|min_length[6]|max_length[12]'); 复制代码
第一个参数是表单域的名称。
第二个参数是它的字面名称。用来显示表单域的作用。
第三个参数是验证规则的列表,用"|"分开。
在这里:http://codeigniter.com/user_guid ... .html#rulereference,你可以看到很多验证规则。
最后,我们调用run()进行验证,如果用户输入不正确将返回FALSE。
显示验证错误
接下来要做的是向用户显示错误信息。
编辑: system/application/views/signup_form.php
PHP复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Signup Form</title>
<link rel="stylesheet" href=" <?php echo base_url (); ?>css/style.css"
type="text/css" media="all">
</head>
<body>
<div id="signup_form">
<p class="heading">New User Signup</p>
<?php echo form_open ('signup/submit'); ?>
<?php echo validation_errors ('<p class="error">','</p>'); ?>
<p>
<label for="username">Username: </label>
<?php echo form_input ('username',set_value ('username')); ?>
</p>
<p>
<label for="password"> assword: </label>
<?php echo form_password ('password'); ?>
</p>
<p>
<label for="passconf">Confirm Password: </label>
<?php echo form_password ('passconf'); ?>
</p>
<p>
<label for="email">E-mail: </label>
<?php echo form_input ('email',set_value ('email')); ?>
</p>
<p>
<?php echo form_submit ('submit','Create my account'); ?>
</p>
<?php echo form_close (); ?>
</div>
</body>
</html>
复制代码
validation_errors() 显示表单验证返回的错误列表(17行)。
第一个和第二个参数是用来包住错误输出的html代码。
在21行和33行,我传递第二个参数给form_input()函数。这样做,当表单再次显示的时候,它将被上次输入的值填充。用户就不需要从头开始输入了。
提交成功View
先做一个简单点儿的。
创建: system/application/views/submit_success.php
测试表单
在表单里输入一些无效的数据并提交。
http://localhost/ci_doctrine/signup
如果你输入的信息是正确的,你应该能看到Success!消息。
保存用户
现在,表单工作正常,我们要用Doctrine模型把用户保存到数据库。
编辑system/application/controllers/signup.php下的submit()函数。
PHP复制代码 <?php
class Signup extends Controller {
// ...
public function submit() {
if ($this->_submit_validate() === FALSE) {
$this->index();
return;
}
$u = new User();
$u->username = $this->input->post('username');
$u->password = $this->input->post('password');
$u->email = $this->input->post('email');
$u->save();
$this->load->view('submit_success');
}
// ...
}
复制代码
正如你看到的,我们做的所有工作就是创建一个User对象,给参数附值并调用save()函数。Doctrine就会把新记录保存到数据库!如些简单!
注意:我们使用$this->input->post()得到输入表单的值。使用CodeIgniter时,我们不直接使用全局变量如$_POST。这提供额外的安全方面的好处。
注意2:把用户输入附值给Doctrine模型时,我们不使用任何sql过滤,如mysql_real_escape_string()。因为Doctrine会帮我们搞定。
测试表单
访问: http://localhost/ci_doctrine/signup, 输入合适的值提交.
检查数据表的内容:
运行正常,但我们还没完全完成。
一个小问题
试试以同样的用户名和e-mail提交表单。你将看到:
HTML复制代码 <br />
<b>Fatal error </b>: Uncaught exception 'Doctrine_Connection_Mysql_Exception' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'testing' for key 'username'' in C:\wamp\www\ci_doctrine\system\application\plugins\doctrine\lib\Doctrine\Connection.php:1084
Stack trace:
#0 C:\wamp\www\ci_doctrine\system\application\plugins\doctrine\lib\Doctrine\Connection\Statement.php(253): Doctrine_Connection->rethrowException(Object(PDOException), Object(Doctrine_Connection_Statement))
#1 C:\wamp\www\ci_doctrine\system\application\plugins\doctrine\lib\Doctrine\Connection.php(1049): Doctrine_Connection_Statement->execute(Array)
#2 C:\wamp\www\ci_doctrine\system\application\plugins\doctrine\lib\Doctrine\Connection.php(693): Doctrine_Connection->exec('Insert INTO use...', Array)
#3 C:\wamp\www\ci_doctrine\system\application\plugins\doctrine\lib\Doctrine\Connection\UnitOfWork.php(595): Doctrine_Connection->insert(Object(Doctrine_Table), Array)
#4 C:\wamp\www\ci_doctrine\system\application\plugins\doctrine\lib\Doctrine in <b>C:\wamp\www\ci_doctrine\system\application\plugins\doctrine\lib\Doctrine\Connection.php </b> on line <b>1084 </b><br />
复制代码
出错是因为,我们尝试将同样的值插入到表唯一索引的字段中。
处理重复
我们可以像这样简单的检查重复:
PHP复制代码
$user_table = Doctrine::getTable('User');
if ($user_table->findOneByUsername($username)) {
// ... username already exists!
}
复制代码
这是第一次涉及到用Doctrine来获取数据记录。
在第一行,为我们的User模型获得表对象。传递的名称是模型的名称。而不是表的名称。当你的模型名称和表名称不一样的时候,知道这点很重要。
然后我们调用了一个魔术函数:findOneBy*()。只所以说它魔术,是因为它可以在其它属性上调用。例如:findOneByEmail()。你只需要在后面添加属性名称(可以是驼峰格式)。
我们可以同时为用户名和密码,把这个代码添加到_submit_validate()函数。不过这不是我想做的。
扩展CodeIgniter类库
因为我们使用Doctrine来节省时间和避免代码重复。在这里,我们以同样的想法进行才是合适的。
我们可能需要检查其它模型或来自其它控制器的重复记录。所以我们通过扩展表单验证类创建一个可重用的验证规则,
利用这种方式,其它表单将具有同样的功能而不需要有重复的代码。
创建: system/application/libraries/MY_Form_validation.php
PHP复制代码
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation {
function unique ($value, $params)
{
$CI =& get_instance ();
$CI->form_validation->set_message('unique',
'The %s is already being used.');
list($model, $field) = explode(".", $params, 2);
$find = "findOneBy".$field;
if (Doctrine ::getTable($model)->$find($value)) {
return false;
} else {
return true;
}
}
} 复制代码
我们看一下代码:
第3行:新类需要有前缀MY_,并继承核心类CI_Form_validation。
第5行:我们将创建名为unique的验证规则。在form_validation类里,方法名称和规则名称是匹配的,这取决与父类是怎么样设置的。
第5行:第一个参数$value是输入表单域的值。
第5行:第二个参数$params是传送给规则的参数名称。我们的验证规则使用这样的结构:unique[model.field]。你一会儿会看到。
第7-9行:我们需要得到CodeIgniter的超级对象。这样才能访问form_validation实例和设置出错信息。
第12+行:提取model.field中的值,组建findOneBy函数的名称,检查记录是否存在。
你可以在文档中阅读关于创建类库的知识。
http://codeigniter.com/user_guide/general/creating_libraries.html
http://codeigniter.org.cn/user_guide/general/creating_libraries.html
使用新的表单验证规则
编辑system/application/controllers/signup.php第二行:
PHP复制代码
<?php
class Signup extends Controller {
// ...
private function _submit_validate() {
// validation rules
$this->form_validation->set_rules('username', 'Username',
'required|alpha_numeric|min_length[6]|max_length[12]|unique[User.username]');
// ...
$this->form_validation->set_rules('email', 'E-mail',
'required|valid_email|unique[User.email]');
// ...
}
// ...
}
复制代码
我们使用了新的表单验证规则unique,在方括号内提供了模型的名称和表单域的名称。
再次测试表单
访问: http://localhost/ci_doctrine/signup
以同样的输入尝试注册两次。
你会看到两个错误:
耐心等等
这是今天的内容. 我们讨论了不少新的话题,希望你喜欢.下一部分,我们将创建一个用户登录系统。
下次见! |
评分
-
查看全部评分
|