Das Folgende ist eine umfassende Analyse des Quellcodes der setInc-Methode von thinkphp3.2.0, die hoffentlich für alle hilfreich ist.
Werfen wir zunächst einen Blick auf das offizielle Beispiel von setInc:
erfordert a Feld und Ein sich selbst erhöhender Wert (Standard ist 1)
Anhand des folgenden Beispiels analysieren wir Schritt für Schritt, wie die zugrunde liegende Implementierung implementiert wird:
<?php namespace Home\Controller; use Think\Controller; class TestController extends Controller { public function test() { $tb_test = M('test'); $tb_test->where(['id'=>1])->setInc('test_number',2); //每次添加2 dump($tb_test->getLastSql()); //string(67) "UPDATE `tb_test` SET `test_number`=test_number+2 WHERE ( `id` = 1 )" } }
Kapitel Der erste Schritt besteht darin, den Quellcode der setInc-Methode zu finden:
Hier habe ich die globale Suchmethode von phpstrom verwendet und festgestellt, dass sich setInc unter projThinkPHPLibraryThinkModel.class.php
befindet/** * 字段值增长 * @access public * @param string $field 字段名 * @param integer $step 增长值 * @return boolean */ public function setInc($field,$step=1) { return $this->setField($field,array('exp',$field.'+'.$step)); }
Sie können sehen, dass hier die setField-Methode verwendet wird und dann der benutzerdefinierte Ausdruck exp verwendet wird, um $field = $field + $step festzulegen. An diesem Punkt verstehen wir ein wenig über das Prinzip.
Aber die Frage kommt wieder. Wie wird setField implementiert? Unter derselben Datei finden Sie die setField-Methode:
/** * 设置记录的某个字段值 * 支持使用数据库字段和方法 * @access public * @param string|array $field 字段名 * @param string $value 字段值 * @return boolean */ public function setField($field,$value='') { if(is_array($field)) { $data = $field; }else{ $data[$field] = $value; } return $this->save($data); }
Hier sehen wir die häufig verwendete Speichermethode, wobei $data[$field] = $value; eigentlich $data[ 'test_number '] = array("exp",test_number+2")
Dann schauen wir uns die am häufigsten verwendeten Speichermethoden an:
/** * 保存数据 * @access public * @param mixed $data 数据 * @param array $options 表达式 * @return boolean */ public function save($data='',$options=array()) { if(empty($data)) { // 没有传递数据,获取当前数据对象的值 if(!empty($this->data)) { $data = $this->data; // 重置数据 $this->data = array(); }else{ $this->error = L('_DATA_TYPE_INVALID_'); return false; } } // 数据处理 $data = $this->_facade($data); // 分析表达式 $options = $this->_parseOptions($options); $pk = $this->getPk(); if(!isset($options['where']) ) { // 如果存在主键数据 则自动作为更新条件 if(isset($data[$pk])) { $where[$pk] = $data[$pk]; $options['where'] = $where; unset($data[$pk]); }else{ // 如果没有任何更新条件则不执行 $this->error = L('_OPERATION_WRONG_'); return false; } } if(is_array($options['where']) && isset($options['where'][$pk])){ $pkValue = $options['where'][$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; }
Die wichtigsten sind $options = $this->_parseOptions($options); und $result = $this->db->update($data,$options); Ersteres konvertiert die Parameter in SQL für Spleiß-String-Array, das die Aktualisierungsmethode
/** * 更新记录 * @access public * @param mixed $data 数据 * @param array $options 表达式 * @return false | integer */ public function update($data,$options) { $this->model = $options['model']; $sql = 'UPDATE ' .$this->parseTable($options['table']) .$this->parseSet($data) .$this->parseWhere(!empty($options['where'])?$options['where']:'') .$this->parseOrder(!empty($options['order'])?$options['order']:'') .$this->parseLimit(!empty($options['limit'])?$options['limit']:'') .$this->parseLock(isset($options['lock'])?$options['lock']:false) .$this->parseComment(!empty($options['comment'])?$options['comment']:''); return $this->execute($sql,$this->parseBind(!empty($options['bind'])?$options['bind']:array())); }
unter projtptestThinkPHPLibraryThinkDb.class.php aufruft. Am Ende wird tatsächlich die Ausführungsmethode der Treiberklasse projThinkPHPLibraryThinkDbDriverMysql.class.php verwendet.
/** * 执行语句 * @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('db_write',1); // 记录开始执行时间 G('queryStartTime'); $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; } }
Schließlich wird die unterste Ebene mysql_query verwendet, um die SQL-Anweisung auszuführen.
Bisher wurde der Quellcode von setInc grob überprüft. Ich glaube, dass jeder ein besseres Verständnis dafür hat, wie setInc ausgeführt wird.
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.
Verwandte Empfehlungen:
ThinkPHP3.2-Methode zur Implementierung des WeChat-Zugriffs und Abfrage-Token-Werts
Das obige ist der detaillierte Inhalt vonQuellcode-Analyse der setInc-Methode in thinkphp3.2.0. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!