2007年12月05日 星期三 下午 04:14
keywords:substr,substr utf-8 gbk gb2312 编码
STEP 1:
utf-8是变长的unicode编码。
以下是unicode和utf8对应关系
U-00000000 - U-0000007F: 0xxxxxxx [1 byte]
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx [2 byte]
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx [3 byte]
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx [4 btye]
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx [5 byte]
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx [6 byte]
可以看出utf-8编码的数据其byte可以分为3类:0xxxxxxx,10xxxxxx和1110xxxx(再大的也归这类,很少使用);
A类 字节值小于127(--0x80),一个字节即表示一个字,例如:数字以及大小写字母;
B类 字节值在128(0x80)和192(0xC0)之间的。该类字节只有后6位有效,不能单独存在,必须和前面字节连起来才能表示一个完整的字符,处理不当就产生乱码。
C类 字节值大于192(0xC0++)的。该类字节如果小于224(0xE0,也就是11000000-11011111,定小于1110xxxx)那么它应和下一个字节(B类)后6位连起来才能用。若小于240(0xF0,也就是1110xxxx)则需和后两个字节连用。以此类推。
UTF与unicode的关系:
Unicode是一个字符集, 可以看作为内码.而UTF 是一种编码方式, 它的出现是因为unicode不适宜在某些场合直接传输和处理. UTF-16直接就是unicode编码, 没有变换, 但它包含了0x00在编码内, 头256字节码的第一个byte都是0x00, 在操作系统(C语言)中有特殊意义, 会引起问题. 采用UTF-8编码对unicode的直接编码作些变换可以避免这问题, 并带来一些优点.
STEP 2: 汉字编码规范:
BIG5=繁体中文
GB2312=ASCII+常用汉字+符号
GBK=GB2312+不常用字(含BIG5繁体汉字)+图形符号
GB18030=GBK+Ext-A+藏、蒙、维吾尔等文字
向上兼容,中文Windows的缺省内码还是GBK,但是Unicode只与ASCII兼容(ISO-8859-1),与GBK码不兼容,需要根据编码表做转换。
所以,对于汉字的GBK编码是这样表示的:把一个汉字用两个字节来表示,其首字节对应0x81-0xFE(即129-224),尾字节对应除掉 (0x7F)的0x40-oxFE(即64-126和128-224)。汉字的GBK编码首字节的起始编码0x81,其二进制即为0000 1000 0000 0000,可见若一个字符的二进制逻辑与0x81之后为0时,该字符一定小于0x81,此时该字符必定不是汉字,反之,该字符应该是一个汉字的首字节。
下面是网上找到的一个中英文混合字符串的截取的常用代码:
function gb_substr($str, $start, $len)
{
$s = '';
$j = 0;
for ($i=0; $i if (ord($str[$i]) & 0x81 != 0) { //或ord($str[$i]) > '0x80'
$t = $str[$i].$str[$i+1];
if (($i >= $start) && ($i+1 < $start+$len)) $s.= $t;
$i++;
} else {
$t = $str[$i];
if (($i >= $start) && ($i < $start+$len)) $s.= $t;
}
if ($i >= $start+$len) break;
}
return $s;
}
STEP 3:utf-8编码的字串截取函数实现
PHP中没有函数可用,substr()力不从心,又因为UTF-8分别有1,2,3字节编码,中日韩文都是3字节编码,处理时根据字符编码中首字节大小区分字节数量。
下面是我的博客中用到的处理函数:
function substr_cn($str,$start=0,$len)
{
$strlen=strlen($str);
for($i=0;$i<$strlen;$i++)
{
if($i>=$start&&$i<($start+$len))
{
if(ord(substr($str,$i,1))>'0xE0')
{
$tmpstr.=substr($str,$i,3); //utf-8 code
$i=$i+2;
}
else
$tmpstr.=substr($str,$i,1);
}
}
if(strlen($tmpstr)>$len)
{
$len--;
return substr_cn($str,$start,$len);
}
return $tmpstr;
}
STEP 4:相关的一个完整函数供研究使用:
function cut_str($sourcestr,$cutlength)
{
$returnstr='';
$i=0;
$n=0;
$str_length=strlen($sourcestr);//字符串的字节数
while (($n<$cutlength) and ($i<=$str_length))
{
$temp_str=substr($sourcestr,$i,1);
$ascnum=Ord($temp_str);//得到字符串中第$i位字符的ascii码
if ($ascnum>=224) //如果ASCII位高与224,
{
$returnstr=$returnstr.substr($sourcestr,$i,3); //根据UTF-8编码规范,将3个连续的字符计为单个字符
$i=$i+3; //实际Byte计为3
$n++; //字串长度计1
}
elseif ($ascnum>=192) //如果ASCII位高与192,
{
$returnstr=$returnstr.substr($sourcestr,$i,2); //根据UTF-8编码规范,将2个连续的字符计为单个字符
$i=$i+2; //实际Byte计为2
$n++; //字串长度计1
}
elseif ($ascnum>=65 && $ascnum<=90) //如果是大写字母,
{
$returnstr=$returnstr.substr($sourcestr,$i,1);
$i=$i+1; //实际的Byte数仍计1个
$n++; //但考虑整体美观,大写字母计成一个高位字符
}
else //其他情况下,包括小写字母和半角标点符号,
{
$returnstr=$returnstr.substr($sourcestr,$i,1);
$i=$i+1; //实际的Byte数计1个
$n=$n+0.5; //小写字母和半角标点等与半个高位字符宽...
}
}
if ($str_length>$cutlength){
$returnstr = $returnstr . "...";//超过长度时在尾处加上省略号
}
return $returnstr;
}
keywords:substr,substr utf-8 gbk gb2312 编码
STEP 1:
utf-8是变长的unicode编码。
以下是unicode和utf8对应关系
U-00000000 - U-0000007F: 0xxxxxxx [1 byte]
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx [2 byte]
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx [3 byte]
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx [4 btye]
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx [5 byte]
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx [6 byte]
可以看出utf-8编码的数据其byte可以分为3类:0xxxxxxx,10xxxxxx和1110xxxx(再大的也归这类,很少使用);
A类 字节值小于127(--0x80),一个字节即表示一个字,例如:数字以及大小写字母;
B类 字节值在128(0x80)和192(0xC0)之间的。该类字节只有后6位有效,不能单独存在,必须和前面字节连起来才能表示一个完整的字符,处理不当就产生乱码。
C类 字节值大于192(0xC0++)的。该类字节如果小于224(0xE0,也就是11000000-11011111,定小于1110xxxx)那么它应和下一个字节(B类)后6位连起来才能用。若小于240(0xF0,也就是1110xxxx)则需和后两个字节连用。以此类推。
UTF与unicode的关系:
Unicode是一个字符集, 可以看作为内码.而UTF 是一种编码方式, 它的出现是因为unicode不适宜在某些场合直接传输和处理. UTF-16直接就是unicode编码, 没有变换, 但它包含了0x00在编码内, 头256字节码的第一个byte都是0x00, 在操作系统(C语言)中有特殊意义, 会引起问题. 采用UTF-8编码对unicode的直接编码作些变换可以避免这问题, 并带来一些优点.
STEP 2: 汉字编码规范:
BIG5=繁体中文
GB2312=ASCII+常用汉字+符号
GBK=GB2312+不常用字(含BIG5繁体汉字)+图形符号
GB18030=GBK+Ext-A+藏、蒙、维吾尔等文字
向上兼容,中文Windows的缺省内码还是GBK,但是Unicode只与ASCII兼容(ISO-8859-1),与GBK码不兼容,需要根据编码表做转换。
所以,对于汉字的GBK编码是这样表示的:把一个汉字用两个字节来表示,其首字节对应0x81-0xFE(即129-224),尾字节对应除掉 (0x7F)的0x40-oxFE(即64-126和128-224)。汉字的GBK编码首字节的起始编码0x81,其二进制即为0000 1000 0000 0000,可见若一个字符的二进制逻辑与0x81之后为0时,该字符一定小于0x81,此时该字符必定不是汉字,反之,该字符应该是一个汉字的首字节。
下面是网上找到的一个中英文混合字符串的截取的常用代码:
function gb_substr($str, $start, $len)
{
$s = '';
$j = 0;
for ($i=0; $i
$t = $str[$i].$str[$i+1];
if (($i >= $start) && ($i+1 < $start+$len)) $s.= $t;
$i++;
} else {
$t = $str[$i];
if (($i >= $start) && ($i < $start+$len)) $s.= $t;
}
if ($i >= $start+$len) break;
}
return $s;
}
STEP 3:utf-8编码的字串截取函数实现
PHP中没有函数可用,substr()力不从心,又因为UTF-8分别有1,2,3字节编码,中日韩文都是3字节编码,处理时根据字符编码中首字节大小区分字节数量。
下面是我的博客中用到的处理函数:
function substr_cn($str,$start=0,$len)
{
$strlen=strlen($str);
for($i=0;$i<$strlen;$i++)
{
if($i>=$start&&$i<($start+$len))
{
if(ord(substr($str,$i,1))>'0xE0')
{
$tmpstr.=substr($str,$i,3); //utf-8 code
$i=$i+2;
}
else
$tmpstr.=substr($str,$i,1);
}
}
if(strlen($tmpstr)>$len)
{
$len--;
return substr_cn($str,$start,$len);
}
return $tmpstr;
}
STEP 4:相关的一个完整函数供研究使用:
function cut_str($sourcestr,$cutlength)
{
$returnstr='';
$i=0;
$n=0;
$str_length=strlen($sourcestr);//字符串的字节数
while (($n<$cutlength) and ($i<=$str_length))
{
$temp_str=substr($sourcestr,$i,1);
$ascnum=Ord($temp_str);//得到字符串中第$i位字符的ascii码
if ($ascnum>=224) //如果ASCII位高与224,
{
$returnstr=$returnstr.substr($sourcestr,$i,3); //根据UTF-8编码规范,将3个连续的字符计为单个字符
$i=$i+3; //实际Byte计为3
$n++; //字串长度计1
}
elseif ($ascnum>=192) //如果ASCII位高与192,
{
$returnstr=$returnstr.substr($sourcestr,$i,2); //根据UTF-8编码规范,将2个连续的字符计为单个字符
$i=$i+2; //实际Byte计为2
$n++; //字串长度计1
}
elseif ($ascnum>=65 && $ascnum<=90) //如果是大写字母,
{
$returnstr=$returnstr.substr($sourcestr,$i,1);
$i=$i+1; //实际的Byte数仍计1个
$n++; //但考虑整体美观,大写字母计成一个高位字符
}
else //其他情况下,包括小写字母和半角标点符号,
{
$returnstr=$returnstr.substr($sourcestr,$i,1);
$i=$i+1; //实际的Byte数计1个
$n=$n+0.5; //小写字母和半角标点等与半个高位字符宽...
}
}
if ($str_length>$cutlength){
$returnstr = $returnstr . "...";//超过长度时在尾处加上省略号
}
return $returnstr;
}
<?php
header ( "content-type:text/html; charset=utf-8" );
function strcut($string, $length, $dot = '...',$charset='utf-8')
{
$strlen = strlen($string);
if($strlen <= $length) return $string;
$strcut = '';
if(strtolower($charset) == 'utf-8')
{
$n = $tn = $noc = 0;
while($n < $strlen)
{
$t = ord($string[$n]);
if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
$tn = 1; $n++; $noc++;
} elseif(194 <= $t && $t <= 223) {
$tn = 2; $n += 2; $noc += 2;
} elseif(224 <= $t && $t <= 239) {
$tn = 3; $n += 3; $noc += 3;
} elseif(240 <= $t && $t <= 247) {
$tn = 4; $n += 4; $noc += 4;
} elseif(248 <= $t && $t <= 251) {
$tn = 5; $n += 5; $noc += 5;
} elseif($t == 252 || $t == 253)
{
$tn = 6; $n += 6; $noc += 6;
}
else
{
$n++;
}
if($noc >= $length) break;
}
if($noc > $length) $n -= $tn;
$strcut = substr($string, 0, $n);
}
else
{
$dotlen = strlen($dot);
$maxi = $length - $dotlen - 1;
for($i = 0; $i < $maxi; $i++)
{
$strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
}
}
var_dump($strcut);
return $strcut;
}
echo "jjjkkklll";
echo strcut("向kk向向向kk向向向kk向向kkklllllllllllmmmmmmmmmmmmmmm向东阳",12)
?>
<?php
$dir = @ opendir("software");
while (($file = readdir($dir)) !== false)
{
echo "filename: " . $file."\n";
}
closedir($dir);
?>
第一范式的目标是确保每列的原子性
如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF)
第二范式要求每个标只描述一件事。
除了主建外其他列都依赖于主建
第三范式
如果一个关系满足2NF,并除了主建以外的其他列都不传值依赖于主建。
其实范式是关系型数据的基本知识.
1Nf--第1范式就是没有表中有表,即二维表就可以了
2Nf--第2范式就是表中没有重复列.
3Nf--第3范式就是没有传递依赖,表中所有列都函数依赖于主关键字.(比如,表a(ID,sum1,Sid,a1),表b(Sid,a1)例子中ID为表a的关键字,Sid为表b的关键字.
我们说表a传递依赖于表b,应该规范为表a(ID,sum1,Sid),表b(Sid,a1)
一般要求关系表能够满足第3范式就可以了.
膘哥网上有更详细的介绍内容:
http://neatstudio.com/show-288-1.shtml
http://neatstudio.com/show-291-1.shtml
http://neatstudio.com/show-664-1.shtml
http://neatstudio.com/show-666-1.shtml
第一范式及第二范式的依赖问题截图:
如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF)
第二范式要求每个标只描述一件事。
除了主建外其他列都依赖于主建
第三范式
如果一个关系满足2NF,并除了主建以外的其他列都不传值依赖于主建。
其实范式是关系型数据的基本知识.
1Nf--第1范式就是没有表中有表,即二维表就可以了
2Nf--第2范式就是表中没有重复列.
3Nf--第3范式就是没有传递依赖,表中所有列都函数依赖于主关键字.(比如,表a(ID,sum1,Sid,a1),表b(Sid,a1)例子中ID为表a的关键字,Sid为表b的关键字.
我们说表a传递依赖于表b,应该规范为表a(ID,sum1,Sid),表b(Sid,a1)
一般要求关系表能够满足第3范式就可以了.
膘哥网上有更详细的介绍内容:
http://neatstudio.com/show-288-1.shtml
http://neatstudio.com/show-291-1.shtml
http://neatstudio.com/show-664-1.shtml
http://neatstudio.com/show-666-1.shtml
第一范式及第二范式的依赖问题截图:
天堂海() 10:05:58
大家有没有遇到mkdir时,如果文件夹已经存在,就报错
莫莫() 10:07:20
先判断啊
莫莫() 10:07:24
总是这样的
申寒光() 10:07:38
if exist
膘叔() 10:12:48
file_exists
is_dir
膘叔(19129540) 10:12:55
都可以判断的吧?
大家有没有遇到mkdir时,如果文件夹已经存在,就报错
莫莫() 10:07:20
先判断啊
莫莫() 10:07:24
总是这样的
申寒光() 10:07:38
if exist
膘叔() 10:12:48
file_exists
is_dir
膘叔(19129540) 10:12:55
都可以判断的吧?
软件:
zend fro eclipse,ESFTP
功能:
本机编写好代码,然后通过ESFTP上传(单个文件或者多个文件或者目录)到开发机。没有ESFTP就还得rz这个软件不错。。呵呵!
对zend for Eclipse 建立通过svn导出的工程(这个在FILE->NEW->PROJECT->SVN->Project from svn->create a new repository local ->next->URL填入:https://svn.intra.sina.com.cn/space/develop/APP_PHP/trunk (这个trunk下面有 pengyou,deamon,framework,不能写到https后面,因为后面还得要选trunk下面的目录,密码啥的可能得输入) next 弹出一个框,大意就是是否显示异常的目录和其他版本,这儿选择否NO,列出目录后:选择pengyou ,点击finish,选择:check out as a project with the name specified,点finish,点选pengyou 点击OK,开始从svn中检出了)。在修改后通过对文件上点击右键,Team commit。
zend fro eclipse,ESFTP
功能:
本机编写好代码,然后通过ESFTP上传(单个文件或者多个文件或者目录)到开发机。没有ESFTP就还得rz这个软件不错。。呵呵!
对zend for Eclipse 建立通过svn导出的工程(这个在FILE->NEW->PROJECT->SVN->Project from svn->create a new repository local ->next->URL填入:https://svn.intra.sina.com.cn/space/develop/APP_PHP/trunk (这个trunk下面有 pengyou,deamon,framework,不能写到https后面,因为后面还得要选trunk下面的目录,密码啥的可能得输入) next 弹出一个框,大意就是是否显示异常的目录和其他版本,这儿选择否NO,列出目录后:选择pengyou ,点击finish,选择:check out as a project with the name specified,点finish,点选pengyou 点击OK,开始从svn中检出了)。在修改后通过对文件上点击右键,Team commit。
研究了两宿的MSN协议(http://msnpiki.msnfanatic.com/index.php/Main_Page),终于搞定了一个稳定高效的msn好友列表导入程序,为啥说最稳定高效呢,这是我试过一些别人的实现后对比得到的,通常遇到的问题有两种:一个是非常慢,甚至被MSN服务器给挂起不断开,二是在面对一个用户有五六百个好友(比如我)的时候,就会以失败告终,经过不断调试和修改,最终这些问题都搞定了,甚是愉快!
几点收获:1. 低版本的协议更快,更好用 2. 面对超多好友的时候,避免挂起需要对ILN和MSG同时进行判断 3.命令行执行比web执行更可靠 4.必要的调试功能太重要了 5.为避免用户体验不佳,最好在获取好友列表的时候,使用HDN 隐身状态
提示: 索要代码暂时不提供,部分代码可能涉及公司代码安全,可以就具体问题和我讨论
参看:http://www.toplee.com/blog/71.html/comment-page-3#comment-31512
鄙人先后在CERNET做过拨号接入,在Yahoo&3721搞过搜索前端,在猫扑处理过mop.com的架构升级,在6.cn视频网站从事开发工作,还在多年的工作中接触和开发过不少大中型网站的模块,因此在大型网站应对高负载和并发的解决方案上有一些积累和经验,希望和大家一起探讨。
老乡那么牛的人都研究了两晚,一个msn导入想到高效的实现,可见对工作的态度和责任值得我学习啊。
几点收获:1. 低版本的协议更快,更好用 2. 面对超多好友的时候,避免挂起需要对ILN和MSG同时进行判断 3.命令行执行比web执行更可靠 4.必要的调试功能太重要了 5.为避免用户体验不佳,最好在获取好友列表的时候,使用HDN 隐身状态
提示: 索要代码暂时不提供,部分代码可能涉及公司代码安全,可以就具体问题和我讨论
参看:http://www.toplee.com/blog/71.html/comment-page-3#comment-31512
鄙人先后在CERNET做过拨号接入,在Yahoo&3721搞过搜索前端,在猫扑处理过mop.com的架构升级,在6.cn视频网站从事开发工作,还在多年的工作中接触和开发过不少大中型网站的模块,因此在大型网站应对高负载和并发的解决方案上有一些积累和经验,希望和大家一起探讨。
老乡那么牛的人都研究了两晚,一个msn导入想到高效的实现,可见对工作的态度和责任值得我学习啊。
zend studio 11.0.1 CSDN破解:
http://download.csdn.net/download/meiqing520/7844645
zend studio 11.0.1 如何实现汉化的?
汉化:
Help->
install new software...->
点击右边的Add按钮->
在弹框中
name栏里写ZH_CN
在Location里写http://download.eclipse.org/technology/babel/update-site/R0.12.0/juno/
然后点击ok
这时会提示pending...(等待...),
等侍完成后会出来很多语言列表让你选择,
请选择“Babel Language Packs in Chinese(Simplified)”简体中文包选择项,
阅读全文
http://download.csdn.net/download/meiqing520/7844645
zend studio 11.0.1 如何实现汉化的?
汉化:
Help->
install new software...->
点击右边的Add按钮->
在弹框中
name栏里写ZH_CN
在Location里写http://download.eclipse.org/technology/babel/update-site/R0.12.0/juno/
然后点击ok
这时会提示pending...(等待...),
等侍完成后会出来很多语言列表让你选择,
请选择“Babel Language Packs in Chinese(Simplified)”简体中文包选择项,
阅读全文
用的是Zend for Eclipse 6.0 和 SVN进行PHP的开发。最近一个周,我突然发现一个奇怪的现象,以前在ZEND的文件浏览窗里无法显示文件的相关函数和类信息,在outline窗口里也是没有内容显示,同时,代码提示功能也没有了,一直不解是怎么回事,在网上搜索了好几次,没有任务人提到这个问题,看来这个问题比较少见,没办法,只好自己解决了。
先分析表象。我在ZEND又建立了一个新项目,这里我发现在新的项目没有这个问题,而在原来的项目里还是有问题,两个项目都开着,看来不是编辑器出错了。
无聊之际,我分别打开两个项目的文件夹,比较后发现,新项目文件夹里的.settings目录里的内容和原项目里的不一样,新项目里多了几个文件,分别是:
com.zend.php.javabridge.core.prefs
org.eclipse.core.resources.prefs
org.eclipse.php.core.projectOptions.prefs
老项目里只有一个文件,我想,问题出在这里?如是我把这三个文件都复制到老项目的相应文件夹里,并替换了已经存在的一个文件,于是我兴冲冲再次打开Zend,可是,可是,问题依旧!
唉,看来还有其它的问题,经常仔细比对后,发现新项目下的.project文件与老项目里的.project文件不同,新项目下的.project里引用了上面的说的三个文件,而老项目里没有,于是,我用新项目下的.project替换了老项目下的,再次打开,嘿嘿,搞掂了!
事后再想想,原来有一次,不知什么原因在用SVN update的时候,提示.project文件有错,于是我把这个文件删除了,之后,zend自动重建了一个,重建后的文件就跟以前不一样了,问题了就出现了!
唉!
情况二:
解决办法:
复制一个正常项目下的 .settings目录和.project文件替换有问题的项目里的同名目录和文件即可!
我自己以前解决方法是:
newproject --》project contents:
user default: directory的后面加上斜杠即可。
好像新版本没有这个问题。
附录:
这个问题应该不是一个问题,所以大家提得比较少,要想使用代码提示等相关内容,必需以php项目的方式导出svn的项目。再最新的ZFE里边自带svn,check out时选择以新项目的方式检出,同时设定项目类型为PHP。
其实你可以分别new 两个项目,一个以php方式,一个以普通项目。对比一下就发现原因了。
不知道什么原因,Zend Studio Eclipse 的代码自动补全功能(Code Assist)不能用了,也无法通过 Ctrl点击 类定位。
最近尝试 PHP5.3RC 一直在折磨 Zend Studio Eclipse 。
Google 一番以后找到解决方法如下:
将工程的 .project 文件打开, <buildspec> <natures> 替换成以下内容:
<buildspec>
<buildcommand>
<name>org.eclipse.php.core.PhpIncrementalProjectBuilder</name>
<arguments>
</arguments>
</buildcommand>
</buildspec>
<natures>
<nature>org.eclipse.php.core.PHPNature</nature>
</natures>
然后重新 build 工程。
国际惯例,方法的出处是:https://www.zend.com/en/forums/index.php?t=msg&goto=15534
单击某变量其他相同变量也变灰的标记恢复办法:
File Switch Workspace:[修改回原来的文件目录即可,默认就有这个功能,只是在开发中变更后可能就没有这个默认功能]
C:\Documents and Settings\jackxiang\Zend\workspaces\DefaultWorkspace
先分析表象。我在ZEND又建立了一个新项目,这里我发现在新的项目没有这个问题,而在原来的项目里还是有问题,两个项目都开着,看来不是编辑器出错了。
无聊之际,我分别打开两个项目的文件夹,比较后发现,新项目文件夹里的.settings目录里的内容和原项目里的不一样,新项目里多了几个文件,分别是:
com.zend.php.javabridge.core.prefs
org.eclipse.core.resources.prefs
org.eclipse.php.core.projectOptions.prefs
老项目里只有一个文件,我想,问题出在这里?如是我把这三个文件都复制到老项目的相应文件夹里,并替换了已经存在的一个文件,于是我兴冲冲再次打开Zend,可是,可是,问题依旧!
唉,看来还有其它的问题,经常仔细比对后,发现新项目下的.project文件与老项目里的.project文件不同,新项目下的.project里引用了上面的说的三个文件,而老项目里没有,于是,我用新项目下的.project替换了老项目下的,再次打开,嘿嘿,搞掂了!
事后再想想,原来有一次,不知什么原因在用SVN update的时候,提示.project文件有错,于是我把这个文件删除了,之后,zend自动重建了一个,重建后的文件就跟以前不一样了,问题了就出现了!
唉!
情况二:
解决办法:
复制一个正常项目下的 .settings目录和.project文件替换有问题的项目里的同名目录和文件即可!
我自己以前解决方法是:
newproject --》project contents:
user default: directory的后面加上斜杠即可。
好像新版本没有这个问题。
附录:
这个问题应该不是一个问题,所以大家提得比较少,要想使用代码提示等相关内容,必需以php项目的方式导出svn的项目。再最新的ZFE里边自带svn,check out时选择以新项目的方式检出,同时设定项目类型为PHP。
其实你可以分别new 两个项目,一个以php方式,一个以普通项目。对比一下就发现原因了。
不知道什么原因,Zend Studio Eclipse 的代码自动补全功能(Code Assist)不能用了,也无法通过 Ctrl点击 类定位。
最近尝试 PHP5.3RC 一直在折磨 Zend Studio Eclipse 。
Google 一番以后找到解决方法如下:
将工程的 .project 文件打开, <buildspec> <natures> 替换成以下内容:
<buildspec>
<buildcommand>
<name>org.eclipse.php.core.PhpIncrementalProjectBuilder</name>
<arguments>
</arguments>
</buildcommand>
</buildspec>
<natures>
<nature>org.eclipse.php.core.PHPNature</nature>
</natures>
然后重新 build 工程。
国际惯例,方法的出处是:https://www.zend.com/en/forums/index.php?t=msg&goto=15534
单击某变量其他相同变量也变灰的标记恢复办法:
File Switch Workspace:[修改回原来的文件目录即可,默认就有这个功能,只是在开发中变更后可能就没有这个默认功能]
C:\Documents and Settings\jackxiang\Zend\workspaces\DefaultWorkspace
来源:http://www.qgy18.com/tag/fiddler/
在测试或者优化web应用时,经常需要替换一些静态资源,如css/image/js等。当然,这些工作是在开发环境来做,直接ftp替换也没什么问题。但有的时候仅仅是想调研一下而不想影响环境的稳定,或者想方便的对比两段代码效果,就可以利用一个小工具来完成工作——Fiddler。
还有一个抓包工具wireshark :
抓包工具
wireshark 非常详细的抓包工具,缺点是在拦截http的post数据上传时看不到上传的数据格式
Fiddler 微软开发的专用于拦截http请求的工具,亮点功能在于:1.可以直接查看到get\post数据的内容 2.可以以多种方式浏览数据(text\xml\json) 3.可以直接模拟请求 包括模拟agent或者其他自定义头---一句话,非常强大的工具,信不信由你,我反正信了。
================================================================================
先来简单的介绍下Fiddler(官网|需要.NET Framework v2.0|MicroSoft出品):一个集web性能分析、数据监测、自动响应、创建请求四大功能于一身,自带众多实用小工具,支持插件扩展的HTTP调试工具。通过简单的配置代理(IE中全自动、FF中需如下图手动配置),就可以开始使用Fiddler了。
在火狐浏览器菜单栏的“工具(T)”->"选项(O).."->“高级”->“网络”->"设置(E)..."下选择“手动配置代理”
这篇文章讲的只是利用fiddler来替换静态资源,利用的是它的自动响应功能。选择软件右侧的AutoResponder这个tab,点“Add”按钮来添加一条规则,在Rule Editor里的文本框填上要被替换资源的url,后面的文本框选择源文件就OK了。如下图:
搞定,就这么简单,现在只要请求被命中,就会被转发到指定的源文件了。修改代码后保存一下F5就能生效,既方便又不会影响到他人。这个功能挖掘下还可以干一些其它有意思的事情:配置Rule时,选择转发404之类的错误码,就可以用来测试Ajax的onError事件;把类似于Http://www.***.com/1.html这样的url转发到本地页面,就可以在本地代码里用Ajax请求www.***.com的内容。由于本地页面是通过Http://www.***.com/1.html来访问,不再有跨域问题了。这在做一个获取数据程序的时候很有用。虽说最后还是要用后端程序来解决跨域问题,但开发前期利用Fiiddler做转发,非常的高效!
用它做Flash的Post上传调试:
1)打开fiddle2
2)Flash进行POST上传下
3)查看Fiddle:左边选 URl,右边点Inspector里的WebForms,下面看Response里的:TextView,如果是Json可以远json这一项能看到json格式给你封装展现好了的,也就是让你看到POST后的返回相关的数值。
Array
(
[Filename] => video-2013-03-20-07-54-44.mp4
[upload_file_name] => video-2013-03-20-07-54-44.mp4
[upload_file_content_type] => application/octet-stream
[upload_file_path] => /data/app/test.local/upload_tmp/0051067597
[upload_file_md5] => 17e71fff75f6fe211d95e1f486e7185b
[upload_file_size] => 25302039
[Upload] => Submit Query
)
其实上面还可以粗略看到Flash上传的一个协议,如相当于web里的form表单中的file域:
------------gL6Ef1gL6GI3Ef1cH2GI3gL6gL6KM7
Content-Disposition: form-data; name="Filename"
video-2013-03-20-07-54-44.mp4
------------gL6Ef1gL6GI3Ef1cH2GI3gL6gL6KM7
Content-Disposition: form-data; name="upload_file"; filename="video-2013-03-20-07-54-44.mp4"
Content-Type: application/octet-stream
在测试或者优化web应用时,经常需要替换一些静态资源,如css/image/js等。当然,这些工作是在开发环境来做,直接ftp替换也没什么问题。但有的时候仅仅是想调研一下而不想影响环境的稳定,或者想方便的对比两段代码效果,就可以利用一个小工具来完成工作——Fiddler。
还有一个抓包工具wireshark :
抓包工具
wireshark 非常详细的抓包工具,缺点是在拦截http的post数据上传时看不到上传的数据格式
Fiddler 微软开发的专用于拦截http请求的工具,亮点功能在于:1.可以直接查看到get\post数据的内容 2.可以以多种方式浏览数据(text\xml\json) 3.可以直接模拟请求 包括模拟agent或者其他自定义头---一句话,非常强大的工具,信不信由你,我反正信了。
================================================================================
先来简单的介绍下Fiddler(官网|需要.NET Framework v2.0|MicroSoft出品):一个集web性能分析、数据监测、自动响应、创建请求四大功能于一身,自带众多实用小工具,支持插件扩展的HTTP调试工具。通过简单的配置代理(IE中全自动、FF中需如下图手动配置),就可以开始使用Fiddler了。
在火狐浏览器菜单栏的“工具(T)”->"选项(O).."->“高级”->“网络”->"设置(E)..."下选择“手动配置代理”
这篇文章讲的只是利用fiddler来替换静态资源,利用的是它的自动响应功能。选择软件右侧的AutoResponder这个tab,点“Add”按钮来添加一条规则,在Rule Editor里的文本框填上要被替换资源的url,后面的文本框选择源文件就OK了。如下图:
搞定,就这么简单,现在只要请求被命中,就会被转发到指定的源文件了。修改代码后保存一下F5就能生效,既方便又不会影响到他人。这个功能挖掘下还可以干一些其它有意思的事情:配置Rule时,选择转发404之类的错误码,就可以用来测试Ajax的onError事件;把类似于Http://www.***.com/1.html这样的url转发到本地页面,就可以在本地代码里用Ajax请求www.***.com的内容。由于本地页面是通过Http://www.***.com/1.html来访问,不再有跨域问题了。这在做一个获取数据程序的时候很有用。虽说最后还是要用后端程序来解决跨域问题,但开发前期利用Fiiddler做转发,非常的高效!
用它做Flash的Post上传调试:
1)打开fiddle2
2)Flash进行POST上传下
3)查看Fiddle:左边选 URl,右边点Inspector里的WebForms,下面看Response里的:TextView,如果是Json可以远json这一项能看到json格式给你封装展现好了的,也就是让你看到POST后的返回相关的数值。
Array
(
[Filename] => video-2013-03-20-07-54-44.mp4
[upload_file_name] => video-2013-03-20-07-54-44.mp4
[upload_file_content_type] => application/octet-stream
[upload_file_path] => /data/app/test.local/upload_tmp/0051067597
[upload_file_md5] => 17e71fff75f6fe211d95e1f486e7185b
[upload_file_size] => 25302039
[Upload] => Submit Query
)
其实上面还可以粗略看到Flash上传的一个协议,如相当于web里的form表单中的file域:
------------gL6Ef1gL6GI3Ef1cH2GI3gL6gL6KM7
Content-Disposition: form-data; name="Filename"
video-2013-03-20-07-54-44.mp4
------------gL6Ef1gL6GI3Ef1cH2GI3gL6gL6KM7
Content-Disposition: form-data; name="upload_file"; filename="video-2013-03-20-07-54-44.mp4"
Content-Type: application/octet-stream
前段时间实习,一直在搞Python,都把Linux和C丢一边了,这段时间准备重新复习一下Linux下的C编程,加深理解。
今天写了一段忑恶心的代码,Linux下的chmod的简单实现,主要是支持两种方式:
1. 输入一个八进制数直接修改文件的权限;
2. 通过"u+w, g-wr"等方式来修改,不使用getopt函数解析参数,直接自己手动解析;
主要是string_chmod函数写得让自己都感到恶心,中午也没想到比较好的解决方法,功能是实现了,但是代码重复太多了,还有就是因为前段时间工作看惯了Python代码,现在看这样的代码确实太恶了。
代码和执行结果如下:
/*
* filename: my_chmod.c
* Email: lin.jian1986@gmail.com
* Date: 2008/10/24
*/
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include "../my_error.h"
#define MODE O777
#define CHMOD(file, MODE); { \
if ( chmod(file, statbuf.st_mode) < 0 ) \
my_error( "chmod" ); \
break; \
}
/* return 'n' when arg is number, or 's' if arg is string*/
int number_or_string( const char *arg )
{
assert( arg != NULL );
if ( arg[0] >= '0' && arg[0] <= '9' )
return 'n';
return 's';
}
/* the implement of number argument */
void number_chmod( const char *arg, const char *file )
{
int mode;
mode = atoi( arg );
if ( mode > 777 || mode < 0 ) {
fprintf( stderr, "usage: mode" );
exit ( 1 );
}
/* To change a decimal system to a octal system */
sscanf( arg, "%o", &mode );
if ( chmod(file, mode) == -1 )
exit ( 2 );
}
/* the implement of string argument */
void string_chmod( const char *arg, const char *file )
{
int i, j;
int mode;
struct stat statbuf;
if ( stat(file, &statbuf) < 0 )
my_error( "stat" );
for ( i = 0; i < strlen(arg); i += j + 1 ) {
/* if change the user mode */
if ( arg[i] == 'u' ) {
for ( j = 2; arg[i + j] != ' ' && arg[i + j] != '\t'; ++j ) {
switch ( arg[i + j] ) {
case 'r':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IRUSR;
else
statbuf.st_mode &= ~S_IRUSR;
CHMOD(file, MODE);
case 'w':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IWUSR;
else
statbuf.st_mode &= ~S_IWUSR;
CHMOD(file, MODE);
case 'x':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IXUSR;
else
statbuf.st_mode &= ~S_IXUSR;
CHMOD(file, MODE);
default:
exit ( 1 );
}
}
}
/* if change the group mode */
else if ( arg[i] == 'g' ) {
for ( j = 2; arg[i + j] != ' ' && arg[i + j] != '\t'; ++j ) {
switch ( arg[i + j] ) {
case 'r':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IRGRP;
else
statbuf.st_mode &= ~S_IRGRP;
CHMOD(file, MODE);
case 'w':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IWGRP;
else
statbuf.st_mode &= ~S_IWGRP;
CHMOD(file, MODE);
case 'x':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IXGRP;
else
statbuf.st_mode &= ~S_IXGRP;
CHMOD(file, MODE);
default:
exit ( 1 );
}
}
}
/* if change the other user mode */
else if ( arg[i] == 'o' ) {
for ( j = 2; arg[i + j] != ' ' && arg[i + j] != '\t'; ++j ) {
switch ( arg[i + j] ) {
case 'r':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IROTH;
else
statbuf.st_mode &= ~S_IROTH;
CHMOD(file, MODE);
case 'w':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IWOTH;
else
statbuf.st_mode &= ~S_IWOTH;
CHMOD(file, MODE);
case 'x':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IXOTH;
else
statbuf.st_mode &= ~S_IXOTH;
CHMOD(file, MODE);
default:
exit ( 1 );
}
}
}
}
}
int main( int argc, char *argv[] )
{
int mode;
char buf[20];
if ( argc < 3 ) {
fprintf( stderr, "usage: argc < 3" );
exit (1);
}
if ( number_or_string(argv[1]) == 'n' )
number_chmod( argv[1], argv[argc - 1] );
else {
strcpy( buf, argv[1] );
for ( int i = 2; i < argc - 1; i++ ) {
strcat( buf, " ");
strcat( buf, argv[i] );
}
string_chmod( buf, argv[argc - 1] );
}
return 0;
}
ken@ken-laptop:~/linux_c/chap6$ ls -l test.c
-rwxrwxrwx 1 ken ken 0 2008-10-23 19:14 test.c
ken@ken-laptop:~/linux_c/chap6$ ./my_chmod 745 test.c
ken@ken-laptop:~/linux_c/chap6$ ls -l test.c
-rwxr--r-x 1 ken ken 0 2008-10-23 19:14 test.c
ken@ken-laptop:~/linux_c/chap6$ ./my_chmod u-rw g+w o-rx test.c
ken@ken-laptop:~/linux_c/chap6$ ls -l test.c
---xrw---- 1 ken ken 0 2008-10-23 19:14 test.c
今天写了一段忑恶心的代码,Linux下的chmod的简单实现,主要是支持两种方式:
1. 输入一个八进制数直接修改文件的权限;
2. 通过"u+w, g-wr"等方式来修改,不使用getopt函数解析参数,直接自己手动解析;
主要是string_chmod函数写得让自己都感到恶心,中午也没想到比较好的解决方法,功能是实现了,但是代码重复太多了,还有就是因为前段时间工作看惯了Python代码,现在看这样的代码确实太恶了。
代码和执行结果如下:
/*
* filename: my_chmod.c
* Email: lin.jian1986@gmail.com
* Date: 2008/10/24
*/
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include "../my_error.h"
#define MODE O777
#define CHMOD(file, MODE); { \
if ( chmod(file, statbuf.st_mode) < 0 ) \
my_error( "chmod" ); \
break; \
}
/* return 'n' when arg is number, or 's' if arg is string*/
int number_or_string( const char *arg )
{
assert( arg != NULL );
if ( arg[0] >= '0' && arg[0] <= '9' )
return 'n';
return 's';
}
/* the implement of number argument */
void number_chmod( const char *arg, const char *file )
{
int mode;
mode = atoi( arg );
if ( mode > 777 || mode < 0 ) {
fprintf( stderr, "usage: mode" );
exit ( 1 );
}
/* To change a decimal system to a octal system */
sscanf( arg, "%o", &mode );
if ( chmod(file, mode) == -1 )
exit ( 2 );
}
/* the implement of string argument */
void string_chmod( const char *arg, const char *file )
{
int i, j;
int mode;
struct stat statbuf;
if ( stat(file, &statbuf) < 0 )
my_error( "stat" );
for ( i = 0; i < strlen(arg); i += j + 1 ) {
/* if change the user mode */
if ( arg[i] == 'u' ) {
for ( j = 2; arg[i + j] != ' ' && arg[i + j] != '\t'; ++j ) {
switch ( arg[i + j] ) {
case 'r':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IRUSR;
else
statbuf.st_mode &= ~S_IRUSR;
CHMOD(file, MODE);
case 'w':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IWUSR;
else
statbuf.st_mode &= ~S_IWUSR;
CHMOD(file, MODE);
case 'x':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IXUSR;
else
statbuf.st_mode &= ~S_IXUSR;
CHMOD(file, MODE);
default:
exit ( 1 );
}
}
}
/* if change the group mode */
else if ( arg[i] == 'g' ) {
for ( j = 2; arg[i + j] != ' ' && arg[i + j] != '\t'; ++j ) {
switch ( arg[i + j] ) {
case 'r':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IRGRP;
else
statbuf.st_mode &= ~S_IRGRP;
CHMOD(file, MODE);
case 'w':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IWGRP;
else
statbuf.st_mode &= ~S_IWGRP;
CHMOD(file, MODE);
case 'x':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IXGRP;
else
statbuf.st_mode &= ~S_IXGRP;
CHMOD(file, MODE);
default:
exit ( 1 );
}
}
}
/* if change the other user mode */
else if ( arg[i] == 'o' ) {
for ( j = 2; arg[i + j] != ' ' && arg[i + j] != '\t'; ++j ) {
switch ( arg[i + j] ) {
case 'r':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IROTH;
else
statbuf.st_mode &= ~S_IROTH;
CHMOD(file, MODE);
case 'w':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IWOTH;
else
statbuf.st_mode &= ~S_IWOTH;
CHMOD(file, MODE);
case 'x':
if ( arg[i + 1] == '+' )
statbuf.st_mode |= S_IXOTH;
else
statbuf.st_mode &= ~S_IXOTH;
CHMOD(file, MODE);
default:
exit ( 1 );
}
}
}
}
}
int main( int argc, char *argv[] )
{
int mode;
char buf[20];
if ( argc < 3 ) {
fprintf( stderr, "usage: argc < 3" );
exit (1);
}
if ( number_or_string(argv[1]) == 'n' )
number_chmod( argv[1], argv[argc - 1] );
else {
strcpy( buf, argv[1] );
for ( int i = 2; i < argc - 1; i++ ) {
strcat( buf, " ");
strcat( buf, argv[i] );
}
string_chmod( buf, argv[argc - 1] );
}
return 0;
}
ken@ken-laptop:~/linux_c/chap6$ ls -l test.c
-rwxrwxrwx 1 ken ken 0 2008-10-23 19:14 test.c
ken@ken-laptop:~/linux_c/chap6$ ./my_chmod 745 test.c
ken@ken-laptop:~/linux_c/chap6$ ls -l test.c
-rwxr--r-x 1 ken ken 0 2008-10-23 19:14 test.c
ken@ken-laptop:~/linux_c/chap6$ ./my_chmod u-rw g+w o-rx test.c
ken@ken-laptop:~/linux_c/chap6$ ls -l test.c
---xrw---- 1 ken ken 0 2008-10-23 19:14 test.c
zend for eclipse 6.1 加上这个玩意就好了,不用zmtx zmrx (freeBSD)和rz (Linux)了,感觉不错。
实际开发时经常需要把新修改的文件丢到测试机上运行,通常使用的是SFTP方式,需要单独开着一个类似WinSCP的工具。
esftp是一款Linux插件,有了它就可以在Eclipse中上传、下载Linux服务器上的文件,不需要再单独使用别的软件。
安装、使用:
1,下载插件:http://sourceforge.net/projects/esftp
2,简单配置一下
用一下:
esftp目前存在的问题:当本地目录名与服务器上不同时,esftp不能正确将文件放到正确的目录下,不过个人觉得已经很好了!
实际开发时经常需要把新修改的文件丢到测试机上运行,通常使用的是SFTP方式,需要单独开着一个类似WinSCP的工具。
esftp是一款Linux插件,有了它就可以在Eclipse中上传、下载Linux服务器上的文件,不需要再单独使用别的软件。
安装、使用:
1,下载插件:http://sourceforge.net/projects/esftp
2,简单配置一下
用一下:
esftp目前存在的问题:当本地目录名与服务器上不同时,esftp不能正确将文件放到正确的目录下,不过个人觉得已经很好了!
谁有php操作共享内存的代码?
APC这个方案不错,得看:http://leepiao.blog.163.com/blog/static/48503130201121811722907/
$shm_id = shmop_open(0xff3, "c", 0644, 100);
用这句后出现以下错误,怎样解决
Call to undefined function: shmop_open()
解决方法:
Linux:(共享内存只适用于linux兼容系统)
php编译的时候,configure 后面加 --enable-shmop
Windows:
win,php.ini中 extension=php_shmop.dll 前的分号去掉,重启web服务器 !
必须参考:http://blog.csdn.net/laruence/archive/2008/04/15/2294451.aspx
2 share2.php 用于显示共享内存的内容
最近想用它做点什么,可是思想还不成熟,暂时先放个例子在这里,以便以后使用。
共享内存首先是使用内存空间,虽然不是直接访问内存地址,由于不受磁盘io和网络带宽限制,在性能方面,共享内存比其它数据交互方式有巨大的优势。跟memcache比,这个共享内存不需要依赖其他的服务,只需要php编译时加入shmop的支持即可。
其次,它是共享的,同一台机器上所有的程序,都有访问它的权利。常做进程间通信用。php程序,每次执行完,生命也就结束了。
但是共享内存中的数据不一样,直到销毁前,它能让一份数据一直保留在内存中。使后来的程序能够使用它。
下面是一个使用共享内存做的简单计数器。能很高效的记录次数,缺点是内存数据不能永久保存,可以用daemon每隔几分钟同步一次共享内存与数据库。
ipcs -h for help.
可以看到,共享内存的key, shmid,所有者,权限,大小,attach数,和状态。
删除共享内存可以用ipcrm -m shmid或ipcrm -M shmkey命令来完成。
看,现在那份放在共享内存中的数据已经被删掉了。
阅读全文
APC这个方案不错,得看:http://leepiao.blog.163.com/blog/static/48503130201121811722907/
$shm_id = shmop_open(0xff3, "c", 0644, 100);
用这句后出现以下错误,怎样解决
Call to undefined function: shmop_open()
解决方法:
Linux:(共享内存只适用于linux兼容系统)
php编译的时候,configure 后面加 --enable-shmop
Windows:
win,php.ini中 extension=php_shmop.dll 前的分号去掉,重启web服务器 !
必须参考:http://blog.csdn.net/laruence/archive/2008/04/15/2294451.aspx
<?php
if($stop!=1)
{
// 判断是否已经创建
$shm_id = @shmop_open(0xff3, "a", 0644, 100);
if($shm_id) {
echo "内存块已经创建\n";
exit();
}
// 创建 100 字节的系统标识为 0xff3 的共享内存块
$shm_id = @shmop_open(0xff3, "c", 0644, 100);
if(!$shm_id) {
echo "共享内存块创建失败\n";
}
// 写一些内容
for($i=0;$i<10;$i++)
{
$shm_bytes_written = shmop_write($shm_id, "共享块$i", ($i*10));
}
echo "创建成功";
shmop_close($shm_id);
}
else
{
// 是否存在
$shm_id = @shmop_open(0xff3, "a", 0644, 100);
if(!$shm_id) {
echo "没有找到共享内存块\n";
exit();
}
// 删除
if(!shmop_delete($shm_id)) {
echo "删除失败.";
}
shmop_close($shm_id);
echo "内存块删除完毕!";
}
?>
if($stop!=1)
{
// 判断是否已经创建
$shm_id = @shmop_open(0xff3, "a", 0644, 100);
if($shm_id) {
echo "内存块已经创建\n";
exit();
}
// 创建 100 字节的系统标识为 0xff3 的共享内存块
$shm_id = @shmop_open(0xff3, "c", 0644, 100);
if(!$shm_id) {
echo "共享内存块创建失败\n";
}
// 写一些内容
for($i=0;$i<10;$i++)
{
$shm_bytes_written = shmop_write($shm_id, "共享块$i", ($i*10));
}
echo "创建成功";
shmop_close($shm_id);
}
else
{
// 是否存在
$shm_id = @shmop_open(0xff3, "a", 0644, 100);
if(!$shm_id) {
echo "没有找到共享内存块\n";
exit();
}
// 删除
if(!shmop_delete($shm_id)) {
echo "删除失败.";
}
shmop_close($shm_id);
echo "内存块删除完毕!";
}
?>
2 share2.php 用于显示共享内存的内容
<?php
// 打开共享内存块 0xff3
$shm_id = @shmop_open(0xff3, "a", 0644, 100);
if(!$shm_id) {
echo "不能打开共享内存块\n";
exit();
}
// 读出里面的内容
$my_string = shmop_read($shm_id, 0, $shm_size);
if(!$my_string) {
echo "没有内容或者不能读\n";
}
echo $my_string."\n";
shmop_close($shm_id);
?>
// 打开共享内存块 0xff3
$shm_id = @shmop_open(0xff3, "a", 0644, 100);
if(!$shm_id) {
echo "不能打开共享内存块\n";
exit();
}
// 读出里面的内容
$my_string = shmop_read($shm_id, 0, $shm_size);
if(!$my_string) {
echo "没有内容或者不能读\n";
}
echo $my_string."\n";
shmop_close($shm_id);
?>
最近想用它做点什么,可是思想还不成熟,暂时先放个例子在这里,以便以后使用。
共享内存首先是使用内存空间,虽然不是直接访问内存地址,由于不受磁盘io和网络带宽限制,在性能方面,共享内存比其它数据交互方式有巨大的优势。跟memcache比,这个共享内存不需要依赖其他的服务,只需要php编译时加入shmop的支持即可。
其次,它是共享的,同一台机器上所有的程序,都有访问它的权利。常做进程间通信用。php程序,每次执行完,生命也就结束了。
但是共享内存中的数据不一样,直到销毁前,它能让一份数据一直保留在内存中。使后来的程序能够使用它。
下面是一个使用共享内存做的简单计数器。能很高效的记录次数,缺点是内存数据不能永久保存,可以用daemon每隔几分钟同步一次共享内存与数据库。
?php
$shm_id = shmop_open(0x00000001, "c", 0644, 4); //通过一个指定的key来打开一个共享内存,
//这个key可以是自己指定,也可以用ftok生成
$data = unpack('Ncount',shmop_read($shm_id, 0, 4)); //解包数据
$count = $data['count']+1; //加一
shmop_write($shm_id, pack('N',$count), 0); //打包数据
shmop_close($shm_id); //关闭共享内存
echo $count; //输出数字
exit(0); //退出
?>
命令行查看$shm_id = shmop_open(0x00000001, "c", 0644, 4); //通过一个指定的key来打开一个共享内存,
//这个key可以是自己指定,也可以用ftok生成
$data = unpack('Ncount',shmop_read($shm_id, 0, 4)); //解包数据
$count = $data['count']+1; //加一
shmop_write($shm_id, pack('N',$count), 0); //打包数据
shmop_close($shm_id); //关闭共享内存
echo $count; //输出数字
exit(0); //退出
?>
ipcs -h for help.
[root@localhost html]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000001 262144 root 644 4 0
[root@localhost html]#
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000001 262144 root 644 4 0
[root@localhost html]#
可以看到,共享内存的key, shmid,所有者,权限,大小,attach数,和状态。
删除共享内存可以用ipcrm -m shmid或ipcrm -M shmkey命令来完成。
[root@localhost html]# ipcrm -M 0x00000001
[root@localhost html]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
[root@localhost html]#
[root@localhost html]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
[root@localhost html]#
看,现在那份放在共享内存中的数据已经被删掉了。
阅读全文
关于领导:领导说这事得1周完成。
关于技术经理:我们得加班加点可以完成。
关于下属:我们周末或者下班得迟一点回去了。
领导说:干完 了?
技术经理:干完了。
我问:上线了吗?
技术经理:没有。
要不就是修改了N个方案,一直在干活,没有任何积累,搞得精疲力尽,还得不到承认,搞个毛啊。优秀人才一个接一个的走,软件蓝领的照旧。接着搞,没有一个靠谱的。。。领导难道就一直是伯乐,但就是没有找到千里马?呵呵。思考中。。。
nm看可执行文件定义了哪些函数。
nm用来列出目标文件的符号清单。下面是nm命令的格式: nm [-a|--debug-syms] [-g|--extern-only] [-B][-C|--demangle] [-D|--dynamic] [-s|--print-armap][-o|--print-file-name] [-n|--numeric-sort][-p|--no-sort] [-r|--reverse-sort] [--size-sort][-u|--undefined-only] [-l|--line-numbers] [--help][--version] [-t radix|--radix=radix][-P|--portability] [-f format|--format=format][--target=bfdname] [objfile...]
如果没有为nm命令指出目标文件,则nm假定目标文件是a.out。下面列出该命令的任选项,大部分支持“-”开头的短格式和“—“开头的长格式。
* -A、-o或--print-file-name:在找到的各个符号的名字前加上文件名,而不是在此文件的所有符号前只出现文件名一次。
例如nm libtest.a的输出如下:
CPThread.o:
00000068 T Main__8CPThreadPv
00000038 T Start__8CPThread
00000014 T _._8CPThread
00000000 T __8CPThread
00000000 ? __FRAME_BEGIN__
…………………………………
则nm –A 的输出如下:
libtest.a:CPThread.o:00000068 T Main__8CPThreadPv
libtest.a:CPThread.o:00000038 T Start__8CPThread
libtest.a:CPThread.o:00000014 T _._8CPThread
libtest.a:CPThread.o:00000000 T __8CPThread
libtest.a:CPThread.o:00000000 ? __FRAME_BEGIN__
…………………………………………………………
* -a或--debug-syms:显示调试符号。
* -B:等同于--format=bsd,用来兼容MIPS的nm。
* -C或--demangle:将低级符号名解码(demangle)成用户级名字。这样可以使得C++函数名具有可读性。
* -D或--dynamic:显示动态符号。该任选项仅对于动态目标(例如特定类型的共享库)有意义。
* -f format:使用format格式输出。format可以选取bsd、sysv或posix,该选项在GNU的nm中有用。默认为bsd。
* -g或--extern-only:仅显示外部符号。
* -n、-v或--numeric-sort:按符号对应地址的顺序排序,而非按符号名的字符顺序。
* -p或--no-sort:按目标文件中遇到的符号顺序显示,不排序。
* -P或--portability:使用POSIX.2标准输出格式代替默认的输出格式。等同于使用任选项-f posix。
* -s或--print-armap:当列出库中成员的符号时,包含索引。索引的内容包含:哪些模块包含哪些名字的映射。
* -r或--reverse-sort:反转排序的顺序(例如,升序变为降序)。
* --size-sort:按大小排列符号顺序。该大小是按照一个符号的值与它下一个符号的值进行计算的。
* -t radix或--radix=radix:使用radix进制显示符号值。radix只能为“d”表示十进制、“o”表示八进制或“x”表示十六进制。
* --target=bfdname:指定一个目标代码的格式,而非使用系统的默认格式。
* -u或--undefined-only:仅显示没有定义的符号(那些外部符号)。
* -l或--line-numbers:对每个符号,使用调试信息来试图找到文件名和行号。对于已定义的符号,查找符号地址的行号。对于未定义符号,查找指向符号重定位入口的行号。如果可以找到行号信息,显示在符号信息之后。
* -V或--version:显示nm的版本号。
* --help:显示nm的任选项。
如:
nm -D /lib/libc.so.6 | grep log
nm用来列出目标文件的符号清单。下面是nm命令的格式: nm [-a|--debug-syms] [-g|--extern-only] [-B][-C|--demangle] [-D|--dynamic] [-s|--print-armap][-o|--print-file-name] [-n|--numeric-sort][-p|--no-sort] [-r|--reverse-sort] [--size-sort][-u|--undefined-only] [-l|--line-numbers] [--help][--version] [-t radix|--radix=radix][-P|--portability] [-f format|--format=format][--target=bfdname] [objfile...]
如果没有为nm命令指出目标文件,则nm假定目标文件是a.out。下面列出该命令的任选项,大部分支持“-”开头的短格式和“—“开头的长格式。
* -A、-o或--print-file-name:在找到的各个符号的名字前加上文件名,而不是在此文件的所有符号前只出现文件名一次。
例如nm libtest.a的输出如下:
CPThread.o:
00000068 T Main__8CPThreadPv
00000038 T Start__8CPThread
00000014 T _._8CPThread
00000000 T __8CPThread
00000000 ? __FRAME_BEGIN__
…………………………………
则nm –A 的输出如下:
libtest.a:CPThread.o:00000068 T Main__8CPThreadPv
libtest.a:CPThread.o:00000038 T Start__8CPThread
libtest.a:CPThread.o:00000014 T _._8CPThread
libtest.a:CPThread.o:00000000 T __8CPThread
libtest.a:CPThread.o:00000000 ? __FRAME_BEGIN__
…………………………………………………………
* -a或--debug-syms:显示调试符号。
* -B:等同于--format=bsd,用来兼容MIPS的nm。
* -C或--demangle:将低级符号名解码(demangle)成用户级名字。这样可以使得C++函数名具有可读性。
* -D或--dynamic:显示动态符号。该任选项仅对于动态目标(例如特定类型的共享库)有意义。
* -f format:使用format格式输出。format可以选取bsd、sysv或posix,该选项在GNU的nm中有用。默认为bsd。
* -g或--extern-only:仅显示外部符号。
* -n、-v或--numeric-sort:按符号对应地址的顺序排序,而非按符号名的字符顺序。
* -p或--no-sort:按目标文件中遇到的符号顺序显示,不排序。
* -P或--portability:使用POSIX.2标准输出格式代替默认的输出格式。等同于使用任选项-f posix。
* -s或--print-armap:当列出库中成员的符号时,包含索引。索引的内容包含:哪些模块包含哪些名字的映射。
* -r或--reverse-sort:反转排序的顺序(例如,升序变为降序)。
* --size-sort:按大小排列符号顺序。该大小是按照一个符号的值与它下一个符号的值进行计算的。
* -t radix或--radix=radix:使用radix进制显示符号值。radix只能为“d”表示十进制、“o”表示八进制或“x”表示十六进制。
* --target=bfdname:指定一个目标代码的格式,而非使用系统的默认格式。
* -u或--undefined-only:仅显示没有定义的符号(那些外部符号)。
* -l或--line-numbers:对每个符号,使用调试信息来试图找到文件名和行号。对于已定义的符号,查找符号地址的行号。对于未定义符号,查找指向符号重定位入口的行号。如果可以找到行号信息,显示在符号信息之后。
* -V或--version:显示nm的版本号。
* --help:显示nm的任选项。
如:
nm -D /lib/libc.so.6 | grep log