针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例


Posted in PHP onJune 16, 2018

本文实例讲述了针对thinkPHP5框架存储过程bug重写的存储过程扩展类。分享给大家供大家参考,具体如下:

近期用tp5框架调取存储过程发现有bug,借鉴了一些官方的函数、以及找了个mysqli的类把存储过程重新写了个扩展类,下面两个类直接放置项目extend目录的stored(这个文件夹名称请按个人习惯命名)目录下,需要注意的是类增加命名空间namespace stored就OK。

1、mysqli类,此类直接在网上找的,新增一个getAllData()的函数来获取存储过程多条数据集

<?php
namespace stored;
/*
掌握满足单例模式的必要条件
(1)私有的构造方法-为了防止在类外使用new关键字实例化对象
(2)私有的成员属性-为了防止在类外引入这个存放对象的属性
(3)私有的克隆方法-为了防止在类外通过clone成生另一个对象
(4)公有的静态方法-为了让用户进行实例化对象的操作
*/
class mysqli{
  //私有的属性
  private static $dbcon=false;
  private $host;
  private $port;
  private $user;
  private $pass;
  private $db;
  private $charset;
  private $link;
  //私有的构造方法
  protected function __construct($config=array()){
    header('content-type:text/html;charset=utf-8');
    $this->host = $config['hostname'] ? $config['hostname'] : 'localhost';
    $this->port = $config['hostport'] ? $config['hostport'] : '3306';
    $this->user = $config['username'] ? $config['username'] : 'root';
    $this->pass = $config['password'] ? $config['password'] : 'root';
    $this->db = $config['database'] ? $config['database'] : 'zhijian';
    $this->charset=isset($config['charset']) ? $config['charset'] : 'utf8';
    //连接数据库
    $this->db_connect();
    //选择数据库
    $this->db_usedb();
    //设置字符集
    $this->db_charset();
  }
  //连接数据库
  private function db_connect(){
    $this->link=mysqli_connect($this->host,$this->user,$this->pass);
    if(!$this->link){
      echo "数据库连接失败<br>";
      echo "错误编码".mysqli_errno($this->link)."<br>";
      echo "错误信息".mysqli_error($this->link)."<br>";
      exit;
    }
  }
  //设置字符集
  private function db_charset(){
    mysqli_query($this->link,"set names {$this->charset}");
  }
  //选择数据库
  private function db_usedb(){
    mysqli_query($this->link,"use {$this->db}");
  }
  //私有的克隆
  private function __clone(){
    die('clone is not allowed');
  }
  //公用的静态方法
  public static function getIntance(){
    if(self::$dbcon==false){
      self::$dbcon=new self;
    }
    return self::$dbcon;
  }
  //执行sql语句的方法
  public function query($sql){
    $res=mysqli_query($this->link,$sql);
    if(!$res){
      echo "sql语句执行失败<br>";
      echo "错误编码是".mysqli_errno($this->link)."<br>";
      echo "错误信息是".mysqli_error($this->link)."<br>";
    }
    return $res;
  }
  //打印数据
  public function p($arr){
    echo "<pre>";
    print_r($arr);
    echo "</pre>";
  }
  public function v($arr){
    echo "<pre>";
    var_dump($arr);
    echo "</pre>";
  }
  //获得最后一条记录id
  public function getInsertid(){
    return mysqli_insert_id($this->link);
  }
  /**
   * 查询某个字段
   * @param
   * @return string or int
   */
  public function getOne($sql){
    $query=$this->query($sql);
    return mysqli_free_result($query);
  }
  //获取一行记录,return array 一维数组
  public function getRow($sql,$type="assoc"){
    $query=$this->query($sql);
    if(!in_array($type,array("assoc",'array',"row"))){
      die("mysqli_query error");
    }
    $funcname="mysqli_fetch_".$type;
    return $funcname($query);
  }
  //获取一条记录,前置条件通过资源获取一条记录
  public function getFormSource($query,$type="assoc"){
    if(!in_array($type,array("assoc","array","row")))
    {
      die("mysqli_query error");
    }
    $funcname="mysqli_fetch_".$type;
    return $funcname($query);
  }
  //获取多条数据,二维数组
  public function getAll($sql){
    $query=$this->query($sql);
    $list=array();
    while ($r=$this->getFormSource($query,"row")) {
      $list[]=$r;
    }
    return $list;
  }
  /**
   * 定义添加数据的方法
   * @param string $table 表名
   * @param string orarray $data [数据]
   * @return int 最新添加的id
   */
  public function insert($table,$data){
    //遍历数组,得到每一个字段和字段的值
    $key_str='';
    $v_str='';
    foreach($data as $key=>$v){
      if(empty($v)){
        die("error");
      }
      //$key的值是每一个字段s一个字段所对应的值
      $key_str.=$key.',';
      $v_str.="'$v',";
    }
    $key_str=trim($key_str,',');
    $v_str=trim($v_str,',');
    //判断数据是否为空
    $sql="insert into $table ($key_str) values ($v_str)";
    $this->query($sql);
    //返回上一次增加操做产生ID值
    return $this->getInsertid();
  }
  /*
   * 删除一条数据方法
   * @param1 $table, $where=array('id'=>'1') 表名 条件
   * @return 受影响的行数
   */
  public function deleteOne($table, $where){
    if(is_array($where)){
      foreach ($where as $key => $val) {
        $condition = $key.'='.$val;
      }
    } else {
      $condition = $where;
    }
    $sql = "delete from $table where $condition";
    $this->query($sql);
    //返回受影响的行数
    return mysqli_affected_rows($this->link);
  }
  /*
  * 删除多条数据方法
  * @param1 $table, $where 表名 条件
  * @return 受影响的行数
  */
  public function deleteAll($table, $where){
    if(is_array($where)){
      foreach ($where as $key => $val) {
        if(is_array($val)){
          $condition = $key.' in ('.implode(',', $val) .')';
        } else {
          $condition = $key. '=' .$val;
        }
      }
    } else {
      $condition = $where;
    }
    $sql = "delete from $table where $condition";
    $this->query($sql);
    //返回受影响的行数
    return mysqli_affected_rows($this->link);
  }
  /**
   * [修改操作description]
   * @param [type] $table [表名]
   * @param [type] $data [数据]
   * @param [type] $where [条件]
   * @return [type]
   */
  public function update($table,$data,$where){
    //遍历数组,得到每一个字段和字段的值
    $str='';
    foreach($data as $key=>$v){
      $str.="$key='$v',";
    }
    $str=rtrim($str,',');
    //修改SQL语句
    $sql="update $table set $str where $where";
    $this->query($sql);
    //返回受影响的行数
    return mysqli_affected_rows($this->link);
  }
  /**
   * @func: 获取存储过程多条数据集
   * @author: bieanju
   * @return: array
   * @createtime: 2017-12-25
   */
  public function getAllData($sql){
    if (mysqli_multi_query($this->link,$sql)) {
      do {
        if ($result = mysqli_store_result($this->link)) {
          while ($row = mysqli_fetch_assoc($result)) {
            $list[] = $row;
          }
          /*必须释放*/
          mysqli_free_result($result);
        }else{
          return false;
        }
        /*mysqli_next_result($this->link) && mysqli_more_results($this->link)*/
      } while (mysqli_next_result($this->link) && mysqli_more_results($this->link));
    } else {
      return false;
    }
    return $list;
  }
}
?>

