2020-10-03 17:23:32 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace fastphp\db;
|
|
|
|
|
|
|
|
|
|
|
|
use \PDOStatement;
|
|
|
|
|
|
|
|
|
|
|
|
class Sql
|
|
|
|
|
|
{
|
|
|
|
|
|
//数据库表名
|
|
|
|
|
|
protected $table;
|
|
|
|
|
|
|
|
|
|
|
|
//where 和 order拼装后的条件
|
|
|
|
|
|
private $filter = '';
|
|
|
|
|
|
|
|
|
|
|
|
//pdo 绑定的参数集合
|
|
|
|
|
|
private $param = array();
|
|
|
|
|
|
|
|
|
|
|
|
private $field = '*';
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询条件拼接
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param $where 条件
|
|
|
|
|
|
* @return $this
|
2020-10-11 19:23:42 +08:00
|
|
|
|
* ['id'=>1] 或者 '`id`=1' 尽量不要使用string 因为没有做防sql注入
|
|
|
|
|
|
* 多条件查询
|
|
|
|
|
|
* ['id'=>['<',100]]
|
2020-10-03 17:23:32 +08:00
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function where($where)
|
|
|
|
|
|
{
|
2020-10-26 12:14:54 +08:00
|
|
|
|
$this->filter .= '';
|
2020-10-13 09:38:55 +08:00
|
|
|
|
if ($where) {
|
2020-11-17 10:18:30 +08:00
|
|
|
|
if (!strpos($this->filter, 'WHERE') !== false) {
|
2020-10-24 15:40:56 +08:00
|
|
|
|
$this->filter .= ' WHERE ';
|
2020-10-26 12:14:54 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
$this->filter .= ' AND ';
|
2020-10-24 15:40:56 +08:00
|
|
|
|
}
|
2020-10-13 09:38:55 +08:00
|
|
|
|
if (is_string($where)) {
|
2020-10-24 18:40:28 +08:00
|
|
|
|
$this->filter .= $where;
|
2020-10-03 17:23:32 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
$flag = true;
|
2020-11-17 10:18:30 +08:00
|
|
|
|
$ins = ['in', 'IN', 'not in', 'NOT IN'];
|
2020-10-13 09:38:55 +08:00
|
|
|
|
foreach ($where as $key => $value) {
|
|
|
|
|
|
if ($flag) {
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$flag = false;
|
2020-10-13 09:38:55 +08:00
|
|
|
|
if (is_array($value)) {
|
2020-11-17 10:18:30 +08:00
|
|
|
|
if (in_array($value[0], $ins)) {
|
|
|
|
|
|
$this->filter .= ' `' . $key . '` ' . $value[0] . '(' . implode(',', $value[1]) . ')';
|
2020-10-23 16:48:49 +08:00
|
|
|
|
} else {
|
2020-11-17 10:18:30 +08:00
|
|
|
|
$param_key = $this->paramIsExit($key, $this->param);
|
2020-10-26 12:14:54 +08:00
|
|
|
|
$this->filter .= ' `' . $key . '` ' . $value[0] . ' :' . $param_key;
|
|
|
|
|
|
$this->param[$param_key] = $value[1];
|
2020-10-23 16:48:49 +08:00
|
|
|
|
}
|
2020-10-03 17:23:32 +08:00
|
|
|
|
} else {
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$this->filter .= ' `' . $key . '` = :' . $key;
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$this->param[$key] = $value;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2020-10-13 09:38:55 +08:00
|
|
|
|
if (is_array($value)) {
|
2020-11-17 10:18:30 +08:00
|
|
|
|
if (in_array($value[0], $ins)) {
|
|
|
|
|
|
$this->filter .= ' AND `' . $key . '` ' . $value[0] . '(' . implode(',', $value[1]) . ')';
|
2020-10-23 16:48:49 +08:00
|
|
|
|
} else {
|
2020-11-17 10:18:30 +08:00
|
|
|
|
$param_key = $this->paramIsExit($key, $this->param);
|
2020-10-26 12:14:54 +08:00
|
|
|
|
$this->filter .= ' AND `' . $key . '` ' . $value[0] . ' :' . $param_key;
|
|
|
|
|
|
$this->param[$param_key] = $value[1];
|
2020-10-23 16:48:49 +08:00
|
|
|
|
}
|
2020-10-03 17:23:32 +08:00
|
|
|
|
} else {
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$this->filter .= ' AND `' . $key . '` = :' . $key;
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$this->param[$key] = $value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return $this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-17 10:18:30 +08:00
|
|
|
|
public function paramIsExit($key, $param)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!isset($param[$key])) {
|
2020-10-26 12:14:54 +08:00
|
|
|
|
return $key;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$key .= $key;
|
2020-11-17 10:18:30 +08:00
|
|
|
|
return $this->paramIsExit($key, $param);
|
2020-10-24 15:40:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-20 16:01:10 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* left join
|
|
|
|
|
|
* @param array $order 排序条件
|
|
|
|
|
|
* @return $this
|
|
|
|
|
|
* $order='id desc'
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function join($condition = '')
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($condition) {
|
|
|
|
|
|
$this->filter = ' LEFT JOIN ' . $condition . ' ';
|
|
|
|
|
|
}
|
|
|
|
|
|
return $this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-10-03 17:23:32 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 拼装排序条件
|
|
|
|
|
|
* @param array $order 排序条件
|
|
|
|
|
|
* @return $this
|
2020-10-11 19:23:42 +08:00
|
|
|
|
* $order='id desc'
|
2020-10-03 17:23:32 +08:00
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function order($order = 'id desc')
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($order) {
|
|
|
|
|
|
$this->filter .= ' ORDER BY ' . $order . ' ';
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
return $this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* group by
|
|
|
|
|
|
* @param array $order
|
|
|
|
|
|
* @return $this
|
2020-10-11 19:23:42 +08:00
|
|
|
|
* $group=['sex','name']
|
2020-10-03 17:23:32 +08:00
|
|
|
|
*/
|
2020-11-17 10:18:30 +08:00
|
|
|
|
public function group($group = [], $having = '')
|
2020-10-13 09:38:55 +08:00
|
|
|
|
{
|
2020-10-23 16:48:49 +08:00
|
|
|
|
if ($group) {
|
2020-10-05 13:43:53 +08:00
|
|
|
|
$this->filter .= ' GROUP BY ';
|
2020-11-17 10:18:30 +08:00
|
|
|
|
$this->filter .= ' ' . implode(' ,', $group) . ' ' . $having . ' ';
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
return $this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-10-05 13:43:53 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 查询limit
|
2020-10-13 09:38:55 +08:00
|
|
|
|
* @param string
|
2020-10-05 13:43:53 +08:00
|
|
|
|
* @return $this
|
2020-10-11 19:23:42 +08:00
|
|
|
|
* $limit = '100' 限制查询100条
|
|
|
|
|
|
* $limit = '2,100' 查询第二页 100条数据
|
2020-10-05 13:43:53 +08:00
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function limit($limit = '100')
|
|
|
|
|
|
{
|
|
|
|
|
|
$this->filter .= ' LIMIT ' . $limit . ' ';
|
2020-10-05 13:43:53 +08:00
|
|
|
|
return $this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-10-03 17:23:32 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 查询字段
|
|
|
|
|
|
* @param string $field
|
|
|
|
|
|
* @return $this
|
2020-10-11 19:23:42 +08:00
|
|
|
|
* $field = 'id,count(1),sub(num)'
|
2020-10-03 17:23:32 +08:00
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function field($field = '*')
|
|
|
|
|
|
{
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$this->field = $field;
|
|
|
|
|
|
return $this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询所有
|
|
|
|
|
|
* @return mixed
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function fetchAll()
|
|
|
|
|
|
{
|
|
|
|
|
|
$sql = sprintf('SELECT %s FROM `%s` %s', $this->field, $this->table, $this->filter);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$this->filter = '';
|
|
|
|
|
|
$sth = Db::pdo()->prepare($sql);
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$sth = $this->formatParam($sth, $this->param);
|
2020-10-26 12:14:54 +08:00
|
|
|
|
$this->param = [];
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$sth->execute();
|
|
|
|
|
|
|
|
|
|
|
|
return $sth->fetchAll();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询一条
|
|
|
|
|
|
* @return mixed
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function fetch()
|
|
|
|
|
|
{
|
2020-11-17 10:18:30 +08:00
|
|
|
|
$sql = sprintf('SELECT %s FROM `%s` %s LIMIT 1', $this->field, $this->table, $this->filter);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$this->filter = '';
|
|
|
|
|
|
$sth = Db::pdo()->prepare($sql);
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$sth = $this->formatParam($sth, $this->param);
|
2020-10-26 12:14:54 +08:00
|
|
|
|
$this->param = [];
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$sth->execute();
|
|
|
|
|
|
|
|
|
|
|
|
return $sth->fetch();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据条件(id)删除
|
|
|
|
|
|
* @param $id
|
|
|
|
|
|
* @return mixed
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function delete()
|
|
|
|
|
|
{
|
2020-11-17 10:18:30 +08:00
|
|
|
|
$sql = sprintf('DELETE FROM `%s` %s LIMIT 1', $this->table, $this->filter);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$this->filter = '';
|
|
|
|
|
|
$sth = Db::pdo()->prepare($sql);
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$sth = $this->formatParam($sth, $this->param);
|
2020-10-26 12:14:54 +08:00
|
|
|
|
$this->param = [];
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$sth->execute();
|
|
|
|
|
|
|
|
|
|
|
|
return $sth->rowCount();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 新增数据
|
|
|
|
|
|
* @param $data
|
|
|
|
|
|
* @return mixed
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function add($data)
|
|
|
|
|
|
{
|
|
|
|
|
|
$sql = sprintf('INSERT INTO `%s` %s', $this->table, $this->formatInsert($data));
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$sth = Db::pdo()->prepare($sql);
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$sth = $this->formatParam($sth, $data);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$sth->execute();
|
|
|
|
|
|
|
|
|
|
|
|
return $sth->rowCount();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 新增多条数据
|
|
|
|
|
|
* @param $data
|
|
|
|
|
|
* @return int
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function addAll($data)
|
|
|
|
|
|
{
|
|
|
|
|
|
$sql = sprintf('INSERT INTO `%s` %s', $this->table, $this->formatInsertAll($data));
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$sth = Db::pdo()->prepare($sql);
|
|
|
|
|
|
$sth->execute();
|
|
|
|
|
|
|
|
|
|
|
|
return $sth->rowCount();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 修改数据
|
|
|
|
|
|
* @param $data
|
|
|
|
|
|
* @return mixed
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function update($data)
|
|
|
|
|
|
{
|
|
|
|
|
|
$sql = sprintf('UPDATE `%s` SET %s %s', $this->table, $this->formatUpdate($data), $this->filter);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$this->filter = '';
|
|
|
|
|
|
$sth = Db::pdo()->prepare($sql);
|
2020-11-17 10:18:30 +08:00
|
|
|
|
$sth = $this->formatUpdateParam($sth, $data);
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$sth = $this->formatParam($sth, $this->param);
|
2020-10-26 12:14:54 +08:00
|
|
|
|
$this->param = [];
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$sth->execute();
|
|
|
|
|
|
|
|
|
|
|
|
return $sth->rowCount();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 绑定具体变量值
|
|
|
|
|
|
* @param PDOStatement $sth
|
|
|
|
|
|
* @param array $params
|
|
|
|
|
|
* @return PDOStatement
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
public function formatParam(PDOStatement $sth, $params = [])
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach ($params as $param => &$value) {
|
|
|
|
|
|
$param = is_int($param) ? $param + 1 : ':' . ltrim($param, ':');
|
|
|
|
|
|
$sth->bindParam($param, $value);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
return $sth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-17 10:18:30 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 绑定具体变量值update
|
|
|
|
|
|
* @param PDOStatement $sth
|
|
|
|
|
|
* @param array $params
|
|
|
|
|
|
* @return PDOStatement
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function formatUpdateParam(PDOStatement $sth, $params = [])
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach ($params as $param => &$value) {
|
|
|
|
|
|
$param = ':' . ltrim($param, ':').'update';
|
|
|
|
|
|
$sth->bindParam($param, $value);
|
|
|
|
|
|
}
|
|
|
|
|
|
return $sth;
|
|
|
|
|
|
}
|
2020-10-03 17:23:32 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 将数组转化为插入格式的sql语句
|
|
|
|
|
|
* @param $data
|
|
|
|
|
|
* @return string
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
private function formatInsert($data)
|
|
|
|
|
|
{
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$fields = [];
|
|
|
|
|
|
$names = [];
|
2020-10-13 09:38:55 +08:00
|
|
|
|
foreach ($data as $key => $value) {
|
|
|
|
|
|
$fields[] = sprintf('`%s`', $key);
|
|
|
|
|
|
$names[] = sprintf(':%s', $key);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$field = implode(',', $fields);
|
|
|
|
|
|
$name = implode(',', $names);
|
|
|
|
|
|
return sprintf('(%s) VALUES(%s)', $field, $name);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 格式化插入数据
|
|
|
|
|
|
* @param $data
|
|
|
|
|
|
* @return string
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
private function formatInsertAll($data)
|
|
|
|
|
|
{
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$fields = [];
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$values = '';
|
|
|
|
|
|
foreach ($data[0] as $key => $value) {
|
|
|
|
|
|
$fields[] = sprintf('`%s`', $key);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
2020-10-13 09:38:55 +08:00
|
|
|
|
foreach ($data as $k => $v) {
|
|
|
|
|
|
$values .= '(\'' . implode('\',\'', $v) . '\'),';
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
2020-10-13 09:38:55 +08:00
|
|
|
|
$field = implode(',', $fields);
|
|
|
|
|
|
$values = rtrim($values, ',');
|
|
|
|
|
|
return sprintf('(%s) VALUES %s', $field, $values);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 更新数据的格式转换
|
|
|
|
|
|
* @param $data
|
|
|
|
|
|
* @return string
|
|
|
|
|
|
*/
|
2020-10-13 09:38:55 +08:00
|
|
|
|
private function formatUpdate($data)
|
|
|
|
|
|
{
|
2020-10-03 17:23:32 +08:00
|
|
|
|
$fields = [];
|
2020-10-13 09:38:55 +08:00
|
|
|
|
foreach ($data as $key => $value) {
|
2020-11-17 10:18:30 +08:00
|
|
|
|
$fields[] = sprintf('`%s`=:%s', $key, $key.'update');
|
|
|
|
|
|
$this->param[$key.'update'] = $value;
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
2020-10-13 09:38:55 +08:00
|
|
|
|
return implode(',', $fields);
|
2020-10-03 17:23:32 +08:00
|
|
|
|
}
|
2020-10-13 09:38:55 +08:00
|
|
|
|
}
|