首页 > 后端开发 > php教程 > thinkphp3.2.0中setInc方法的源码分析

thinkphp3.2.0中setInc方法的源码分析

不言
发布: 2023-03-30 17:28:02
原创
1530 人浏览过

下面为大家分享一篇thinkphp3.2.0 setInc方法 源码全面解析,具有很好的参考价值,希望对大家有所帮助。

我们先来看一下setInc的官方示例:

需要一个字段和一个自增的值(默认为1)

我们通过下面这个例子来一步步分析他的底层是怎么实现的:

1

2

3

4

5

6

7

8

9

10

11

12

<?php

namespace Home\Controller;

use Think\Controller;

 

class TestController extends Controller {

  public function test() {

    $tb_test = M(&#39;test&#39;);

    $tb_test->where([&#39;id&#39;=>1])->setInc(&#39;test_number&#39;,2); //每次添加2

    dump($tb_test->getLastSql());

    //string(67) "UPDATE `tb_test` SET `test_number`=test_number+2 WHERE ( `id` = 1 )"

  }

}

登录后复制

第一步肯定是要找到setInc方法的源码:

这里我用到了phpstrom全局搜索的方法,找到了setInc是在proj\ThinkPHP\Library\Think\Model.class.php下

1

2

3

4

5

6

7

8

9

10

/**

   * 字段值增长

   * @access public

   * @param string $field 字段名

   * @param integer $step 增长值

   * @return boolean

   */

  public function setInc($field,$step=1) {

    return $this->setField($field,array(&#39;exp&#39;,$field.&#39;+&#39;.$step));

  }

登录后复制

可以看到这里用到了setField这个方法,然后用exp自定义表达式设置 $field = $field + $step 到这里,我们稍微了解了一点原理。

可是问题又来了setField又是怎么实现的呢?在同个文件下,找到setField方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

   * 设置记录的某个字段值

   * 支持使用数据库字段和方法

   * @access public

   * @param string|array $field 字段名

   * @param string $value 字段值

   * @return boolean

   */

  public function setField($field,$value=&#39;&#39;) {

    if(is_array($field)) {

      $data      $field;

    }else{

      $data[$field]  =  $value;

    }

    return $this->save($data);

  }

登录后复制

这里我们看到了常用到的save方法,这里的 $data[$field] = $value; 其实就是 $data['test_number'] = array("exp","test_number+2")

接着来看最常用的save方法:

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

45

46

47

48

49

/**

   * 保存数据

   * @access public

   * @param mixed $data 数据

   * @param array $options 表达式

   * @return boolean

   */

  public function save($data=&#39;&#39;,$options=array()) {

    if(empty($data)) {

      // 没有传递数据,获取当前数据对象的值

      if(!empty($this->data)) {

        $data      $this->data;

        // 重置数据

        $this->data   =  array();

      }else{

        $this->error  =  L(&#39;_DATA_TYPE_INVALID_&#39;);

        return false;

      }

    }

    // 数据处理

    $data    $this->_facade($data);

    // 分析表达式

    $options  $this->_parseOptions($options);

    $pk     $this->getPk();

    if(!isset($options[&#39;where&#39;]) ) {

      // 如果存在主键数据 则自动作为更新条件

      if(isset($data[$pk])) {

        $where[$pk]     =  $data[$pk];

        $options[&#39;where&#39;]  =  $where;

        unset($data[$pk]);

      }else{

        // 如果没有任何更新条件则不执行

        $this->error    =  L(&#39;_OPERATION_WRONG_&#39;);

        return false;

      }

    }

    if(is_array($options[&#39;where&#39;]) && isset($options[&#39;where&#39;][$pk])){

      $pkValue  $options[&#39;where&#39;][$pk];

    }   

    if(false === $this->_before_update($data,$options)) {

      return false;

    }   

    $result   $this->db->update($data,$options);

    if(false !== $result) {

      if(isset($pkValue)) $data[$pk]  = $pkValue;

      $this->_after_update($data,$options);

    }

    return $result;

  }

登录后复制

最主要是的$options = $this->_parseOptions($options);和$result = $this->db->update($data,$options); 前者把参数转换成用于拼接sql的字符串数组,后者调用了proj\tptest\ThinkPHP\Library\Think\Db.class.php下的update方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

/**

   * 更新记录

   * @access public

   * @param mixed $data 数据

   * @param array $options 表达式

   * @return false | integer

   */

  public function update($data,$options) {

    $this->model =  $options[&#39;model&#39;];

    $sql  = &#39;UPDATE &#39;

      .$this->parseTable($options[&#39;table&#39;])

      .$this->parseSet($data)

      .$this->parseWhere(!empty($options[&#39;where&#39;])?$options[&#39;where&#39;]:&#39;&#39;)

      .$this->parseOrder(!empty($options[&#39;order&#39;])?$options[&#39;order&#39;]:&#39;&#39;)

      .$this->parseLimit(!empty($options[&#39;limit&#39;])?$options[&#39;limit&#39;]:&#39;&#39;)

      .$this->parseLock(isset($options[&#39;lock&#39;])?$options[&#39;lock&#39;]:false)

      .$this->parseComment(!empty($options[&#39;comment&#39;])?$options[&#39;comment&#39;]:&#39;&#39;);

    return $this->execute($sql,$this->parseBind(!empty($options[&#39;bind&#39;])?$options[&#39;bind&#39;]:array()));

  }

登录后复制

最后其实就是用到了proj\ThinkPHP\Library\Think\Db\Driver\Mysql.class.php这个驱动类的execute方法。

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

/**

   * 执行语句

   * @access public

   * @param string $str sql指令

   * @return integer|false

   */

  public function execute($str) {

    $this->initConnect(true);

    if ( !$this->_linkID ) return false;

    $this->queryStr = $str;

    //释放前次的查询结果

    if ( $this->queryID ) {  $this->free();  }

    N(&#39;db_write&#39;,1);

    // 记录开始执行时间

    G(&#39;queryStartTime&#39;);

    $result =  mysql_query($str, $this->_linkID) ;

    $this->debug();

    if ( false === $result) {

      $this->error();

      return false;

    } else {

      $this->numRows = mysql_affected_rows($this->_linkID);

      $this->lastInsID = mysql_insert_id($this->_linkID);

      return $this->numRows;

    }

  }

登录后复制

最后用最底层的mysql_query执行SQL语句。

到此为止,setInc的源码已经大致过了一遍了。想必大家对setInc如何执行也更了解了一点。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

thinkPHP3.2实现微信接入及查询token值的方法

以上是thinkphp3.2.0中setInc方法的源码分析的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
最新问题
为什么thinkphp比laravel性能好?
来自于 1970-01-01 08:00:00
0
0
0
php6支持的thinkphp版本
来自于 1970-01-01 08:00:00
0
0
0
mscms.qishouzhijia.com,自学thinkphp做的一个网站
来自于 1970-01-01 08:00:00
0
0
0
ThinkPHP什么要使用composer?
来自于 1970-01-01 08:00:00
0
0
0
thinkphp上传文件
来自于 1970-01-01 08:00:00
0
0
0
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板