2、存储过程调用扩展类库:

<?php
/**
 * 针对存储过程处理类
 * @author: bieanju
 * @createtime: 2017-12-21
 */
namespace stored;
use think\Config;
class procs extends mysqli{
  public $mysqli;
  /*
   * 存储过程数据参数
   * */
  protected $data = [];
  /*
   * 执行语句
   * */
  protected $sql = '';
  public function __construct($type = "mysqli"){
    $config = C("存储过程库配置参数");
    if($type == "mysql"){
      $config = Config::get('database');
    }
    $this->mysqli = new mysqli($config);
  }
  /**
   * 根据参数绑定组装最终的SQL语句 便于调试
   * @access public
   * @param string  $sql 带参数绑定的sql语句
   * @param array   $bind 参数绑定列表
   * @return string
   */
  private function getRealSql($sql, array $bind = [])
  {
    foreach ($bind as $key => $val) {
      $value = is_array($val) ? $val[0] : $val;
      $value = is_string($val) ? "'{$val}'" : $val;
      // 判断占位符
      $sql = is_numeric($key) ?
        substr_replace($sql, $value, strpos($sql, '?'), 1) :
        str_replace(
          [':' . $key . ')', ':' . $key . ',', ':' . $key . ' '],
          [$value . ')', $value . ',', $value . ' '],
          $sql . ' ');
    }
    return rtrim($sql);
  }
  /**
   * @func:存储过程执行并得到数据集
   * @author: bieanju
   * @return: boolean
   * @createtime: 2017-12-22
   */
  protected function procs(){
    $procedure = in_array(strtolower(substr(trim($this->sql), 0, 4)), ['call', 'exec']);
    // 参数绑定
    if ($procedure) {
      $sql = $this->getRealSql($this->sql,$this->data);
      return $this->mysqli->getAllData($sql);
    }
    return false;
  }
  /**
   * @func: 存储过程数据
   * @author: bieanju
   * @return: array
   * @createtime: 2017-12-22
   */
  public function data($data = [])
  {
    $this->data = $data;
    return $this;
  }
  /**
   * @func: 存储过程sql
   * @author: bieanju
   * @return: array
   * @createtime: 2017-12-22
   */
  public function sql($sql = '')
  {
    $this->sql = $sql;
    return $this;
  }
  /**
   * 使用DEMO
  */
  public function demo(){
    return $this->sql("call demo(?,?,?,?,?,?)")->procs();
  }
}
?>

