Maison > Article > développement back-end > Analyse complète du code source de la méthode thinkphp3.2.0 setInc
Ce qui suit est une analyse complète du code source de la méthode thinkphp3.2.0 setInc, qui a une bonne valeur de référence. J'espère qu'elle sera utile à tout le monde. Jetons un coup d'œil ensemble
Jetons d'abord un coup d'œil à l'exemple officiel de setInc :
Nécessite un champ et une valeur d'incrémentation automatique (la valeur par défaut est 1)
Nous utilisons l'exemple suivant pour analyser étape par étape comment sa mise en œuvre sous-jacente est mise en œuvre :
<?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 )" } }
La première étape est de trouver le code source de la méthode setInc :
Ici j'ai utilisé phpstrom Méthode de recherche globale, setInc se trouve sous projThinkPHPLibraryThinkModel.class.php
/** * 字段值增长 * @access public * @param string $field 字段名 * @param integer $step 增长值 * @return boolean */ public function setInc($field,$step=1) { return $this->setField($field,array('exp',$field.'+'.$step)); }
Vous pouvez voir que la méthode setField est utilisée ici, puis utilisez exp pour personnaliser l'expression Paramètre de formule $field = $field + $step À ce stade, nous comprenons un peu le principe.
Mais la question revient. Comment setField est-il implémenté ? Sous le même fichier, recherchez la méthode setField :
/** * 设置记录的某个字段值 * 支持使用数据库字段和方法 * @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); }
Ici, nous voyons la méthode de sauvegarde couramment utilisée, voici $ data [$field] = $value; En fait, c'est $data['test_number'] = array("exp","test_number+2")
Ensuite, regardons le Méthode de sauvegarde la plus couramment utilisée :
/** * 保存数据 * @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; }
La chose la plus importante est $options = $this->_parseOptions($options ); et $result = $this->db->update($data,$options); Le premier convertit les paramètres en un tableau de chaînes pour épisser SQL, et le second appelle la méthode de mise à jour sous projtptestThinkPHPLibraryThinkDb.class.php. :
/** * 更新记录 * @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())); }
Au final, la méthode d'exécution de la classe pilote projThinkPHPLibraryThinkDbDriverMysql.class.php est réellement utilisée.
/** * 执行语句 * @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; } }
Enfin, utilisez le mysql_query de niveau le plus bas pour exécuter l'instruction SQL.
Jusqu'à présent, le code source de setInc a été grossièrement revu. Je pense que tout le monde comprend mieux comment setInc est exécuté.
Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !
Recommandations associées :
Introduction à la méthode d'importation de la bibliothèque de balises personnalisées thinkPHP2.1
ThinkPHP écrit l'insertion de tableaux et Méthode pour obtenir le dernier ID de données inséré
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!