codeigniter,看完这些,就可以用它做项目了

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>