CodeIgniter 框架

1、什么是框架:
   框架就是一套提供基本功能组件,并做了安全控制,使程序员的工作重点放在业务逻辑上面,框架规范了编程规则,程序员可以基于这套规则进行功能组件扩展.减少代码的编写量


2.什么是CodeIgniter?
CodeIgniter是一个小巧的php框架,名称由两个单词组成,code代码Igniter点火器,连起来意思是代码点火器(什么意思?),简称CI
  先简单介绍下CI,是一个极其轻量级的php framework。这个可以个YII比较下。php的framework 有一个最大的特点,MVC的层次很清晰,使用后会让你对Model, view, controller有更好的认识。
 CodeIgniter 是一套给 PHP 网站开发者使用的应用程序开发框架和工具包。她提供一套丰富的标准库以及简单的接口和逻辑结构,其目的是使开发人员更快速地进行项目开发。使用 CodeIgniter 可以减少代码的编写量,并将你的精力投入到项目的创造性开发上。 
  CodeIgniter是由Ellislab公司的CEORickEllis开发的。其核心框架是为这个程序特别编写的,而其他很多类库、辅助函数和子系统则来自于RickEllis和PaulBurdick编写的内容管理系统  ExpressionEngine。来自RubyonRails的灵感启发我们创造了一个PHP框架,并且将框架的概念引入到网络社区的一般意识中。 




3.什么是MVC:
   MVC 是一种将应用程序的逻辑层和表现层进行分离的方法。
   模型 (Model) 代表你的数据结构。通常来说,你的模型类将包含取出、插入、更新你的数据库资料这些功能。 
   
  视图 (View) 是展示给用户的信息。一个视图通常是一个网页,但是在 CodeIgniter 中,一个视图也可以是一个页面片段,如页头、页尾。它还可以是一个 RSS 页面,或任何其它类型的“页面”。 
  
  控制器 (Controller) 是模型、视图以及其他任何处理 HTTP 请求所必须的资源之间的中介,并生成网页。




4.ci优点:
  是免费的  是轻量级的  是快速的  使用 M-V-C 模型   生成干净的 URL
 功能强大  是可扩展的  不需要模板引擎   已彻底文档化   拥有一个友好的用户社区




5. ci安装
   http://codeigniter.org.cn/
   下载 解压
  解压后目录介绍:
application  项目应用目录
-----cache 保存cache文件目录
-----config 配置文件目录
-----controllers  网站控制层文件
-----errors 保存错误输出信息文件
-----helpers 框架自带助手类文件目录
-----hooks 用户定义钩子类文件目录
-----language 用户定义提示信息语言文件目录
-----libraries 用户定义扩展类文件目录
-----logs 日志文件目录
-----models 网站业务逻辑层文件目录
-----views 网站展现层文件目录
-----third_party  插件类文件目录,可扩展添加新文件


system  框架核心目录
index.php  程序的主入口




6.构建自己项目:


6.1配置:
     首页配置 index.php
  在部署项目的时候 通常我们需要修改index.php 两个地方
   $system_path='system';  通常我们修改成 include或者 core 或者其他你系统自定义目录名
   $application_folder='application';  通常修改成你的项目名称 或者你自定义目录名
 
 修改配置文件:
    app/application/config/config.php


   $config['base_url'] = 'http://127.0.0.1/myapp/';     修改成你服务器上的项目的根目录


   $config['encryption_key'] = 'test123!@';  如果你要使用session 那么ci 是需要你的加密密钥 所以这里需要填写自定义的密钥


在config文件下配置$config['base_url'],加载URL类后,通过base_url()调用


$config['url_suffix'] = '.html';  设置后缀名  example.com/index.php/class/function/ID.html  


$config['global_xss_filtering'] = FALSE;  改为 true 那么ci 将自动过滤xss  通常我们选择手动过滤xss攻击


数据库配置文件
  app/application/config/database.php
   
db['default']['hostname'] = 'localhost';  #数据库服务器名
$db['default']['username'] = 'root'; #数据库服务器用户名
$db['default']['password'] = 'test123'; #数据库密码
$db['default']['database'] = 'mytest'; #数据库名
$db['default']['dbdriver'] = 'mysql';  #数据库驱动
$db['default']['dbprefix'] = 'mytest_';  #设置表前缀
$db['default']['pconnect'] = TRUE;  #是否使用长链接
$db['default']['db_debug'] = TRUE;  #是否启用数据库调试 在正式布置项目是 建议设为 false
$db['default']['cache_on'] = FALSE;  #是否开启数据库缓存
$db['default']['cachedir'] = '';  #数据缓存目录地址
$db['default']['char_set'] = 'utf8'; #设置编码
$db['default']['dbcollat'] = 'utf8_general_ci'; #数据库坚持编码
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE; 




