一个类,论一个实习生的态度

这代码注释写的 让我有点汗颜

真的欣赏这种小老弟

<?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);
*/

?>
讨论数量: 15

这实习生有点水平啊

2年前 评论
Er1c (楼主) 2年前

我自卑了、工作一年還是只會框架 CURD 、 :cry:。留個坐標等待以後學習

2年前 评论
pndx

这有点牛呀

2年前 评论

好工整,// 也有空格,论这个,超越好多人。

2年前 评论
qingshui 2年前
美丽 2年前

这种小老弟来一打

2年前 评论

我也是这样写注释,我只是不希望隔了几个月回来看自己写的代码看不懂 :joy:

2年前 评论

就喜欢和这样的人一起写代码

2年前 评论

:relaxed: 强迫症,必须格式化,不能有警告啥的提示

2年前 评论
huchao399 2年前
小李世界 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!