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();









0 0
原创粉丝点击