路由配置文件
   app/applicatioin/config/routers.php


$route['default_controller'] = "home";  默认控制器
$route['404_override'] = '';   #自定义 404 错误页面地址




ci默认的url路由:
据模型-视图-控制器模式,在此 URL 段一般以如下形式表示:
  example.com/index.php/class/function/ID
     1.第一段表示调用控制器类。即Controllers
     2.第二段表示调用类中的函数或方法。即该Controller下的一个function
     3.第三及更多的段表示的是传递给控制器的参数。如 ID 或其他各种变量。
  获取uri段
   $this->uri->segment(n); 获取指定段
   $this->uri->uri_string();返回完全的uri;http://example.com/index.php/news/local/345
  其他url函数参考URL帮助














如果我们需要修改url路由为get方式: index.php?c=class&m=function&id=345


那么需要修改配置文件即可,打开application/config/config.php
$config['enable_query_strings'] = FALSE;  #改成 true
$config['controller_trigger'] = 'c';
$config['function_trigger'] = 'm';


注意:开启之后仍可以第一种URL规则


6.2运行流程:
配置完成后了解ci 的运行流程
  index.php---路由解析---安全验证---application/controller---view---cache--index.php
  


6.3命名规则
命名规则:
   控制器: 文件名与类名相同,文件名首字母小写,类名首字母大写
   模型:   文件名与类名相同,文件名首字母小写,类名首字母大写  Namemodel
   视图:   后缀名 .php


去掉index.php


  apache 重写
  进入D:\AppServ\Apache2.2\conf找到
   #LoadModule rewrite_module modules/mod_rewrite.so  去掉#


  找到
  <Directory />
    Options FollowSymLinks ExecCGI Indexes
    AllowOverride None   修改成  AllowOverride All  并且全文修改
    Order deny,allow
    Deny from all
    Satisfy all
</Directory>
  


保存重启


进入cmd 运行下面的命令
  
D:\>cd AppServ/www/myapp


D:\AppServ\www\myapp>copy con .htaccess
^Z
已复制         1 个文件。




进入.htaccess文件
RewriteEngine on  #打开apache重写


#重写配置
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f 


#重写规则
RewriteRule ^(.*)$ index.php/$1 [L]


6.4控制器
所有控制器必须继承 CI_Controller  子类必须实现父类的构造方法
在子类构造函数里面 调用控制的构造函数 
  home.php


class Home  extends CI_Controller{
  public  function __construct(){
    parent::__construct();
   }




}


6.5控制器调用视图并传递参数
ci有一个默认的执行方法  index
public function index(){
header('content-type:text/html;charset=utf-8');
$this->load->view('public/header'); //控制器调用视图
$this->load->view('index');
        $this->load->view('public/footer');
 }


控制器传递数据给view
   $data=array();
  $this->load->view('public/header',$data); //控制器调用视图


6.6 视图语法规则:
  ci的视图语法同php几乎完全相同, 不同的是判断与循环可以使用下面的语法规则替代:


条件判断
 <?php if ($username == 'sally'): ?>


   <h3>Hi Sally</h3>


<?php elseif ($username == 'joe'): ?>


   <h3>Hi Joe</h3>


<?php else: ?>


   <h3>Hi unknown user</h3>


<?php endif; ?>


循环:
  <?php foreach ($todo as $item): ?>


    <? echo  $item; ?>


<?php endforeach; ?>






6.7控制器调用模型:
    $this->load->model('Model_name');
    $this->Model_name->function(); 
 比如:
 $this->load->model('Usermodel');
 $id=$this->Usermodel->addUser();


6.8 模型
   usermodel.php


  class Usermodel extends CI_Model {
    public function __construct(){
       parent::__construct();
      //加载数据库类
       $this->load->database(); //一旦被载入,你可以在任何地方像这样使用它
    }
    
    public function addUser(){
    $data=array('id'=>null,'name'=>'mymy','pwd'=>md5('123456'));
    $id=$this->db->insert('user',$data);  //执行成功后返回true
    return $id;
    }


    public function updateUser($id){
    $where=array('id'=>$id);
    $setDatas=array('pwd'=>md5('test123'));
    $r=$this->db->update('user',$setDatas,$where);
    return $r;
    }




}


