1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//数组中的成员类型相同,顺序可以不同。例如[1, true] 与 [false, 2]是相似的。
//数组的长度一致。
//类型的判断范围,需要区分:String, Boolean, Number, undefined, null, 函数,日期, window.
function arraysSimilar(arr1, arr2){
//判断边界
if (!(arr1 instanceof Array) || !(arr2 instanceof Array)) {
return false;
}

//判断长度
if (arr1.length != arr2.length) return false;

var i = 0, n = arr1.length, countMap1 = {}, countMap2 = {}, t1, t2, TYPES = ['string', 'boolean', 'number', 'undefined', null, 'function', 'date', 'window'];

for ( ; i < n; i++) {
t1 = typeOf(arr1[i]);
t2 = typeOf(arr2[i]);
if (countMap1[t1]) {
countMap1[t1] ++;
}else{
countMap1[t1] = 1;
}
if (countMap2[t2]) {
countMap2[t2] ++;
}else{
countMap2[t2] = 1;
}
}

function typeOf(ele){
var r;
if (ele === null) r = 'null';
else if(ele instanceof Array) r = 'array';
else if(ele === window) r = 'window';
else if(ele instanceof Date) r = 'date';
else r = typeof ele;
return r;

}

for (i = 0; i < TYPES.length; i++) {
if (countMap1[TYPES[i]] != countMap2[TYPES[i]]) return false;
}

return true;
}
document.write(arraysSimilar([1,true], [false, 2]));

数组中的成员类型相同,顺序可以不同。例如[1, true][false, 2]是相似的
数组的长度一致
类型的判断范围,需要区分:String, Boolean, Number, undefined, null, 函数日期, window

课程格子和超级课程表这两个应用,想必大学生都很熟悉,使用自己的学号和教务系统的密码,就可以将自己的课表导入,随时随地都可以在手机上查看。
其实稍微了解一点php的话,我们也可以做一个类似这样的web 应用。

解决掉验证码

这是正方的一个小bug,当我们进入登陆界面时,浏览器会去请求服务器,服务器会生成一个验证码图片。如果我们不去请求这个图片,那么正方后台也不会生成相应的验证码,于是这样我们就有了可乘之机,让我高兴会儿~这时,我们在不填写验证码的情况下,可以很流畅的进入。大家可以在自己的电脑上禁止访问验证码的地址,然后试试这是不是真的~当然,这只对正方有效。

php 的curl 模拟登陆

这里直接贴一个脚本之家对 curl 的讲解http://www.jb51.net/article/51299.htm
接下来就是相关代码了,相信很多人和我一样,只喜欢看例子,对于长篇大论的讲解,转头就走……不过这个习惯还是不好……废话不多说!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//模拟登陆
function curl_request($url,$post='',$cookie='', $returnCookie=0){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
curl_setopt($curl, CURLOPT_REFERER, "这里一定要换成教务系统登陆的url"); //填写教务系统url
if($post) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
}
if($cookie) {
curl_setopt($curl, CURLOPT_COOKIE, $cookie);
}
curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
curl_setopt($curl, CURLOPT_TIMEOUT, 20);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($curl);
if (curl_errno($curl)) {
return curl_error($curl);
}
curl_close($curl);
if($returnCookie){
list($header, $body) = explode("\r\n\r\n", $data, 2);
preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
$info['cookie'] = substr($matches[1][0], 1);
$info['content'] = $body;
return $info;
}else{
return $data;
}
}

教务系统登陆页面的隐藏字段

