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; $iif (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;

}

<?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

第一范式及第二范式的依赖问题截图:
点击在新窗口中浏览此图片
天堂海()  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
都可以判断的吧?
软件:
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导入想到高效的实现,可见对工作的态度和责任值得我学习啊。
[概述]

自5.1开始对分区(Partition)有支持,6.0应比较稳定阅读全文
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)”简体中文包选择项,
阅读全文
用的是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
来源: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(官网&#124;需要.NET Framework v2.0&#124;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
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不能正确将文件放到正确的目录下,不过个人觉得已经很好了!
谁有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
<?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 "内存块删除完毕!";
}
?>


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


最近想用它做点什么,可是思想还不成熟,暂时先放个例子在这里,以便以后使用。

共享内存首先是使用内存空间,虽然不是直接访问内存地址,由于不受磁盘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);                                            //退出
?>
命令行查看
        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]#


可以看到,共享内存的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]#


看,现在那份放在共享内存中的数据已经被删掉了。

阅读全文
              
关于领导:领导说这事得1周完成。
关于技术经理:我们得加班加点可以完成。
关于下属:我们周末或者下班得迟一点回去了。
领导说:干完 了?
技术经理:干完了。
我问:上线了吗?
技术经理:没有。



要不就是修改了N个方案,一直在干活,没有任何积累,搞得精疲力尽,还得不到承认,搞个毛啊。优秀人才一个接一个的走,软件蓝领的照旧。接着搞,没有一个靠谱的。。。领导难道就一直是伯乐,但就是没有找到千里马?呵呵。思考中。。。

nm命令

WEB2.0 jackxiang 2009-7-21 14:23
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
分页: 214/272 第一页 上页 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 下页 最后页 [ 显示模式: 摘要 | 列表 ]