常用数据库操作函数:
  $this->db->insert(表名,数据);  插入


  $this->db->update(表名,数据,条件);  修改
  $this->db->delete(表名,条件);  删除
  $this->db->truncate(表名); 清空表数据
  链接查询
  $this->db->select('title')->from('mytable')->where('id', $id)->limit(10, 20);
  查询:
   $this->db->query(sql语句);
   $this->db->get(表名);  //等价于 select * from 表名
  $query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset);
  //等价于: select * from 表名 where id=$id limit $offset,$limit; 


  查询时 select 和 get 一起使用
 $this->db->select('title, content, date');
 $query = $this->db->get('表名');
 //等价于 select title, content, date from 表名


查询预防sql注入:
   $this->db->escape()
  封装查询
  $sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?"; 
  $this->db->query($sql, array(3, 'live', 'Rick'));


查询资源处理: 所有的查询都将返回一个资源结果集  $query=$this->db->query($sql);
  $query->num_rows(); 返回当前请求的行数
  $query->free_result();会释放当前查询所占用的内存并删除其关联的资源标识
  $query->result_array(); 执行成功时将记录集作为关联数组返回。失败时返回空数组,通常使用foreach遍历


  foreach ($query->result_array() as $row){
   echo $row['title'];
   echo $row['name'];
   echo $row['body'];
}


  row_array(); 获取某一行数据
  $this->db->count_all();返回指定表的总行数
  $this->db->affected_rows();当执行写入操作(insert,update等)的查询后,显示被影响的行数。
  $this->db->insert_id();执行插入成功后的id


  事物
  $this->db->trans_begin();
  $this->db->query('一条SQL查询...');
  $this->db->query('另一条查询...');
  $this->db->query('还有一条查询...');
if ($this->db->trans_status() === FALSE){
    $this->db->trans_rollback();
}else{
    $this->db->trans_commit();
}


备注:$this->db->query()可以执行insert update select


其他详见手册数据库类操作


数据库缓存:
  在你需要缓存数据的地方打开缓存,然后查询数据
  $this->db->cache_on();
  $query = $this->db->query("SELECT * FROM mytable");


 清除所有的缓存:
   $this->db->cache_delete_all();


 清除指定缓存:
   $this->db->cache_delete('控制器', '方法');
  如果你访问的是  xxxx.com/index.php/a/aa,那么ci将会在缓存目录下面创建a/aa缓存文件


注意:缓存的目的主要是为了减少数据库的服务器压力,打开缓存需要配置缓存目录地址
    /applicaton/config/database.php/
      $db['default']['cachedir'] = './cache';




6.9 session的应用
  使用session必须配置session
    /application/config/config.php


  $config['encryption_key'] = 'abc@%^%'; //配置自定义密钥
  $config['sess_expiration'] = 7200;    //session 持续的秒数,2小时
  $config['sess_encrypt_cookie'] = FALSE;    //是否对 session 数据加密


  session 是作为插件库存在的所以使用时必须加装插件session库
 this->load->library('session');


$session_id = $this->session->userdata('session_id'); //获取sessionid不存在,返回FALSE
$this->session->set_userdata($array);    //添加 session数组
$this->session->set_userdata('some_name', 'some_value');同时添加多个session


$this->session->unset_userdata('some_name');   //删除 Session 数据


$this->session->sess_destroy();     //销毁 Session


6.10 帮助函数使用


$this->load->helper('number');     数字辅助函数


$this->load->helper('string');     字符串帮助函数


$this->load->helper('url');        url辅助函数
  echo  site_url("news/local/123");#http://example.com/index.php/news/local/123
  echo  current_url(); 返回当前完整的url
  echo  base_url();  返回配置文件中的url基本配置 http://127.0.0.1/myapp/
  echo  base_url('news/local/123'); #http://127.0.0.1/myapp/news/local/123
  echo  anchor('news/local/123', '链接点我', array('title' => '标题'));#<a href="http://example.com/index.php/news/local/123" title="标题">链接点我</a>
  $atts = array(
              'width'      => '800',
              'height'     => '600',
              'scrollbars' => 'yes',
              'status'     => 'yes',
              'resizable'  => 'yes',
              'screenx'    => '0',
              'screeny'    => '0'
            );


echo anchor_popup('news/local/123', 'Click Me!', $atts); 新开一个窗口
redirect是ci的一个URL辅助函数
redirect('/','location',301);// url重定向  如果写入成功,返回首页






$this->load->helper('form');       表单辅助函数


生成一个标准的input




form_open()  普通form表单头


$attributes = array('class' => 'email', 'id' => 'myform');
echo form_open('email/send', $attributes);




