一个类,论一个实习生的态度
这代码注释写的 让我有点汗颜
真的欣赏这种小老弟
<?php
class Model
{
/*
* @var host 主机名
* @var dbuser 用户名
* @var dbpass 密码
* @var dbname 数据库名
* @var charset 字符集
* @var prefix 前缀
* @var link 数据库连接资源
* @var tableName 表名
* @var sql sql语句
* @var options 操作数组
*/
protected $host;
protected $dbuser;
protected $dbpass;
protected $dbname;
protected $charset;
protected $prefix;
protected $link;
protected $tableName = 'user';
protected $sql;
protected $options;
// 构造方法
public function __construct($config)
{
// 初始化成员变量
$this->host = $config['DB_HOST'];
$this->dbuser = $config['DB_USER'];
$this->dbpass = $config['DB_PASS'];
$this->dbname = $config['DB_NAME'];
$this->charset = $config['DB_CHARSET'];
$this->prefix = $config['DB_PREFIX'];
// 连接数据库
$this->link = $this->connect();
// 得到数据表名
$this->tableName = $this->getTableName();
// 初始化操作数组
$this->initOptions();
}
// 连接数据库
protected function connect()
{
// 连接数据库
$link = mysqli_connect($this->host, $this->dbuser, $this->dbpass);
// 判断是否连接成功
if (!$link) {
die('数据库连接失败!');
}
// 选择数据库
mysqli_select_db($link, $this->dbname);
// 设置字符集
mysqli_set_charset($link, $this->charset);
// 返回资源
return $link;
}
// 获取表名
protected function getTableName()
{
// 1. 设置了成员变量 获取表名
if (!empty($this->tableName)) {
return $this->prefix.$this->tableName;
}
// 2. 没设置成员变量 通过类名获取表名
// - 2.1 得到当前类名
$className = get_class($this);
// - 2.2 截取除Model以外的字符 并 转换成小写
// - 2.2 例如:UsersModel 截取 Users
$table = strtolower(substr($className, 0, -5));
return $this->prefix.$table;
}
// 初始化操作数组
protected function initOptions()
{
$arr = ['where','table','field','order','group','having','limit'];
foreach ($arr as $val) {
// 1.初始化数组,清空键对应的值
$this->options[$val] = '';
// 2.将table的值,设置为tableName
if ($val == 'table') {
$this->options[$val] = $this->tableName;
} else if($val == 'field') {
$this->options[$val] = '*';
}
}
}
// field 方法
public function field($field)
{
// 如果不为空 再进行处理
if (!empty($field)){
if (is_string($field)) {
$this->options['field'] = $field;
} else if(is_array($field)) {
$this->options['field'] = join(',', $field);
}
}
// 如果为空 直接返回
return $this;
}
// table 方法
public function table($table)
{
if (!empty($table)) {
$this->options['table'] = $table;
}
return $this;
}
// where 方法
public function where($where)
{
if (!empty($where)) {
$this->options['where'] = 'where '.$where;
}
return $this;
}
// group 方法
public function group($group)
{
if (!empty($group)) {
$this->options['group'] = 'group by '.$group;
}
return $this;
}
// having 方法
public function having($having)
{
if (!empty($having)) {
$this->options['having'] = 'having '.$having;
}
return $this;
}
// order 方法
public function order($order)
{
if (!empty($order)) {
$this->options['order'] = 'order by '.$order;
}
return $this;
}
// limit 方法
public function limit($limit)
{
if (!empty($limit)) {
if (is_string($limit)) {
$this->options['limit'] = 'limit '.$limit;
} else if(is_array($limit)) {
$this->options['limit'] = 'limit '.join(',', $limit);
}
}
return $this;
}
// select 方法
public function select()
{
// 1. 预写一个带有占位符的sql语句 实现无顺序链式查询
$sql = 'SELECT %FIELD% FROM %TABLE% %WHERE% %GROUP% %HAVING% %ORDER% %LIMIT%';
// 2. 将options中对应的值依次替换上面的占位符
$sql = str_replace([
'%FIELD%',
'%TABLE%',
'%WHERE%',
'%GROUP%',
'%HAVING%',
'%ORDER%',
'%LIMIT%'
], [
$this->options['field'],
$this->options['table'],
$this->options['where'],
$this->options['group'],
$this->options['having'],
$this->options['order'],
$this->options['limit']
], $sql);
// 3. 保存sql语句 方便打印sql语句 检查错误
$this->sql = $sql;
// 4. 执行sql语句
return $this->query($sql);
}
// insert 方法
// $data: 关联数组 键->字段名 值->字段值
public function insert($data)
{
// 1. 处理值是字符串问题,两边添加引号
$data = $this->parseValue($data);
// 2. 提取所有的键(字段)
$keys = array_keys($data);
// 3. 提取所有的值(字段值)
$vals = array_values($data);
// 4. 增加数据的sql语句
$sql = 'insert into %TABLE%(%FIELD%) values(%VALUES%)';
// 5. 替换占位符的值
$sql = str_replace([
'%TABLE%',
'%FIELD%',
'%VALUES%'
], [
$this->options['table'],
join(',', $keys),
join(',', $vals)
], $sql);
// 6. 保存sql语句 方便打印sql语句 检查错误
$this->sql = $sql;
// 7. 执行sql语句
return $this->exec($sql, true);
}
// 处理字符串函数
// 传递进来一个数组 将数组中值为字符串的两边加上引号
protected function parseValue($data)
{
// 1. 遍历数组
foreach ($data as $key=>$value) {
// 2. 判断是否为字符串
if (is_string($value)) {
// 2.1 如果是字符串 两边拼接引号
$value = '"'.$value.'"';
}
// 3. 组建新的数组
$res[$key] = $value;
}
// 4. 返回处理后的数组
return $res;
}
// delete 方法
public function delete()
{
// 1. 拼接sql语句
$sql = 'delete from %TABLE% %WHERE%';
// 2. 替换占位符的值
$sql = str_replace(['%TABLE%', '%WHERE%'], [
$this->options['table'],
$this->options['where']
], $sql);
// 3. 保存sql语句 方便打印sql语句 检查错误
$this->sql = $sql;
// 4. 执行sql语句
return $this->exec($sql);
}
// update 方法
public function update($data)
{
// 1. 处理值是字符串问题,两边添加引号
$data = $this->parseValue($data);
// 2. 将关联数组拼接为固定形式 键=值
$value = $this->parseUpdate($data);
// 3. 更新数据的sql语句
$sql = 'update %TABLE% set %VALUE% %WHERE%';
// 4. 替换占位符的值
$sql = str_replace(['%TABLE%', '%VALUE%', '%WHERE%'], [
$this->options['table'],
$value,
$this->options['where'],
], $sql);
// 5. 保存sql语句
$this->sql = $sql;
// 6. 执行sql语句
return $this->exec($sql);
}
protected function parseUpdate($data)
{
foreach($data as $key => $val) {
$res[] = $key.'='.$val;
}
return join(',', $res);
}
// max 方法
public function max($field)
{
// 通过调用select方法进行查询
$res = $this->field('max('.$field.') as max')->select();
// 返回的是二维数组
return $res[0]['max'];
}
// query 查询(有结果集)
public function query($sql)
{
// 1. 初始化options数组中的值
$this->initOptions();
// 2. 执行sql查询语句
$data = mysqli_query($this->link, $sql);
// 3. 提取结果集
if ($data && mysqli_affected_rows($this->link)) {
while ($val = mysqli_fetch_assoc($data)) {
// 3.1 存储到数组中
$res[] = $val;
}
return $res;
}
}
// exec 增删改(无结果集)
public function exec($sql, $isInsert = false)
{
// 1. 初始化options数组中的值
$this->initOptions();
// 2. 执行sql语句
$res = mysqli_query($this->link, $sql);
if ($res && mysqli_affected_rows($this->link)) {
// 3. 判断是否是插入语句 根据不同语句返回不同结果
if ($isInsert) {
return mysqli_insert_id($this->link);
} else {
return mysqli_affected_rows($this->link);
}
}
return false;
}
// __get 魔术方法获取sql语句 提供受保护的属性给外部访问
public function __get($name)
{
if ($name == 'sql') {
return $this->sql;
}
return false;
}
// 析构方法
public function __destruct()
{
// 关闭数据库
mysqli_close($this->link);
}
public function __call($name, $args)
{
// 1. 获取前5个字符
$str = substr($name, 0, 5);
// 2. 获取后面的字段名并转换为小写
$field = strtolower(substr($name, 5));
// 3. 判断前五个字符是否是getBy
if ($str == 'getBy') {
return $this->where($field.'="'.$args[0].'"')->select();
}
return false;
}
}
$conn = include 'config.php';
$db = new Model($conn);
/* 测试select
$res = $db->table('user')->select();
var_dump($res);
var_dump($db->sql);
*/
/* 测试insert
$data = [
'username' => 'InsertUserName',
'password' => '123456',
'money' => 1000
];
$insertId = $db->table('user')->insert($data);
var_dump($insertId);
var_dump($db->sql);
*/
/* 测试update
$data = [
'username' => 'updated',
'password' => '123123',
'money' => 5000
];
$up = $db->table('user')->where('id = 12')->update($data);
var_dump($up);
var_dump($db->sql);
*/
/* 测试delete
$bool = $db->table('user')->where('id = 14')->delete();
var_dump($bool);
var_dump($db->sql);
*/
/* 测试max
$max = $db->table('user')->max('money');
var_dump($max);
var_dump($db->sql);
*/
/* 测试getBy
$by = $db->getByUserName('goudan');
var_dump($by);
var_dump($db->sql);
*/
?>
推荐文章: