CodeIgniter控制器之业务逻辑实例分析_php实例_脚本之家

by admin on 2019年11月26日

本文分析了CodeIgniter连贯操作的底层原理。分享给大家供大家参考,具体如下:

本文实例分析了thinkphp连贯操作用法。分享给大家供大家参考。具体分析如下:

PHP中的连贯操作看起来的确很酷,也非常的方便代码的阅读,当然了必须是在OOP中用才行,在过程化的程序中,就没有必要用这种方法了。有实现这个方法的有用_CALL来实现的,而我下面写的这个例子,则不是用_call的,大家可以扩展一下吧。

本文实例讲述了CodeIgniter配置之SESSION用法。分享给大家供大家参考,具体如下:

本文实例分析了CodeIgniter控制器之业务逻辑。分享给大家供大家参考,具体如下:

php oop连贯操作原理

一、常用连贯操作,可以接连使用但没前后顺序之分,后面一定要有方法select,updata,delete,find

下面写的这个SQL语句组合类,主要是用于学习的,如果有同学想拿去用,请再完善一下。

刚使用Codeigniter时也被其中的SESSION迷惑过,后来就再也没用过CI自带的SESSION,想必还是有必要整理一下SESSION。为弄清CI中的SESSION,先来说一下PHP中SESSION是如何工作的。由于HTTP协议本身是无状态的,所以当保留某个用户的访问状态信息时,需要客户端有一个唯一标识传给服务端,这个唯一标识就是SESSION
ID,存放在客户端的COOKIE中,然后服务端根据该标识读取存放的用户状态信息,达到保存会话状态的目的。PHP中启动一个会话需要执行下面语句:复制代码 代码如下:session_start();

前面分析了公用控制器按模块分发,方便对特定模块的控制,而具体的实现类则是放在library中。那放在library中是否合适呢?以及控制器中更多的业务逻辑该放在哪里?

->符号其实是传递对象指针的。或许这么说是不对的。

1.where:帮助我们设置查询条件

/* * SQL语句组合实例类,始发文章web开发笔记 * 学习用,非专业类 * */class sql{private $sql=array("from"=>"","where"=>"","order"=>"","limit"=>""); public function from {$this->sql["from"]="FROM ".$tableName;return $this;} public function where {$this->sql["where"]="WHERE ".$_where;return $this;} public function order {$this->sql["order"]="ORDER BY ".$_order;return $this;} public function limit {$this->sql["limit"]="LIMIT 0,".$_limit;return $this;}public function select {return "SELECT ".$_select." ".(implode;}} $sql =new sql(); echo $sql->from->where->order->select();//输出 SELECT * FROM testTable WHERE id=1 ORDER BY id DESC LIMIT 0,10

1、客户端每次请求时会有一些信息存放中HTTP头中发送给服务端,以用户第一次访问为例:复制代码 代码如下:Request
HeadersAccept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding:gzip,deflate,sdchAccept-Language:zh-CN,zh;q=0.8Cache-Control:max-age=0Connection:keep-aliveHost:s.localUser-Agent:Mozilla/5.0
AppleWebKit/537.36 Chrome/31.0.1650.63 Safari/537.36

先说下对CI中几个文件夹的理解

但是,我们可以这么的理解。

2.order:对结果进行排序复制代码
代码如下:$arr=$m->order;//字符串方法,默认是asc升序排列,加desc改为降序排列
$arr=$m->order(array(‘id’=>’desc’,’sex’=>’asc’))->select();
//数组方法3.limit:限制结果复制代码
代码如下:limit//从第2条取出5条 limit//字条串形式参数
limit默认是从0开始4.field:设置查询字段复制代码 代码如下:field(‘username as name,id’)
//传字符,修改字段名
field(array(‘username’=>’name’,’id’)//传数组查询,修改字段名 field
//获取除了id以外的所有字段5.table:表格

2、服务端接到请求处理后并返回给客户端,并在HTTP
Response中加上添加COOKIE的请求,告诉浏览器需要设置一个COOKIE,COOKIE名为PHPSESSID,值为r887k5n4scg32d4ba34huuhmq7,如:复制代码 代码如下:Response
HeadersCache-Control:no-store, no-cache, must-revalidate, post-check=0,
pre-check=0Connection:Keep-AliveContent-Length:0Content-Type:text/htmlDate:Sun,
08 Dec 2013 12:56:56 GMTExpires:Thu, 19 Nov 1981 08:52:00
GMTKeep-Alive:timeout=5, max=100Pragma:no-cacheServer:Apache/2.2.11
PHP/5.4.7Set-Cookie:PHPSESSID=r887k5n4scg32d4ba34huuhmq7;
path=/X-Powered-By:PHP/5.4.7

helpers、libraries:
存放一系列辅助函数、辅助类,用来辅助控制器、业务逻辑实现功能。他们中的方法应当尽量避免与CI依赖,依赖越紧越难以复用。以邮件发送为例,发送邮件时很多参数是不变的,如编码、协议、端口等,我们可能会在config下进行配置这些参数,然后library封装一个邮件发送的类,并在其中获取CI实例后读取这些参数。此时就出现了与CI实例的依赖,该类就只能在CI框架中使用,其他系统要用到,就只能重写了,没达到复用的目的。如果发送的类只是接收参数,并封装发送方法呢?所以说,尽可能的让helpers、libraries变的简单,职责变得单一。

普通用法:

7.having:与分组有关

3、当客户端再次访问该网站的页面时,浏览器会将该COOKIE发送给服务端,服务端根据COOKIE的值去读取服务器上存放SESSION的文件,拿到到会话信息,如:复制代码 代码如下:Request
HeadersAccept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding:gzip,deflate,sdchAccept-Language:zh-CN,zh;q=0.8Cache-Control:max-age=0Connection:keep-aliveCookie:PHPSESSID=r887k5n4scg32d4ba34huuhmq7Host:s.localUser-Agent:Mozilla/5.0
AppleWebKit/537.36 Chrome/31.0.1650.63

controllers:
控制器目录。控制器主要用来接管程序,起到连接的作用。通常情况下,我们会把业务逻辑写在action中。但随着业务变得复杂,action代码将越来越臃肿,难以维护。

a="hello"; return $this; } public function actionb() { $this->b="world"; return $this; } public function actionc() { echo $this->a." ".$this->b; }}$oktest=new test;$oktest->actionb;?>