form_open_multipart()  #文件上传表单头


form_close()  form 结束标签 </form>




form_hidden()


form_password("表单name","表单value","表单事件")


或者数组方式


$data= array(
'name'        => 'userpwd',
'id'          => 'regpwd',
'value'       => '',
    'onblur'=>'checkPwd(this.value)',
       'maxlength'   => '100',
      'size'        => '50',
      'style'       => 'width:50%',
);




echo form_input($data);


form_upload()


form_textarea()


form_dropdown()  下拉<select></select>


form_checkbox()
form_radio()


form_submit()


form_label()


$js = 'onClick="some_function()"';
echo form_button('mybutton', 'Click Me', $js); 


set_radio()
set_checkbox()
set_select()
set_value()


表单安全处理数据:手动创建表单才有用
<input type="text" name="myform" value="<var<<?php echo form_prep($string); ?></var<" />


 
同时加载多个辅助函数
 $this->load->helper( array('helper1', 'helper2', 'helper3') );




6.11 rest路由重定向规则:
 application/config/routes.php 


$route['product/:num'] = "catalog/product_lookup";
即将被重定向
:num 将匹配一个只包含有数字的segment(段).
:any 将匹配一个包含任何字符的segment.
  如果你的url是: http://127.0.0.1/myapp/index.php/product/1 那么将自动转向控制器中catalog类中product_lookup方法


$route['product/(:num)'] = "catalog/product_lookup_by_id/$1";
  当“product”作为 URL 中第一个分段时,如果第二分段是数字,那么将自动转向控制器中catalog类product_lookup_by_id方法,将数字作为参数


$route['blog/joe'] = "blogs/users/34";
 如果URL的前两个分段是"blog"和"joe",那么将会重定向到"blogs"类的"users"方法中处理.并且将ID"34"设为参数.






6.12 缓存
 $this->output->cache(n);
只需将上面的代码放在你的controller的function中的任何位置:
其中 n 是你希望缓存更新的 分钟 数。
注意:Benchmark 标签在使用了缓存的页面仍然可用。
警告: 由于CI存储缓存文件的方式,只有通过 view 文件的输出才能被缓存。
如果你不再想使用缓存,仅需将上面的代码从你的controller里面删除即可。
注意: 这样做并不能让缓存文件立即消失,它将会自动过期并被删除。
如果你想立即删除那些文件,就必须自己动手了。


6.13 安全
 ------安全---------------------------------------------------------
1.过滤不良数据. 
2.验证数据以确保符合正确的类型, 长度, 大小等. 
3.在提交数据到你的数据库之前将其转换.
xss 安全数据配置
  预防跨站式伪造
  打开你的 application/config/config.php 
   config['csrf_protection'] = TRUE;
 
   自动过滤xss
    打开你的 application/config/config.php 
    $config['global_xss_filtering'] = TRUE;


   手动过滤xss
     $data = $this->security->xss_clean($data);


   获取表单数据
   使用 $this->input->post() 获取数据


 综合使用:
   $yzm=$this->security->xss_clean($this->input->post('yzmcode')); 


6.14常用功能类:
  
 表单验证类应用:
    使用表单验证类


控制器部分
public function test3(){
    //加载类
    $this->load->library('form_validation');
    $data['title']='校内新闻网';
    $this->load->view('header',$data);
   
    //表单验证规则
    $this->form_validation->set_rules('username', 'Username', 'required|min_length[5]|max_length[12]');
    $this->form_validation->set_rules('password', 'Password', 'required|matches[passconf]');
    $this->form_validation->set_rules('passconf', '重复密码', 'required');
    $this->form_validation->set_rules('email', 'Email', 'required|valid_email');
     $this->form_validation->set_error_delimiters('<span class="error">', '</span>');
   
    //如果$this->form_validation->run() 返回false 就表明验证失败
    if ($this->form_validation->run() == FALSE)
    {
    $this->load->view('myform');
    }else{
     //如果验证成功 就在这里处理
    $this->load->view('formsuccess');
    }
    $this->load->view('footer');
   }


模型部分
 user.php
<?php
class user extends CI_Model {
  public  function __construct(){
  parent::__construct();
   
  }
  
  public function insert($data){
  $name=$this->input->post('username');
  $password=$this->input->post('password');
    $email=$this->input->post('email');
  $data = array(
               'username' => $name,
               'password' => $password,
               'email' => $email
            );


     if($this->db->insert('user', $data)){
      return  $this->db->insert_id();
     } 
  }
  