举个栗子
<input type="hidden" name="__VIEWSTATE" value="dDwyODE2NTM0OTg7Oz61eIbnKVojBioGYtg2vsy2SklwiA==">
这些东西在登陆的时候也是需要带上的,顺便贴出函数,顺便暴漏了博主的学校……皇家种地大学(主要是正则表达式的运用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//登陆页面的隐藏字段
function getView(){
$url = 'http://jw.hzau.edu.cn/default2.aspx';
$result = curl_request($url);
$pattern = '/<input type="hidden" name="__VIEWSTATE" value="(.*?)" \/>/is';
preg_match_all($pattern, $result, $matches);
$res[0] = $matches[1][0];

return $res[0] ;
}
  //返回教室查询页面的隐藏值
private function getViewJs($cookie,$xh){
$url = "http://jw.hzau.edu.cn/xxjsjy.aspx?xh={$xh}";
$result = curl_request($url,'',$cookie);
$pattern = '/<input type="hidden" name="__VIEWSTATE" value="(.*?)" \/>/is';
preg_match_all($pattern, $result, $matches);
$res[0] = $matches[1][0];
return $res[0] ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function login($xh,$pwd){
$url = 'http://jw.hzau.edu.cn/default2.aspx';
$post['__VIEWSTATE'] = $this->getView();
$post['txtUserName'] = $xh; //填写学号
$post['TextBox2'] = $pwd; //填写密码
$post['txtSecretCode'] = '';
$post['lbLanguage'] = '';
$post['hidPdrs'] = '';
$post['hidsc'] = '';
$post['RadioButtonList1'] = iconv('utf-8', 'gb2312', '学生');
$post['Button1'] = iconv('utf-8', 'gb2312', '登录');
$result = curl_request($url,$post,'', 1);
return $result['cookie'];
}

让我们来试试查课表的功能

格式有点乱额,大家凑合着看,我把课表转成了一个二维关联数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//返回课表字符串
private function classresult($xh,$pwd){
date_default_timezone_set("PRC"); //时区设置
$classList = "";//声明课表变量

$cookie = $this->login($xh,$pwd);
$view = $this->getViewJs($cookie,$xh);//验证密码是否正确

//如果密码正确
if (!empty($view)) {
$url = "http://jw.hzau.edu.cn/xskbcx.aspx?xh={$xh}";
$result = curl_request($url,'',$cookie); //保存的cookies
preg_match_all('/<table id="Table1"[\w\W]*?>([\w\W]*?)<\/table>/',$result,$out);
$table = $out[0][0]; //获取整个课表

preg_match_all('/<td [\w\W]*?>([\w\W]*?)<\/td>/',$table,$out);
$td = $out[1];
$length = count($td);

//获得课程列表
for ($i=0; $i < $length; $i++) {
$td[$i] = str_replace("<br>", "", $td[$i]);

$reg = "/{(.*)}/";

if (!preg_match_all($reg, $td[$i], $matches)) {
unset($td[$i]);
}
}

$td = array_values($td); //将课程列表数组重新索引
$tdLength = count($td);
for ($i=0; $i < $tdLength; $i++) {
$td[$i] = iconv('GB2312','UTF-8',$td[$i]);
}

//将课表转换成数组形式
function converttoTable($table){
$list = array(
'sun' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'mon' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'tues' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'wed' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'thur' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'fri' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'sat' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
)
);
$week = array("sun"=>"周日","mon"=>"周一","tues"=>"周二","wed"=>"周三","thur"=>"周四","fri"=>"周五","sat"=>"周六");
$order = array('1,2','3,4','5,6','7,8','9,10');
foreach ($table as $key => $value) {
$class = $value;
foreach ($week as $key => $weekDay) {
$pos = strpos($class,$weekDay);
// echo $pos;
if ($pos) {
$weekArrayDay = $key; //获取list数组中的第一维key
foreach ($order as $key => $orderClass) {
$pos = strpos($class,$orderClass);
if ($pos) {
$weekArrayOrder = $orderClass; //获取该课程是第几节
break;
}
}
break;
}
}
$list[$weekArrayDay][$weekArrayOrder] = $class;
}
return $list;
}

//调用函数
return converttoTable($td);
}else{
return 0;
}
}

再试试查询空教室的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//空教室查询结果
public function roomresult(){
$xh = ""; //设置学号
$pwd = ""; //学号对应的密码

$cookie = $this->login($xh,$pwd);
$url = "http://jw.hzau.edu.cn/xs_main.aspx?xh={$xh}";
$result = curl_request($url,'',$cookie); //保存的cookies

$url="http://jw.hzau.edu.cn/xxjsjy.aspx?xh={$xh}";
$post['Button2'] = iconv('utf-8', 'gb2312', '空教室查询');
$post['__EVENTARGUMENT']='';
$post['__EVENTTARGET']='';
$post['__VIEWSTATE'] = $this->getViewJs($cookie,$xh);
$post['ddlDsz'] = iconv('utf-8', 'gb2312', '单');
$post['ddlSyXn'] = '2014-2015'; //学年
$post['ddlSyxq'] = '1';
$post['jslb'] = '';
$post['xiaoq'] = '';

$post['kssj']=$_GET['start']; //提交的开始查询时间
$post['sjd']=$_GET['class'];//提交的课程节次

$post['xn']='2014-2015';//所在学年
$post['xq']='2';//所在学期
$post['xqj']='6';//当天星期几
$post['dpDataGrid1:txtPageSize']=90;//每页显示条数

$result = curl_request($url,$post,$cookie,0);

preg_match_all('/<span[^>]+>[^>]+span>/',$result,$out);
$tip = iconv('gb2312', 'utf-8', $out[0][3]);//获取页面前部的提示内容
preg_match_all('/<table[\w\W]*?>([\w\W]*?)<\/table>/',$result,$out);
$table = iconv('gb2312', 'utf-8', $out[0][0]); //获取查询列表

$this->load->view("classroom",array('tip'=>$tip,'table'=>$table));
}

总结起来就是这些了,每个学校的教务系统都不尽相同,这时我们可以借助火狐浏览器的 firebug 抓包,看看到底提交了哪些东西。如果不成功,要看看自己该提交的东西post 上去了没有,如果再不成功

就这些了,赶快去试试吧!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<textarea name="" id="txt1" cols="30" rows="10"></textarea>
<input type="text" name="" id="txt2">
<input type="button" id="btn1" value="留言">

<script>
window.onload = function (){
var oTxt1 = document.getElementById("txt1");
var oTxt2 = document.getElementById("txt2");
var oBtn1 = document.getElementById("btn1");
        
oTxt2.onkeydown = function (ev){
var oEvent = ev || event;
if (oEvent.keyCode === 13 && oEvent.ctrlKey) {
oTxt1.value += oTxt2.value + '\n';
oTxt2.value = "";
}
}
}
</script>

</body>
</html>

附上另外两个属性: shiftKey, altKey

MVC

  1. 入口文件
    唯一一个让浏览器直接请求的脚本文件
  2. 控制器 controller
    负责协调模型和视图
  3. 模型model
    只负责提供数据,保存数据
  4. 视图
    只负责显示,以及搜集用户的输入(表单)
  5. action 动作
    是控制器中的方法用于被浏览器请求

CI中的MVC

  1. pathinfo模式http://localhost/php/ci/index.php/控制器文件/动作
1
2
3
4
application目录中
controller 控制器
views 视图
models 模型

控制器

  1. 不需要加后缀,直接是 类名.php
  2. 文件名全部小写
  3. 所有的控制器需要直接或间接继承自 CI_Controller 类
  4. 以下划线开头的方法,不能被浏览器请求,但是可以被内部调用
  5. 控制器中只有public 的方法,才能作为动作方法名不区分大小写
  6. 与类名相同的方法,会被php当做构造方法,因此不要创建与类名相同的方法

视图

  1. 在控制器中如何加载视图
1
$this->load->view(视图);//直接写视图名字,不用加扩展名
  1. 视图中直接使用原生php代码,不使用模板引擎
  2. 在视图中分配变量
1
2
3
4
$this->load->vars('title',"这是标题");
$data['title'] = "这是标题";
$data['list'] = $list;
$this->load->vars($data); //可以多次调用

在视图中
      

1
2
3
4
5
6
7
<?php foreach($list as $item): ?>
<tr>
<td><?php echo $item['id']; ?></td>
<td><?php echo $item['name']; ?></td>
<td><?php echo $item['email']; ?></td>
</tr>
<?php endforeach; ?>

  1. 推荐使用
1
2
<?php foreach($list as $item):?>
<?php endforeach; ?>

ci的超级对象

当前的控制器对象属性
装载器类的实例$this->load
装载器类提供的方法:

1
2
3
4
5
view() 装载视图
vars() 分配变量
database() 装载数据库操作对象
model() 装在模型
helper() 辅助函数

$this->uriCI_URI类的实例
CI_URI提供的方法:segment()用于获取url中某一段的值
传统pathinfo:入口文件.php/控制器/动作/参数1/值1/参数2/值2
CI的pathinfo:入口文件.php/控制器/动作/值1/值2

1
2
$this->uri->segment(3);//对应 值1
$this->uri->segment(4);//对应 值2
1
2
3
public function index($p=0){
echo $p;
}

$this->input() 输入类是CI_Input()的实例,提供的方法

1
2
$this->input->post('username');//$_POST['username'](无get,可以使用segment())
$this->input->server('DOCUMENT_ROOT');

在视图中,可以直接使用$this 来只用超级对象

数据库访问

修改配置文件application/config/database.php

将数据库访问对象,装载到超级对象的属性中 $this->db

1
2
3
4
5
6
$this->load->database();
$res = $this->db->query($sql);//返回一个对象
$res->result(); //返回数组,数组中是一个一个的对象
$res->result_array(); //返回二维数组,是关联数组
$res->row(); //返回第一条记录,直接是一个对象
$res->row_array();//第一条记录的数组

程序实例

  • 查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public function showusers(){
//装载数据库操作类
$this->load->database();

//装载成功之后会放入超级对象的属性中,默认属性名是db/
//var_dump($this->db);

$sql = "select * from blog_user";

//返回一个对象
$res = $this->db->query($sql); // mysql_query()

//var_dump($res); //返回值是一个对象

$users = $res->result();

//mysql_fetch_object(); 返回对象
//mysql_fetch_assoc(); 返回关联数组

$data['user_list'] = $users;
$this->load->view('index/users',$data);
}
  • 添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function add{
$this->load->database();

$sql = "insert into blog_user (name,password) values ('mary',md5('mary'))";

$bool = $this->db->query($sql);

if($bool){
//mysql_affected_rows
echo $this->db->affected_rows(); //受影响行数
echo $this->db->insert_id(); //自增id
}


}

在上述两个例子中,存在安全问题,以及表前缀不能自动修改的问题,一以下例子针对这两个问题做了改进

  • 修改(表前缀与参数绑定)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public function test8(){
//此处可以在autoload.php 中配置“自动加载”,$autoload['libraries'] = array('database');
//$this->load->database();


//$name = $this->input->post('name');
$data[0] = 'lili';
$data[1] = 'lili';
//$db['default']['swap_pre'] = 'swap_'; 数据库配置文件中的交换表前缀
$sql = "insert into swap_user (name,password) values (?,?)";

$bool = $this->db->query($sql,$data);//SQL语句中有多个?时,需要传入索引数组

if($bool){
  echo "添加成功!";
}
}

数据库中的AR模型(Active Record)

  1. 在 database.php 文件中
1
$active_record = TRUE;
  1. 自动加载
1
$autoload['libraries'] = array('database');

  

  1. 在配置文件中,配置表前缀后,会自动添加     
    1
    2
    3
    4
    5
    6
    7
    8
    $res = $this->db->get("表名"); //返回结果集对象
    $res -> result();

    $this->db->insert('表名',关联数组);

    $bool = $this->db->update('表名',关联数组,条件);

    $bool = $this->db->delete('表名',条件);

连贯操作

1
2
3
4
5
6
7
8
9
// select id,name from tableName where id >= 3 order by id desc limit 2,3
$res = $this->db->select('id,name')
->from('user')
->where('id >=',2)
->limit(3,2) //跳过2条取出3条数据
->order_by('id desc')
->get();
var_dump($res->result());
echo $this->db->last_query();

->where() 的一些用法

1
2
3
// $res = $this->db->where('name =','zhongshan')->get('user');
// $res = $this->db->where('name !=','zhongshan')->get('user');
$res = $this->db->where(array('name' => 'mary','id >' => 2))->get('user');

复杂的查询,请用 $this->db->query($sql,$data); //使用?绑定参数

如何扩展CI的控制器

编写自己的控制器,application/core/MY_Controller.php文件
其他控制器就可以继承自 MY_Controller
config.php中,可以修改前缀 $config['subclass_prefix'] = 'MY_'

1
2
3
4
5
6
7
8
9
10
11
12
class MY_Controller extends CI_Controller{
  //构造方法会自动调用
   public function __construct(){
    parent::__construct(); //调用父类的构造方法

    //登陆验证...

    //权限验证...
  }

public function funcname(){
}

模型

继承自 CI_Model,在模型中,可以使用超级对象的属性文件名全部小写,类名首字母大写。建议使用 _model 做为后缀,防止和控制器类名冲突

程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// model

<?php
/**
* 用户模型
* @author zhongshan <1194567130@qq.com>
*/

class User_model extends CI_Model{
//返回所有用户
public function getAll(){
$res = $this->db->get('user');
return $res -> result();
}
}



// controller

<?php
class User extends MY_Controller{
  public function index(){
    //加载模型,可以起一个别名,加载完成后,自动成为超级对象的属性
    $this->load->model('User_model','user');

    $list = $this->user->getAll(); //调用模型,获取数据

    $this->load->view("user/index",array('list' => $list));

  }
}

// views

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <?php var_dump($list) ?>

</body>
</html>

url相关函数

1
2
3
$this->load->helper('url');//可以根据需要配置自动加载,在 autoload.php 中
site_url('控制器/方法')
base_url()

设置路由

1
2
3
4
5
6
application/config/routes.php
//默认控制器
$route['default_controller'] = "welcome";

//http://localhost/php/ci/index.php/news/123456/4.html
$route['news/[\d]{6}/([\d]+)\.html'] = 'article/show/$1';

隐藏入口文件

开启apache的rewrite模块,在httpd.conf 文件中,LoadModule rewrite_module modules/mod_rewrite.so
重启服务器,在根目录下放入 .htaccess 文件

分页类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//装载类文件
$this->load->library('pagination');
//每页显示10 条数据
$page_size = 10;

$config['base_url'] = site_url('user/test');

// 一共有多少条数据
$config['total_rows'] = 100;

//每页显示多少条
$config['per_page'] = $page_size;

$config['first_link'] = '首页';
$config['next_link'] = '下一页';
$config['uri_segment'] = 3; //分页的数据查询偏移量在哪一段上

$this->pagination->initialize($config);

$offset = intval($this->uri->segment(3)); //和 $config['uri_segment'] 对应

$sql = "select * from user limit {$offset},{$page_size}";

echo $sql;

//创建链接
$data['links'] = $this->pagination->create_links();

$this->load->view('user/test',$data);

文件上传

  1. 手动创建好上传目录
  2. 程序实例
1
2
3
4
// 表单
<form action="<?php echo site_url('user/upload'); ?>" method="post" enctype="multipart/form-data">
<input type="file" name="pic" /><input type="submit" value="提交" />
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//控制器

public function upload(){
  //上传目录需要手工创建
  $config['upload_path'] = './uploads/';
  $config['allowed_types'] = 'gif|png|jpg|jpeg';
  //生成新的文件名
  $config['file_name'] = uniqid();
  //装载文件上传类
  $this->load->library('upload',$config);
  $this->upload->do_upload('pic');

  var_dump($this->upload->data());
  //获取上传之后的数据
  $data = $this->upload->data();

  $filename = $data['file_name'];
  echo $filename;
}

session

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public function login(){
  //生成一个随机字符串作为一个加密用的 key
  //保存到 config.php 中的 $config['encryption_key'] = '';
  // echo md5(uniqid());exit;
  $this->load->library('session');

  $user = array('id'=>3,'name'=>'jack');

  // session_start();
  // $_SESSION['user'] = $user;
  $this->session->set_userdata('user',$user);
  //不要在这里获取放入的数据,只有页面重新加载或跳转到别的url中,才能获取

  //一次性的数据,只能读取一次
  $this->session->set_flashdata('index','abcdefghij');
}

public function show_session(){
  $this->load->library('session');
  //取 CI session 中的数据
  $user = $this->session->userdata('user');
  var_dump($user);


  //下次刷新,就没有了
  $test = $this->session->flashdata('index');
  echo $test;

}

验证码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public function valid(){
  $this->load->helper('captcha');
  $vals = array(
    'word' => rand(1000,9999),
    'img_path' => './captcha/',
    'img_url' => base_url().'/captcha/',
    'img_width' => 100,
    'img_height' => 30,
    'expiration' => 60*10 //过期时间,时间一到,会自动删除图片
  );

  $cap = create_captcha($vals);
  echo $cap['image'];

  echo $cap['word'];

  session_start();
  //验证时,对比 $_SESSION['cap']
  $_SESSION['cap'] = $cap['word'];
}

表单验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 控制器文件

public function insert(){
  // var_dump($this->input->post('name'));

  $this->load->library('form_validation');

  $this->form_validation->set_rules('name','用户名','required');
  $this->form_validation->set_rules('email','邮箱','valid_email');

  $bool = $this->form_validation->run();

  if ($bool) {
    //调用模型保存到数据库

  }else{
    //显示错误信息
    $this->load->view('user/add');
  }

}

// 视图文件

<?php echo validation_errors(); ?>
<form action="<?php echo site_url('user/insert');?>" method="post">
name:<input type="text" name="name" value="<?php echo set_value('name');?>"><?php echo form_error('name','<span>','</span>'); ?><br>
pass: <input type="password" name="pass"><br>
age: <input type="number" name="age"><br>
sex: <input type="text" name="sex"><br>
email: <input type="text" name="email" value="<?php echo set_value('email');?>"><?php echo form_error('email','<span>','</span>'); ?><br>

<input type="submit" value="提交">
</form>

ie8及以下对html5相关语义标签的支持

1
2
3
<!-[if lt IE9]>
<script src="html5.js"></script>
<![endif]->

表单

  1. form属性,实现form与其中的标签分离
1
2
3
<form id="login" action="login.php" method="get"></form>
<input form="login" type="text" name="user" id="">
<input form="login" type="submit" value="提交">
  1. formaction ,实现不同的动作提交到不同的后台处理;formmethod,不同的提交方式;placeholder,提示字符
1
2
3
4
5
<form id="login" action="login.php" method="get"></form>
<input form="login" placeholder="请输入用户名" type="text" name="user" id="">
<input form="login" formaction="del.php" formmethod="get" type="submit" name="dosubmit" value="删除">
<input form="login" formaction="pass.php" formmethod="post" type="submit" name="dosubmit" value="通过">
<input form="login" formaction="notpass.php" formmethod="get" type="submit" name="dosubmit" value="不通过">
  1. autofocus 自动获得焦点,这里可以贴一下js的实现代码
1
2
3
4
<script>
var username = document.getElementById('username');
username.focus();
</script>

  1. autocomplete 根据输入记录自动补全
1
autocomplete="on" autocomplete="off"
  1. list提示列表
1
2
3
4
5
6
7
<input form="login" list="listtest" autofocus autocomplete="on" id="username" placeholder="请输入用户名" type="text" name="user" id="">
<datalist id="listtest">
<option>this is one</option>
<option>this is two</option>
<option>this is three</option>
<option>this is four</option>
</datalist>

改良的input元素种类(可以简单的使用这些元素来实现js的功能)

  1. <input type="search" name="" id="">

  2. tel 属性

1
2
<input type="tel" name="" id=""> 没有特殊的校验规则
<input type="tel" title="只能输入十位数字" pattern="^\d{10}$">可以添加正则属性
  1. url 专门用来输入url
1
<input type="url" name="" id="">
  1. email
1
<input type="email" required> 该字段是必须的
  1. 时间属性
1
2
3
4
5
6
Datetime: <input type="datetime" name="" id=""><br>
Date: <input type="date" name="" id=""><br>
month: <input type="month" value="2015-02"><br>
week: <input type="week" name="" value="2015-W10"><br>
time: <input type="time" name="" id=""><br>
Datetime-local: <input type="datetime-local" name="" id=""><br>
  1. number 限制输入数字

小提示乱入:
input中加入 formnovalidate 属性可设置不验证

1
<input type="number" name="num" max="20" min="0" step="3">
  1. range 与number类似
1
2
<input type="range" onchange="document.getElementById('num').value = this.value" name="num" max="20" min="0" step="3" value="0"><br>
<output id="num">0</output>
  1. color 颜色选择器
  2. multiple 选择多个文件
1
<input type="file" name="pic" multiple accept="image/*"> 仅仅支持上传图片

html5 中新增加的标签

  1. <mark></mark> 黄色背景强调
  2. <wbr> 软换行
  3. 进度条,可以使用 js 控制它们的 value
1
2
<progress min="0" max="100" value="20" id="pro"></progress>
<meter min="0" max="100" low="30" high="80" id="pro"></meter>
  1. canvas 通过js 画图
  2. details 详细信息
1
2
3
4
5
6
7
8
<details>
<summary>
标题
</summary>
内容
内容
内容
</details>
  1. ruby 拼音注释
1
2
3
<ruby>
妹子<rp>(</rp><rt>meizi</rt><rp>)</rp>
</ruby>

html5 废除的元素

<font></font> <u></u>等元素

html5 新增的元素和废除的元素

  1. <base>
1
2
<base target="_blank" href="http://www.yangguang520.cn">
<a href="index.php">云课堂</a>
  1. 有序列表倒转
1
2
3
4
5
6
7
8
<ol reversed>
<li>列表</li>
<li>列表</li>
<li>列表</li>
<li>列表</li>
<li>列表</li>
<li>列表</li>
</ol>
  1. async 设置 js 异步加载