alias 用于给当前数据表定义别名 字符串

从而达到保存会话状态的目的。但也需要注意,如果获取到用户A登录的SESSION
ID会怎么样?根据上面的逻辑,如果在请求过程中把获取到的SESSION
ID一并发送给服务端,服务端根据SESSION
ID读取文件,发现文件内容存在,从而判定用户为A用户,也就是获取到了A用户的用户状态,从而可能可以进行一些敏感操作。所以在会话有效期内,获取到了SESSION
ID即获取到了用户的授权,这是比较危险的,以本地的一个管理系统为例,通过chrome登录后查看到客户端COOKIE如下图:

models:
模型目录。CI的模型的主要职责就是和数据库打交道,获取数据。很多时候也会把业务逻辑放在模型中,但业务逻辑与模型实际上是两种东西了。模型只是获取数据,业务逻辑可能是把这些数据根据业务需要进行组合,组合方式可能有很多种,放在模型中会让模型难以维护且不利于复用。说个碰到的例子,对数据按一定条件做缓存,获取数据和缓存结果两个流程写在同一个方法中,但同样的数据需要做另一种形式的缓存时发现,获取数据的方法就没法重用了。

连贯用法:

page 用于查询分页 字符串和数字

假如如果通过某种手段获取到了SESSION ID,
可以模拟发送一个相同的COOKIE过去即可实现登录。FireFox中可添加COOKIE,打开Firebug后Cookies中新建cookie,确定之后刷新页面即可登录到管理系统,如下图:

third_party:第三方类库目录。拿到一个类库后不要直接使用,
可以在library中进行一次封装,让其更适应于系统,其他人使用起来难度也会降低。

a="hello"; return $this; } public function actionb() { $this->b="world"; return $this; } public function actionc() { echo $this->a." ".$this->b; }}$oktest=new test->actionb;?>

join* 用于对查询的join支持 字符串和数组

通常情况下可通过js获取到cookie,所以需要注意转义,防止数据展示时被执行了。接下来看看CI中的SESSION。在配置文件中有几个跟Session配置相关的参数,影响到Session的使用,它们是:

可以发现,每个文件夹都有自己的职责,每个模块都有自己的家,都有自己的职能。那业务逻辑该怎么办?

连起来了。可以把操作串起来。

union* 用于对查询的union支持 字符串、数组和对象

//session保存在cookie中的名称$config['sess_cookie_name'] = 'ci_session';//session的有效时间$config['sess_expiration'] = 7200;//是否关闭浏览器session失效$config['sess_expire_on_close'] = FALSE;//SESSION是否加密存放在COOKIE中$config['sess_encrypt_cookie'] = FALSE;//是否保存在数据库中$config['sess_use_database'] = FALSE;//存在数据库中,则数据库表名$config['sess_table_name'] = 'ci_sessions';//是否匹配IP$config['sess_match_ip'] = FALSE;//是否匹配UserAgent$config['sess_match_useragent'] = TRUE;//更新时间时间$config['sess_time_to_update'] = 300;