  public function select(){
  $query=$this->db->get('user');
   $data=array();
  foreach ($query->result_array() as $row)
  {
  $data[]=$row;
  }
  return $data;
   
  }
    
  
  
}


?>


视图部分
  


<?php echo form_open('news/test4'); ?>
<h5>Username</h5>
<input type="text" name="username" value="<?php echo set_value('username'); ?>" size="50" />
<?php echo form_error('username'); ?>


<h5>Password</h5>


<input type="text" name="password" value="<?php echo set_value('password'); ?>" size="50" /><?php echo form_error('password'); ?>


<h5>Password Confirm</h5>


<input type="text" name="passconf" value="<?php echo set_value('passconf'); ?>" size="50" /><?php echo form_error('passconf'); ?>


<h5>Email Address</h5>


<input type="text" name="email" value="<?php echo set_value('email'); ?>" size="50" /><?php echo form_error('email')<div><input type="submit" value="Submit" /></div>


</form>


------------------------------
分页类的应用:


public function to_page(){


   
 $this->load->library('pagination'); //加载分页类


  设置分页配置
  $config['base_url'] = base_url().'test/index/1';  #完整的 URL 路径通向包含你的分页控制器类/方法。
  $config['total_rows'] = '200'; #分页的数据总行数
  $config['per_page'] = '20';  #每个页面中展示的数量,
  $config['uri_segment'] = 3; #页数的url分段
  $config ['num_links'] = 3; #当前页码前后标签个数,默认3
  $config['suffix'] = '.html'; #追加伪静态
封装html分页标签:
               $config ['full_tag_open'] = '<div class="pages">'; // 分页开始样式
$config ['full_tag_close'] = '</div>'; // 分页结束样式

$config ['first_link'] = '首页'; // 第一页显示
$config ['first_tag_open'] = '<span class="sp1">';
$config ['first_tag_close'] = '</span>';

$config ['last_link'] = '尾页'; // 最后一页显示
$config ['last_tag_open'] = '<span class="sp1">';
$config ['last_tag_close'] = '</span>';

$config ['next_link'] = '下一页 >'; // 下一页显示
$config ['next_tag_open'] = '<span class="sp1">';
$config ['next_tag_close'] = '</span>';

$config ['prev_link'] = '< 上一页'; // 上一页显示
$config['prev_tag_open'] = '<span class="sp1">';
$config['prev_tag_close'] = '</span>';

$config ['cur_tag_open'] = '<span class="sp2"><b>'; // 当前页开始样式
$config ['cur_tag_close'] = '</b></span>'; // 当前页结束样式

$config['num_tag_open'] = '<span class="sp1">';
$config['num_tag_close'] = '</span>';


将配置文件写入
$this->pagination->initialize($config); 
输出链接
               return $this->pagination->create_links();
}


在模型中查询数据:
  通过sql limit或者数组的方式进行分页






//当我们需要的时候就调用分页函数  
    $data['page_list']=$this->to_page();  //返回分页链接






在视图中:
  分页的css 样式
 <style>
.pages {
border: 1px;
height: 30px;
}


.pages .sp1 {
height: 30px;
line-height: 30px;
margin-left: 10px;
}


.pages .sp2 {
margin-left: 10px;
border: 1px solid #e0e0e0;
background: red;
color: #fff;
padding: 5px 10px 5px 10px;
}


.pages .sp1 a {
border: 1px solid #e0e0e0;
background: #ebebeb;
padding: 5px 10px 5px 10px;
}
</style>


循环数据
   <?php foreach ($need as $v):?>
<li>
         <span class="rq"><?=$v->addtime?></span> 
 <a href="open/show_job_need_info/<?=$v->qzid?>.html"> <?=$v->uname?> </a> 
 <a href="open/show_job_need_list/<?=$v->jid?>.html"> <?=$v->typename?> </a> 
 <?=$v->free?>
</li>
<?php endforeach;?>




<div><?php  echo $pages; ?></div>  //显示分页的链接


-------------------------------------
验证码辅助函数的应用:


  ci的验证码是生成图片后需要保存,网页加载保存后的图片,所有我们需要在application的同级目录中创建一个captcha 用来保存验证码图片
在实际开发过程中,生成验证码的方法应该写在模型里这样可以确保每一个控制器都可以访问到它




