4. static有什么用途?(请至少说明两种)
1.限制变量的作用域
2.设置变量的存储域
7. 引用与指针有什么区别?
1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
2) 不存在指向空值的引用,但是存在指向空值的指针。
8. 描述实时系统的基本特性
在特定时间内完成特定的任务,实时性与可靠性
9. 全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
全局变量储存在静态数据库,局部变量在堆栈
10. 什么是平衡二叉树?
左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1
11. 堆栈溢出一般是由什么原因导致的?
没有回收垃圾资源
12. 什么函数不能声明为虚函数?
constructor
13. 冒泡排序算法的时间复杂度是什么?
O(n^2)
14. 写出float x 与“零值”比较的if语句。
if(x>0.000001&&x<-0.000001)
16. Internet采用哪种网络协议?该协议的主要层次结构?
tcp/ip 应用层/传输层/网络层/数据链路层/物理层
17. Internet物理地址和IP地址转换采用什么协议?
ARP (Address Resolution Protocol)(地址解析协议)
18.IP地址的编码分为哪俩部分?
IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。
2.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。
循环链表,用取余操作做
3.不能做switch()的参数类型是:
switch的参数不能为实型。
华为
阅读全文
1.限制变量的作用域
2.设置变量的存储域
7. 引用与指针有什么区别?
1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
2) 不存在指向空值的引用,但是存在指向空值的指针。
8. 描述实时系统的基本特性
在特定时间内完成特定的任务,实时性与可靠性
9. 全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
全局变量储存在静态数据库,局部变量在堆栈
10. 什么是平衡二叉树?
左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1
11. 堆栈溢出一般是由什么原因导致的?
没有回收垃圾资源
12. 什么函数不能声明为虚函数?
constructor
13. 冒泡排序算法的时间复杂度是什么?
O(n^2)
14. 写出float x 与“零值”比较的if语句。
if(x>0.000001&&x<-0.000001)
16. Internet采用哪种网络协议?该协议的主要层次结构?
tcp/ip 应用层/传输层/网络层/数据链路层/物理层
17. Internet物理地址和IP地址转换采用什么协议?
ARP (Address Resolution Protocol)(地址解析协议)
18.IP地址的编码分为哪俩部分?
IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。
2.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。
循环链表,用取余操作做
3.不能做switch()的参数类型是:
switch的参数不能为实型。
华为