既然这样,
我们也应该给业务逻辑安个家,建立一个唯一的目录用来存放业务逻辑,暂且命名为service。控制器主要负责接收参数并调用service,service来调用模型,各层各尽其责。

看起来直观多了。阅读代码时也轻松了很多。

distinct 用于查询的distinct支持 布尔值

CI自带的SESSION没有服务端文件存储,所有的信息都存放在客户端COOKIE中,当调用$this->load->library;时会启动一个会话,即设置一个COOKIE,COOKIE的内容如下:

我们可以重写MY_Load,增加service方法,直接通过复制代码
代码如下:$this->load->service;来调用。但业务逻辑很多都需要获取CI实例,这里可以参考模型的方法,core建立一个MY_Service,其他service均继承该类,这样子service里用法就跟控制器里一样了。

类里面操作都返回了一个指针。

lock 用于数据库的锁机制 布尔值

Array([session_id] => f05138a9513e4928cb0a57672cfe3b53[ip_address] => 127.0.0.1[user_agent] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36  Chrome/31.0.1650.63 Safari/537.36[last_activity] => 1386569398[user_data] =>)
class MY_Service{ public function __construct() { log_message('debug', "Service Class Initialized"); } function __get { $CI = & get_instance(); return $CI->$key; }}

他等价于你初始化的那个对象 $oktest

cache 用于查询缓存 支持多个参数

当客户端请求时会将这些信息在HTTP头中传输给服务端,服务端从HTTP头中读取到SESSION信息。同样的可以实现会话,但该方式有很多的不确定因素,根据源码说几点吧:

其实主要思路还是需要有一层用来处理业务逻辑,java中都有这一层。随着对CI的不断熟悉,发觉这里需要这一层,达到解放控制器和模型的目的。和这种类似的做法还有很多,如果系统中有很多地方需要用到web
service
或者说cache之类的,其实也可以按照上面的思路单独放在一个文件夹中处理,方便管理。

所以下面的操作可以连续起来。

relation 用于关联查询字符串

1、如果日志文件中出现:The session cookie data did not match what was
expected. This could be a possible hacking
attempt.说明两个问题:a.sess_encrypt_cookie为false,SESSION在COOKIE中未加密存放
b.读取到COOKIE后,校验失败。涉及到加解密、参数处理的情况,容易出现匹配不通过的情况,若不通过则清空SESSION。

更多关于CodeIgniter相关内容感兴趣的读者可查看本站专题:《codeigniter入门教程》和《CI框架进阶教程》

return $this

from=$_from; return $this; } public function where { $this->where=$_where; return $this; } public function order($_order='ORDER BY id DESC') { $this->order=$_order; return $this; } public function limit { $this->limit=$_limit; return $this; } public function select { $this->select=$_select; return $this->select." ".$this->from." ".$this->where." ".$this->order." ".$this->limit; }}$sql =new sql->where->select();?>

validate 用于数据自动验证 数组

2、如果sess_match_ip为true,当客户端IP变化时,SESSION将校验不通过,从而清空SESSION。

希望本文所述对大家基于CodeIgniter框架的PHP程序设计有所帮助。

更多关于CodeIgniter相关内容感兴趣的读者可查看本站专题:《codeigniter入门教程》、《CI框架进阶教程》、《php优秀开发框架总结》、《ThinkPHP入门教程》、《ThinkPHP常用方法总结》、《Zend
FrameWork框架入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

auto 用于数据自动完成 数组

3、sess_match_useragent默认为true,当客户端UserAgent变化时,校验不通过,清空SESION。简单的例子,通过IE浏览器访问,若切换到不同的IE模式,Agent不同,所以校验不通过,清空SESSION。

希望本文所述对大家基于CodeIgniter框架的PHP程序设计有所帮助。

filter 用于数据过滤 字符串

可以看到,当出现上面任何一种情况时,SESSION都会清空,出现登录不成功或者跳转到登录页面的情况。如果说不加密、不校验IP、UserAgent呢?因为COOKIE是存放在客户端,需要伴随HTTP请求发给服务端,一来过多的COOKIE会影响速度,对一些图片等资源来说完全时浪费带宽;二来COOKIE只能存储4K的数据,加密处理后能存放的更小。

scope* 用于命名范围 字符串、数组

种种的不确定因素将产生各种奇怪的问题,避免过多的纠结,果断改用其他方式吧。

希望本文所述对大家的ThinkPHP框架程序设计有所帮助。

更多关于CodeIgniter框架相关内容感兴趣的读者可查看本站专题:《codeigniter入门教程》

希望本文所述对大家基于CodeIgniter框架的PHP程序设计有所帮助。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图