引用验证码帮助
$this->load->helper('captcha');
$vals = array(
//'word' => rand(1000, 10000), #验证码的内容,生成一个随机数  不是必须的
'img_path' => './static/captcha/',  #必须的
'img_url' => base_url().'static/captcha/', #必须存在该目录
   'img_width' =>150,  //是必须的
'img_height' =>30,    //是必须的
'expiration' => 10//指定了验证码图片的超时删除时间. 默认是2小时. 不是必须的  单位是秒
 
);
$cap = create_captcha($vals);  #返回一个数组格式如下 数组格式为: 
                   array('image'  生成一个 <img  />标签
                           'word' 验证码值              
                     )


$this->session->set_userdata('capyzm',$cap['word']); #使用sesson保存数据


return $cap['image'];


在视图页面使用验证码
 <?php  echo $cap['image'] ?> 




----------------------------
文件上传下载:






------------------------
ajax 验证:


view
<div id="remind" style="display:none"></div> 错误提示部分
<form action="/ci/index.php/user/reg" method="post" name="reg_form" id="reg_form">
用户名:<input type="text" name="username" id="username" value=""><br>
密码:<input type="password" name="pwd" id="pwd" value=""><br>
<input type="button" name="zc" id="zc" value="注册">
</form>
<script>
$("#zc").click(function(){
var user = $("#username").val();
var pwd = $("#pwd").val();
$.post("/ci/index.php/user/ajax_check_reg", {user:user,pwd:pwd},function(data){
        if(data!=='submit'){
$("#remind").css('display','block');
$("#remind").html(data);
        }else{
        $("#reg_form").submit();  //form表单提交
        }
}); 
});
</script>




controller
  //验证用户注册的方法
  public function ajax_check_reg(){
$this->load->model('user_model');
$this->user_model->check_user_reg($_POST['user'],$_POST['pwd']);
}




model
  function check_user_reg($user,$pwd){
    if(!trim($user)){
    echo '用户名不能为空';
    exit();
    }elseif(iconv_strlen($user)>7){
    echo '用户名最大长度为7';
    exit();
    }elseif(!trim($pwd)){
    echo '密码不能为空';
    exit();
    }elseif(strlen($pwd)<6){
    echo '密码长度最少为6';
    exit();
    }
    $query = $this->db->get_where('user', array('name' => $user));
    if($query->num_rows()){
      echo '用户名已经被注册';
    }else{
      session_start();
      $_SESSION['login_name']=$user;
      echo 'submit';
    }
    }




