浮点型
又称为精度类型,是一种可能丢失精度的数据类型,数据可能不那么准确
float 单精度类型
4字节存储,7位精度,表示数据范围比整数大得多
float 表示不指定小数位的浮点数
float(M, D)表示一共存储M个有效数字,其中小数部分占D位
double 双精度类型
8个字节存储,表示范围更大,精度有15位左右
double 表示不指定小数位的浮点数
double(M, D)表示一共存储M个有效数字,其中小数部分占D位
如何选择
当需要存储的小数对精度要求不高时,可以选择FLOAT单精度浮点型,可以节省内存空间,提高计算速度。
当需要进行高速数学计算、科学计算、卫星定位计算等对精度要求较高时,可以选择DOUBLE双精度浮点型。
当需要进行精确计算,如工资结算、转账打款等财务类型的数据,可以选择DECIMAL定点型。
<?php
class Mysql
{
public $link;
public function __construct()
{
$this->conn();
}
/**
* 连接数据库,从配置文件读取配置信息
*/
public function conn()
{
$cfg = require 'config.php';
try {
$this->link = new PDO("mysql:dbname={$cfg['databaseName']};host={$cfg['host']};charset={$cfg['charset']};port={$cfg['port']}", $cfg['name'], $cfg['password']);
$this->link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // 设置禁止本地模拟prepare
//$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);// 设置捕获异常
} catch (PDOException $e) {
die("Error: " . $e->getMessage());
}
}
/**
* 查询多行数据
* @param string $table 表名字
* @param string $where where条件
* @param string $field 字段
* @param string $additional 附加sql语句
* @return array
*/
public function getAll($table, $where = [], $field = "*", $additional = '')
{
if (strpos($field, ",") !== false) {
$arr = explode(",", $field);
$str = '';
foreach ($arr as $v) {
$str .= "`{$v}`,";
}
$field = substr($str, 0, -1);
} else if ($field != "*") {
$field = "`{$field}`";
}
$sql = "SELECT {$field} FROM `{$table}`";
$sql2 = '';
$value = [];
if ($where) {
if (!is_array($where[0])) {
if (strtolower($where[1]) == 'in') {
$where[1] = 'IN';
$sql2 = " `{$where[0]}` {$where[1]} (";
if (is_array($where[2])) {
foreach ($where[2] as $v) {
$value[] = $v;
$sql2 .= '?,';
}
} else {
$value[] = $where[2];
$sql2 .= '?';
}
$sql2 = rtrim($sql2, ',') . ')';
} else {
$value[] = $where[2];
$sql2 = " `{$where[0]}` {$where[1]} ?";
}
} else {
foreach ($where as $v) {
if (strtolower($v[1]) == 'in') {
$v[1] = 'IN';
$sql2 .= " `{$v[0]}` {$v[1]} (";
if (is_array($v[2])) {
foreach ($v[2] as $v2) {
$value[] = $v2;
$sql2 .= "?,";
}
} else {
$value[] = $v[2];
$sql2 .= "?";
}
$sql2 = rtrim($sql2, ',') . ') AND';
} else {
$value[] = $v[2];
$sql2 .= " `{$v[0]}` {$v[1]} ? AND";
}
}
$sql2 = substr($sql2, 0, -4);
}
if ($sql2) {
$sql .= " WHERE " . $sql2;
}
}
if ($additional) {
$sql .= ' ' . $additional;
}
$res = $this->link->prepare($sql);
$res->execute($value);
$data = $res->fetchAll(PDO::FETCH_ASSOC);
return $data;
}
/**
* 查询单行数据
* @param string $table 表名字
* @param string $where where条件
* @param string $field 字段
* @param string $additional 附加sql语句
* @return array
*/
public function getRow($table, $where = [], $field = "*", $additional = '')
{
if (strpos($field, ",") !== false) {
$arr = explode(",", $field);
$str = '';
foreach ($arr as $v) {
$str .= "`{$v}`,";
}
$field = substr($str, 0, -1);
} else if ($field != "*") {
$field = "`{$field}`";
}
$sql = "SELECT {$field} FROM `{$table}`";
$sql2 = '';
$value = [];
if ($where) {
if (!is_array($where[0])) {
if (strtolower($where[1]) == 'in') {
$where[1] = 'IN';
$sql2 = " `{$where[0]}` {$where[1]} (";
if (is_array($where[2])) {
foreach ($where[2] as $v) {
$value[] = $v;
$sql2 .= '?,';
}
} else {
$value[] = $where[2];
$sql2 .= '?';
}
$sql2 = rtrim($sql2, ',') . ')';
} else {
$value[] = $where[2];
$sql2 = " `{$where[0]}` {$where[1]} ?";
}
} else {
foreach ($where as $v) {
if (strtolower($v[1]) == 'in') {
$v[1] = 'IN';
$sql2 .= " `{$v[0]}` {$v[1]} (";
if (is_array($v[2])) {
foreach ($v[2] as $v2) {
$value[] = $v2;
$sql2 .= "?,";
}
} else {
$value[] = $v[2];
$sql2 .= "?";
}
$sql2 = rtrim($sql2, ',') . ') AND';
} else {
$value[] = $v[2];
$sql2 .= " `{$v[0]}` {$v[1]} ? AND";
}
}
$sql2 = substr($sql2, 0, -4);
}
if ($sql2) {
$sql .= " WHERE " . $sql2;
}
}
if ($additional) {
$sql .= ' ' . $additional;
}
$res = $this->link->prepare($sql);
$res->execute($value);
$data = $res->fetch(PDO::FETCH_ASSOC);
return $data;
}
/**
* 自动创建sql语句并执行
* @param string $table 表名字
* @param array $data 关联数组 键/值与表的列/值对应
* @param string $act 1为insert,2为update
* @param array $where 条件,用于update
* @return int 成功为insert产生的主键值,update是影响的行数,失败为0
*/
public function exec($table, $data, $act = 1, $where = [])
{
$value = [];
if ($act == 1) {
$sql = "INSERT INTO `{$table}` (`";
$sql .= implode('`,`', array_keys($data)) . '`)';
$str = '';
foreach ($data as $v) {
$str .= "?,";
}
$str = substr($str, 0, -1);
$sql .= " VALUES ({$str})";
$value = array_values($data);
} else {
$sql = "UPDATE `{$table}` SET ";
foreach ($data as $k => $v) {
$sql .= "`" . $k . '`= ' . " ?,";
$value[] = $v;
}
$sql = rtrim($sql, ',');
$sql2 = '';
if ($where) {
if (!is_array($where[0])) {
if (strtolower($where[1]) == 'in') {
$where[1] = 'IN';
$sql2 = " `{$where[0]}` {$where[1]} (";
if (is_array($where[2])) {
foreach ($where[2] as $v) {
$value[] = $v;
$sql2 .= '?,';
}
} else {
$value[] = $where[2];
$sql2 .= '?';
}
$sql2 = rtrim($sql2, ',') . ')';
} else {
$value[] = $where[2];
$sql2 = " `{$where[0]}` {$where[1]} ?";
}
} else {
foreach ($where as $v) {
if (strtolower($v[1]) == 'in') {
$v[1] = 'IN';
$sql2 .= " `{$v[0]}` {$v[1]} (";
if (is_array($v[2])) {
foreach ($v[2] as $v2) {
$value[] = $v2;
$sql2 .= "?,";
}
} else {
$value[] = $v[2];
$sql2 .= "?";
}
$sql2 = rtrim($sql2, ',') . ') AND';
} else {
$value[] = $v[2];
$sql2 .= " `{$v[0]}` {$v[1]} ? AND";
}
}
$sql2 = substr($sql2, 0, -4);
}
if ($sql2) {
$sql .= " WHERE " . $sql2;
}
}
}
$res = $this->link->prepare($sql);
$run = $res->execute($value);
if ($run) {
if ($act == 1) {
return $this->link->lastInsertId();
} else {
return $res->rowCount();
}
} else {
return 0;
}
}
/**
* 删除数据
* @param string $table 表名字
* @param array $where where条件
* @return bool
*/
public function delete($table, $where = [])
{
$sql = "DELETE FROM `{$table}`";
$sql2 = '';
$value = [];
if ($where) {
if (!is_array($where[0])) {
if (strtolower($where[1]) == 'in') {
$where[1] = 'IN';
$sql2 = " `{$where[0]}` {$where[1]} (";
if (is_array($where[2])) {
foreach ($where[2] as $v) {
$value[] = $v;
$sql2 .= '?,';
}
} else {
$value[] = $where[2];
$sql2 .= '?';
}
$sql2 = rtrim($sql2, ',') . ')';
} else {
$value[] = $where[2];
$sql2 = " `{$where[0]}` {$where[1]} ?";
}
} else {
foreach ($where as $v) {
if (strtolower($v[1]) == 'in') {
$v[1] = 'IN';
$sql2 .= " `{$v[0]}` {$v[1]} (";
if (is_array($v[2])) {
foreach ($v[2] as $v2) {
$value[] = $v2;
$sql2 .= "?,";
}
} else {
$value[] = $v[2];
$sql2 .= "?";
}
$sql2 = rtrim($sql2, ',') . ') AND';
} else {
$value[] = $v[2];
$sql2 .= " `{$v[0]}` {$v[1]} ? AND";
}
}
$sql2 = substr($sql2, 0, -4);
}
if ($sql2) {
$sql .= " WHERE " . $sql2;
}
}
$res = $this->link->prepare($sql);
return $res->execute($value);
}
/**
* count数据
* @param string $table 表名字
* @param array $where where条件
* @param string $field 字段
* @return int
*/
public function count($table, $where = [],$field = '*')
{
$sql = "SELECT COUNT({$field}) FROM `{$table}`";
$sql2 = '';
$value = [];
if ($where) {
if (!is_array($where[0])) {
if (strtolower($where[1]) == 'in') {
$where[1] = 'IN';
$sql2 = " `{$where[0]}` {$where[1]} (";
if (is_array($where[2])) {
foreach ($where[2] as $v) {
$value[] = $v;
$sql2 .= '?,';
}
} else {
$value[] = $where[2];
$sql2 .= '?';
}
$sql2 = rtrim($sql2, ',') . ')';
} else {
$value[] = $where[2];
$sql2 = " `{$where[0]}` {$where[1]} ?";
}
} else {
foreach ($where as $v) {
if (strtolower($v[1]) == 'in') {
$v[1] = 'IN';
$sql2 .= " `{$v[0]}` {$v[1]} (";
if (is_array($v[2])) {
foreach ($v[2] as $v2) {
$value[] = $v2;
$sql2 .= "?,";
}
} else {
$value[] = $v[2];
$sql2 .= "?";
}
$sql2 = rtrim($sql2, ',') . ') AND';
} else {
$value[] = $v[2];
$sql2 .= " `{$v[0]}` {$v[1]} ? AND";
}
}
$sql2 = substr($sql2, 0, -4);
}
if ($sql2) {
$sql .= " WHERE " . $sql2;
}
}
$res = $this->link->prepare($sql);
$res->execute($value);
$data = $res->fetch(PDO::FETCH_NUM);
return $data[0];
}
}
config.php
<?php
return array(
'host' => 'localhost',
'name' => 'root',
'password' => 'root',
'databaseName' => 'cs_cn',
'port' => '3306',
'charset' => 'utf8'
);
使用方法
<?php
require 'Mysql.class.php';
$mysql = new Mysql();
// 添加
$data = [
'code' => mt_rand(1000000000,9999999999),
'url' => 'https://www.zzwws.cn',
'ip' => mt_rand(1000000000,9999999999),
'add_time' => time()
];
$res = $mysql->exec('zz_url',$data);
if($res){
echo '添加成功';
}else{
echo '添加失败';
}
// 修改
$data = [
'code' => mt_rand(1000000000,9999999999)
];
$where = ['id','=',51];
// 或者
// $where = [
// ['id','=',51],
// ['ip','=','3755406202']
// ];
$res = $mysql->exec('zz_url',$data,2,$where);
if($res){
echo '修改成功';
}else{
echo '修改失败';
}
// 查询一行数据
$row = $mysql->getRow('zz_url',['id','=',51],'id,code');
if(!$row){
echo '获取失败';
}
print_r($row);
// 查询多行数据
$rows = $mysql->getAll('zz_url');
print_r($rows);
// 删除
$where = [
['id','=',52]
];
// 或者
// $where = [
// ['id','in',[1,2,3]]
// ];
$res = $mysql->delete('zz_url',$where);
var_dump($res);
// count
$count = $mysql->count('zz_url',['url','=','https://www.zzwws.cn']);
var_dump($count);
// query方法(没有预处理)
$res = $mysql->link->query("SELECT * FROM zz_url WHERE id = '1'");
$row = $res->fetch(PDO::FETCH_ASSOC);
print_r($row);
]]>错误原因:高版本数据库(8.0)转存sql文件 并导入低版本数据库(5.6)
解决办法:
方案一:升级MySQL至高版本
方案二:将需要导入的sql文件,把其中的utf8mb4_0900_ai_ci全部替换为utf8mb4_unicode_ci或者utf8mb4_general_ci,重新执行sql文件
' or 1=1#
当我们在用户名处输入' or 1=1#
,密码随便写,把它带入到语句中,就变成了
select * from user where uername='' or1=1#' and password='123456'
在SQL语句中#是注释符,所以后面的语句都会被注释掉
select * from user where username='' or1=1
也就是说可以用 'or 1=1#
这么一个字符串就可以绕开登录的密码,直接进入程序,防止这种情况出现,可以使用以下的预处理机制!
使用 PDO
1、通过传递一个插入值的数组执行一条预处理语句
$st = $db->prepare('select * from zz_order where id = ? and name = ?');
$st->execute([$id,$name]);// 成功时返回 true,失败时返回 false
$data = $st->fetch(PDO::FETCH_ASSOC);
print_r($data);
2、在 prepare 函数里面把参数用 ‘:name’ 这样的形式来替代,然后使用 execute 绑定参数。
$st = $db->prepare('select * from zz_order where id = :id');
$st->execute([':id' => $id]);
$data = $st->fetch(PDO::FETCH_ASSOC);
print_r($data);
3、通过绑定 PHP 变量执行一条预处理语句
$st = $db->prepare("select * from zz_order where id = ?");
$st->bindParam(1, $id);
$st->execute();
$data = $st->fetchAll(PDO::FETCH_ASSOC);
print_r($data);
使用 Mysqli
在 prepare 函数里面把参数用 ‘?’ 来替代,然后使用 bind_param 绑定参数。在 bind_param 中,第一个参数 's' 代表了参数的类型与个数(此处为一个字符串类型)。
$stmt = $db->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
//bind_param参数类型
i - integer(整型)
d - double(双精度浮点型)
s - string(字符串)
b - BLOB(布尔值)
PDO
需要注意的是使用PDO去访问MySQL数据库时,真正的prepared statements默认情况下是不使用的。为了解决这个问题,你需要禁用模拟的prepared statements。下面是使用PDO创建一个连接的例子:
try {
$db = new PDO('mysql:dbname=cs_cn;host=127.0.0.1;charset=utf8', 'root', 'root');
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);// 设置禁止本地模拟prepare
//$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);// 设置捕获异常
} catch (PDOException $e) {
die("Error!: " . $e->getMessage() . "<br/>");
}
ThinkPHP防止sql注入:https://www.zzwws.cn/archives/5488/
]]>解决办法:
把字段类型由int改为bigint,就可以了.
下面是mysql的数据类型详解
1.整型(xxxint)
MySQL数据类型 | 含义 |
---|---|
tinyint(m) | 1个字节表示(-128~127) |
smallint(m) | 2个字节表示(-32768~32767) |
mediumint(m) | 3个字节表示(-8388608~8388607) |
int(m) | 4个字节表示(-2147483648~2147483647) |
bigint(m) | 8个字节表示(+-9.22*10的18次方) |
2.浮点型(float和double)
MySQL数据类型 | 含义 |
---|---|
float(m,d) | 单精度浮点型,8位精度(4字节),m是十进制数字的总个数,d是小数点后面的数字个数 |
double(m,d) | 双精度浮点型,16位精度(8字节) |
参数m只影响显示效果,不影响精度,d却不同,会影响到精度。比如设一个字段定义
3.定点数(decimal)
decimal(m,d) 定点类型浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。参数m是定点类型数字的最大个数(精度),范围为0~65,d小数点右侧数字的个数,范围为0~30,但不得超过m。对定点数的计算能精确到65位数字。
4.字符串(char,varchar,xxxtext)
MySQL数据类型 | 含义 |
---|---|
char(n) | 固定长度的字符串,最多255个字符 |
varchar(n) | 固定长度的字符串,最多65535个字符 |
tinytext | 可变长度字符串,最多255个字符 |
text | 可变长度字符串,最多65535个字符 |
mediumtext | 可变长度字符串,最多2的24次方-1个字符 |
longtext | 可变长度字符串,最多2的32次方-1个字符 |
5.二进制数据(xxxBlob)
XXXBLOB和xxxtext是对应的,不过存储方式不同,xxxTEXT是以文本方式存储的,如果存储英文的话区分大小写,而xxxBlob是以二进制方式存储的,不区分大小写。xxxBlob存储的数据只能整体读出。xxxTEXT可以指定字符集,xxxblob不用指定字符集。
6.日期时间类型(date,time,datetime,timestamp)
MySQL数据类型 | 含义 |
---|---|
date | 日期'2008-12-2' |
time | 时间'12:25:36' |
datetime | 日期时间'2008-12-2 22:06:44' |
timestamp | 不固定 |
timestamp比较特殊,如果定义一个字段的类型为timestamp,这个字段的时间会在其他字段修改的时候自动刷新。所以这个数据类型的字段可以存放这条记录最后被修改的时间,而不是真正来的存放时间。
7.数据类型的属性
MySQL关键字 | 含义 |
---|---|
NULL | 数据列可包含NULL值 |
NOT NULL | 数据列不允许包含NULL值 |
DEFAULT xxx | 默认值,如果插入记录的时候没有指定值,将取这个默认值 |
PRIMARY KEY | 主键 |
AUTO_INCREMENT | 递增,如果插入记录的时候没有指定值,则在上一条记录的值上加1,仅适用于整数类型 |
UNSIGNED | 无符号 |
CHARACTER SET name | 指定一个字符集 |
PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted
这个问题在PHP的官方网站上叫缓冲查询和非缓冲查询(Buffered and Unbuffered queries)。PHP的查询缺省模式是缓冲模式。也就是说,查询数据结果会一次全部提取到内存里供PHP程序处理。这样给了PHP程序额外的功能,比如说,计算行数,将指针指向某一行等。更重要的是程序可以对数据集反复进行二次查询和过滤等操作。但这种缓冲查询模式的缺陷就是消耗内存,也就是用空间换速度。
相对的,另外一种PHP查询模式是非缓冲查询,数据库服务器会一条一条的返回数据,而不是一次全部返回,这样的结果就是PHP程序消耗较少的内存,但却增加了数据库服务器的压力,因为数据库会一直等待PHP来取数据,一直到数据全部取完。
很显然,缓冲查询模式适用于小数据量查询,而非缓冲查询适应于大数据量查询。
对于PHP的缓冲模式查询大家都知道,下面列举的例子是如何执行非缓冲查询API。
非缓冲查询方法一: mysqli
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
if ($uresult) {
while ($row = $uresult->fetch_assoc()) {
echo $row['Name'] . PHP_EOL;
}
}
$uresult->close();
?>
非缓冲查询方法二: pdo_mysql
<?php
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$uresult = $pdo->query("SELECT Name FROM City");
if ($uresult) {
while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) {
echo $row['Name'] . PHP_EOL;
}
}
?>
非缓冲查询方法三: mysql
<?php
$conn = mysql_connect("localhost", "my_user", "my_pass");
$db = mysql_select_db("world");
$uresult = mysql_unbuffered_query("SELECT Name FROM City");
if ($uresult) {
while ($row = mysql_fetch_assoc($uresult)) {
echo $row['Name'] . PHP_EOL;
}
}
?>
]]><?php
class Mysql
{
public $link;
public function __construct()
{
$this->conn();
}
/**
* 连接数据库,从配置文件读取配置信息
*/
public function conn()
{
$cfg = require 'config.php';
$this->link = new mysqli($cfg['host'], $cfg['name'], $cfg['password'], $cfg['databaseName'], $cfg['port']);
$this->query('set names ' . $cfg['charset']);
}
/**
* 发送query查询
* @param string $sql sql语句
* @return mixed
*/
public function query($sql)
{
return $this->link->query($sql);
}
/**
* 查询多行数据
* @param string $sql sql语句
* @return array
*/
public function getAll($sql)
{
$res = $this->query($sql);
$data = [];
while ($row = $res->fetch_assoc()) {
$data[] = $row;
}
return $data;
}
/**
* 查询单行数据
* @param string $sql sql语句
* @return array
*/
public function getRow($sql)
{
$res = $this->query($sql);
return $res->fetch_assoc();
}
/**
* 查询单个数据
* @param string $sql sql语句
* @return array mixed
*/
public function getOne($sql)
{
$res = $this->query($sql);
return $res->fetch_row()[0];
}
/**
* 自动创建sql语句并执行
* @param string $table 表名字
* @param array $data 关联数组 键/值与表的列/值对应
* @param string $act 动作/update/insert
* @param string $where 条件,用于update
*
*/
public function exec($table, $data, $act = 'insert', $where = '0')
{
if ($act == 'insert') {
//插入语句 insert into 表名 (字段1,字段2) values ('values1','values2')
$sql = "insert into $table (";
$sql .= implode(',', array_keys($data)) . ')';
$sql .= " values ('";
$sql .= implode("','", array_values($data)) . "')";
} else {
//修改语句 update 表名 set 字段1='values1',字段2='values2' where id=1
$sql = "update $table set ";
foreach ($data as $k => $v) {
$sql .= $k . '=' . "'$v',";
}
$sql = rtrim($sql, ',');
$sql .= " where $where";
}
return $this->query($sql);
}
/**
* 返回上一条insert语句产生的主键值
*/
public function lastId()
{
return $this->link->insert_id;
}
/**
* 返回上一条语句影响的行数
*/
public function affectRows()
{
return $this->link->affected_rows;
}
}
Upload.class.php
<?php
abstract class AUpload
{
public $allowext = array('jpg', 'jpeg', 'png', 'rar');
public $maxsize = 1;
protected $error = '';
abstract public function getInfo($name);
abstract public function createDir();
abstract public function randStr($len = 8);
abstract protected function checkType($ext);
abstract protected function checkSize($size);
abstract public function up($name);
public function getError()
{
return $this->error;
}
}
class Upload extends AUpload
{
/**
* 分析$_FILES中$name域的信息,比如$_FILES['pic']
* @param string $name 表单中的file里的name值
* @return array 上传文件的信息
*/
public function getInfo($name)
{
return $_FILES[$name];
}
/**
* 创建目录 /upload/2021/01/04
* @return string 目录路径
*/
public function createDir()
{
$dir = '/upload/' . date('Y/m/d');
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
return $dir;
}
/**
* 生成随机字符串
* @param int $len 随机字符串的长度
* @return string 返回生成的字符串
*/
public function randStr($len = 6)
{
$str = str_shuffle('abcedfghjkmnpqrstuvwxyzABCEDFGHJKMNPQRSTUVWXYZ0123456789');
return substr($str, 0, $len);
}
/**
* 检查文件类型
* @param $ext 文件后缀
* @return boolean
*/
protected function checkType($ext)
{
return in_array($ext, $this->allowext);
}
/**
* 检测文件大小
* @param $size 文件大小
* @return boolean
*/
protected function checkSize($size)
{
return $size < $this->maxsize * 1024 * 1024;
}
/**
* 上传文件
* @param string $name 表单中file的name值
* @return string 上传的文件,如/upload/2021/01/04/1609749834kfyzXr.jpg
*/
public function up($name)
{
if (!isset($_FILES[$name])) {
echo '没有上传文件';exit();
}
$info = $this->getInfo($name);
$ext = ltrim(strrchr($info['name'], '.'), '.');
if (!$this->checkType($ext)) {
echo '不允许上传此类型文件';exit();
}
if (!$this->checkSize($info['size'])) {
echo '文件过大';exit();
}
$dir = $this->createDir();
$filename = time() . $this->randStr() . '.' . $ext;
if (move_uploaded_file($info['tmp_name'], $dir . '/' . $filename)) {
$data['path'] = $dir;
$data['filename'] = $filename;
return $data;
} else {
echo '上传失败';
}
}
}
$file = new Upload();
var_dump($file->up('pic'));
upload.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>上传</title>
</head>
<body>
<form action="Upload.class.php" method="post" enctype="multipart/form-data">
<input type="file" name="pic">
<button type="submit" id="submit">提交</button>
</form>
</body>
</html>
config.php
<?php
return array(
'host' => 'localhost',
'name' => 'cs',
'password' => '123456',
'databaseName' => 'cs',
'port' => '3306',
'charset' => 'utf8'
);
$mysql = new Mysql();
1、增
$art['title'] = trim($_POST['title']);
$art['cat_id'] = trim($_POST['cat_id']);
$art['content'] = trim($_POST['content']);
$art['pubtime'] = time();
if ($mysql->exec('art', $art)) {
echo('添加成功');
} else {
echo('添加失败');
}
2、删
$sql = "delete from cat where cat_id='$cat_id'";
if ($mysql->query($sql)) {
echo('删除成功');
} else {
echo('删除失败');
}
3、改
$cat_id = $_GET['cat_id'];
$cat['catname'] = trim($_POST['catname']);
if ($mysql->exec('cat',$cat,'update',"cat_id=$cat_id")) {
echo('修改成功');
} else {
echo('修改失败');
}
4、查
查询多行数据
$sql = "select * from cat";
$arr = $mysql->getAll($sql);
print_r($arr);
取出一行数据
$sql = "select * from cat where cat_id='$cat_id'";
if (!$mysql->getRow($sql)) {
echo('栏目不存在');
exit();
}
查询返回一个结果
$sql = "select * from cat where cat_id='$cat_id'";
echo $mysql->getOne($sql);
获取上一步insert 操作产生的主键id
$mysql->lastId();
]]>因为其长度固定,char的存取速度还是要比varchar要快得多,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以会占据多余的空间,可谓是以空间换取时间效率。varchar则刚好相反,以时间换空间。
区别之二,存储的容量不同
对 char 来说,最多能存放的字符个数 255,和编码无关。
而 varchar 呢,最多能存放 65532 个字符。varchar的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是 65,532字节。
<?php
/**
* mysql.php mysql系列操作函数
* @author nianbaibai
*/
/**
* 连接数据库
*
* @return resource 连接成功,返回连接数据库的资源
*/
function mConn()
{
static $conn = null;
if ($conn === null) {
$db = require ROOT . '/lib/config.php';
$conn = mysqli_connect("$db[host]", "$db[name]", "$db[password]", "$db[databaseName]", "$db[port]");
mysqli_query($conn, 'set names ' . $db['charset']);
}
return $conn;
}
/**
* 查询的函数
* @return mixed resoure/bool
*/
function mQuery($sql)
{
$rs = mysqli_query(mConn(), $sql);
if ($rs) {
// mLog($sql);//执行成功的日志,如果需要的可以显示这段
} else {
mLog($sql . "\n" . mysqli_error(mConn()));
}
return $rs;
}
/**
* log日志记录功能
* @param str $str 待记录的字符串
*/
function mLog($str)
{
$filename = ROOT . '/log/' . date('Ymd') . '.txt';
$log = "-----------------------------------------\n" . date('Y/m/d H:i:s') . "\n" . $str . "\n" . "-----------------------------------------\n\n";
return file_put_contents($filename, $log, FILE_APPEND);
}
/**
* select 查询多行数据
*
* @param str $sql select 待查询的sql语句
* @return mixed select 查询成功,返回二维数组,失败返回false
*/
function mGetAll($sql)
{
$rs = mQuery($sql);
if (!$rs) {
return false;
}
$data = array();
while ($row = mysqli_fetch_assoc($rs)) {
$data[] = $row;
}
return $data;
}
/*$sql = "select * from cat";
print_r(mGetAll($sql));
*/
/**
* select 取出一行数据
*
* @param str $sql 待查询的sql语句
* @return arr/false 查询成功 返回一个一维数组
*/
function mGetRow($sql)
{
$rs = mQuery($sql);
if (!$rs) {
return false;
}
return mysqli_fetch_assoc($rs);
}
/*$sql = "select * from cat where cat_id=1";
print_r(mGetRow($sql));*/
/**
* select 查询返回一个结果
*
* @param str $sql 待查询的select语句
* @return mixed 成功,返回结果,失败返回false
*/
function mGetOne($sql)
{
$rs = mQuery($sql);
if (!$rs) {
return false;
}
return mysqli_fetch_row($rs)[0];
}
/*$sql = "select count(*) from art where cat_id=1";
echo mGetOne($sql);*/
/**
* 自动拼接insert 和 update sql语句,并且调用mQuery() 去执行sql
*
* @param str $table 表名
* @param arr $data 接收到的数据,一维数组
* @param str $act 动作 默认为'insert'
* @param str $where 防止update更改时少加where条件
* @return bool insert 或者update 插入成功或失败
*/
function mExec($table, $data, $act = 'insert', $where = 0)
{
if ($act == 'insert') {
$sql = "insert into $table (";
$sql .= implode(',', array_keys($data)) . ") values ('";
$sql .= implode("','", array_values($data)) . "')";
return mQuery($sql);
} else if ($act == 'update') {
$sql = "update $table set ";
foreach ($data as $k => $v) {
$sql .= $k . "='" . $v . "',";
}
$sql = rtrim($sql, ',') . " where " . $where;
return mQuery($sql);
}
}
//$data = array('title'=>'今天的空气' , 'content'=>'空气质量优' , 'pubtime'=>12345678,'author'=>'baibai');
//insert into art (title,content,pubtime,author) values ('今天的空气','空气质量优','12345678','baibai');
//update art set title='今天的空气',conte='空气质量优',pubtime='12345678',author='baibai' where art_id=1;
//echo mExec('art' , $data , 'update' , 'art_id=1');;
//insert into cat (id,catname) values (5 , 'test');
/**
* 取得上一步insert 操作产生的主键id
*/
function getLastId()
{
return mysqli_insert_id(mConn());
}
/**
* 使用反斜线 转义字符串
* @param arr 待转义的数组
* @return arr 被转义后的数组
*/
function _addslashes($arr)
{
foreach ($arr as $k => $v) {
if (is_string($v)) {
$arr[$k] = addslashes($v);
} else if (is_array($v)) {
$arr[$k] = _addslashes($v);
}
}
return $arr;
}
config.php
<?php
//salt为cookie登录的安全码
return array(
'host' => 'localhost',
'name' => 'cs',
'password' => '123456',
'databaseName' => 'cs',
'port' => '3306',
'charset' => 'utf8',
'salt' => 'Q!!RN13q&y'
);
func.php
<?php
/**
*@param str $msg 成功返回的信息
*@param str $file 跳转的文件名,返回上一页为-1
*@param int $time 延时跳转的时间,单位秒
*/
function succ($msg, $file = '', $time = 1)
{
$res = 'succ';
require ROOT . '/view/admin/info.html';
if ($file != '') {
if ($file == '-1') {
// header("Refresh:$time;url=$_SERVER[HTTP_REFERER]");
echo '<script>window.setTimeout(function() {window.history.back(-1);},' . $time . '000)</script>';
} else {
header("Refresh:$time;url=$file");
}
}
exit();
}
/**
*@param str $msg 失败返回的报错信息
*@param str $file 跳转的文件名,返回上一页为-1
*@param int $time 延时跳转的时间,单位秒
*/
function error($msg, $file = '', $time = 1)
{
$res = 'fail';
require ROOT . '/view/admin/info.html';
if ($file != '') {
if ($file == '-1') {
// header("Refresh:$time;url=$_SERVER[HTTP_REFERER]");
echo '<script>window.setTimeout(function() {window.history.back(-1);},' . $time . '000)</script>';
} else {
header("Refresh:$time;url=$file");
}
}
exit();
}
/**
*获取访客IP
*/
function getRealIp()
{
static $realip = null;
if ($realip !== null) {
return $realip;
}
if (getenv('REMOTE_ADDR')) {
$realip = getenv('REMOTE_ADDR');
} else if (getenv('HTTP_CLIENT_IP')) {
$realip = getenv('HTTP_CLIENT_IP');
} else if (getenv('HTTP_X_FROWARD_FOR')) {
$realip = getenv('HTTP_X_FROWARD_FOR');
}
return $realip;
}
/**
* 生成随机字符串
* @param int $num 生成的随机字符串的个数
* @return str 生成的随机字符串
*/
function randStr($num = 6)
{
$str = str_shuffle('abcedfghjkmnpqrstuvwxyzABCEDFGHJKMNPQRSTUVWXYZ0123456789');
return substr($str, 0, $num);
}
//echo randStr();
/**
* 创建目录 ROOT.'/upload/2015/01/25/qwefas.jpg'
* @return str 成功返回路径,失败返回false
*/
function createDir()
{
$path = '/upload/' . date('Y/m/d');
$fpath = ROOT . $path;
if (is_dir($fpath) || mkdir($fpath, 0777, true)) {
return $path;
} else {
return false;
}
}
/**
* 获取文件后缀
* @param str $filename 文件名
* @return str 文件的后缀名,且带点.
*/
function getExt($filename)
{
return strrchr($filename, '.');
}
/**
* 检测用户是否登录
* @return bool 已登录返回true,未登录返回false
*/
function acc()
{
if (!isset($_COOKIE['name']) || !isset($_COOKIE['ccode'])) {
return false;
}
return $_COOKIE['ccode'] === cCode($_COOKIE['name']);
}
/**
* 加密用户名
* @param str $name 用户登陆时输入的用户名
* @return str md5(用户名+salt)=>md5码
*/
function cCode($name)
{
$salt = require ROOT . '/lib/config.php';
return md5($name . '|' . $salt['salt']);
}
info.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="rside">
<?php if($res == 'succ'){?>
<div class="succ"><?php echo $msg?></div>
<?php }else if($res == 'fail'){?>
<div class="danger"><?php echo $msg?></div>
<?php }?>
</div>
</body>
</html>
login.php
<?php
require 'lib/init.php';
if (acc()) {
header('location: artlist.php');
}
if (empty($_POST)) {
require ROOT . '/view/admin/login.html';
} else {
$name = trim($_POST['username']);
if ($name == '') {
error('用户名不能为空');
}
if (!preg_match('/^[A-Za-z0-9_\x{4e00}-\x{9fa5}]+$/u', $name)) {
//用户名只能由数字、字母、中文汉字及下划线组成,不能包含特殊符号,在php中,不支持[\u4e00-\u9fa5]匹配汉字,而是用\x表示十六进制数据,然而php中用"[\x4e00-\x9fa5]"的写法也是错的,必须用{}把它包起来才行。此外,由于编码关系,需要用到"/u"声明编码格式。
error('用户名格式不正确');
}
$password = trim($_POST['password']);
if ($password == '') {
error('密码不能为空');
}
// $sql = "select * from user where name='$name' and password='$password'";
$sql = "select * from user where name='$name'";
$res = mGetRow($sql);
if (!$res) {
error('用户名不存在');
} else if (md5($res['salt'] . $password) !== $res['password']) {//这里的salt为密码的安全码,可以在注册成功后生成一个随机的安全码
error('密码错误');
} else {
setcookie('name', $res['name']);
setcookie('ccode', cCode($res['name']));
header('location: artlist.php');
}
}
init.php
<?php
//echo __DIR__,'<br>';//D:\xampp\htdocs\1\Blog
//echo __FILE__,'<br>';//D:\xampp\htdocs\1\Blog\init.php
//echo __LINE__;//4
header('content-type:text/html;charset=utf8');
define('ROOT', dirname(__DIR__)); //定义个ROOT常量,dirname往上跳一级
require ROOT . '/lib/mysql.php';
require ROOT . '/lib/func.php';
$_GET = _addslashes($_GET);
$_POST = _addslashes($_POST);
$_COOKIE = _addslashes($_COOKIE);
首先引入init.php,这里的art和cat是表名,mysqli_query($conn, $sql)可变为mQuery($sql)
1、增
$art['title'] = trim($_POST['title']);
$art['cat_id'] = trim($_POST['cat_id']);
$art['content'] = trim($_POST['content']);
$art['pubtime'] = time();
if (mExec('art', $art)) {
succ('添加成功');
} else {
error('添加失败');
}
2、删
$sql = "delete from cat where cat_id='$cat_id'";
if (mQuery($sql)) {
succ('删除成功');
} else {
error('删除失败');
}
3、改
$cat_id = $_GET['cat_id'];
$cat['catname'] = trim($_POST['catname']);
if (mExec('cat',$cat,'update',"cat_id=$cat_id")) {
succ('修改成功');
} else {
error('修改失败');
}
4、查
查询多行数据
$sql = "select * from cat";
$arr = mGetAll($sql);
print_r($arr);
取出一行数据
$sql = "select * from cat where cat_id='$cat_id'";
if (!mGetRow($sql)) {
error('栏目不存在');
exit();
}
查询返回一个结果
$sql = "select * from cat where cat_id='$cat_id'";
echo mGetOne($sql);
获取上一步insert 操作产生的主键id
getLastId();
使用反斜线,转义字符串
使用方法:在顶部添加一下代码
$_GET = _addslashes($_GET);
$_POST = _addslashes($_POST);
$_COOKIE = _addslashes($_COOKIE);
检测用户是否登录
if(!acc()){
header('location: login.php');
}
登录成功后添加name和ccode的cookie,请参考上面的login.php
setcookie('name', $res['name']);
setcookie('ccode', cCode($res['name']));
退出登录
setcookie('name', '', 0);
setcookie('ccode', '', 0);
header('location: login.php');
]]>