http://blog.chinaunix.net/u2/74524/showart_1137527.html
tftp服务的安装,对于RedHat9.0,tftp 的RPM包在安装光盘的第三张盘下,可以用mount /dev/cdrom mnt/cdrom 将其挂载后,拷贝到/home/work目录下
安装
rpm -ivh tftp-server-0.32********
rpm -ivh tftp-0.32*******(这个包是客户端登陆tftp服务器所需要的)
安装完后,进行配置及开启服务
在linux下,不管使用的是哪一种super-server,inetd或者xinetd,默认情况下TFTP服务是禁用的,所以要修改文件来开启服务。
切换到cd /etc目录下
打开tftp服务的配置文件
命令为emacs xinedt.d/tftp
修改后的文件如下:
对应的部分参数说明
修改项server_args= -s <path> -c,其中<path>处可以改为你的tftp-server的根目录,参数-s指定chroot,-c指定了可以创建文件
保存后退出
切换目录 cd /home/work
建立tftp的启动目录 tftpboot
mkdir tftpboot
然后重新开启tftp服务
命令为:service xinetd restart
这样,tftp-server就启动了。
你可以用查询命令看tftp服务是否开启
netstat -a | grep tftp
显示结果为
udp 0 0 *:tftp *:*
表明服务已经开启
你可以登陆本机测试以下,命令如下:
#tftp your-ip-address
tftp>get <download file>
tftp>put <upload file>
tftp>q
这样你就在linux下建立了tftp服务器,u-boot可以直接登录到你的主机上了,不用再切换到windows下用tftpd32.exe来建立服务器了。
安装
rpm -ivh tftp-server-0.32********
rpm -ivh tftp-0.32*******(这个包是客户端登陆tftp服务器所需要的)
安装完后,进行配置及开启服务
在linux下,不管使用的是哪一种super-server,inetd或者xinetd,默认情况下TFTP服务是禁用的,所以要修改文件来开启服务。
切换到cd /etc目录下
打开tftp服务的配置文件
命令为emacs xinedt.d/tftp
修改后的文件如下:
service tftp
{ socket_type =dgram
protocol =udp
wait =yes
user =root
server =/usr/sbin/in.tftpd
server_args =-s /home/work/tftpboot -c
disable =no
per_source =11
cps =100 2
flags =IPv4
}
{ socket_type =dgram
protocol =udp
wait =yes
user =root
server =/usr/sbin/in.tftpd
server_args =-s /home/work/tftpboot -c
disable =no
per_source =11
cps =100 2
flags =IPv4
}
对应的部分参数说明
修改项server_args= -s <path> -c,其中<path>处可以改为你的tftp-server的根目录,参数-s指定chroot,-c指定了可以创建文件
保存后退出
切换目录 cd /home/work
建立tftp的启动目录 tftpboot
mkdir tftpboot
然后重新开启tftp服务
命令为:service xinetd restart
这样,tftp-server就启动了。
你可以用查询命令看tftp服务是否开启
netstat -a | grep tftp
显示结果为
udp 0 0 *:tftp *:*
表明服务已经开启
你可以登陆本机测试以下,命令如下:
#tftp your-ip-address
tftp>get <download file>
tftp>put <upload file>
tftp>q
这样你就在linux下建立了tftp服务器,u-boot可以直接登录到你的主机上了,不用再切换到windows下用tftpd32.exe来建立服务器了。
第一题:两个运放,一个同相连的,一个反相连的,求输入与输出的关系,这个不难,一会就出来了,搞定10分;
第二题:好像是模电书上的一个,有关三极管饱和截止的,提出了输出电压与电流的要求,求两个电阻的取值;做是做了,但不知对不对,也没把握,10分
第三题:高频当中的,一个电阻与电容的串联将其等效为电阻与电容的并联,要求推导,不会;这个后来回来和同学说,他们还说是一个作业题,高频课基本上没听,这个就没戏了。
第四题:两个运放,有反馈,连接是一个的输入是另一个的输入,输出是另一个的输入,中间还有些电阻,求放大倍数与输入阻抗,不会做;
第五题:用555定时器搭建的多谐振荡器,充放电时间由555中的三极管的截止与饱和来控制时间不一样,第一问填很多空,5分;第二问画参考电压,图像3分,第三问要求求充放电时间了,也就是周期,三要素法记不住公式了,基本没戏了,12分,这问做不上;
第六题:用51单片机的P0口的三个端口来控制74HC595(移位寄存器)来控制一个数码管从0显示到9,要求肉眼能看清变化,数码管是共阴的。
这个没问题,搞定,不过刚开始写程序时,没有把数码管的0~9的码表写上去,后来交卷后发现忘了,就用了定义了一个空数组,留在那没写。
第七题:C语言的数据结构题,FIFO,前两问简单,第三问记不清了,但是也没去做了。
第二题:好像是模电书上的一个,有关三极管饱和截止的,提出了输出电压与电流的要求,求两个电阻的取值;做是做了,但不知对不对,也没把握,10分
第三题:高频当中的,一个电阻与电容的串联将其等效为电阻与电容的并联,要求推导,不会;这个后来回来和同学说,他们还说是一个作业题,高频课基本上没听,这个就没戏了。
第四题:两个运放,有反馈,连接是一个的输入是另一个的输入,输出是另一个的输入,中间还有些电阻,求放大倍数与输入阻抗,不会做;
第五题:用555定时器搭建的多谐振荡器,充放电时间由555中的三极管的截止与饱和来控制时间不一样,第一问填很多空,5分;第二问画参考电压,图像3分,第三问要求求充放电时间了,也就是周期,三要素法记不住公式了,基本没戏了,12分,这问做不上;
第六题:用51单片机的P0口的三个端口来控制74HC595(移位寄存器)来控制一个数码管从0显示到9,要求肉眼能看清变化,数码管是共阴的。
这个没问题,搞定,不过刚开始写程序时,没有把数码管的0~9的码表写上去,后来交卷后发现忘了,就用了定义了一个空数组,留在那没写。
第七题:C语言的数据结构题,FIFO,前两问简单,第三问记不清了,但是也没去做了。
添加到whell组有两种方式:
1.修改在/etc/passwd
或者:vipw 将组改成0
找不到则:whereis vipw
cd到目录然后:vipw即可!
2.visudo
whereis visudo
然后:
# User alias specification
User_Alias USER_G01 = yunfeng,hongliang1,mazhen,jianxin,xubin,xiangdong2
关于进入Mysql:
mysql> show databases'
'> ;
'>
由于'没有闭合,再输入';即可推出到:
mysql>(Ctrl+z)
terminal:
0> jobs -l
[1] 7787 Stopped mysql -h10.69.3.198 -P4406 -uqwe -p123 -A relation
[2] 8082 Stopped mysql -h10.69.3.198 -P4406 -uqwe -p123 -A relation
fg 1 or 2 回去!
1.修改在/etc/passwd
或者:vipw 将组改成0
找不到则:whereis vipw
cd到目录然后:vipw即可!
2.visudo
whereis visudo
然后:
# User alias specification
User_Alias USER_G01 = yunfeng,hongliang1,mazhen,jianxin,xubin,xiangdong2
关于进入Mysql:
mysql> show databases'
'> ;
'>
由于'没有闭合,再输入';即可推出到:
mysql>(Ctrl+z)
terminal:
0> jobs -l
[1] 7787 Stopped mysql -h10.69.3.198 -P4406 -uqwe -p123 -A relation
[2] 8082 Stopped mysql -h10.69.3.198 -P4406 -uqwe -p123 -A relation
fg 1 or 2 回去!
并发编程:
———————————————————————————————————————————————————————————
最近有个项目需要用file_put_contents函数写txt文件,由于需要频繁操作,所以经常出现前半截内容缺失的情况,非常苦恼。
后来查询资料发现,file_put_contents函数有个参数LOCK_EX非常有用,加上它之后,再也没有出现过内容缺失的情况了。
这个参数LOCK_EX的意思很直白,就是写文件时,先锁上这个文件,这样只允许某个客户端访问的时候写,其他客户端访问不能写了。
我的用法如下:
file_put_contents($file, $content, FILE_APPEND|LOCK_EX)
解释:
$file=>这个是写入文件的路径+文件名
$content=>这个是写入文件的内容
FILE_APPEND=>直接在该文件已有的内容后面追加内容
LOCK_EX=>写文件的时候先锁定,防止多人同时写入造成内容丢失
摘自:http://www.wyxuan.com/184.html
————————————————————————————————————————————————————————————————
PHP file_put_contents() 函数 写入txt文本函数:
定义和用法
file_put_contents() 函数把一个字符串写入文件中。
与依次调用 fopen(),fwrite() 以及 fclose() 功能一样。
语法
file_put_contents(file,data,mode,context)
参数 描述
file 必需。规定要写入数据的文件。如果文件不存在,则创建一个新文件。
data 可选。规定要写入文件的数据。可以是字符串、数组或数据流。
mode
可选。规定如何打开/写入文件。可能的值:
FILE_USE_INCLUDE_PATH
FILE_APPEND
LOCK_EX
context
可选。规定文件句柄的环境。
context 是一套可以修改流的行为的选项。若使用 null,则忽略。
说明
参数 data 可以是数组(但不能是多维数组)。
自 PHP 5.1.0 起,data 参数也可以被指定为 stream 资源,stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。
对 context 参数的支持是 PHP 5.0.0 添加的。
返回值
该函数将返回写入到文件内数据的字节数。
提示和注释
提示:使用 FILE_APPEND 可避免删除文件中已有的内容。
注释:本函数可安全用于二进制对象。
例子
<?php
echo file_put_contents("test.txt","Hello World. Testing!");
?>
输出:
26
说明
参数 data 可以是数组(但不能是多维数组)。
自 PHP 5.1.0 起,data 参数也可以被指定为 stream 资源,stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。
对 context 参数的支持是 PHP 5.0.0 添加的。
返回值
该函数将返回写入到文件内数据的字节数。
提示和注释
提示:使用 FILE_APPEND 可避免删除文件中已有的内容。
注释:本函数可安全用于二进制对象。
来自:http://blog.sina.com.cn/s/blog_88441e630100tj60.html
<?php
//pup5新支持功能file_put_contents()
$content = '你好';
file_put_contents('file.txt',$content);
//file_put_contents($curl_url_info["error_log_file"],$url_get_str,FILE_APPEND);
//FILE_APPEND 追加写。。。
//输出json格式数据
$hello = array('1','2','3');
$helloJson = json_encode($hello);
//print_r($helloJson);
//exit;
echo <<<eot
<script language="JavaScript" type="text/JavaScript">
//在javascript中新建一个对象json_js,输出的代码为var json_js = ["1","2","3"];
var json_js = $helloJson;
//看看效果
//弹出窗口显示1
alert(json_js[0]);
alert(json_js[1]);
</script>
eot;
?>
//pup5新支持功能file_put_contents()
$content = '你好';
file_put_contents('file.txt',$content);
//file_put_contents($curl_url_info["error_log_file"],$url_get_str,FILE_APPEND);
//FILE_APPEND 追加写。。。
//输出json格式数据
$hello = array('1','2','3');
$helloJson = json_encode($hello);
//print_r($helloJson);
//exit;
echo <<<eot
<script language="JavaScript" type="text/JavaScript">
//在javascript中新建一个对象json_js,输出的代码为var json_js = ["1","2","3"];
var json_js = $helloJson;
//看看效果
//弹出窗口显示1
alert(json_js[0]);
alert(json_js[1]);
</script>
eot;
?>
———————————————————————————————————————————————————————————
最近有个项目需要用file_put_contents函数写txt文件,由于需要频繁操作,所以经常出现前半截内容缺失的情况,非常苦恼。
后来查询资料发现,file_put_contents函数有个参数LOCK_EX非常有用,加上它之后,再也没有出现过内容缺失的情况了。
这个参数LOCK_EX的意思很直白,就是写文件时,先锁上这个文件,这样只允许某个客户端访问的时候写,其他客户端访问不能写了。
我的用法如下:
file_put_contents($file, $content, FILE_APPEND|LOCK_EX)
解释:
$file=>这个是写入文件的路径+文件名
$content=>这个是写入文件的内容
FILE_APPEND=>直接在该文件已有的内容后面追加内容
LOCK_EX=>写文件的时候先锁定,防止多人同时写入造成内容丢失
摘自:http://www.wyxuan.com/184.html
————————————————————————————————————————————————————————————————
PHP file_put_contents() 函数 写入txt文本函数:
定义和用法
file_put_contents() 函数把一个字符串写入文件中。
与依次调用 fopen(),fwrite() 以及 fclose() 功能一样。
语法
file_put_contents(file,data,mode,context)
参数 描述
file 必需。规定要写入数据的文件。如果文件不存在,则创建一个新文件。
data 可选。规定要写入文件的数据。可以是字符串、数组或数据流。
mode
可选。规定如何打开/写入文件。可能的值:
FILE_USE_INCLUDE_PATH
FILE_APPEND
LOCK_EX
context
可选。规定文件句柄的环境。
context 是一套可以修改流的行为的选项。若使用 null,则忽略。
说明
参数 data 可以是数组(但不能是多维数组)。
自 PHP 5.1.0 起,data 参数也可以被指定为 stream 资源,stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。
对 context 参数的支持是 PHP 5.0.0 添加的。
返回值
该函数将返回写入到文件内数据的字节数。
提示和注释
提示:使用 FILE_APPEND 可避免删除文件中已有的内容。
注释:本函数可安全用于二进制对象。
例子
<?php
echo file_put_contents("test.txt","Hello World. Testing!");
?>
输出:
26
说明
参数 data 可以是数组(但不能是多维数组)。
自 PHP 5.1.0 起,data 参数也可以被指定为 stream 资源,stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。
对 context 参数的支持是 PHP 5.0.0 添加的。
返回值
该函数将返回写入到文件内数据的字节数。
提示和注释
提示:使用 FILE_APPEND 可避免删除文件中已有的内容。
注释:本函数可安全用于二进制对象。
来自:http://blog.sina.com.cn/s/blog_88441e630100tj60.html
1.新加通过curl的参数就知道是不是有bom在http头
2.对svn里加入 钩子来去掉里面的bom头。
3.对shell怎么去掉bom进行了摘录。 2013-08-14
一同事在输出XML的时候在firefox下没有问题,在IE下提示:
文档的顶层无效。处理资源 'http://public.sina.com.cn/message/program/application/1.php?uid=1&group=0&status=2&charset=utf-8&datatype=xm...
<?xml version="1.0" encoding="UTF-8"?>
^
蒙了,我找了整个她的哪个输出的php程序,都没有发现问题,但是在我将源代码保存后,通过editplus查看的时候,发现前面有一个不明飞行物,于是经过一步一步的调试发现原来在底层的数据层有一个utf8编码的bom,通过editplus看不出来,通过zend for eclipse6.1.*也看不出来,但是可以通过vi zend studio看到这个玩意!
vi 看到: <feff>
zend studio:看到一个小点。。。
zend studio 通过gbk编码:出现: 锘�
这种问题可以通过:notepad++ 的转换功能给转换为没有bom即可,完毕!
再次追溯原因:
通过svn查到,其出现这个原因是由于以下步骤操作导致的:
1.用记事本建立一个ansi的文本文件为phptest.php ,写入<?php ?>用zend studio打开没有发现问题。
2.然后通过记事本打开,另存为utf-8.用zend studio打开发现问题,<?php 前面出现 锘� (GBK编码打开是这样,设为uft-8后出现一个小点。。。)。
总结:
最后,我用记事本建立ansi文件,然后写入<?php ?>,再用editplus打开,然后通过另存为utf8,没有发现改问题,看来确实是记事本的问题!
最好用editplus建立utf8文件,谢谢!
如有bom输出会在setcookie的时候出现下面错误:Cannot modify header information - headers already sent by ....
如果在setcookie之前输出了任何文本内容,便会有上述错误提示。由于页面头部require了若干文件,一行行排查是很麻烦的事情!
解决方法如下:
我在该页面顶部加上:
在setcookie之前加上代码:
这是为了获取setcookie之前页面输出的内容。页面运行后,显示输出了一个空字符串,也就是说,setcookie之前没有任何输出。
避免方法:用vim打开了源文件,发觉vim有打开bomb选项,怀疑因此给代码添加了隐藏的字符串,关闭之: set nobomb
http://hi.baidu.com/jimmyhouse/blog/item/247dd517bb77040fc83d6d2f.html
http://www.phpq.net/research/php-utf8-bom.html
http://www.phpchina.com/html/80/t-37580.html
工作心得
对于上次邮件里面讨论到的PHP BOM问题,我来说来句就当心得吧,其实这个BOM问题一直在我们进行开发的时候经常出现,前些日子在企业邮箱里面第一次遇到这个问题,当时好像是企业的图标LOGO没有办法显示出来,因为<img src="img.php">,是img.php去读一个图片的内容然后给img显示,经过长仔细排查出现在输出图片资源前就有输出,那时候用的是notepad+editplus,最后用Zend studio来看这个文件头出现一个锘�字,证明了该问题。
第二次遇到BOM问题,是陈鑫鑫在纸条项目里面输出XML数据到IE浏览器中展现出现XML错误。
第三次也就是我们的记录APP调用外部接口返回用户的昵称出现乱码,经琳琳查也由BOM造成!
为何经常出现这种类似的问题,我看大家都在按照自己的方式来建立和开发PHP,特别是用Notepad来新建文件,系统默认在是ANSI格式,但我们的PHP编码是UTF-8的,于是又通过Notepad的另存为修改为UTF-8格式的,这样也就产生了一个BOM,最后,再用现在统一的开发工具Zend for eclipse去编辑这个带BOM的PHP文件,但BOM依然存在文件当中,它一般是表现不出任何问题,但一旦在页面前不能有输出的情况:如上面我遇到的三种情况它也就显现出来了。
BOM如此讨厌,该如何避免:
建议:
1. 切实统一开发工具:统一用Zend for eclipse 来新建PHP文件,和修改PHP文件编码!
2. 在项目完成后对目录里面所有的PHP 文件进行遍历驱出有可能出现的BOM。如:用sed批量替换掉bom:(syscore目录和所有下级目录的PHP文件替换)
补充:
bluexchen(陈胜益) 17:44:39
一:
用Shell如何清除一个目录下所有带BOM的文件中的BOM信息:
在Linux下的SVN中的文件,可能由于开发人员的编辑器的问题,上传上来后的文件带有utf8的BOM,会造成页面访问的问题,现在需要一个shell命令,一键清除一个目录下所有带BOM的文件中的BOM信息。
grep -r -I -l $'^\xEF\xBB\xBF' /path | xargs sed -i 's/^\xEF\xBB\xBF//g'
来自:http://www.dewen.org/q/4111
二:
使用Shell去除BOM:
发现有些文档在Shell下面处理的时候,第一个字节总是无法正常显示,出现乱码. 后来发现原来是BOM在作怪,BOM一共占用了3个字节. 通过UE可以在保存的时候,选择不保存BOM来去除.
但是我既然是在Linux下面做处理,为什么不直接通过Shell脚本来处理呢.查了资料之后发现下面的命令可以实现.
echo -ne '\xef\xbb\xbf123456' | awk '{if(NR==1)sub(/^\xef\xbb\xbf/,""); print}'
-ne是确保可以打印出16进制
\xef\xbb\xbf是UTF8 BOM的16进制表示
awk 后面命令意思就是,如果第一行是以UTF8 的BOM开头,则去除
BOM的详细解释
http://www.cnblogs.com/chengmo/archive/2010/10/30/1864004.html
来自:http://flyfoxs.iteye.com/blog/1485713
shell> curl -s http://phone.10086.cn/ | head -1 | sed -n l
\357\273\277<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional\
//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r$
如上所示,前三个字节分别是357、273、277,这就是八进制的BOM。
curl -s http://phone.10086.cn/ | head -1 | hexdump -C
00000000 ef bb bf 3c 21 44 4f 43 54 59 50 45 20 68 74 6d |...<!DOCTYPE htm|
00000010 6c 20 50 55 42 4c 49 43 20 22 2d 2f 2f 57 33 43 |l PUBLIC "-//W3C|
00000020 2f 2f 44 54 44 20 58 48 54 4d 4c 20 31 2e 30 20 |//DTD XHTML 1.0 |
00000030 54 72 61 6e 73 69 74 69 6f 6e 61 6c 2f 2f 45 4e |Transitional//EN|
00000040 22 20 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33 |" "http://www.w3|
00000050 2e 6f 72 67 2f 54 52 2f 78 68 74 6d 6c 31 2f 44 |.org/TR/xhtml1/D|
00000060 54 44 2f 78 68 74 6d 6c 31 2d 74 72 61 6e 73 69 |TD/xhtml1-transi|
00000070 74 69 6f 6e 61 6c 2e 64 74 64 22 3e 0d 0a |tional.dtd">..|
如上所示,前三个字节分别是EF、BB、BF,这就是十六进制的BOM。
注:用到了第三方网站的页面,不能保证例子始终可用。 实际做项目开发时,可能会面对成百上千个文本文件,如果有几个文件混入了BOM,那么很难察觉,如果没有带BOM的UTF-8文本文件,可以用vi杜撰几个,相关命令如下:
设置UTF-8编码:
:set fileencoding=utf-8
添加BOM:
:set bomb
删除BOM:
:set nobomb
查询BOM:
:set bomb?
如何检测UTF-8编码中的BOM呢?
shell> grep -r -I -l $'^\xEF\xBB\xBF' /path
如何删除UTF-8编码中的BOM呢?
shell> grep -r -I -l $'^\xEF\xBB\xBF' /path | xargs sed -i 's/^\xEF\xBB\xBF//;q'
推荐:如果你使用SVN的话,可以在pre-commit钩子里加上相关代码用以杜绝BOM。
#!/bin/bash
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
for FILE in $($SVNLOOK changed -t "$TXN" "$REPOS" | awk '/^[AU]/ {print $NF}'); do
if $SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | grep -q $'^\xEF\xBB\xBF'; then
echo "Byte Order Mark be found in $FILE" 1>&2
exit 1
fi
done
来自:http://huoding.com/2011/05/14/78
2.对svn里加入 钩子来去掉里面的bom头。
3.对shell怎么去掉bom进行了摘录。 2013-08-14
一同事在输出XML的时候在firefox下没有问题,在IE下提示:
文档的顶层无效。处理资源 'http://public.sina.com.cn/message/program/application/1.php?uid=1&group=0&status=2&charset=utf-8&datatype=xm...
<?xml version="1.0" encoding="UTF-8"?>
^
蒙了,我找了整个她的哪个输出的php程序,都没有发现问题,但是在我将源代码保存后,通过editplus查看的时候,发现前面有一个不明飞行物,于是经过一步一步的调试发现原来在底层的数据层有一个utf8编码的bom,通过editplus看不出来,通过zend for eclipse6.1.*也看不出来,但是可以通过vi zend studio看到这个玩意!
vi 看到: <feff>
zend studio:看到一个小点。。。
zend studio 通过gbk编码:出现: 锘�
这种问题可以通过:notepad++ 的转换功能给转换为没有bom即可,完毕!
再次追溯原因:
通过svn查到,其出现这个原因是由于以下步骤操作导致的:
1.用记事本建立一个ansi的文本文件为phptest.php ,写入<?php ?>用zend studio打开没有发现问题。
2.然后通过记事本打开,另存为utf-8.用zend studio打开发现问题,<?php 前面出现 锘� (GBK编码打开是这样,设为uft-8后出现一个小点。。。)。
总结:
最后,我用记事本建立ansi文件,然后写入<?php ?>,再用editplus打开,然后通过另存为utf8,没有发现改问题,看来确实是记事本的问题!
最好用editplus建立utf8文件,谢谢!
如有bom输出会在setcookie的时候出现下面错误:Cannot modify header information - headers already sent by ....
如果在setcookie之前输出了任何文本内容,便会有上述错误提示。由于页面头部require了若干文件,一行行排查是很麻烦的事情!
解决方法如下:
我在该页面顶部加上:
ob_start();
在setcookie之前加上代码:
ob_get_clean();
这是为了获取setcookie之前页面输出的内容。页面运行后,显示输出了一个空字符串,也就是说,setcookie之前没有任何输出。
避免方法:用vim打开了源文件,发觉vim有打开bomb选项,怀疑因此给代码添加了隐藏的字符串,关闭之: set nobomb
http://hi.baidu.com/jimmyhouse/blog/item/247dd517bb77040fc83d6d2f.html
http://www.phpq.net/research/php-utf8-bom.html
http://www.phpchina.com/html/80/t-37580.html
工作心得
对于上次邮件里面讨论到的PHP BOM问题,我来说来句就当心得吧,其实这个BOM问题一直在我们进行开发的时候经常出现,前些日子在企业邮箱里面第一次遇到这个问题,当时好像是企业的图标LOGO没有办法显示出来,因为<img src="img.php">,是img.php去读一个图片的内容然后给img显示,经过长仔细排查出现在输出图片资源前就有输出,那时候用的是notepad+editplus,最后用Zend studio来看这个文件头出现一个锘�字,证明了该问题。
第二次遇到BOM问题,是陈鑫鑫在纸条项目里面输出XML数据到IE浏览器中展现出现XML错误。
第三次也就是我们的记录APP调用外部接口返回用户的昵称出现乱码,经琳琳查也由BOM造成!
为何经常出现这种类似的问题,我看大家都在按照自己的方式来建立和开发PHP,特别是用Notepad来新建文件,系统默认在是ANSI格式,但我们的PHP编码是UTF-8的,于是又通过Notepad的另存为修改为UTF-8格式的,这样也就产生了一个BOM,最后,再用现在统一的开发工具Zend for eclipse去编辑这个带BOM的PHP文件,但BOM依然存在文件当中,它一般是表现不出任何问题,但一旦在页面前不能有输出的情况:如上面我遇到的三种情况它也就显现出来了。
BOM如此讨厌,该如何避免:
建议:
1. 切实统一开发工具:统一用Zend for eclipse 来新建PHP文件,和修改PHP文件编码!
2. 在项目完成后对目录里面所有的PHP 文件进行遍历驱出有可能出现的BOM。如:用sed批量替换掉bom:(syscore目录和所有下级目录的PHP文件替换)
find ./syscore -type f -name "*.php" -exec sed -i '1s/^\xef\xbb\xbf//' {} \;
<?
//此文件用于快速测试UTF8编码的文件是不是加了BOM,并可自动移除
//By Bob Shen
$basedir="./paper/tech/trunk/message"; //修改此行为需要检测的目录,点表示当前目录
$auto=0; //是否自动移除发现的BOM信息。1为是,0为否。
//以下不用改动
if ($dh = opendir($basedir)) {
while (($file = readdir($dh)) !== false) {
if ($file!='.' && $file!='..' && !is_dir($basedir."/".$file)) echo "filename: $file ".checkBOM("$basedir/$file")." <br>";
}
closedir($dh);
}
function checkBOM ($filename) {
global $auto;
$contents=file_get_contents($filename);
$charset[1]=substr($contents, 0, 1);
$charset[2]=substr($contents, 1, 1);
$charset[3]=substr($contents, 2, 1);
if (ord($charset[1])==239 && ord($charset[2])==187 && ord($charset[3])==191) {
if ($auto==1) {
$rest=substr($contents, 3);
rewrite ($filename, $rest);
return ("<font color=red>BOM found, automatically removed.</font>");
} else {
return ("<font color=red>包含BOM</font>");
}
}
else return ("未发现BOM");
}
function rewrite ($filename, $data) {
$filenum=fopen($filename,"w");
flock($filenum,LOCK_EX);
fwrite($filenum,$data);
fclose($filenum);
}
?>
//此文件用于快速测试UTF8编码的文件是不是加了BOM,并可自动移除
//By Bob Shen
$basedir="./paper/tech/trunk/message"; //修改此行为需要检测的目录,点表示当前目录
$auto=0; //是否自动移除发现的BOM信息。1为是,0为否。
//以下不用改动
if ($dh = opendir($basedir)) {
while (($file = readdir($dh)) !== false) {
if ($file!='.' && $file!='..' && !is_dir($basedir."/".$file)) echo "filename: $file ".checkBOM("$basedir/$file")." <br>";
}
closedir($dh);
}
function checkBOM ($filename) {
global $auto;
$contents=file_get_contents($filename);
$charset[1]=substr($contents, 0, 1);
$charset[2]=substr($contents, 1, 1);
$charset[3]=substr($contents, 2, 1);
if (ord($charset[1])==239 && ord($charset[2])==187 && ord($charset[3])==191) {
if ($auto==1) {
$rest=substr($contents, 3);
rewrite ($filename, $rest);
return ("<font color=red>BOM found, automatically removed.</font>");
} else {
return ("<font color=red>包含BOM</font>");
}
}
else return ("未发现BOM");
}
function rewrite ($filename, $data) {
$filenum=fopen($filename,"w");
flock($filenum,LOCK_EX);
fwrite($filenum,$data);
fclose($filenum);
}
?>
<?php
/*
查找一个目录里面的UTF-8 Born 头
用法
/opt/bin/php GetUtf8Born.php {dir}
例如
/opt/bin/php GetUtf8Born.php /opt/www/
*/
$is_fix_file = 1; //定义是否修复文件 1 为不修复 2 为修复
$d = $_SERVER['argv'][1];
if (!is_dir($d)) exit("Not Dir\n");
$shell = "/usr/bin/find $d -type f";
$r = exec($shell, $s_r);
if(!empty($s_r))
{
foreach($s_r as $file)
{
if(GetBorn($file))
{
echo $file . "\n";
if($is_fix_file == 2)
{
FixBorn($file);
}
}
}
}
exit;
function FixBorn($file)
{
if(!is_file($file))
{
return false;
}
$file_base_name = basename($file);
$file_path = dirname($file);
$r = ReadF($file, $file_string);
if(!$r)
{
return false;
}
//Utf-8 头占用3个字符占位 去掉即可
$new_string = substr($file_string, 3);
//开始备份文件
if (!copy($file, $file_path . "/Utf8Bom_" . $file_base_name))
{
return false;
}
// 写入新文件
if(!WriteF($file, $new_string))
{
return false;
}
return true;
}
function ReadF($file, &$string)
{
$fp = fopen($file, "r");
if(!$fp)
{
return false;
}
while (!feof ($fp))
{
$string .= fgets($fp, 1024);
}
fclose($fp);
return true;
}
function WriteF($file, $string)
{
$fp = fopen($file, "w+");
if(!$fp || !is_writable($file))
{
return false;
}
if (!fwrite($fp, $string))
{
return false;
}
fclose($fp);
return true;
}
function GetBorn($file)
{
if(!is_file($file))
{
return false;
}
$fp = fopen($file, "r");
$s = fgets($fp, 64);
fclose($fp);
$s = trim(bin2hex($s));
//if (strpos($s, "efbbbf") !== false)
if (substr($s, 0, 6) == "efbbbf")
{
return true;
}
return false;
}
?>
/*
查找一个目录里面的UTF-8 Born 头
用法
/opt/bin/php GetUtf8Born.php {dir}
例如
/opt/bin/php GetUtf8Born.php /opt/www/
*/
$is_fix_file = 1; //定义是否修复文件 1 为不修复 2 为修复
$d = $_SERVER['argv'][1];
if (!is_dir($d)) exit("Not Dir\n");
$shell = "/usr/bin/find $d -type f";
$r = exec($shell, $s_r);
if(!empty($s_r))
{
foreach($s_r as $file)
{
if(GetBorn($file))
{
echo $file . "\n";
if($is_fix_file == 2)
{
FixBorn($file);
}
}
}
}
exit;
function FixBorn($file)
{
if(!is_file($file))
{
return false;
}
$file_base_name = basename($file);
$file_path = dirname($file);
$r = ReadF($file, $file_string);
if(!$r)
{
return false;
}
//Utf-8 头占用3个字符占位 去掉即可
$new_string = substr($file_string, 3);
//开始备份文件
if (!copy($file, $file_path . "/Utf8Bom_" . $file_base_name))
{
return false;
}
// 写入新文件
if(!WriteF($file, $new_string))
{
return false;
}
return true;
}
function ReadF($file, &$string)
{
$fp = fopen($file, "r");
if(!$fp)
{
return false;
}
while (!feof ($fp))
{
$string .= fgets($fp, 1024);
}
fclose($fp);
return true;
}
function WriteF($file, $string)
{
$fp = fopen($file, "w+");
if(!$fp || !is_writable($file))
{
return false;
}
if (!fwrite($fp, $string))
{
return false;
}
fclose($fp);
return true;
}
function GetBorn($file)
{
if(!is_file($file))
{
return false;
}
$fp = fopen($file, "r");
$s = fgets($fp, 64);
fclose($fp);
$s = trim(bin2hex($s));
//if (strpos($s, "efbbbf") !== false)
if (substr($s, 0, 6) == "efbbbf")
{
return true;
}
return false;
}
?>
补充:
bluexchen(陈胜益) 17:44:39
<?php
$aa = headers_sent();
var_dump($aa);
session_start();
if (isset($_SESSION['test_sess'])){
$_SESSION['test_sess']++;
}else{
$_SESSION['test_sess'] = 0;
}
echo $_SESSION['test_sess'];
?>;
$aa = headers_sent();
var_dump($aa);
session_start();
if (isset($_SESSION['test_sess'])){
$_SESSION['test_sess']++;
}else{
$_SESSION['test_sess'] = 0;
}
echo $_SESSION['test_sess'];
?>;
一:
用Shell如何清除一个目录下所有带BOM的文件中的BOM信息:
在Linux下的SVN中的文件,可能由于开发人员的编辑器的问题,上传上来后的文件带有utf8的BOM,会造成页面访问的问题,现在需要一个shell命令,一键清除一个目录下所有带BOM的文件中的BOM信息。
grep -r -I -l $'^\xEF\xBB\xBF' /path | xargs sed -i 's/^\xEF\xBB\xBF//g'
来自:http://www.dewen.org/q/4111
二:
使用Shell去除BOM:
发现有些文档在Shell下面处理的时候,第一个字节总是无法正常显示,出现乱码. 后来发现原来是BOM在作怪,BOM一共占用了3个字节. 通过UE可以在保存的时候,选择不保存BOM来去除.
但是我既然是在Linux下面做处理,为什么不直接通过Shell脚本来处理呢.查了资料之后发现下面的命令可以实现.
echo -ne '\xef\xbb\xbf123456' | awk '{if(NR==1)sub(/^\xef\xbb\xbf/,""); print}'
-ne是确保可以打印出16进制
\xef\xbb\xbf是UTF8 BOM的16进制表示
awk 后面命令意思就是,如果第一行是以UTF8 的BOM开头,则去除
BOM的详细解释
http://www.cnblogs.com/chengmo/archive/2010/10/30/1864004.html
来自:http://flyfoxs.iteye.com/blog/1485713
shell> curl -s http://phone.10086.cn/ | head -1 | sed -n l
\357\273\277<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional\
//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r$
如上所示,前三个字节分别是357、273、277,这就是八进制的BOM。
curl -s http://phone.10086.cn/ | head -1 | hexdump -C
00000000 ef bb bf 3c 21 44 4f 43 54 59 50 45 20 68 74 6d |...<!DOCTYPE htm|
00000010 6c 20 50 55 42 4c 49 43 20 22 2d 2f 2f 57 33 43 |l PUBLIC "-//W3C|
00000020 2f 2f 44 54 44 20 58 48 54 4d 4c 20 31 2e 30 20 |//DTD XHTML 1.0 |
00000030 54 72 61 6e 73 69 74 69 6f 6e 61 6c 2f 2f 45 4e |Transitional//EN|
00000040 22 20 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33 |" "http://www.w3|
00000050 2e 6f 72 67 2f 54 52 2f 78 68 74 6d 6c 31 2f 44 |.org/TR/xhtml1/D|
00000060 54 44 2f 78 68 74 6d 6c 31 2d 74 72 61 6e 73 69 |TD/xhtml1-transi|
00000070 74 69 6f 6e 61 6c 2e 64 74 64 22 3e 0d 0a |tional.dtd">..|
如上所示,前三个字节分别是EF、BB、BF,这就是十六进制的BOM。
注:用到了第三方网站的页面,不能保证例子始终可用。 实际做项目开发时,可能会面对成百上千个文本文件,如果有几个文件混入了BOM,那么很难察觉,如果没有带BOM的UTF-8文本文件,可以用vi杜撰几个,相关命令如下:
设置UTF-8编码:
:set fileencoding=utf-8
添加BOM:
:set bomb
删除BOM:
:set nobomb
查询BOM:
:set bomb?
如何检测UTF-8编码中的BOM呢?
shell> grep -r -I -l $'^\xEF\xBB\xBF' /path
如何删除UTF-8编码中的BOM呢?
shell> grep -r -I -l $'^\xEF\xBB\xBF' /path | xargs sed -i 's/^\xEF\xBB\xBF//;q'
推荐:如果你使用SVN的话,可以在pre-commit钩子里加上相关代码用以杜绝BOM。
#!/bin/bash
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
for FILE in $($SVNLOOK changed -t "$TXN" "$REPOS" | awk '/^[AU]/ {print $NF}'); do
if $SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | grep -q $'^\xEF\xBB\xBF'; then
echo "Byte Order Mark be found in $FILE" 1>&2
exit 1
fi
done
来自:http://huoding.com/2011/05/14/78
private function setQueue($data,$q="MultiMsgSend") {
$str_url = 'http://10.210.71.85/send_message.php';
$data = "queuename={$q}&queuedata={$data}";
$ch_curl = curl_init ();
curl_setopt ( $ch_curl, CURLOPT_TIMEOUT, 3 );
curl_setopt ( $ch_curl, CURLOPT_HEADER, false );
curl_setopt($ch_curl,CURLOPT_POST,TRUE);
curl_setopt($ch_curl,CURLOPT_POSTFIELDS,$data);
curl_setopt ( $ch_curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch_curl, CURLOPT_URL, $str_url );
$str_return = curl_exec ( $ch_curl );
if ($str_return === false)
{
$this->setErrorNo(11);
return false;
}
curl_close ( $ch_curl );
return true;
}
$str_url = 'http://10.210.71.85/send_message.php';
$data = "queuename={$q}&queuedata={$data}";
$ch_curl = curl_init ();
curl_setopt ( $ch_curl, CURLOPT_TIMEOUT, 3 );
curl_setopt ( $ch_curl, CURLOPT_HEADER, false );
curl_setopt($ch_curl,CURLOPT_POST,TRUE);
curl_setopt($ch_curl,CURLOPT_POSTFIELDS,$data);
curl_setopt ( $ch_curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch_curl, CURLOPT_URL, $str_url );
$str_return = curl_exec ( $ch_curl );
if ($str_return === false)
{
$this->setErrorNo(11);
return false;
}
curl_close ( $ch_curl );
return true;
}
发现MySQL的explain还是很有迷惑性的。
看下面两个sql的explain,(i,j)是tt的主键
mysql> explain select * from tt where i between 3 and 5 and j = 4\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tt
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: NULL
rows: 8
Extra: Using where; Using index
1 row in set (0.00 sec)
mysql> explain select * from tt where i > 2 and i < 6 and j = 4\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tt
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 8
Extra: Using where; Using index
1 row in set (0.00 sec)
看上去如果使用了between,那么MySQL可以用的索引的两列。但仔细的研究了一下,发现实际并不是这样。between 3 and 5可以写为(i>3 or i=3) and (i<5 or i=5),是这两个等号使用了两列,而大于和小于的判断仍然是index扫描,只用了一列。
再看另一个
mysql> explain select * from tt where i in (3,4,5) and j=4\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tt
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: NULL
rows: 3
Extra: Using where; Using index
1 row in set (0.00 sec)
这个才是真正用了两列,可以看到这里估计的行数是3,而刚才两个是8。用 show status 可以看得更清楚一些:
mysql> show status like 'handler_read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
6 rows in set (0.00 sec)
mysql> select * from tt where i in (3,4,5) and j=4;
+---+---+
| i | j |
+---+---+
| 3 | 4 |
+---+---+
1 row in set (0.00 sec)
mysql> show status like 'handler_read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 4 |
| Handler_read_next | 1 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
6 rows in set (0.00 sec)
mysql> select * from tt where i between 3 and 5 and j = 4;
+---+---+
| i | j |
+---+---+
| 3 | 4 |
+---+---+
1 row in set (0.00 sec)
mysql> show status like 'handler_read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 6 |
| Handler_read_next | 10 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
6 rows in set (0.00 sec)
后一个sql中有9次read_next_key,说明做了索引扫描。
由于zend for eclipse6.1.0 没有php_memcache.dll这个动态链接库,我们在phpunit测试的时候会报找不到php_memcache类的错,于是只需要把php_memcache.dll(对应版本的:php_memcache.dll)放入:D:\Program Files\Zend\Zend Studio for Eclipse - 6.1.0\plugins\org.zend.php.debug.debugger.win32.x86_5.2.14.v20080602\resources\php5\ext\php-cgi.exe,然后修改D:\Program Files\Zend\Zend Studio for Eclipse - 6.1.0\plugins\org.zend.php.debug.debugger.win32.x86_5.2.14.v20080602\resources\php5\php.ini 加入一行:extension=php_memcache.dll ,重新启动zend for eclipse6.1.0即可!
http://blog.s135.com/apmserv/bin/5.2.6/sina/
D:\Program Files\Zend\Zend Studio for Eclipse - 6.0.1\plugins\org.zend.php.debug.debugger.win32.x86_5.2.14.v20080602\resources\php5\ext
D:\Program Files\Zend\Zend Studio for Eclipse - 6.0.1\plugins\org.zend.php.debug.debugger.win32.x86_5.2.14.v20080602\resources\php5\ext
加密日志
<?php
/**
* 倒库程序雏形,将space的数据分析后导入到现有数据库中
*
*/
class import_export
{
private $dsn="";
private $user="";
private $password="";
private $pdo="";
public function import_export($dsn,$user,$password)
{
$this->dsn = $dsn;
$this->user = $user;
$this->password = $password;
$this->pdo = new PDO($this->dsn, $this->user, $this->password);
}
public function fetch_result($query)
{
$rs = $this->pdo->query($query);
$result_arr = $rs->fetchAll();
return $result_arr;
}
public function insert($insert_sql)
{
$count = $this->pdo->exec($insert_sql);
if($count)
{
return true;
}else{
return false;
}
}
public function get_pdo_obj()
{
return $this->db;
}
public function lastInsertId()
{
return $this->pdo->lastInsertId();
}
}
?>
<?php
$time_begin = time();
$conf_array = array("db_host"=>"localhost","port"=>"3306","dbname"=>"public","user"=>"root","password"=>"");
$dsn = "mysql:host={$conf_array['db_host']};port={$conf_array['port']};dbname={$conf_array['dbname']}";
$user = $conf_array['user'];
$password = $conf_array['password'];
$pdo = new import_export($dsn,$user,$password);
for($i=1;$i<100000000000;$i++)
{
$time_end = time();
if($time_end - $time_begin >= 60)
{
exit;
}
$insert_sql = "INSERT INTO `information` ( `infoid` , `group` , `productid` , `connection` , `invitetype` , `content` , `addition` ) VALUES (NULL , '1', '2', '2', '1', '的的的的的的的的的的的的的的的的的的', '的的的的的的的的的的的的的的的的的的的的的的的的');"; //插入数据库的sql语句
$import_export2 = $pdo->insert($insert_sql);
$insert_id = $pdo->lastInsertId();
$insert_sql2 = "INSERT INTO `relation` ( `id` , `owneruid` , `otheruid` , `type` , `status` , `infoid` , `ctime` , `uniq_key` ) VALUES (NULL , '1', '2', '1', '11', $insert_id, '2008-10-02 20:30:21', '45646546456456456456456456456456465');"; //插入数据库的sql语句
$import_export2 = $pdo->insert($insert_sql2);
}
?>