-----------------------
补充:
  扩展自己的类


  在application/libraries/下面创建自己的类


   文件名: My类名.php
   类名:   class My类名{
             public function __construct(){
  parent::__construct();
     }
             public funcitoin test(){


            }


       }


   在使用需要加载自己的类
   $this->load->library('My类名');


  使用类的对象调用函数
    $this->my类名->some_function();  // 对象的实例名永远都是小写的 








  


  


  






















 
























  








  


  























  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大多数PHPer都想写出运行状态良好的应用程序,而且希望尽可能做得简单且不费事。这篇文章是有关 CodeIgniter 的(以下简称 CI),CI 是一个达成以上目标的框架。 如果你只是要达成一个最终的结果,而把中间所有的编码细节和复杂统统丢给一个框架,CI 是你最好的朋友。 CI 有很多优点:免费,轻量级,容易安装,它能使你的编程生涯变得很轻松。 这一章我们会告诉你: CI 能为你做什么? 什么是“框架”?CI 为什么能被称为框架? “开源”商业模式。 CI 的某些不足(是的,它并不完美)。 1.1 CodeIgniter 能为你做什么? 如果你已经是一位 PHPer,开发过 PHP 应用,CodeIgniter 将会帮助你做得更好,更容易达成目标。CI 会减少你的代码量。你的脚本可读性也会更好,更容易升级。它会使你的网站结构更紧凑,代码更强健,如果没有很好地研究 CI 的源代码,你可能还无法察觉到它的强健。 对大多数兄弟来讲,你可能已经花了不少时间,系统地学习了 PHP、HTML 和 CSS,当然还有 MySQL 什么的,不过如果使用 CI,你只需要一些基本的 LAMP(WAMP)知识,你没有必要先成为一个专家才能使用 CI。你完全可以先借助于 CI 或别的什么框架软件,成为一个有生产力的 PHP 程序员,拿着高薪然后优雅地进一步学习 PHP 的中高级知识,直至成为一位真正的 PHP 骨灰级的人物。 下述情形,你最好不要使用CI: 你没有一点PHP和HTML的基本知识。 你想用最少的代码,快速简便的写一个基本的内容管理系统(CMS)(可以看看Expression Engine)。 你想写一个只有几个标准特性的简单的网站。 1.1.1 节省时间 CI 学习周期短,见效快。让我们试着评估一下相关的要素: CI 如何减少代码量? 你真的可以减少很多工作量:敲击键盘的次数减少了,代码错误减少了,你只需要很少的时间调试代码。代码量减少还意味着你只需要较少的空间来存放应用程序。 举两个例子(稍后它们会被进一步分析,因此不用担心如何了解它们的工作原理!) 想象你正在写一个 MySQL 数据库查询。可能的代码如下: 复制代码到剪贴板PHP 代码$connection = mysql_connect("localhost","fred","12345"); mysql_select_db("websites", $connection); $result = mysql_query ("SELECT * FROM sites", $connection); while ($row = mysql_fetch_array($result, MYSQL_NUM)) { foreach ($row as $attribute) print "{$attribute[1]} "; }现在看看 CI 如何处理同一个问题: 复制代码到剪贴板PHP 代码$this->load->database('websites'); $query = $this->db->get('sites'); foreach ($query->result() as $row) { print $row->url; }比较字符数:前者 336,后者 112。 第二个例子,现在让我们想象你正在用 HTML 写一个数据输入窗口,你想要一个下拉输入框。下拉框中有三个选项。代码如下: 复制代码到剪贴板HTML 代码<select name="type"> <option value="1">www.this.com</option> <option value="2">www.that.com</option> <option value="3" selected>www.theother.com</option> </select>CI 的写法和前例一样,因为它把相关内容放入一个数组,更容易由 PHP 进行处理: 复制代码到剪贴板PHP 代码$urlarray = array( '1' => 'www.this.com', '2' => 'www.that.com', '3' => 'www.theother.com', ); $variable .= form_dropdown('url', $urlarray, '3');在 HTML 中,你需要输入 154 个字符;在 CI 中,只需要 128 个字符。 1.1.2 使你的网站更健壮 你不需要写很多代码,是因为 CI 提供了许多标准的功能,这些经过仔细推敲的框架内的代码,对安全性和输入进行了有效的校验和考虑。初学者往往没有足够的能力全面兼顾功能和安全。(这也是中高级程序员与新手之间能力差异的一个方面) 1.1.2.1 确保你的链接自动更新 设想你正在编写一个菜单页面,有许多超链接可重定向到其他页面。他们全部以传统的 HTML 格式编写: 复制代码到剪贴板HTML 代码<a href="http://www.mysite.com/index.php/start/hello/fred">say hello to Fred</a>后来,你决定转移网站到其他 URL。这意谓你必须仔细地去查找并修改代码中的每一处 URL,否则它们将无法正常工作。 CI 给你一个简单的函数,可以这样编写超链接: 复制代码到剪贴板PHP 代码echo anchor('start/hello/fred', 'Say hello to Fred');CI 推荐你把你的 URL 放入一个配置文件中供你的脚本读取。CI 的 anchor 函数会自动从配置文件中提取相关 URL。因此,当你修改一个 URL 时,你只需要修改配置文件中的对应链接,然后所有超链接将自动更新。 1.1.2.2 防止对数据库的攻击:对单输入的数据进行校验和处理 数据输入可能引发许多问题。因为 HTML 和数据库的限制,数据中总包含特定的符号—举例来说,省略符号和引号—可能导致你的数据库遭到攻击,最终得到你无法预料的结果。 解决方案是在把这些数据存入数据库前对这些数据进行相关处理。这样做会浪费一些系统时间,增加一些额外编码。 CI 的单辅助函数会自动地完成这些工作。因此,当你编写一个输入框时: 复制代码到剪贴板PHP 代码echo form_input('username', 'johndoe');CI 也隐式地执行下列校验函数: 复制代码到剪贴板PHP 代码function form_prep($str = '') { if ($str === '') { return ''; } $temp = '__TEMP_AMPERSANDS__'; // Replace entities to temporary markers so that // htmlspecialchars won't mess them up $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str); $str = preg_replace("/&(\w+);/", "$temp\\1;", $str); $str = htmlspecialchars($str); // In case htmlspecialchars misses these. $str = str_replace(array("'", '"'), array("'", """), $str); // Decode the temp markers back to entities $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); $str = preg_replace("/$temp(\w+);/","&\\1;",$str); return $str; }上述函数捕获像“&”这样的特殊字符,以便在你的页面提交时不会造成混乱。你应该知道,有些字符会引起问题。 并不是所有的用户都会中规中矩的输入符合要求的信息,你也不可能知道使用浏览器输入信息的是什么人,他们在想什么,做什么。你可以使用 CI 来防止输入不符合要求的信息。当然,你大可不必知道 CI 是如何在幕后为你做到这一切的,你只需要简单地输入如下代码: 复制代码到剪贴板PHP 代码echo form_input('username', 'johndoe');1.1.3 增强你的代码 CI 使你写代码更容易了。不像有些类库如 PEAR 等,集成比较困难,(有时候你会找不到支持 PEAR 的空间),CI 很容易集成,只要把它放入一个目录,它就能很好地工作。CI 所有代码的可读性好,也很健壮,推出前经过社区用户的认真测试,所以在你可以使用时,这些代码已经经历了很多考验。 让我们看两个例子。 1.1.3.1 发送 Email 和附件很简单 发送 Email 的功能实现起来比较复杂,但是,使用 CI 将使这件事变得很简单: 复制代码到剪贴板PHP 代码$this->load->library('email'); $this->email->from('your@your-site.com', 'Your Name'); $this->email->subject('Email Test'); $this->email->message('Testing the email class.'); $this->email->send();实现发送 Email 的功能中有一些不容易解决的技术问题:比如设置文本自动换行(取消设置的话则可以保持长 URL 地址不被换行或截断)或发送附件。标准的 PHP 实现起来比较复杂,CI 简化了这些工作,它的 Email 类使得发送附件很简单: 复制代码到剪贴板PHP 代码$this->email->attach('/path/to/photo1.jpg');CI 把内部的复杂部分悄悄地完成了,举例来说,实现了列举近百种不同附件的 MIME 类型的功能。所以它知道你的相片 photo1.jpg 是一个“image/jpeg”MIME 类型。因此它在你附件的适当位置填写必要的限制符号,它处理文本的换行,让你轻松标记出不希望出现换行的文本块。 1.1.3.2 压缩用户要下载的文件以加快下载速度 为了加快下载速度,常见的做法是在下载之前压缩下载文件。你可能不知道如何处理。但 CI 可以方便地让你用 4 行代码完成此功能: 复制代码到剪贴板PHP 代码$name = 'mydata1.txt'; $data = 'the contents of my file..........'; $this->zip->add_data($name, $data); $this->zip->archive('c:/my_backup.zip');运行这些代码,你会在你的 C 盘根目录下找到一个压缩文件,解压后即为原始文件。 你网站的用户并不清楚你是如何简便实现这个功能的,但他们能体会到你的网站的下载速度很快,而你只用了数分种(而不是数小时)就实现了这个功能。 1.2 CodeIgniter 是什么?框架又是什么? 当发明计算机编程不久之后,便有人发现,这其中涉及到了太多的重复操作。之后,也许是 Ada Lovelace(人类历史上的首位程序员),又或许是 Alan Turning,决定将计算机程序模块化,从而使得片段程序代码可以重复使用。PHP 程序员们早已习惯了将需要重复使用的代码写在函数中,并将这些函数放在 include 文件里。 同样的,框架是为重用而发明的,存放在独立的文件中,用来简化重复操作的代码。 上面例子中连接数据库和编写 HTML 单元素的工作都可以调用相关的 CI 函数来进行简化。 它超越了这一点。有很多种方法实现同样的功能;大多数的框架会让你按照它实现的方法来做。他们选择了一种方式来解决问题,所以你也必须要遵循这种方式。如果方式得当,编程便会轻松许多,反之则会事倍功半。 好的框架设计能实现需要的功能,而且尽可能地不互相牵连。一个好框架为你做出各种功能的实现,并且给你提供一步一步的编程指导。 提到框架时,就不能不提到著名的框架:Ruby on Rails。 Rails 做得相当成功,因为它籍由最少量的编码,提供简便快速的网站开发。本质上,它是一个结构和一组工具,专为使用 Ruby 语言的用户开发,允许你快速建立 Ruby 系统原型。它不是 Ruby 语言中唯一的框架,但它一定是最有开发效率和最有名的。另一方面,如果你已经花了很大功夫学习 PHP 的话,那么从 Ruby 重新开始又要重头学起。 为 PHP 开发的框架有很多个(大约 40 个),CI 只是其中之一。其它的还包括 Zend Framework、Cake、Trax 等。下列网址可以找到一个针对十种框架的简明图分析:http://www.phpit.net/article/ten-different-php-frameworks/。 如果你访问上述网址中相关产品的官方网站,你将会注意到,每个论坛都有一个共同的热点,就是到底哪一个框架是最好的?事实似乎是每个都有它的长处,而且又都有自己的弱点。我的评估标准是:我很忙;因此框架应该节省我的时间,从中选择一个后,就坚持使用下去,因此就有了这本介绍 CI 的书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值