短信是一项全球性技术,几乎每个拥有手机的人都在使用。尽管短信编程的覆盖范围比智能手机市场大得多,但其覆盖范围却要少得多,而且往往仍然没有资本化。在本教程中,我将向您展示如何创建允许用户输入手机号码的网站注册表单。接下来我将向您展示如何使用PHP进行服务器端电话号码验证,以检查用户输入的手机号码是否确实是他的手机。在此过程中,我们将使用 jQuery 来执行客户端验证,并使用 CodeIgniter 作为我们的开发框架。
让我们首先概述该解决方案。用户将访问注册表单,选择国家/地区,然后输入手机号码。提交注册表单后,用户需要输入发送到所输入手机号码的验证码,才能激活新帐户。如果用户在输入验证码之前关闭页面并稍后再次访问注册表单,则仍会显示电话号码表单。好的,我们开始吧!
从 www.codeigniter.com 下载 CodeIgniter。接下来,解压该文件夹并将其复制到 Web 服务器的 Web 根目录(您必须有权访问可以解析 PHP 的 Web 服务器才能完成本教程)。复制到您的网络根目录是可选的,但这样做将帮助我们更好地浏览源文件。
在应用程序目录中,导航到 config 目录并打开 config.php。这是主要配置,我们需要在其中设置一些设置,如下面的代码所示:
$config['base_url'] = "http://localhost/sending_sms/"; ... $config['index_page'] = "index.php"; ... $config['uri_protocol'] = "AUTO";
接下来,在同一配置文件夹中打开database.php并完成以下分配:
db['default']['hostname'] = "localhost"; $db['default']['username'] = "root"; $db['default']['password'] = "__password__"; $db['default']['database'] = "sms_users";
最后,打开 config 文件夹中的 autoload.php,然后添加一些我们需要的库和帮助程序:
$autoload['libraries'] = array('database'); ... $autoload['helper'] = array('url', 'form', 'cookie');
让我们创建注册控制器。在 application/controllers 文件夹中创建一个名为 signup.php 的文件,然后让我们开始编写主要注册功能的代码:
class Signup extends Controller { function Signup(){ parent::Controller(); } function index(){ $this->load->view('signup' ); } }
我已经创建了 Signup 类,您会注意到它与文件具有相同的名称,并且它扩展了 Controller。我创建了 index() 函数来处理注册表单的显示。我们称之为index,因为这是使用默认url 访问时调用的默认函数,不带任何段。我们还必须在config/routes.php中配置默认控制器(signup):
$route['default_controller'] = "signup";
如果您现在测试该应用程序,您将收到一条错误消息,告诉您“无法加载请求的文件:signup.php”。这是因为我们还没有创建注册视图。我们现在就开始吧。
在application/views文件夹中创建一个新文件signup.php并输入以下标记:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Signup</title> <link rel="stylesheet" href="<?php echo base_url(); ?>css/reset.css" type="text/css" /> <link rel="stylesheet" href="<?php echo base_url(); ?>css/design.css" type="text/css" /> </head> <body> <div id="wrap"> <h2>Signup form</h2> <?php echo validation_errors('<div class="error">', '</div>'); ?> <?php echo form_open('signup/process', array('id'=>'form') ); ?> <?php echo form_label('Name:', 'name'); ?> <?php echo form_input( array('name'=>'name', 'id'=>'name', 'class'=>'required', 'value'=>set_value('name') ) ); ?> <?php echo form_label('Email:', 'email'); ?> <?php echo form_input( array('name'=>'email', 'id'=>'email', 'class'=>'required email', 'value'=>set_value('email') ) ); ?> <?php echo form_label('Country:', 'country'); ?> <?php echo form_dropdown('country', $countries, '','id="country" class="required"' ); ?> <?php echo form_label('Mobile phone:', 'mobile'); ?> <div><?php echo form_input( array('name'=>'prefix', 'id'=>'prefix', 'value'=>set_value('prefix') ) ); ?> <?php echo form_input( array('name'=>'mobile', 'id'=>'mobile', 'class'=>'required digits', 'value'=>set_value('mobile') ) ); ?> </div> <div align="center"><?php echo form_submit('register', 'Register', 'class="submit"' ); ?></div> </div> </body> </html>
让我解释一下一些标记。我在头部添加了一个带有通常的 meyerweb 重置 CSS 规则的 reset.css 文件和一个 design.css 文件,我们稍后将对其进行编码。我已将这两个文件放在根目录中名为 'css' 的文件夹中。我使用 base_url() 获取视图文件中的根目录。
我使用表单助手来创建表单开口,同时给出表单“表单”的 id,我使用相同的表单助手创建了几个标签和输入。您会注意到我将一个数组作为带有 id 或 class 键的 form_input() 函数的第二个参数传递。有关使用表单助手的更多信息,请阅读 CodeIgniter 文档。我使用 form_dropdown() 创建一个选择框,它会传递一个名为 $countries 的选项数组。我们还没有这个数组,但我们稍后也会制作它。
在css目录下创建文件design.css,放入application/views文件夹中,并输入以下css规则:
body { background-color: #CFCFCF; padding: 0px; margin: 0px; font-size: 12px; font-family: Helvetica, Verdana, Arial, sans-serif; } #wrap { width: 400px; margin-left: auto; margin-right: auto; margin-top: 40px; background-color: #ECECEC; border: solid 1px #FCFCFC; padding: 10px; } h2 { margin-bottom: 10px; font-size: 18px; } label { display: block; } input, select { width: 380px; padding: 5px; margin-bottom: 10px; } select { width: 390px; } #prefix { width: 50px; margin-right: 10px; margin-bottom: 0px; display:inline; } #mobile { width: 305px; display:inline; } input.submit { background-color: #E0E0E0; border: solid 1px #C5C5C5; width: 140px; font-weight: bold; margin-top: 10px; } input.error, select.error { margin-bottom: 0px; border: solid 1px #FFCCCC; } div.error { padding: 5px; background-color: #ffeeee; border: solid 1px #FFCCCC; color: #ff0000; } div.ok { padding: 5px; background-color: #CCFFCC; border: solid 1px #44CC44; color:#336633; margin-bottom: 10px; }
我创建了换行 div 样式,通过将 margin-left 和 margin-right 设置为 auto 使其居中。然后,我对输入进行了样式设置,确保它们在所有浏览器中保持一致,然后创建了 3 个错误类:.error、.ok 和 input.error。我们将把它与 jQuery 验证插件一起使用。我还在我认为有必要进行样式设计的地方使用了 5px 填充。
如果您现在进行测试,您将收到一条通知,提示“未定义的变量国家/地区”和“为 foreach() 提供的参数无效”。我们如何添加国家/地区?好吧,我们可以将它们直接嵌入到选择中,但我们将使用配置文件。这确保我们可以轻松快速地更改任何国家/地区代码。我将包含国家/地区代码的表从countrycode.org 复制到一个新文件中,并使用巧妙的 jQuery 来处理单个字符串中的所有内容,从而得到最终的配置文件。我不会详细介绍。如果你想知道,请发表评论。在 application/config 文件夹中创建一个名为“countries.php”的新文件,并使用以下模型在 #config 数组中添加国家/地区:
$config = array(); $config[''] = ''; $config['93'] = 'Afghanistan'; $config['355'] = 'Albania'; $config['213'] = 'Algeria'; ... $config['967'] = 'Yemen'; $config['260'] = 'Zambia'; $config['263'] = 'Zimbabwe';
我使用前缀代码作为数组中的键。我们如何在视图中访问它?我们将在之前创建的控制器函数 index() 中加载这个特定的配置文件:
function index(){ $this->config->load('countries', true); $data['countries'] = $this->config->item('countries'); $this->load->view('signup', $data ); }
我使用“$this->config->load()”来加载配置。您会注意到我还传递了 true 作为第二个参数。这会在全局配置中创建一个名为“国家/地区”的单独条目。如果我们不传递 true,则配置设置(来自 config 的数组)将添加到全局配置数组中。之后,我们只需将配置项分配给 $data['countries'],然后视图就会将其识别为 $countries。我还将 $data 数组作为第二个参数传递给视图。如果您现在测试该页面,您将在选择框中看到所有国家/地区!很好,对吧?
是时候做一些 jQuery 了。我们将为此使用 jquery 验证插件。该插件已经在 Microsoft 的 CDN 中,因此我们将从那里获取它,以及从 Google 的 CDN 获取 jQuery。我们还需要元数据插件才能直接在 html 中编写类:
<!-- html head --><br /><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script><br /><script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script><br /><script type="text/javascript" src="<?php echo base_url(); ?>js/jquery.metadata.js"></script> <script type="text/javascript"> $(document).ready( function(){ $('#form').validate( {'errorElement': 'div' } ); }); </script> <!-- html head -->
验证插件的工作原理是向输入提供类名:required 用于要求非空值,email 用于验证电子邮件地址,数字 用于数字输入,以及更多我不会涉及的内容。您会注意到我对输入中的类进行了硬编码,只需查看开头的 html 即可。如果您现在进行测试,您会发现在输入后出现一个错误 div,其中包含我在 css 中编码的 .error 类。我还编写了 input.error 类,因为无效的输入也被分配了一个 .error 类。如果用户启用了 JavaScript,这将验证表单。
现在,当用户选择一个国家/地区时,我们将使用一个巧妙的事件来更改前缀输入的值。这样做只是为了视觉目的,因为在后端我们将从国家/地区值中获取前缀,但这会向用户显示如何输入他的电话。我们现在就这样做:
<script type="text/javascript"> $(document).ready( function(){ $('#form').validate( {'errorElement': 'div' } ); //change the prefix based on the country select $('#country').change( function(){ $('#prefix').val( $('#country option:selected').val() ); }); }); </script>
好的,所以我创建了一个用于选择的更改事件的函数,并将所选选项的值分配给前缀输入值。没什么大不了的,但它使我们的注册表单变得非常简单。
这就是注册视图所需的全部内容。让我们创建激活函数和视图。
这是用户成功注册后将看到的页面。将会有一条消息告诉他检查他的手机,因为我们已经向他发送了一个他必须输入的代码。在signup.php控制器中,创建一个名为activate()的新函数:
function activate(){ $data = array(); $data['error'] = ''; $this->load->view('activate', $data ); }
如果激活不正确,我已经定义了一个错误变量以在视图中使用。当我们成功输入用户详细信息并发送短信后,将访问此页面。我们还将在 application/views 文件夹中创建一个名为 activate.php 的新文件,并输入以下标记:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Activate</title> <link rel="stylesheet" href="<?php echo base_url(); ?>css/reset.css" type="text/css" /> <link rel="stylesheet" href="<?php echo base_url(); ?>css/design.css" type="text/css" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script> <script type="text/javascript" src="<?php echo base_url(); ?>js/jquery.metadata.js"></script> <script type="text/javascript"> $(document).ready( function(){ $('.ok').hide().fadeIn(800); $('#form').validate( {'errorElement': 'div' } ); }); </script> </head> <body> <div id="wrap"> <h2>Confirm mobile phone</h2> <div class="ok">Your account has been created. A sms has been sent to your mobile with a 5 digit activation code. Please enter the code to complete signup:</div> <?php echo $error; ?> <?php echo form_open('signup/activate', array('id'=>'form') ); ?> <?php echo form_label('Code:', 'code'); ?> <?php echo form_input( array('name'=>'code', 'id'=>'code', 'class'=>'required digits', 'value'=>set_value('code') ) ); ?> <div align="center"><?php echo form_submit('signup', 'Complete signup', 'class="submit"' ); ?></div> <hr /> If you haven't received the sms, please <a href="#">click here</a> to send it again </div> </body> </html>
这里的标记非常简单。我已经包含了相同的 jQuery 和验证插件。在 document.ready 事件中,我像第一页一样调用了 jquery.validate() 。我们将使用 validate 来验证授权代码。我还淡入消息 div,以显示成功消息。我还设置了“required”和“digits”的类名,以将输入字段限制为数字和非空值。还有一条消息,其中包含供用户重新发送激活码的选项,但我不会详细介绍此功能,因为它与基本注册非常相似。
让我们创建一个函数来处理数据并将其插入数据库。我们还将使用验证库。在服务器上进行验证很重要,因为有些人可以关闭 JavaScript,因此验证将不起作用。这是一个后备措施,可以确保表中不会有任何无效数据。函数流程如下:
function process(){ $this->load->library('form_validation'); if ( $this->form_validation->run() ){ $signup = array(); $signup['name'] = $this->input->post('name'); $signup['email'] = $this->input->post('email'); $signup['country'] = $this->input->post('country'); $signup['mobile'] = $this->input->post('country').$this->input->post('mobile'); //generate the unique activation code mt_rand(); $signup['activation'] = rand( 11111, 99999 ); //insert into db $this->db->insert('users', $signup ); //send auth sms set_cookie('signed', $this->db->insert_id(), 86500 ); //redirect redirect('signup/activate'); } else { $this->config->load('countries', true); $data['countries'] = $this->config->item('countries'); $this->load->view('signup', $data ); } }
嗯,代码太多了!让我们看一下所有主要部分:
我们首先加载表单验证库。之后,我们使用表单验证的 run() 函数来检查值是否正确。如果所有输入都通过,我们将使用 $this->input->post('input_name') 创建一个包含所有帖子数据的数组,并将数据插入到名为 users 的表中,我们将一会儿做。这里需要注意的一件事是我还生成了授权代码。我使用 mt_rand() 为随机生成器提供种子并生成唯一的 5 密码数。我们通过运行 rand() 来生成 11111 到 99999 之间的数字来实现这一点。这总是给我们提供长度为 5 个密码的数字。我没有使用 10000,因为我们可以获得一个重复其密码的数字,例如 10002,它看起来不太随机。我还使用数据库中实际插入的插入 ID 值设置了一个名为“signed”的 cookie,然后将用户重定向到激活函数。如果某些字段无效,我们会再次加载国家/地区并加载注册视图。如果您从头开始查看注册视图,您会发现我使用 set_value() 来获取上次注册的使用值。因此,如果存在无效字段,则其余字段将用最后的数据填充。但我们需要在注册视图中更新一行:
<?php echo form_dropdown('country', $countries, @$_POST['country'],'id="country" class="required"' ); ?>
我已将第三个参数替换为 $_POST['country'],确保它不会显示带有 @ 的通知。这会将选择选项设置为提交之前选择的选项。如果我们的帖子数据中没有国家/地区,我们将不会选择任何内容,就像注册开始时的情况一样。
好吧,我打赌您会问:服务器如何知道服务器端验证的正确格式是什么?好吧,我们必须创建验证规则。幸运的是,CodeIgniter 允许您将它们写入 application/config 文件夹中名为 form_validation.php 的配置文件中。如果该文件尚不存在,则创建该文件并输入以下内容:
$config = array( array('field'=>'name', 'label'=>'Name', 'rules'=>'required'), array('field'=>'email', 'label'=>'Email', 'rules'=>'required|valid_email|callback_check_email_exists'), array('field'=>'country', 'label'=>'Country', 'rules'=>'required'), array('field'=>'mobile', 'label'=>'Mobile phone', 'rules'=>'required|numeric') );
我使用这个多维数组来设置相应的验证规则。例如,对于名称字段,我使用“field”键设置名称字段的规则,使用“label”键设置错误消息中的字段名称(如果显示)和“rules”键来设置规则。我用管道字符(即“|”)分隔规则。有关可用规则的更多信息,请查看用户指南中的表单验证文档。我还创建了一个用户定义的回调(callback_check_email_exists)来检查电子邮件是否存在。将 callback_ 添加到规则名称中搜索控制器中的函数并调用它。该函数将检查数据库中是否存在相同的电子邮件地址,来源为:
function check_email_exists( $email ){ $rs = $this->db->where( 'email', $email )->count_all_results('users'); $this->form_validation->set_message('check_email_exists', "We're sorry, this email already exists!"); if( $rs < 1 ){ return true; } return false; }
这是一个简单的函数,它接受一个参数(正在检查的值)并根据格式返回 true 或 false。我们检查表中是否有包含电子邮件地址的结果,如果有,则返回 false。如果我们想要验证,我们必须返回 true,如果无效则返回 false,所以这个函数名称有点尴尬。
现在就别想测试激活了!你会得到一个严重的错误,因为我们还没有创建表!那么,您可以下载源代码并从 users.sql 文件导入 users 表,或者使用以下命令创建它:
CREATE TABLE `users` ( `uid` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `country` INT NOT NULL, `mobile` TEXT NOT NULL, `activation` TEXT NOT NULL, `active` INT NOT NULL, PRIMARY KEY (`uid`) );
在 phpMyAdmin 中运行此代码,您将创建表。
如果您现在测试代码,您将获得所有正确的验证。您只需禁用 JavaScript 即可尝试服务器验证。您不会收到无效数据!我警告过你!
第一部分到此结束。下一次,在本系列的第二部分中,我们将介绍如何使用第三方 SMS 网关服务实际发送 SMS。我希望您喜欢我的教程,并感谢您留下来查看全部内容!
以上是第 1 部分:构建 SMS 订阅表单的详细内容。更多信息请关注PHP中文网其他相关文章!