查询当前数据库有哪些存储过程:
创建一个简单的存储过程
5 存储过程创建完毕,看怎么调用它
显示结果
删除存储过程:
存储过程实例:
PHP调用存储过程:
返回单个数据:
1.1:创建MySQL存储过程:
1.2:PHP调用:
返回多个数据:
2.1:创建MySQL存储过程:
2.2:PHP调用:
P.S.:以上代码执行通过环境 PHP 5.X.X + MySQL 5.X.X
下面就可以正常使用了,以下是例子程序:
mysql>show procedure status where Db='test'
创建一个简单的存储过程
mysql>create procedure hi() select 'hello';
5 存储过程创建完毕,看怎么调用它
mysql>call hi();
显示结果
mysql> call hi();
+-------+
| hello |
+-------+
| hello |
+-------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
+-------+
| hello |
+-------+
| hello |
+-------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
删除存储过程:
DROP PROCEDURE hi;
存储过程实例:
DELIMITER ||
CREATE PROCEDURE showdb( v_offset int, v_pagesize int )
BEGIN
SET @stmt = concat("SELECT * FROM `comment` ORDER BY id DESC LIMIT ",v_offset,",",v_pagesize);
PREPARE s1 FROM @stmt;
EXECUTE s1;
DEALLOCATE PREPARE s1;
END||
DELIMITER ;
CREATE PROCEDURE showdb( v_offset int, v_pagesize int )
BEGIN
SET @stmt = concat("SELECT * FROM `comment` ORDER BY id DESC LIMIT ",v_offset,",",v_pagesize);
PREPARE s1 FROM @stmt;
EXECUTE s1;
DEALLOCATE PREPARE s1;
END||
DELIMITER ;
PHP调用存储过程:
返回单个数据:
1.1:创建MySQL存储过程:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`.`proc_test` $$
CREATE PROCEDURE `test`.`proc_test` (out a int)
BEGIN
select count(*) into a from tblname;
END $$
DELIMITER ;
DROP PROCEDURE IF EXISTS `test`.`proc_test` $$
CREATE PROCEDURE `test`.`proc_test` (out a int)
BEGIN
select count(*) into a from tblname;
END $$
DELIMITER ;
1.2:PHP调用:
$db->query("CALL test.proc_test(@a)");
$res = $db->query("select @a");
$row = $res->fetch_array();
echo $row['@a'];
$res = $db->query("select @a");
$row = $res->fetch_array();
echo $row['@a'];
返回多个数据:
2.1:创建MySQL存储过程:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`.`proc_test` $$
CREATE PROCEDURE `test`.`proc_test` ()
BEGIN
select * from tbl_name;
END $$
DELIMITER ;
DROP PROCEDURE IF EXISTS `test`.`proc_test` $$
CREATE PROCEDURE `test`.`proc_test` ()
BEGIN
select * from tbl_name;
END $$
DELIMITER ;
2.2:PHP调用:
$res=$db->query("CALL test.proc_test()");
while ($arr=$res->fetch_array())
{
echo $arr["Field"] ."<br/>";
}
while ($arr=$res->fetch_array())
{
echo $arr["Field"] ."<br/>";
}
P.S.:以上代码执行通过环境 PHP 5.X.X + MySQL 5.X.X
1 define('CLIENT_MULTI_RESULTS', 131072);
2
3 $link = mysql_connect("127.0.0.1", "root", "",1,CLIENT_MULTI_RESULTS) or die("Could not connect: ".mysql_error());
2
3 $link = mysql_connect("127.0.0.1", "root", "",1,CLIENT_MULTI_RESULTS) or die("Could not connect: ".mysql_error());
下面就可以正常使用了,以下是例子程序:
1 <?php
2 define('CLIENT_MULTI_RESULTS', 131072);
3
4 $link = mysql_connect("127.0.0.1", "root", "",1,CLIENT_MULTI_RESULTS) or die("Could not connect: ".mysql_error());
5 mysql_select_db("vs") or die("Could not select database");
6 ?>
7
8 <?php
9 $result = mysql_query("call get_news_from_class_id(2)") or die("Query failed:" .mysql_error());
10 while($row = mysql_fetch_array($result, MYSQL_ASSOC))
11 {
12 $line = '<tr><td><a target = _blank href=\''.$row["url"].'\'>'.$row["title"].'('.$row["page_time"].')'.'</a></td></tr>';
14 echo $line;
15 printf("\n");
16
17 }
18 mysql_free_result($result);
19 ?>
20
21 <?php
22 mysql_close($link);
23 ?>
2 define('CLIENT_MULTI_RESULTS', 131072);
3
4 $link = mysql_connect("127.0.0.1", "root", "",1,CLIENT_MULTI_RESULTS) or die("Could not connect: ".mysql_error());
5 mysql_select_db("vs") or die("Could not select database");
6 ?>
7
8 <?php
9 $result = mysql_query("call get_news_from_class_id(2)") or die("Query failed:" .mysql_error());
10 while($row = mysql_fetch_array($result, MYSQL_ASSOC))
11 {
12 $line = '<tr><td><a target = _blank href=\''.$row["url"].'\'>'.$row["title"].'('.$row["page_time"].')'.'</a></td></tr>';
14 echo $line;
15 printf("\n");
16
17 }
18 mysql_free_result($result);
19 ?>
20
21 <?php
22 mysql_close($link);
23 ?>
最近在做一个小东西的时候,发现mysql有last_insert_id()这个函数
它的用法如下:记录下来备忘
它必需紧跟在insert 语句执行之后。
//执行insert语句先
$sql="insert into table (name1,name2,...) values('value1','values'...)";
dbx_query($db_link,$sql);
//找出最后一次插入记录的id
$select="select last_insert_id() ";
$result=dbx_query($db_link,$select);
$last_id=$result->data[0][0];
ps: $last_id=mysql_insert_id();
mysql_insert_id() 将 MySQL 内部的 C API 函数 mysql_insert_id() 的返回值转换成 long(PHP 中命名为 int)。如果 AUTO_INCREMENT 的列的类型是 BIGINT,则 mysql_insert_id() 返回的值将不正确。可以在 SQL 查询中用 MySQL 内部的 SQL 函数 LAST_INSERT_ID() 来替代。
具体的请看php手册: mysql_insert_id
来自:http://blog.csdn.net/kemy88/article/details/1108524
_____________________________________________________________________________
show table status\G
show create table message;
LAST_INSERT_ID
自动返回最后一个 INSERT 或 UPDATE 操作为 AUTO_INCREMENT 列设置的第一个发生的值. 参考这里
The ID that was generated is maintained in the server on a per-connection basis.
LAST_INSERT_ID是基于单个connection的, 不可能被其它的客户端连接改变。
可以用 SELECT LAST_INSERT_ID(); 查询LAST_INSERT_ID的值.
Important: If you insert multiple rows using a single INSERT statement, LAST_INSERT_ID() returns the value generated for the first inserted row only.
使用单INSERT语句插入多条记录, LAST_INSERT_ID只返回插入的第一条记录产生的值. 比如
ID 2 是在插入第一条记录aaaa 时产生的.
LAST_INSERT_ID 是与table无关的,如果向表a插入数据后,再向表b插入数据,LAST_INSERT_ID会改变。
一般情况下获取刚插入的数据的id,使用select max(id) from table 是可以的。
但在多线程情况下,就不行了。在多用户交替插入数据的情况下max(id)显然不能用。
这就该使用LAST_INSERT_ID了,因为LAST_INSERT_ID是基于Connection的,只要每个线程都使用独立的Connection对象,LAST_INSERT_ID函数将返回该Connection对AUTO_INCREMENT列最新的insert or update操作生成的第一个record的ID。这个值不能被其它客户端(Connection)影响,保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁。
mysql的last_insert_id()不可靠 Mysql的API有个很有意义的函数last_insert_id()。这个函数的作用是,针对auto_increment字段,返回给定的 数据库链接,上一步 INSERT 查询中产生的 AUTO_INCREMENT 的 ID 号。如果没有指定数据库链接,则使用上一个打开的连接。 很多人质疑last_insert_id()是否是可靠的,以前我也犹豫过。 事实上的结果是mysql_insert_id决不会取错。首先做个测试,在mysql_query("insert.....);之后立刻sleep(1100),其间再做些其他的insert. 然后发现在mysql_insert_id取的值都不会和其他的冲突。 看了半天mysql的代码。mysql_insert_id是这么定义的
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql) { return mysql->;last_used_con->;insert_id; }
参考:http://zhaohe162.blog.163.com/blog/static/38216797201122411193745/
它的用法如下:记录下来备忘
它必需紧跟在insert 语句执行之后。
//执行insert语句先
$sql="insert into table (name1,name2,...) values('value1','values'...)";
dbx_query($db_link,$sql);
//找出最后一次插入记录的id
$select="select last_insert_id() ";
$result=dbx_query($db_link,$select);
$last_id=$result->data[0][0];
ps: $last_id=mysql_insert_id();
mysql_insert_id() 将 MySQL 内部的 C API 函数 mysql_insert_id() 的返回值转换成 long(PHP 中命名为 int)。如果 AUTO_INCREMENT 的列的类型是 BIGINT,则 mysql_insert_id() 返回的值将不正确。可以在 SQL 查询中用 MySQL 内部的 SQL 函数 LAST_INSERT_ID() 来替代。
具体的请看php手册: mysql_insert_id
来自:http://blog.csdn.net/kemy88/article/details/1108524
_____________________________________________________________________________
show table status\G
show create table message;
LAST_INSERT_ID
自动返回最后一个 INSERT 或 UPDATE 操作为 AUTO_INCREMENT 列设置的第一个发生的值. 参考这里
The ID that was generated is maintained in the server on a per-connection basis.
LAST_INSERT_ID是基于单个connection的, 不可能被其它的客户端连接改变。
可以用 SELECT LAST_INSERT_ID(); 查询LAST_INSERT_ID的值.
Important: If you insert multiple rows using a single INSERT statement, LAST_INSERT_ID() returns the value generated for the first inserted row only.
使用单INSERT语句插入多条记录, LAST_INSERT_ID只返回插入的第一条记录产生的值. 比如
1. mysql> INSERT INTO t VALUES (NULL, 'aaaa'), (NULL, 'bbbb'), (NULL, 'cccc');
2. mysql> SELECT * FROM t;
3. +----+------+
4. | id | name |
5. +----+------+
6. | 1 | Bob |
7. | 2 | aaaa |
8. | 3 | bbbb |
9. | 4 | cccc |
10. +----+------+
11. mysql> SELECT LAST_INSERT_ID();
12. +------------------+
13. | LAST_INSERT_ID() |
14. +------------------+
15. | 2 |
16. +------------------+
2. mysql> SELECT * FROM t;
3. +----+------+
4. | id | name |
5. +----+------+
6. | 1 | Bob |
7. | 2 | aaaa |
8. | 3 | bbbb |
9. | 4 | cccc |
10. +----+------+
11. mysql> SELECT LAST_INSERT_ID();
12. +------------------+
13. | LAST_INSERT_ID() |
14. +------------------+
15. | 2 |
16. +------------------+
ID 2 是在插入第一条记录aaaa 时产生的.
LAST_INSERT_ID 是与table无关的,如果向表a插入数据后,再向表b插入数据,LAST_INSERT_ID会改变。
一般情况下获取刚插入的数据的id,使用select max(id) from table 是可以的。
但在多线程情况下,就不行了。在多用户交替插入数据的情况下max(id)显然不能用。
这就该使用LAST_INSERT_ID了,因为LAST_INSERT_ID是基于Connection的,只要每个线程都使用独立的Connection对象,LAST_INSERT_ID函数将返回该Connection对AUTO_INCREMENT列最新的insert or update操作生成的第一个record的ID。这个值不能被其它客户端(Connection)影响,保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁。
mysql的last_insert_id()不可靠 Mysql的API有个很有意义的函数last_insert_id()。这个函数的作用是,针对auto_increment字段,返回给定的 数据库链接,上一步 INSERT 查询中产生的 AUTO_INCREMENT 的 ID 号。如果没有指定数据库链接,则使用上一个打开的连接。 很多人质疑last_insert_id()是否是可靠的,以前我也犹豫过。 事实上的结果是mysql_insert_id决不会取错。首先做个测试,在mysql_query("insert.....);之后立刻sleep(1100),其间再做些其他的insert. 然后发现在mysql_insert_id取的值都不会和其他的冲突。 看了半天mysql的代码。mysql_insert_id是这么定义的
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql) { return mysql->;last_used_con->;insert_id; }
参考:http://zhaohe162.blog.163.com/blog/static/38216797201122411193745/
语法如下:
alter table table_name add index index_name (column_list) ;
alter table table_name add unique (column_list) ;
alter table table_name add primary key (column_list) ;
alter table table_name drop index index_name ;
alter table table_name drop primary key ;
drop index shili on tpsc ;
来源URL:http://www.isstudy.com/mysql/440.html
实际实践如下:
alter table `relation` drop index gots; alter table `relation` drop index gots;
alter table `relation` add index gots(`group`,`owneruid`, `type`,`status`);
create table index_analyse_xiangdong select * from relation limit 21000;
测试用数据表结构如下:
--
1.PRIMARY KEY(主键索引)
mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
2.UNIQUE(唯一索引)
mysql>ALTER TABLE `table_name` ADD UNIQUE (
`column` ) //这个不靠谱
3.INDEX(普通索引)
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
4.FULLTEXT(全文索引)
mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column` )
5.多列索引
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
可以用sql强制使用或不使用索引
IGNORE INDEX (invitetype)
USE INDEX (invitetype)
如
select count from p2p_info1 IGNORE INDEX (invitetype) where invitetype="111";
alter table table_name add index index_name (column_list) ;
alter table table_name add unique (column_list) ;
alter table table_name add primary key (column_list) ;
alter table table_name drop index index_name ;
alter table table_name drop primary key ;
drop index shili on tpsc ;
来源URL:http://www.isstudy.com/mysql/440.html
实际实践如下:
alter table `relation` drop index gots; alter table `relation` drop index gots;
alter table `relation` add index gots(`group`,`owneruid`, `type`,`status`);
create table index_analyse_xiangdong select * from relation limit 21000;
show index from p2p_main; //p2p_main 是表名称
mysql> show index from p2p_main;
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| p2p_main | 0 | PRIMARY | 1 | id | A | 3052412 | NULL | NULL | | BTREE | |
| p2p_main | 1 | oweneruid | 1 | oweneruid | A | 610482 | NULL | NULL | | BTREE | |
| p2p_main | 1 | oweneruid_2 | 1 | oweneruid | A | 610482 | NULL | NULL | | BTREE | |
| p2p_main | 1 | oweneruid_2 | 2 | otheruid | A | 1017470 | NULL | NULL | | BTREE | |
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
mysql> show index from p2p_main;
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| p2p_main | 0 | PRIMARY | 1 | id | A | 3052412 | NULL | NULL | | BTREE | |
| p2p_main | 1 | oweneruid | 1 | oweneruid | A | 610482 | NULL | NULL | | BTREE | |
| p2p_main | 1 | oweneruid_2 | 1 | oweneruid | A | 610482 | NULL | NULL | | BTREE | |
| p2p_main | 1 | oweneruid_2 | 2 | otheruid | A | 1017470 | NULL | NULL | | BTREE | |
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
alter table `p2p_main` add index oweneruid_2(oweneruid ,otheruid );//建立索引,括号里面不能有逗号和单引号
alter table `p2p_main` drop index oweneruid_2; //删除索引:是建立在oweneruid 和otheruid 的联合索引
alter table `p2p_main` drop index oweneruid_2; //删除索引:是建立在oweneruid 和otheruid 的联合索引
explain SELECT SQL_NO_CACHE * FROM `mytest` force index(rstatus,uid) WHERE rstatus =1 AND uid IN ( 3,2,7) \G;
测试用数据表结构如下:
--
-- 表的结构 `p2p_info`
--
CREATE TABLE IF NOT EXISTS `p2p_info` (
`infoid` int(10) unsigned NOT NULL auto_increment,
`group` enum('1','2') collate utf8_bin NOT NULL,
`productid` char(32) collate utf8_bin NOT NULL,
`connection` enum('11','22') collate utf8_bin NOT NULL,
`invitetype` enum('111','222') collate utf8_bin NOT NULL,
`content` text collate utf8_bin NOT NULL,
`addition` text collate utf8_bin NOT NULL,
PRIMARY KEY (`infoid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- 表的结构 `p2p_main`
--
CREATE TABLE IF NOT EXISTS `p2p_main` (
`id` int(10) unsigned NOT NULL auto_increment,
`oweneruid` int(11) NOT NULL,
`otheruid` int(11) NOT NULL,
`type` enum('1','2') NOT NULL default '1',
`status` enum('11','22') NOT NULL default '11',
`infoid` int(11) NOT NULL,
`ctime` datetime NOT NULL,
`uniq_key` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
CREATE TABLE IF NOT EXISTS `p2p_info` (
`infoid` int(10) unsigned NOT NULL auto_increment,
`group` enum('1','2') collate utf8_bin NOT NULL,
`productid` char(32) collate utf8_bin NOT NULL,
`connection` enum('11','22') collate utf8_bin NOT NULL,
`invitetype` enum('111','222') collate utf8_bin NOT NULL,
`content` text collate utf8_bin NOT NULL,
`addition` text collate utf8_bin NOT NULL,
PRIMARY KEY (`infoid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- 表的结构 `p2p_main`
--
CREATE TABLE IF NOT EXISTS `p2p_main` (
`id` int(10) unsigned NOT NULL auto_increment,
`oweneruid` int(11) NOT NULL,
`otheruid` int(11) NOT NULL,
`type` enum('1','2') NOT NULL default '1',
`status` enum('11','22') NOT NULL default '11',
`infoid` int(11) NOT NULL,
`ctime` datetime NOT NULL,
`uniq_key` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
1.PRIMARY KEY(主键索引)
mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
2.UNIQUE(唯一索引)
mysql>ALTER TABLE `table_name` ADD UNIQUE (
`column` ) //这个不靠谱
alter table `index_analyse_xiangdong` ADD UNIQUE key id4(id);
alter table index_analyse_xiangdong drop index id4;
alter table index_analyse_xiangdong drop index id4;
3.INDEX(普通索引)
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
4.FULLTEXT(全文索引)
mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column` )
5.多列索引
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
可以用sql强制使用或不使用索引
IGNORE INDEX (invitetype)
USE INDEX (invitetype)
如
select count from p2p_info1 IGNORE INDEX (invitetype) where invitetype="111";