CodeIgniter学习笔记
来源:互联网 发布:网络通信安全管理员证 编辑:程序博客网 时间:2024/05/16 12:43
1、安装
下载CodeIgniter之后,解压,放到网站的根目录,就完成安装了
2、修改system和application文件夹
为了安全性起见,我们通常要修改默认的system和application文件夹
<1>改为自己想要名字,比如改为mysystem和myapplication
<2>把他挪到webroot以外,这个以外的意思,可以是和webroot并列路径创建一个文件夹,把这两个文件夹丢进去,这样他都不会在web服务器文件目录里
<3>然后要在index.php里面修改路径:
$system_path = '../xxx/mysystem';$application_folder = '../xxx/myapplication';
3、url重写,把路径中的index.php去掉
<1>下载iis的重写模块:https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=5747
需要x86或者x64的模块可以在微软官网上搜索
<2>导入规则
<3>编写一个xx.htaccess文件把规则写进去,然后导入
RewriteRule ^(?!/index.php)(?!/themes)(?!/upload)(?!/static)(?!/application)(?!/st_plugins)(.*)$ /index.php/$1 [I]
<4>在index.php修改
$view_folder = '';将这个变量的值置为空
<5>上面的方法使用过程中发现问题,他并不能真正过滤掉不想添加index.php的路径,比如static里面存放的静态文件。
找了很多方法最终找到了一个:
在web.config里面配置,把下面这段代码粘贴到system.webserver里面:
<rewrite><rules> <rule name="OrgPage" stopProcessing="true"> <match url="^(.*)$" /><conditions logicalGrouping="MatchAll"> <add input="{HTTP_HOST}" pattern="^(.*)$" /> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions><action type="Rewrite" url="index.php/{R:1}" /> </rule></rules></rewrite>发现他会自动在rewrite模块里添加规则,这个规则竟然非常好用,静态文件直接过滤。
4、修改路由,把不想要的路径隐藏
比如,如果我们所有的页面都放在pages/view里面,那么我们也可以不显示这两个字段,在application/config/routes.php修改:
$route['default_controller'] = 'pages/view';$route['(:any)'] = 'pages/view/$1';
5、修改数据库配置
CI的数据库配置文件在application/config/database.php,做如下修改:
$db['default'] = array('dsn'=> '','hostname' => '127.0.0.1',//必填主机名,注意,这个填写为localhost网上有人说会慢100倍,没有考证过。'username' => 'root',//账户名'password' => '123456',//密码'database' => 'testphp',//数据库名'dbdriver' => 'mysqli','dbprefix' => '','pconnect' => FALSE,'db_debug' => (ENVIRONMENT !== 'production'),'cache_on' => FALSE,'cachedir' => '','char_set' => 'utf8','dbcollat' => 'utf8_general_ci','swap_pre' => '','encrypt' => FALSE,'compress' => FALSE,'stricton' => FALSE,'failover' => array(),'save_queries' => TRUE);
6、设置url
<1>设置base_url
在application/config/config.php设置:
$config['base_url'] = 'http://yourdomain.com';$config['index_page'] = '';
注意这个url必须带http的,否则不能识别。
注意:
由于服务器跟测试环境用的域名可能不一样,那么这个一直改来改去就很麻烦了,我们可以让他自动获取:
$config['base_url'] = 'https://'.$_SERVER['SERVER_NAME'];
注意:后面由于使用php-cli访问页面,出现$_SERVER['SERVER_NAME']未定义的报错,所以改回了直接hardcode。
<2>在页面中使用base_url还是site_url?
比如这样拼一个url:
site_url('news/home');=>http://domain.com/index.php/news/home
base_url('news/home');=>http://domain.com/news/home
可以看到,base_url不会加上index.php,而site_url则会自己加上index.php
对于我们已经做过url rewrite的网站来说,要使用base_url以避免出现index.php。
<3>获取url
uri_string(),获取到域名后面那部分;
current_url(),获取全部url,不是真实的url,包括config里面的base_url+uri_string;
注意,这两个都不会把参数带进来,我们可以利用这点,取到当前的url以后,redirect一下,可以去掉所有参数。
<4>跳转url
redirect($url):如果$url是域名后面的uri,则在本站内跳转;如果是全地址,则可以跳到站外。
7、routes
$route['news'] = 'news';
//http://yourdomain/news 访问到controller类news的index函数
$route['news/(:any)'] = 'news/view/$1';
//这个(:any)对应的是$1
//(:any)可以是一个参数,也可以是n个参数,可以是数字,也可以是字母
//比如http://yourdomain/news/t1/t2对应news类的view函数的第一个参数和第二个参数
$route['news/(:num)'] = 'news/view/$1';
//只允许传入数字
简洁明了的路由器设计:
$route['url_1/url_2/test/(:any)'] = 'url_1/url_2/test/index/$1';
每个路径真实的对应一个同名controller,再对应一个真实的同名view。
controller里面只有index方法,而不要用其他的方法。
index可以传参数进去。
以上说的都对,但是这种一一对应的关系是不需要设置路由的,这个是默认路由的,当然前提是没有被设置的路由规则截取了。
默认路由就是一一对应的,比如说:
/test_routes Test_routes.php=>index()
/test_routes/test2 Test_routes.php=>test2()
这些都是默认的,我们不需要设置,并且使用这种一一对应的关系会让我们的逻辑更清晰,不会找东西的时候一头雾水。
因此就使用默认的路由,不要用到routes设置就好了。
注意:
<1>首页使用default_controller
还要注意一点,由于首页是没有路由的,只要访问域名就可以显示了,那么就有一个默认路由,在routes.php里要保留这个:
$route['default_controller'] = 'home';
然后在controller里创建一个Home.php:
<?php/** * Created by PhpStorm. * Date: 2017/2/22 * Time: 14:45 */class Home extends CI_Controller{ public function __construct() { parent::__construct(); } public function index() { $this->load->view('home'); }}
这里假设我们已经创建了home的页面,这index里面指向就可以了。
那么我们就可以通过http://yourdomain.com/或者http://yourdomain.com/home访问首页了。
<2>项目首页也要设路由
项目通常在某文件夹下面,比如a/b/page1.php,a/b/page2.php等多个页面。
我们通常访问a/b/这个路径,需要看到项目home页面,那么我们能做一个名字为b.php的页面放在跟b文件夹同路径下面吗?
答案是不可以,有了b.php他就不会去找文件夹下面的东西了。
所以我们要在b文件夹下面做一个home.php,然后通过路由定位,让a/b/指向home.php,
比如:
$route['a/b'] = 'a/b/home';
就可以了
8、存放静态文件
在url rewrite里面我们看到,static文件夹是不会被自动添加index.php路径的,因此我们可以把静态文件添加到static文件夹里。
在index.php同目录下,创建static文件夹,然后再创建js文件夹,把jquery的文件放到里面。
在php页面这样引用就可以了:
src="static/js/jquery-3.1.1.min.js"
他会请求到:http://yourdomain.com/static/js/jquery-3.1.1.min.js
9、调用自定义类
<1>libraries方式
自定义类放在libraries文件夹里,这样定义自定义类:
<?phpdefined('BASEPATH') OR exit('No direct script access allowed');/*** */class Testzphp{public function __construct($parsms){// 如果类不需要带参数,这个构造函数可以省略}// 这个参数可以直接传递进来public function test($param){return "hello TestZphp!".$param;}}?>
注意点:
1、类名必须和文件名一致;
2、首字母必须大写;
3、默认是不能调用$this的,如果需要调用$this需要这样处理:
class Test_lib { protected $CI; public function __construct() { $this->CI =& get_instance();//将根实例赋给CI,注意这个是'=&',千万不要搞错了!!! } public function somefunc() { $this->CI->load->model('redis_model');//用$this->CI取代原来的$this } }
在controller调用
$this->load->library('zphp/Testzphp');$data['zphp'] = $this->testzphp->test(235);几个 注意点:
1、libraries里面可以放文件夹,调用就是'文件夹名/类名';
2、load进来之后调用的时候不需要那个文件夹名;
3、类名首字母必须改为小写。
类带参数
$params = array('type' => 'large', 'color' => 'red');$this->load->library('zphp/Testzphp', $params);
<2>include方式
另一种调用方式。
10、使用helper
helper是类似于自定义类的一种方式,但是他没有定义类,只有方法。
<1>创建helper
在application/helpers下创建一个php文件,文件名取为mytest_helper.php,文件名必须以_helper结尾。
<?php/** * Created by PhpStorm. * Date: 2017/2/8 * Time: 21:08 * @param $data * @return string */function test_helper($data){ return 'the data is'.$data;}?>
<2>在controller里这样调用:
$this->load->helper('mytest'); echo test_helper('hello');
<3>创建子文件夹
helper同样可以在子文件夹里创建,只需要调用的时候用"文件夹名/类名"调用就可以了。
在helpers/hep下创建:
<?php defined('BASEPATH') OR exit('No direct script access allowed');/** * Created by PhpStorm. * Date: 2017/2/9 * Time: 10:09 * @param $data * @return string */function testhep($data){ return 'the helper under hep data is '.$data;}
在controller里调用:
$this->load->helper('hel/myhep'); echo testhep('world');
11、controller的继承
通常需要有一个base页面来处理登录鉴权等基础事务,每个页面单独处理显然是不合适的。因此我们需要用到controller继承。
在application/core下面创建MY_Controller.php文件:
<?php/** * Created by PhpStorm. * User: * Date: 2017/2/15 * Time: 14:29 */class MY_Controller extends CI_Controller{ public function __construct() { parent::__construct(); $this->load->library('session'); if (!isset($_SESSION['views'])) exit("登录已超时,请重新登录!"); }}?>
注意,这个MY_Controller不需要写index函数,当然也可以写,也可以添加其他函数供子类调用。意思是说,一个子类controller必定需要index或者其他函数(路由访问),但是这个是个例外,不需要。
在controllers里添加一个测试类Testcontroller::
<?php/** * Created by PhpStorm. * User: * Date: 2017/2/15 * Time: 14:31 */class Testcontroller extends MY_Controller{ public function __construct() { parent::__construct(); } public function index() { //echo "world!"; //$this->load->library('session'); //$this->session->views = "hello_new_session"; echo $_SESSION['views']; }}?>
注意:
<1>MY_Controller只能有一个,怎么适应不同页面的需要?
可以通过在MY_Controller定义一个属性,然后通过子类给这个属性设定值,父类根据这个设定的值判断要做什么处理,比如,
在MY_Controller里:
<?php/** * Created by PhpStorm. * Date: 2017/2/15 * Time: 14:29 */class MY_Controller extends CI_Controller{ protected $type = ''; public function __construct() { parent::__construct(); switch ($this->type) { case 'type1': echo 'type1'; break; default: echo 'default'; break; } $this->load->library('session'); if (!isset($_SESSION['views'])) exit("登录已超时,请重新登录!"); }}?>
在子类赋值:
public function __construct() { $this->type='type1'; parent::__construct(); }
这样父类就可以根据这个不同的值,来做不同的处理。
12、参考资料
PHP项目中CodeIgniter使用的一些建议
https://segmentfault.com/a/1190000004551793
13、使用curl
这个curl本来是php的,不属于CI的,写在这里方便查阅。
首先,在php.ini要设置extension=php_curl.dll为开启,然后重启服务器。
在代码里面这样用:
/** * https请求,支持Get和Post * @param $url * @param null $data * @return mixed */ public function https_request($url,$data = null) { $curl = curl_init(); curl_setopt($curl,CURLOPT_URL,$url); curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,FALSE); if (!empty($data)) { curl_setopt($curl,CURLOPT_POST,1); curl_setopt($curl,CURLOPT_POSTFIELDS,$data); } curl_setopt($curl,CURLOPT_RETURNTRANSFER,1); $output = curl_exec($curl); curl_close($curl); return $output; }
14、调用静态函数
比如静态函数,在libraries里面:
<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * Created by PhpStorm. * Date: 2017/2/16 * Time: 15:48 */ class CurlRequest { /** * https请求,支持Get和Post * @param $url * @param null $data * @return mixed */ public static function https_request($url,$data = null) { $curl = curl_init(); curl_setopt($curl,CURLOPT_URL,$url); curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,FALSE); if (!empty($data)) { curl_setopt($curl,CURLOPT_POST,1); curl_setopt($curl,CURLOPT_POSTFIELDS,$data); } curl_setopt($curl,CURLOPT_RETURNTRANSFER,1); $output = curl_exec($curl); curl_close($curl); return $output; } }?>
在controller里面使用:
如果是普通函数:
$this->load->library('CurlRequest'); $res = $this->curlrequest->https_request($url);
但是静态函数这样用:
$this->load->library('CurlRequest'); $str = CurlRequest::https_request($url);
15、自定义配置文件
在application/config里面添加my_config.php,在文件里面添加自定义的参数:
$config['hello'] = 'world';
在controller里这样用:
//测试自定义config $this->config->load('my_config'); echo $this->config->item('hello');
16、autoload
使用autoload才能避免每次使用都要用$this->load->...来加载资源,而且他是全局 应用的。
使用方法:
在application/config/autoload.php里面找到对应的数组添加进去,比如说:
$autoload['libraries'] = array('类名1,不需要带.php','类名2,不需要带.php');$autoload['helper'] = array();$autoload['config'] = array();$autoload['model'] = array();
找到对应的类目,将类名填到括号里,多个就用逗号隔开。
注意:这个autoload跟我们普通的$this->load效果是一样,也就是说$this->load也是全局的,只加载一次,再次load其实不执行。
但是我们不知道是否已经load过了,只好每次load一下。autoload不存在这个问题。
17、json_decode
$str = '{"result":{"access_token":"xx","expire_in":90000,"refresh_token":"yyy","openid":"hhh","shop_name":"jjj","scope":3,"shop_logo":"uuu"},"status":{"status_code":0,"status_reason":"success"}}'; $obj = json_decode($str); if ($obj->{'status'}->{'status_code'}==0) { echo '授权成功'; }else { echo '授权失败'; }
使用方法,通过->一级级往下走就行了。
18、json_encode
这是php的一个工具函数,把值对转为json串,
规则:json_encode里面的参数必须是一个array,这个array里面如果是值对,那么转为一个object,如果是并列排放的一些object,则转为一个数组
例如:
$arr1 = array('id'=>1,'name'=>'Item 1','price'=>'$100'); json_encode($arr1);//{'id':1,'name':'Item 1','price':'$100'} $arr2 = array('id'=>2,'name'=>'Item 2','price'=>'$200'); json_encode($arr2);//{'id':2,'name':'Item 2','price':'$200'} echo json_encode(array(array('id'=>1,'name'=>'Item 1','price'=>'$100'),array('id'=>2,'name'=>'Item 2','price'=>'$200'))); //[{'id':1,'name':'Item 1','price':'$100'},{'id':2,'name':'Item 2','price':'$200'}]
19、实例化
ci的这种load的方法,其实是单例模式,一旦load了一个类,就不会再次实例化,那么如果我们每次使用都想创建一个新的实例应该怎么做?
在类里面写一个静态函数:
public static function getInstance() {return new MyClass();}
MyClass::getInstance ()->my_func();
每次调用都会生成一个新的实例。
20、ajax请求
1、页面设计
codeigniter的ajax请求非常简单,没有其他语言那种弯弯绕绕的感觉,比如什么?method=xx,CI呢就是跟平常页面访问一样的,但是页面访问会返回view,ajax请求则直接返回数据就可以了。因为controller每个方法都对应着一个uri,所以也不用method=xx这种写法,而是直接请求这个uri就可以了,也就是restful风格的请求。
但是程序还是可以知道这个访问是ajax请求还是http请求,我们可以这样判断:
$this->input->is_ajax_request()
有些东西的处理是不一样的,比如说,如果是http请求,当没有登录的时候我们会让他跳到登录页面;如果是ajax我们就不能这样处理了,这样会返回空,我们应该返回提示他没有登录的错误信息。
我们可以在controller的基类判断是否为ajax请求,然后做不同的处理,比如:
在MY_Controller里:
public function __construct() { parent::__construct(); switch ($this->type) { case 'xxx': // do sth. if ($this->input->is_ajax_request()) $this->xxx_ajax(); else $this->xxx(); break; default: exit('未设置controller-type!'); } }
这样就两种请求分流到两个func里了,对于ajax我们要做的是,判断他有没有登录,有登录则不用做任何处理,基类执行完毕会自动跑到子类执行他应该做的;
如果没有登录则用exit('')返回错误信息并退出。
2、处理post数据
(1)两种post方式?
这是以前所不知道的,post数据竟然有两种方式?真的有
一种叫做form data,是值对类型的,比如$.post()这种post方法默认就是用这种方式
一种叫做request payload,这种就是post一个json,所有的数据都在一个json里面,比如bootstrap-table就是用这种方式post
如果用jquery的request payload应该这样做:
$.ajax({ type:"POST", url:"xxx/xxx/", dataType:"json", data:{"email":email,"password":password}, success:function(){ alert('Success'); return true; }, error:function(){ alert('Failed'); return false; }});
可以看到这里的data不是用那种值对的方式了,而是整个就是一个json。
(2)如何获取?
第一种很简单,就是:
$this->input->post('data');第二种就不一样了:
$request_body = file_get_contents('php://input'); $data = json_decode($request_body); $val = $data->{'abc'};//取值
21、数据库的安全性
CI在数据库防止注入方面不遗余力。
所有的数据库封装函数都做了安全性过滤,比如以下:
$this->db->delete//删除$this->db->update//更新$this->db->insert//插入$this->db->get_where//查询
等等,使用这些函数都会自动做安全性过滤。
包括,查询绑定:
$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";$this->db->query($sql, array(3, 'live', 'Rick'));$sql = "SELECT * FROM some_table WHERE id IN ? AND status = ? AND author = ?";$this->db->query($sql, array(array(3, 6), 'live', 'Rick'));
都是安全的。
唯一可能发生危险,没有做安全检查的是:
直接使用query,并且没有做任何绑定,直接在里面拼语句,把参数连接进去。
22、数据库查询的返回对象
$query->num_rows();//返回行数$query->num_fields();//返回字段数$arrObj = $query->result();foreach($arrObj as $row){echo $row->title;echo $row->name;}$arrDict = $query->result_array();foreach($arrDict as $row){echo $row['title'];echo $row['name'];}count($arrDict);//获取行数,在返回json的时候可以通过这个方法设定total的值$rowObj = $query->row();//当前请求的第一行数据作为object返回echo $rowObj->title;echo $rowObj->name;$rowDict = $query->row_array();echo $rowDict['title'];echo $rowDict['name'];$rowObj = $query->row(4);//返回第四行,不存在则返回第0行$rowObj = $query->first_row();$rowObj = $query->last_row();$rowObj = $query->next_row();$rowObj = $query->previous_row();
- CodeIgniter 学习笔记
- CodeIgniter学习笔记总汇
- CodeIgniter学习笔记
- codeigniter 的学习笔记
- php CodeIgniter 学习笔记
- CodeIgniter学习笔记
- PHP框架CodeIgniter学习笔记(一)
- CodeIgniter学习笔记 Item2--CI中的MVC
- CodeIgniter学习笔记 Item5--CI中的AR
- CodeIgniter学习笔记 Item7--用户基础教程 摘要
- CodeIgniter学习笔记 Item8--CI辅助函数
- CodeIgniter学习笔记 Item10--CI总结精华
- CodeIgniter笔记
- CodeIgniter笔记
- codeIgniter 学习
- CodeIgniter 学习
- CodeIgniter学习笔记 Item1--CI简介与MVC设计模式
- CodeIgniter学习笔记 Item3--CI中的超级对象
- java实现 取当前时间的前7天的日期
- 内核驱动宏__init,__exit,__initdata的作用
- 狄更斯笔下的雾霾
- Harris原理及opencv源码分析
- 我读《移动互联网中基于机器学习的用户个性化QoE评估》
- CodeIgniter学习笔记
- 建立linux 软件仓库
- Java开发环境搭建
- QT字符与字符串转换
- MAC平台下Xcode配置使用OpenCV的具体方法
- 超链接传递的中文参数在ie浏览器下乱码
- U盘启动盘制作-适用于Ubutnu&Windows
- 多表查询之联接
- 字符串的包含