3、最终项目中使用demo:

use stored\procs;
/*用use加载后第一步实例化下存储过程类*/
 $this->procs = new procs("mysqli");
/*第二步调用demo方法并获取数据*/
//$data为给存储过程占位符传递的参数必须为array|[ ]
$this->procs->data($data)->demo();

ok是不是调用很简单、多条存储过程的数据集就此拿到!

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

PHP 相关文章推荐
用PHP读取RSS feed的代码
Aug 01 PHP
比较详细PHP生成静态页面教程
Jan 10 PHP
PHP得到mssql的存储过程的输出参数功能实现
Nov 23 PHP
使用Linux五年积累的一些经验技巧
Jun 20 PHP
如何在smarty中增加类似foreach的功能自动加载数据
Jun 26 PHP
php读取mysql的简单实例
Jan 15 PHP
PHP中实现获取IP和地理位置类分享
Feb 10 PHP
PHP函数引用返回的实例详解
Sep 11 PHP
php封装的page分页类完整实例
Oct 18 PHP
php微信公众号开发(4)php实现自定义关键字回复
Dec 15 PHP
laravel5使用freetds连接sql server的方法
Dec 07 PHP
php-fpm重启导致的程序执行中断问题详解
Apr 29 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
Jun 16 #PHP
PHP实现redis限制单ip、单用户的访问次数功能示例
Jun 16 #PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
Jun 16 #PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 #PHP
PHP观察者模式示例【Laravel框架中有用到】
Jun 15 #PHP
PHP堆栈调试操作简单示例
Jun 15 #PHP
在Laravel5.6中使用Swoole的协程数据库查询
Jun 15 #PHP
You might like
php array_filter除去数组中的空字符元素
2020/06/21 PHP
php使用websocket示例详解
2014/03/12 PHP
JS弹出窗口代码大全(详细整理)
2012/12/21 Javascript
IE8对JS通过属性和数组遍历解析不一样的地方探讨
2013/05/06 Javascript
Jquery 动态循环输出表格具体方法
2013/11/23 Javascript
node.js中的fs.fsyncSync方法使用说明
2014/12/15 Javascript
bootstrap3 dialog 更强大、更灵活的模态框
2017/04/20 Javascript
AngularJS使用ng-class动态增减class样式的方法示例
2017/05/18 Javascript
基于React+Redux的SSR实现方法
2018/07/03 Javascript
vue组件开发之用户无限添加自定义填写表单的方法
2018/08/28 Javascript
微信小程序之裁剪图片成圆形的实现代码
2018/10/11 Javascript
js中的闭包实例展示
2018/11/01 Javascript
ES6 Object属性新的写法实例小结
2019/06/25 Javascript
用原生JS实现爱奇艺首页导航栏代码实例
2019/09/19 Javascript
JavaScript使用canvas绘制随机验证码
2020/02/17 Javascript
原生js拖拽功能制作滑动条实例代码
2021/02/05 Javascript
基于python编写的微博应用
2014/10/17 Python
简单的编程0基础下Python入门指引
2015/04/01 Python
分析用Python脚本关闭文件操作的机制
2015/06/28 Python
Python 异常处理的实例详解
2017/09/11 Python
Python实现常见的回文字符串算法
2018/11/14 Python
python Django 创建应用过程图示详解
2019/07/29 Python
numpy中的meshgrid函数的使用
2019/07/31 Python
Keras使用tensorboard显示训练过程的实例
2020/02/15 Python
python GUI库图形界面开发之PyQt5控件QTableWidget详细使用方法与属性
2020/02/25 Python
html5 viewport使用方法示例详解
2013/12/02 HTML / CSS
英国安全产品购物网站:The Safe Shop
2017/03/20 全球购物
联想新加坡官方网站:Lenovo Singapore
2017/10/24 全球购物
自主招生自荐信格式
2013/12/03 职场文书
个人培训自我鉴定
2014/03/28 职场文书
扬尘污染防治方案
2014/06/15 职场文书
民警群众路线教育实践活动对照检查材料
2014/10/04 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
街道党风廉政建设调研报告
2015/01/01 职场文书
Mysql 如何批量插入数据
2021/04/06 MySQL
SQL SERVER中的流程控制语句
2022/05/25 SQL Server