MYSQL:utf-8bom 乱码续集

/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/


<?php

session_start()


/*
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at D:\www\1102\01.php:2) in D:\www\1102\01.php on line 4

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at D:\www\1102\01.php:2) in D:\www\1102\01.php on line 4


session cookie使用前,不能有任何输出,空行空格都不行

*/

?>

 

/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/

<?php
session_start();
?>

/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/

 

<?php

/*
utf-8中文截取无乱码


思路:
如果你看到如下字节,
42 DC 34 af aa

想截取无乱码,那就说明,你知道
从42开始截几个字节,作为一个字符.

比如截1个,截取出来42

再从DC截,你得知道,从DC,往后是几个字节组成了一个字符.

...
...

类推,这样,截取出来的字节才能保证,正是是一个个的字符

所以,关键在于,如何判断一个utf-8字符的字节数?


答: 可以到wiki上查询utf-8的编码规范,那是最权威的.
查阅后得知

最高字节
0xxx xxxx ,1个字节
110xx xxxx , 2个字节
1110 xxxx, 3
1111 0xxxx 4...

*/

 

$str = '中华人aaaa民共b和国,万c岁';


/*
$str 是待截取的字符串
$len 是截取的字符数
*/

function utf8sub($str,$len) {
if($len <= 0) {
return '';
}

$length = strlen($str); //待截取的字符串字节数

// 先取字符串的第一个字节,substr是按字节来的
$offset = 0; // 这是截取高位字节时的偏移量
$chars = 0; // 这是截取到的字符数
$res = ''; // 这是截取的字符串

while($chars < $len && $offset < $length) { //只要还没有截取到$len的长度,就继续进行
$high = decbin(ord(substr($str,$offset,1))); // 重要突破,已经能够判断高位字节

if(strlen($high) < 8) {
// 截取1个字节
$count = 1;
} else if(substr($high,0,3) == '110') {
// 截取2个字节
$count = 2;

} else if(substr($high,0,4) == '1110') {
// 截取3个字节
$count = 3;

} else if(substr($high,0,5) == '11110') {
// 截取4个字节
$count = 4;

} else if(substr($high,0,6) == '111110') {
// 截取5个字节
$count = 5;

} else if(substr($high,0,7) == '1111110') {
// 截取6个字节
$count = 6;
}

// echo $count,'<br />';


$res .= substr($str,$offset,$count);
$chars += 1;
$offset += $count;

}

return $res;

}

echo utf8sub($str,200);

 


/***
我是用字符串来判断的,效率不高.

位运算效果会更好.

110x xxxx & 1110 0000 -> 1100 0000
1110 xxxx & 1111 0000 -> 1110 0000

 

***/

 

/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/

mysql> use test
Database changed
mysql> set names gbk;
Query OK, 0 rows affected (0.05 sec)

mysql> #建立2张一样结构的表,但是引擎不一样
mysql> create table a1 (
-> uname varchar(20),
-> money int
-> )engine myisam charset utf8;
Query OK, 0 rows affected (0.42 sec)

mysql> create table a2 (
-> uname varchar(20),
-> money int
-> )engine innodb charset utf8;
Query OK, 0 rows affected (0.36 sec)

mysql> insert into a1
-> values
-> ('zhangsan',3000),
-> ('lisi',2000);
Query OK, 2 rows affected (0.09 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> insert into a2
-> values
-> ('zhangsan',3000),
-> ('lisi',2000);
Query OK, 2 rows affected (0.11 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> select * from a1;
+----------+-------+
| uname | money |
+----------+-------+
| zhangsan | 3000 |
| lisi | 2000 |
+----------+-------+
2 rows in set (0.01 sec)

mysql> select * from a2;
+----------+-------+
| uname | money |
+----------+-------+
| zhangsan | 3000 |
| lisi | 2000 |
+----------+-------+
2 rows in set (0.02 sec)

mysql> #存储数据上是一样的.
mysql> select * from a1 where uname='zhangsan' for update;
+----------+-------+
| uname | money |
+----------+-------+
| zhangsan | 3000 |
+----------+-------+
1 row in set (0.09 sec)

mysql> #演示事务的原子性
mysql> #如何使用事务呢?
mysql> #start transaction 开启事务
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from a2;
+----------+-------+
| uname | money |
+----------+-------+
| zhangsan | 3000 |
| lisi | 2000 |
+----------+-------+
2 rows in set (0.00 sec)

mysql> update a2 set money = money + 1000 where uname='zhangsan';
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> #减掉李四1000块钱,转账完成.
mysql> update a2 set money = money -1000 where uname='lisi';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> #2步都完成了,这个事务完成了.
mysql> #提交整个事务
mysql> commit;
Query OK, 0 rows affected (0.09 sec)

mysql> #事务的体现呢?
mysql> #再让李四给张三转500
mysql> update a2 set money = money + 500 where uname='zhangsan';
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> update a2 set money = money - 500 where uname='zhangsan';
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from a2;
+----------+-------+
| uname | money |
+----------+-------+
| zhangsan | 4000 |
| lisi | 1000 |
+----------+-------+
2 rows in set (0.01 sec)

mysql> #再次开启事务,体现事务的原子特性
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> #先给张三加500
mysql> update a2 set money = money + 500 where uname='zhangsan';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> #接下来,扣李四500,但失败了.
mysql> #我故意把表名打错,模拟网络故障等失败情景
mysql> update a2 set moneys = money -500 where uname='lisi';
ERROR 1054 (42S22): Unknown column 'moneys' in 'field list'
mysql> #扣李四的钱失败.
mysql> #整体的转账操作,从逻辑上讲,应该失败,即张三的钱,不能多500
mysql> #部分失败,则之前的成功操作怎么处理? 答: 回滚
mysql> rollback;
Query OK, 0 rows affected (0.06 sec)

mysql> #一致性
mysql> #是指操作前后,值的变化,逻辑上成立
mysql> # -500, +300,这样不行.
mysql> #比如, tinyint来存钱,+300,溢出了. 也是失败.
mysql> #隔离性
mysql>
mysql> #黑窗口是柜台,查看事务的隔离性
mysql> #开启事务
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update a2 set money = money + 500 where uname='zhangsan';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> #现在李四的钱还没减少,电话张三,让他收到的500元全取出来.
mysql> #这个事务还没结束,ATM上,张三根本看不到自己的500块.
mysql> update a2 set moneys = money -500 where uname='lisi';
ERROR 1054 (42S22): Unknown column 'moneys' in 'field list'
mysql> update a2 set money = money -500 where uname='lisi';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> #提交事务,同时事务也就完成并结束了.
mysql> commit;
Query OK, 0 rows affected (0.05 sec)

mysql> #持久性
mysql>
mysql> #再来看a1,myisam表
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update a2 set money = money + 500 where uname='zhangsan';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> rollback;
Query OK, 0 rows affected (0.06 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update a1 set money = money + 500 where uname='zhangsan';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> rollback;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> #myisam表,隔离性就没达到
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update a1 set money = money + 500 where uname='zhangsan';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> rollback;
Query OK, 0 rows affected, 1 warning (0.00 sec)

 

posted on 2012-11-03 11:33  besile  阅读(546)  评论(0编辑  收藏  举报