模仿 ThinkPHP - db 类的封装实例:
class Db extends \mysqli
{
// 实例对象
protected static $_instance = null;
// mysql配置
protected static $options = [
// 服务器地址
'host' => '127.0.0.1',
// 数据库名
'database' => 'test',
// 用户名
'username' => 'root',
// 密码
'password' => 'root',
// 端口
'hostport' => '3306',
// socket
"socket" => "",
// 数据库编码默认采用utf8
'charset' => 'utf8mb4',
// 数据库表前缀
'prefix' => 'fd_',
];
// 表
protected $tbl = null;
// 条件
protected $where = "";
// 字段,field 被占有
protected $f = "*";
// 排序
protected $order = "";
// 分页
protected $limit = "";
// 关联
protected $join = "";
// $lastSql
protected $lastSql = "";
/**
* Db constructor.
* @param string $host
* @param string $username
* @param string $passwd
* @param string $dbname
* @param int $port
* @param string $socket
* @author atong
*/
public function __construct(string $host, string $username, string $passwd, string $dbname, int $port, string $socket)
{
@parent::__construct($host, $username, $passwd, $dbname, $port, $socket);
if ($this->connect_errno) {
exit("mysql连接错误[{$this->connect_errno}]:{$this->connect_error}");
}
$this->set_charset(self::$options["charset"]);
}
/**
* 数据库初始化,并取得数据库类实例
* @access public
* @param array $options 连接配置
* @param bool $is_force 连接标识 true 强制重新连接
* @author atong
* @return Mysql
*/
public static function getInstance($options = [])
{
if (self::$_instance == null) {
$db_config = self::$options;
self::$_instance = new self(
$options["host"] ?? $db_config["host"]
, $options["username"] ?? $db_config["username"]
, $options["password"] ?? $db_config["password"]
, $options["database"] ?? $db_config["database"]
, $options["hostport"] ?? $db_config["hostport"]
, $options["socket"] ?? $db_config["socket"]
);
}
return self::$_instance;
}
/**
* todo::链式函数封装
* 模仿 tp db类的风格
*/
// 无前缀
public function _table($tbl)
{
$this->tbl = $tbl;
return $this;
}
// 拼接表(前缀+$tbl)
public function _name($tbl)
{
$this->tbl = self::$options["prefix"] . $tbl;
return $this;
}
public function _alias($alias)
{
$this->tbl .= " AS {$alias} ";
return $this;
}
/**
* @param array $where
* $where = [
* ["id",">",1]
* ["status","=",1]
* ]
* or
* ["id","=","1"]
* or
* [
* "id" => 10,
* "status" => 1
* # 跟tp5一样,val值不能是数组
* ]
* or
* $where = "id > 1"
* @param string $type OR|AND
* @author atong
* @return string|null
*/
public function _where($where, $type = "AND")
{
if ($where) {
if (is_string($where)) {
$this->where .= " {$type} {$where} ";
}
if (is_array($where)) {
// 一维,
if (count($where) == count($where, 1)) {
$keys = array_keys($where);
// 索引数组 断定格式为:["id","=","1"]
if ($keys === array_keys($keys)) {
$this->where .= " $type $where[0] $where[1] '$where[2]' ";
} else {
// 联合数组 断定格式为:["id"=> 10 ,"status" => 1]
foreach ($where as $key => $val) {
$this->where .= " $type $key = '$val' ";
}
}
} else {
foreach ($where as $k => $v) {
$this->where .= " $type $v[0] $v[1] '$v[2]' ";
}
}
}
}
return $this;
}
// 查询字段
public function _field($field)
{
$this->f = is_array($field)
? implode(",", $field)
: $field;
return $this;
}
// 排序
public function _order($order)
{
if (!$this->order) {
$this->order = " ORDER BY {$order} ";
} else {
$this->order .= " ,$order ";
}
return $this;
}
// 分页
public function _page($limit1, $limit2 = "")
{
if (!$limit2) {
$this->limit .= " limit {$limit1} ";
} else {
$this->limit .= " limit " . ($limit1 - 1) * $limit2 . "," . $limit2;
}
return $this;
}
// 表关联
public function _join($tbl, $condition, $relation = "LEFT")
{
$this->join .= " {$relation} JOIN {$tbl}";
$this->join .= " ON {$condition} ";
return $this;
}
// 获取查询语句的 sql
public function _getSelectSql()
{
$this->lastSql .= "SELECT $this->f FROM $this->tbl ";
$this->lastSql .= $this->join;
if ($this->where) {
$this->where = trim(trim(trim($this->where), "AND"), "OR");
$this->lastSql .= " WHERE " . $this->where;
}
$this->lastSql .= $this->order;
$this->lastSql .= $this->limit;
return $this->lastSql;
}
// 获取最新的 sql 语句
public function _getLastSql()
{
return $this->lastSql;
}
// 单记录查询
public function _find($just_do_it = true)
{
$sql = $this->_getSelectSql();
$rs = !$just_do_it ? $sql : $this->getFind($sql);
$this->destroy();
return $rs;
}
// 多记录查询
public function _select($just_do_it = true)
{
$sql = $this->_getSelectSql();
$rs = !$just_do_it ? $sql : $this->getSelect($sql);
$this->destroy();
return $rs;
}
// 删除操作
public function _delete($just_do_it = true)
{
$this->lastSql = "DELETE FROM $this->tbl ";
$this->where = trim(trim(trim($this->where), "AND"), "OR");
$this->lastSql .= " WHERE " . $this->where;
$rs = !$just_do_it ? $this->lastSql : $this->query($this->lastSql);
$this->destroy();
return $rs;
}
// 修改
public function _update($data = [], $just_do_it = true)
{
$this->lastSql = "UPDATE $this->tbl ";
$set = "";
foreach ($data as $field => $val) {
$set .= "{$field} = '$val',";
}
$this->lastSql .= "SET " . trim($set, ",");
$this->where = trim(trim(trim($this->where), "AND"), "OR");
$this->lastSql .= " WHERE " . $this->where;
$rs = !$just_do_it ? $this->lastSql : $this->query($this->lastSql);
$this->destroy();
return $rs;
}
// 插入
public function _insert($data = [], $just_do_it = true)
{
$this->lastSql = "INSERT INTO $this->tbl ";
$fields = $values = "";
foreach ($data as $field => $value) {
$fields .= "" . $field . ",";
$values .= "'" . $value . "',";
}
$this->lastSql .= "(" . trim($fields, ',') . ") VALUES (" . trim($values, ',') . ")";
$rs = !$just_do_it ? $this->lastSql
: ($this->query($this->lastSql) ? $this->insert_id : false);
$this->destroy();
return $rs;
}
// 插入多条记录
public function _insertAll($datas = [], $just_do_it = true)
{
$this->lastSql = "INSERT INTO $this->tbl ";
$fields = $values = "";
foreach ($datas as $k => $data) {
if ($k === 0) {
foreach ($data as $field => $value) {
$fields .= "{$field},";
$values .= "'{$value}',";
}
$this->lastSql .= "(" . trim($fields, ',') . ") VALUES (" . trim($values, ',') . ")";
} else {
$values = "";
foreach ($data as $value) {
$values .= "'" . $value . "',";
}
$this->lastSql .= ",(" . trim($values, ',') . ")";
}
}
$rs = !$just_do_it ? $this->lastSql : $this->query($this->lastSql);
$this->destroy();
return $rs;
}
// 获取异常
public function getErr()
{
exit("语句错误 [{$this->errno}]:{$this->error}");
}
//
public function getFind($sql)
{
$result = $this->query($sql); //mysqli_result对象
if (!is_object($result)) {
exit($sql . "语句错误 [{$this->errno}]:{$this->error}");
}
$row = $result->fetch_array(MYSQLI_ASSOC);
return $row;
}
//
public function getSelect($sql)
{
//mysqli_result对象
$result = $this->query($sql);
if (!is_object($result)) {
exit($sql . "语句错误 [{$this->errno}]:{$this->error}");
}
return $result->fetch_all(MYSQLI_ASSOC);
}
// 销毁对象
protected function destroy()
{
self::$_instance = null;
}
}
使用:
// require "./Db.php";
// 方法
if (!function_exists('db')) {
/**
* db 类操作
* @param $key
* @author atong
* @return mixed
*/
function db($tbl = "")
{
return Db::getInstance()->_name($tbl);
}
}
// 使用
// // 增
$sql1 = db("log")->_insert([
"option_name" => "test key1",
"option_value" => "test valu1"
],false);
echo "\$sql1:{$sql1}";
echo "
";
// // or
$sql2 = db("log")->_insertAll([
[
"option_name" => "test key2",
"option_value" => "test value2"
],
[
"option_name" => "test key3",
"option_value" => "test value3"
],
[
"option_name" => "test key4",
"option_value" => "test value4"
],
],false);
echo "\$sql2:{$sql2}";
echo "
";
// // 删
$sql3 = db("log")->_where(["option_id" => 1])->_delete(false);
echo "\$sql3:{$sql3}";
echo "
";
$sql4 = db("log")->_where([
["option_id","=",10],
["option_id","=",13]
],"OR")->_delete(false);
echo "\$sql4:{$sql4}";
echo "
";
// // 改
$sql5 = db("log")->_where(["option_id","=",1])->_update([
"option_name" => "update",
"option_value" => "update"
],false);
echo "\$sql5:{$sql5}";
echo "
";
$sql6 = db("log")->_where([
"option_id" => 1,
"option_name" => "atong"
])->_find(false);
echo "\$sql6:{$sql6}";
echo "
";
// // 查
$sql7 = db("user")->_alias("u")
->_join("fd_user_vip vip","vip.user_id = u.id")
->_field("u.id,email,level")
->_where("u.id = 1")
->_where([
["u.status","=",1],
["u.create_time",">",time()]
],"OR")
->_order("u.id desc")
->_order("u.create_time ASC")
->_page(1,10)
->_select(false);
echo "\$sql7:{$sql7}";
echo "
";
结果:
结论:以上只是照葫芦画瓢,模仿db类的样子而已,并为考虑安全问题,实际上也只是折腾一下数组字符串的处理拼接罢了。