2013年10月20日 3:47 下午 fisher 分类: Open, 后端, 技术, 社会化媒体

一、PHP全角标点转为半角

< ?php
$str = "0123ABCDFWS\",.?<>{}[]*&^%#@!~()+-|:;";
echo "$str";
echo "
";
$str = preg_replace('/\xa3([\xa1-\xfe])/e', 'chr(ord(\1)-0x80)', $str);
echo $str;

这是网上看来的代码,所有的中文标点的第二个字节减去0X80(即128)所得的数字就是半角所得的数字了。而/e模式表达的是:如果设定了此修正符,preg_replace() 在替换字符串中对逆向引用作正常的替换,将其作为 PHP 代码求值,并用其结果来替换所搜索的字符串。

在非UTF-8模式下这个函数是可行的,但是UTF-8下 这个方法就似乎无效,求能满足UTF-8模式下的这个功能的实现…

二、如果文件是utf8的,那么可以通过
$str = iconv(‘utf-8’, ‘gbk’, $str); 转换编码后,再
preg_replace(‘/\xa3([\xa1-\xfe])/e’, ‘chr(ord(\1)-0x80)’, $str);

有些字符在utf-8中可以表示,而在gbk中无法表示,那么你将utf-8转成gbk不会导致字符丢失吗?可以使用IGNORE:
$str = iconv(‘utf-8’, ‘gbk//IGNORE’, $str);

下边是不同编码对应的正则匹配编码的范围:
UTF8: [\x01-\x7f]|[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}
UTF16: [\x00-\xd7][\xe0-\xff]|[\xd8-\xdf][\x00-\xff]{2}
Big5: [\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|[\xa1-\xfe])
GBK :[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]
GB2312汉字: [\xb0-\xf7][\xa0-\xfe]
GB2312半角标点符号及特殊符号: \xa1[\xa2-\xfe]
GB2312罗马数组及项目序号: \xa2([\xa1-\xaa]|[\xb1-\xbf]|[\xc0-\xdf]|[\xe0-\xe2]|[\xe5-\xee]|[\xf1-\xfc])
GB2312全角标点及全角字母: \xa3[\xa1-\xfe]
GB2312日文平假名: \xa4[\xa1-\xf3]
GB2312日文片假名:\xa5[\xa1-\xf6]
GB18030: [\x00-\x7f]|[\x81-\xfe][\x40-\xfe]|[\x81-\xfe][\x30-\x39][\x81-\xfe][\x30-\x39]

JIS [\x20-\x7e]|[\x21-\x5f]|[\x21-\x7e]{2}
SJIS [\x20-\x7e]|[\xa1-\xdf]|([\x81-\x9f]|[\xe0-\xef])([\x40-\x7e]|[\x80-\xfc])
SJIS全角空格 (?:\x81\x81)
SJIS全角数字 (?:\x82[\x4f-\x58])
SJIS全角大写英文 (?:\x82[\x60-\x79])
SJIS全角小写英文 (?:\x82[\x81-\x9a])
SJIS全角平假名 (?:\x82[\x9f-\xf1])
SJIS全角平假名扩展 (?:\x82[\x9f-\xf1]|\x81[\x4a\x4b\x54\x55])
SJIS全角片假名 (?:\x83[\x40-\x96])
SJIS全角片假名扩展 (?:\x83[\x40-\x96]|\x81[\x45\x5b\x52\x53])

EUC_JP [\x20-\x7e]|\x81[\xa1-\xdf]|[\xa1-\xfe][\xa1-\xfe]|\x8f[\xa1-\xfe]{2}
EUC_JP标点符号及特殊字符 [\xa1-\xa2][\xa0-\xfe]
EUC_JP全角数字 \xa3[\xb0-\xb9]
EUC_JP全角大写英文 \xa3[\xc1-\xda]
EUC_JP全角小写英文 \xa3[\xe1-\xfa]
EUC_JP全角平假名 \xa4[\xa1-\xf3]
EUC_JP全角片假名 \xa3[\xb0-\xb9]|\xa3[\xc1-\xda]|\xa5[\xa1-\xf6][\xa3][\xb0-\xfa]|[\xa1][\xbc-\xbe]|[\xa1][\xdd]
EUC_JP全角汉字 [\xb0-\xcf][\xa0-\xd3]|[\xd0-\xf4][\xa0-\xfe]|[\xB0-\xF3][\xA1-\xFE]|[\xF4][\xA1-\xA6]|[\xA4][\xA1-\xF3]|[\xA5][\xA1-\xF6]|[\xA1][\xBC-\xBE]
EUC_JP全角空格 (?:\xa1\xa1)

EUC半角片假名 (?:\x8e[\xa6-\xdf])
日文半角空格 \x20

三、我觉得没必要那么麻烦,直接写个方法替换就完了,而且正则的效率还低,我就是这么弄的:
/**
* 字符串半角和全角间相互转换
* @param string $str 待转换的字符串
* @param int $type TODBC:转换为半角;TOSBC,转换为全角
* @return string 返回转换后的字符串
*/
function convertStrType($str, $type) {

$dbc = array(
‘0’ , ‘1’ , ‘2’ , ‘3’ , ‘4’ ,
‘5’ , ‘6’ , ‘7’ , ‘8’ , ‘9’ ,
‘A’ , ‘B’ , ‘C’ , ‘D’ , ‘E’ ,
‘F’ , ‘G’ , ‘H’ , ‘I’ , ‘J’ ,
‘K’ , ‘L’ , ‘M’ , ‘N’ , ‘O’ ,
‘P’ , ‘Q’ , ‘R’ , ‘S’ , ‘T’ ,
‘U’ , ‘V’ , ‘W’ , ‘X’ , ‘Y’ ,
‘Z’ , ‘a’ , ‘b’ , ‘c’ , ‘d’ ,
‘e’ , ‘f’ , ‘g’ , ‘h’ , ‘i’ ,
‘j’ , ‘k’ , ‘l’ , ‘m’ , ‘n’ ,
‘o’ , ‘p’ , ‘q’ , ‘r’ , ‘s’ ,
‘t’ , ‘u’ , ‘v’ , ‘w’ , ‘x’ ,
‘y’ , ‘z’ , ‘-’ , ‘ ’ , ‘:’ ,
‘.’ , ‘,’ , ‘/’ , ‘%’ , ‘#’ ,
‘!’ , ‘@’ , ‘&’ , ‘(’ , ‘)’ ,
‘<’ , ‘>’ , ‘"’ , ‘'’ , ‘?’ ,
‘[’ , ‘]’ , ‘{’ , ‘}’ , ‘\’ ,
‘|’ , ‘+’ , ‘=’ , ‘_’ , ‘^’ ,
‘¥’ , ‘ ̄’ , ‘`’

);

$sbc = array( //半角
‘0’, ‘1’, ‘2’, ‘3’, ‘4’,
‘5’, ‘6’, ‘7’, ‘8’, ‘9’,
‘A’, ‘B’, ‘C’, ‘D’, ‘E’,
‘F’, ‘G’, ‘H’, ‘I’, ‘J’,
‘K’, ‘L’, ‘M’, ‘N’, ‘O’,
‘P’, ‘Q’, ‘R’, ‘S’, ‘T’,
‘U’, ‘V’, ‘W’, ‘X’, ‘Y’,
‘Z’, ‘a’, ‘b’, ‘c’, ‘d’,
‘e’, ‘f’, ‘g’, ‘h’, ‘i’,
‘j’, ‘k’, ‘l’, ‘m’, ‘n’,
‘o’, ‘p’, ‘q’, ‘r’, ‘s’,
‘t’, ‘u’, ‘v’, ‘w’, ‘x’,
‘y’, ‘z’, ‘-‘, ‘ ‘, ‘:’,
‘.’, ‘,’, ‘/’, ‘%’, ‘ #’,
‘!’, ‘@’, ‘&’, ‘(‘, ‘)’,
‘< ‘, ‘>’, ‘”‘, ‘\”,’?’,
‘[‘, ‘]’, ‘{‘, ‘}’, ‘\\’,
‘|’, ‘+’, ‘=’, ‘_’, ‘^’,
‘¥’,’~’, ‘`’

);
if($type == ‘TODBC’){
return str_replace( $sbc, $dbc, $str ); //半角到全角
}elseif($type == ‘TOSBC’){
return str_replace( $dbc, $sbc, $str ); //全角到半角
}else{
return $str;
}
}

2013年09月24日 11:17 上午 fisher 分类: Open, 微信, 新传, 社会化媒体

腾讯微博XCSTWX绑定mb新传学院

wechat-国际版

2013年04月14日 12:35 下午 i新传 分类: 电商

今天有一家主机服务商,大概是因为阿里云已经成为其竞争对手且整合支付宝,所以只能用其他支付网关,原先的首信电子商城网关、支付宝网关就下线了。然后,就只能走银行自身平台。

IE果然是落后生产力寄生的地方。早前我对交通银行免activex插件的支付方式是赞赏有加。今天再看,原来只是手机客户端暂时摆脱噩梦般的 acticex,PC端不管是不是用IE你都没法摆脱。本来银行卡支付密码+手机动态短信就足够了吧?非得要加一个activex插件。插件就插件吧,在 没有任何安全软件的情形下,插件让IE8无数次崩溃,说是非正常使用方式。微软哪一天不淘汰该死的activex落后的安全管理模式,哪一天就站不起来。

支付宝垄断恐惧,在电商、支付领域,比之于腾讯有过之无不及。

IE糟糕的多版本分支,与如今安卓系统糟糕的版本分支,如出一辙。

有时,简单就是美。

____________

首发:我i南通

2013年04月7日 6:00 下午 fisher 分类: Open, 微信
公众号名称: 新传学院
类型: 普通公众帐号
微信号: xcstwx
功能介绍: 传播新传资讯,聚合科技信息。微信号: xcstwx
微信:xcstwx

微信:xcstwx

2013年03月12日 12:03 上午 fisher 分类: Open, 后端, 技术, 知识原野

  8     元字符
  9         代码    说明
10         .        匹配除换行符以外的任意字符
11         \d        匹配数字 [表示数字 0-9]
12         \D        匹配除数字意外的任意字符 [\d的反义]
13         \w        匹配字母或数字或下划线或汉字 [表示数字、字母、下划线、汉字 0-9 a-z A-Z]
14         \s        匹配任意的空白符 [表示任意的空白符:空格 ,制表符\t,换行符\n,回车\r,分页\f,垂直制表\v,中文全角空格等]
15         \S        匹配所有的非空白字符 [\s的反义]
16         \b        匹配单词的开始或结束 [匹配单个单词]
17         ^        匹配字符串的开始 [用来匹配要查找字符串的开头 所有的字符都用于比较]
18         $        匹配字符串的结束 [和\b、^ 类似,区别在于 $ 为结尾处 所有的字符都用于比较]
19     正则 模式修正符
20         特点:多个模式修正符可以放在一块使用
21         m    整个字符串按多行来进行匹配。可以理解为将字符串里符合的内容全部匹配出来
22         i    不区分大小写模式的匹配
23         x    忽略掉匹配表达式里[正则表达式]的空格
24         U    匹配最近的字符串,禁止贪婪匹配
25         A    强制从^字符串开始算起,必须配合^使用
26         D    只匹配到$符号的位置处 设置了m就没用了
27         e    把替换字符串当成一个表达式使用。类似eval()函数
28    
29     限定字符
30         代码    说明
31         *        重复零次或多次 [任意次数]
32         +        重复一次或多次 [至少会出现一次]
33         ?        重复零次或一次 [可能会出现一次]
34         {n}        重复 n 次
35         {n, }    重复 n 次或者更多次 [重复n次以上:包括n次] {TIP:貌似达不到预期}
36         {n,m}    重复 n 到 m 次
37    
38     分歧条件
39         |        或 [从左往右检测。如果左边的规则符合,右边的规则将不会去匹配]
40    
41     分组
42        
43 
44     后向引用:
45          捕获:
46              (exp)    匹配exp字符串,并自动分配组号
47              (?<name>exp)    匹配exp字符串,并分配到组号为name的分组里
48              (?:exp)    不匹配exp字符串,并且也不分配组号
49          零宽断言(字符串分割匹配?):
50              (?=exp)        匹配以exp结尾的字符,匹配结果不包括exp
51              (?<=exp)    匹配一exp开头的字符,匹配结果同样不包括exp
52          负向零宽断言(可以看做 ‘[^exp]’ 的反义)
53              (?!exp)        某字符串后边不是exp的
54              (?<!exp)    某字符串前边不是exp的
55          注释:(?#comment)    注释,给人看的
56     
57      贪婪与懒惰:
58          贪婪可以理解为尽可能多的匹配重复的字符
59          懒惰可以理解为尽可能少的匹配重复的字符(尽可能少?搞不明白)
60              示例语法:
61                  *?、+?、??、{n,m}?、{n,}?
62                 
63     EXP:
64         \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} 匹配简单IP

2013年02月20日 8:05 下午 fisher 分类: Open, 技术

    XSLT是一种将XML文档转换为其他文本文档的语言,是建立在XML和XPath之上的国际标准,内容比较多,功能强大。

    对于编程人员来说,XSLT可以看作以前序遍历的方式专门处理XML树状结构的标记语言。以前编程根据XML文档输出纯文本数据时需要写代码以前序遍历方式的方式遍历XML文档对象组成的树状结构,对于每一个特定名称或特定层次的XML节点而输出不同的内容,这个过程比较复杂,代码量大,需用进行很多的状态判断。而XSLT则使用一种简洁明了的标记语言实现了相同的逻辑。因此XSLT从程序逻辑的角度看类似支持递归的编程语言,而且是专门处理XML文档的。

    XSLT转换过程会涉及到三个文本文档,一个是要处理的原始XML文档,第二个就是XSLT样式表文档,该文档包含了XSLT代码,XSLT代码本身就是XML格式,但使用了XML的名称空间。第三个就是XSLT处理输出的文本文档,注意,此处输出的是纯文本文档,这个文档具体是什么格式完全靠XSLT代码来决定,可以是另外一个XML文档,HTML文档,SQL语句字符串或者其他任意格式的字符串数据等等,XSLT转换只能输出纯文本文档,此外就没有限制输出文档的具体格式。

    数据XML文档是一个很简单的XML文档,此处不加说明了。重点说说XSLT样式表文档,XSLT样式表文档本身是一个XML文档。它采用XML的树状结构来描述递归处理过程,也比较好理解。

    在样式表文档中,根元素为 xsl:stylesheet,里面定义了一个名为xsl的名称空间,这个根节点及其属性值都是固定的。

xsl:output元素是可选的,它的method属性用于指定输出文档的格式,可以设置为xml,html或text值。此处使用xml输出样式,说明输出的文档是XML格式的,XSLT转换会尽量生成XML文档,但不作保证,因此仍然有可能生成不合格的XML文档。

    xsl:template用于定义一个XSLT模板,模板类似编程语言中的函数,可实现XSLT代码的重用。模板可以使用name属性定义名称,也可以使用match属性定义匹配的XPath路径,这个模板使用了match属性来匹配XML文档本身。

    然后是 html元素,由于html元素没有使用xsl的前缀,因此不属于xslt代码,因此将原样输出,跟着后面的body,table元素也是一样的。

    xsl:for-each元素类似C#中的foreach语法结果,表示循环遍历元素,它使用select属性指定一个XPath相对路径,XSLT使用这个相对路径查询所有要遍历的XML节点,此时当前节点就是XML文档本身,因此XSLT处理器会调用XmlDocument的SelectNodes函数来获得要遍历的XML节点,函数的参数就是Table/Record。于是我们开始循环遍历所有的Record元素了。

    在循环遍历Record元素时,对每一个Record元素都要输出xsl:for-each的子节点,首先是 tr元素,这不是XSLT元素,因此原样输出。这里还套嵌定义了另外一个for-each元素,于是我们又开始了一个新的循环遍历了,新的循环指定的相对XPath路径是一个星号,表示匹配所有名称的子元素,这类似DOS命令Dir中使用星号匹配所有文件。此处表示循环遍历Record元素下面所有的字段元素。

    对每一个字段元素,首先输出td元素,然后处理xsl:value-of元素,xsl:value-of表示输出指定相对路径的节点的值,这里指定的XPath是一个点号,表示当前节点本身,由于当前节点是XML元素,因此也就输出元素的文本内容,相当于输出XmlElement的InnerText属性值。

xslt文件:

<?xml version=”1.0″ encoding=”utf-8″?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform
xmlns:msxsl=”urn:schemas-microsoft-com:xslt” exclude-result-prefixes=”msxsl”
>
<xsl:output method=”xml” indent=”yes” encoding=”utf-8″/>

 <xsl:template match=”/”>
<xsl:for-each select=”Category”>
<Category>
<xsl:attribute name=”Navigate”>
<xsl:value-of select=”@Navigate”/>
</xsl:attribute>
<xsl:element name=”Name”>
<xsl:value-of select=”Name”/>
</xsl:element>
<xsl:element name=”EngName”>
<xsl:value-of select=”EngName”/>
</xsl:element>
<xsl:element name=”ChtName”>
<xsl:value-of select=”ChtName”/>
</xsl:element>
<xsl:element name=”Description”>
<xsl:value-of select=”Description”/>
</xsl:element>
<xsl:element name=”EngDescription”>
<xsl:value-of select=”EngDescription”/>
</xsl:element>
<xsl:element name=”ChtDescription”>
<xsl:value-of select=”ChtDescription”/>
</xsl:element>
<xsl:element name=”Editor”>
<xsl:value-of select=”Editor”/>
</xsl:element>
<xsl:element name=”LastModified”>
<xsl:value-of select=”LastModified”/>
</xsl:element>
<xsl:element name=”Identity”>
<xsl:text>CAT_ZTF</xsl:text>
</xsl:element>
<xsl:element name=”Notes”>
<xsl:value-of select=”Notes”/>
</xsl:element>
<xsl:element name=”TotalCount”>
<xsl:text>{0}</xsl:text>
</xsl:element>
<xsl:for-each select=”Content”>
<xsl:for-each select=”CatItem”>
<xsl:element name=”CatItem”>
<xsl:attribute name=”Name”>
<xsl:value-of select=”@Name”/>
</xsl:attribute>
<xsl:attribute name=”Code”>
<xsl:value-of select=”@Code”/>
</xsl:attribute>
<xsl:attribute name=”ParentCode”>
<xsl:value-of select=”@ParentCode”/>
</xsl:attribute>
<xsl:attribute name=”CategoryType”>
<xsl:text>CAT_ZTF</xsl:text>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</Category>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

XML文件:

<?xml version=”1.0″ encoding=”GB2312″?>
<Category Navigate=”1″>
<Name>专用分类</Name>
<EngName>New</EngName>
<ChtName>專用分類</ChtName>
<Description/>
<EngDescription/>
<ChtDescription/>
<Editor>Liangying</Editor>
<LastModified>2010-5-31</LastModified>
<Identity>CAT_XXXX</Identity>
<Notes>专用分类</Notes>
<Content Count=”97″>

<CatItem Name=”文艺” Description=”” EngDescription=”” ChtDescription=”” Code=”001″ ParentCode=”” Nav=”tttt?={0}”/>
<CatItem Name=”小说” Description=”” EngDescription=”” ChtDescription=”” Code=”001001″ ParentCode=”001″ Nav=”tttt?={0}”/>
<CatItem Name=”文学” Description=”” EngDescription=”” ChtDescription=”” Code=”001002″ ParentCode=”001″ Nav=”tttt?={0}”/>
<CatItem Name=”散文” Description=”” EngDescription=”” ChtDescription=”” Code=”001003″ ParentCode=”001″ Nav=”tttt?={0}”/>

</Content>
</Category>

转换C#代码:

/// </summary>
/// <param name=”strXmlPath”></param>
/// <param name=”strXsltPath”></param>
/// <returns></returns>
public string TransferXmlByXSLT(string strXmlPath,string strXsltPath)
{

            MemoryStream fs = new MemoryStream();
string outputstring = string.Empty;
try
{
//判断文件是否存在
if (File.Exists(Server.MapPath(strXmlPath)) && File.Exists(Server.MapPath(strXsltPath)))
{
//加载xml文件
XPathDocument doc = new XPathDocument(strXmlPath);
XslTransform transForm = new XslTransform();
//加载xslt文件
transForm.Load(strXsltPath);
XPathNavigator nav = doc.CreateNavigator();
//转换xml
transForm.Transform(nav, null, fs);
fs.Seek(0, SeekOrigin.Begin);
StreamReader stream = new StreamReader(fs);
outputstring = stream.ReadToEnd();

                    fs.Close();
fs.Dispose();
}
else
{
return “”;
}
}
finally
{
fs.Close();
fs.Dispose();
}

            return outputstring;
}

转换后的XML:

<?xml version=”1.0″ encoding=”GB2312″?>
<Category Navigate=”1″>
<Name>专用分类</Name>
<EngName>New</EngName>
<ChtName>專用分類</ChtName>
<Description/>
<EngDescription/>
<ChtDescription/>
<Editor>Liangying</Editor>
<LastModified>2010-5-31</LastModified>
<Identity>CAT_XXXX</Identity>
<Notes>专用分类</Notes>
<TotalCount>{0}</TotalCount>

<CatItem Name=”文艺” Code=”001″ CategoryType=”CAT_ZTF” ParentCode=””  />
<CatItem Name=”小说” Code=”001001″ CategoryType=”CAT_ZTF” ParentCode=”001″  />
<CatItem Name=”文学” Code=”001002″ CategoryType=”CAT_ZTF” ParentCode=”001″  />

<CatItem Name=”散文” Code=”001003″ CategoryType=”CAT_ZTF” ParentCode=”001″  />

</Category>

 

2013年02月7日 2:12 下午 fisher 分类: 后端, 技术

简单来说,当php生成一个数组时,便根据数组的大小生成一个hash表,当数组的key值为数值时,就把key当作hash表的key值,所以我们可以通过构造这个key值来使hash表退化成一条链表,没存放一个数组的值都要去遍历这个链表,导致效率无比低下,废话不多说看看下面代码 同样是存放6万多个数字的数组,没有经过构造key的数组只要0.02秒,经过构造退化的数组需要67秒。

注意第一个步长为1,会平均放到hash表中,元素进来基本不用遍历链表,第二个步长为数组的长度,每次元素进来都是同一个key值,所以都会去遍历相应的链表再存放,导致效率低下,下面是执行时间对照

看到没有,通过这样简单的处理key值,可以通过一般的pc就可以占用牛逼的服务器的Cpu 也就是让你服务器宕机。通过上面的例子差不多也可以看出,php给数组分配给一个数组大小的空间。

 

更多…

2012年12月9日 10:22 上午 fisher 分类: 后端, 技术, 知识原野

MySQL5数据库服务器,大数据中心模式。今年出现过两次大的数据中心宕机/迁移/修复事件。

所涉及数据库已经运行三年,某数据表自增字段ID int(10) ,原有数据插入正常自增至 1800多条,下一条数据突增至1211000,再下面的数据突增至1399000。直接查看这两条新数据,发现是当时被有关权力部门要求隐藏的数据,手工更改的ID(当时没直接删除这两条,而是在后面加了4个0),接下来的数据库就从最大的那条数据开始自增。为什么会这样?

找了点资料:

从网上看到一篇文章,mysql在检测到表中有损坏的记录时,会自动修复,为了保证数据的完整性,mysql会以空格(0x20)写进磁盘来完成修复。根据字段的类型,自增字段的长度不同,所允许的最大值也不同。见下:
int(10) unsigned类型最大值十进制为4294967295,十六进制ffffffff;
mediumint(8) unsigned类型最大值十进制为16777215,十六进制ffffff;
smallint(6) unsigned类型最大值十进制为65535,十六进制ffff;
tinyint(3) unsigned类型最大值十进制为255,十六进制ff
mail中的自增字段是int(10),也就是0x20202020,转换成10进制就是538976288,超过了4294967295这个值,此时,系统会以最大值显示。问了下具体的操作人员,确实做了数据库修复的操作。
摘自后附资料
结论一(关于MYSQL确定和更新某个自增字段最大值的方式):
第 一次对某个表创建并填充好结构文件.frm,索引文件.MYI和数据文件.MYD的数据后,首先读取索引文件.MYI中关于这个自增字段的最大值,并且放 入内存进行计数,以后所有的自增字段最大值都来源于这个内存计数器;隔一段时间重新读取数据文件中对应字段的确切最大值,并和内存的值做比较,然后用两者 中的最大值更新内存的数值和索引文件的数值。
结论二(关于不同的异常修复时对自增字段最大值的影响):
在MYISAM的存储结构中,数据 库数据的异常不一定会导致立刻启动自我修复;并且这种修复不是全面的修复,大多数情况下,它仅仅对数据文件.MYD进行修复,而这种修复并不对索引产生即 时的影响(换句话说,自增字段也不会受到即时的影响);只有当用户要求进行修复的时候,才会全面更新索引(比如输入SQL语句:REPAIR TABLE __TABLE_NAME__)。而一旦更新了索引(无论是手动还是自动更新),对自增字段的影响有可能是爆发性的呈现。

结论一的解释:
在 试验时,我发现假如终止MYSQL进程后再重新启动,tid这个自增键值的最大值是直接读取索引文件cdb_threads.MYI确定,而不管是否和数 据文件cdb_threads.MYD中的tid最大值是否一致。并且发现,1,只要索引文件损坏并且无法自我修复,这个表就有可能无法读取甚至导致 MYSQL进程当掉。2,索引文件并不经常更新,而是有规律的隔段时间写入。
结论二的解释:
我的测试方法很简单,在MYSQL运行时直接 修改数据文件的尾部。用PHPMYADMIN打开表的前几页数据,正常;我直接跳到最后一页,这时候MYSQL提示出错,要修复这个表,刷新了两下,自我 修复完毕,此时出现一条tid:2105376的无用记录,然而插入新记录时,tid赋予的下一个值仍然是3201;只有当我显式的命令修复过后,才赋予 tid下一个值为2105377。
所以,朋友的那个论坛数据库,07年已经出现了异常,然而直到08年12月,才执行了自我修复,然而这种修复在当时没有影响到索引,而是根据前面的结论,继续潜伏一段时间后,才显出tid暴增的问题。

看来,手工修改数据ID,增加4个0之后,数据主键的索引会更新,但不会影响自增(AUTO_INCREMENT)基数。

而数据库出现故障之后,修复恢复数据库时,自增基数会根据索引值的最大ID进行递增。

updated:直接验证修改当前一条数据ID,末尾增加两个零。插入一条新记录,数据是在这末尾加两0的数据ID加1,看来在数据库正常运行情况下,MyISAM格式的数据表ID自增是基于最大值。这应该是MySQL5采用来避免数据主键冲突的最简单方式。

2012年10月28日 6:07 下午 fisher 分类: javascript, 技术, 知识原野

Javascript模块化编程(一):模块的写法

作者: 阮一峰

日期: 2012年10月26日

随着网站逐渐变成”互联网应用程序“,嵌入网页的Javascript代码越来越庞大,越来越复杂。

网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等……开发者不得不使用软件工程的方法,管理网页的业务逻辑。

Javascript模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。

但是,Javascript不是一种模块化编程语言,它不支持”“(class),更遑论”模块”(module)了。(正在制定中的ECMAScript标准第六版,将正式支持”类”和”模块”,但还需要很长时间才能投入实用。)

Javascript社区做了很多努力,在现有的运行环境中,实现”模块”的效果。本文总结了当前"Javascript模块化编程"的最佳实践,说明如何投入实用。虽然这不是初级教程,但是只要稍稍了解Javascript的基本语法,就能看懂。

一、原始写法

模块就是实现特定功能的一组方法。

只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块。

  function m1(){
//…
}

function m2(){
//…
}

上面的函数m1()和m2(),组成一个模块。使用的时候,直接调用就行了。

这种做法的缺点很明显:”污染”了全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系。

二、对象写法

为了解决上面的缺点,可以把模块写成一个对象,所有的模块成员都放到这个对象里面。

  var module1 = new Object({

_count : 0,

m1 : function (){
//…
},

m2 : function (){
//…
}

});

上面的函数m1()和m2(),都封装在module1对象里。使用的时候,就是调用这个对象的属性。

  module1.m1();

但是,这样的写法会暴露所有模块成员,内部状态可以被外部改写。比如,外部代码可以直接改变内部计数器的值。

  module1._count = 5;

三、立即执行函数写法

使用”立即执行函数“(Immediately-Invoked Function Expression,IIFE),可以达到不暴露私有成员的目的。

  var module1 = (function(){

var _count = 0;

var m1 = function(){
//…
};

var m2 = function(){
//…
};

return {
m1 : m1,
m2 : m2
};

})();

使用上面的写法,外部代码无法读取内部的_count变量。

  console.info(module1._count); //undefined

module1就是Javascript模块的基本写法。下面,再对这种写法进行加工。

四、放大模式

如果一个模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用”放大模式”(augmentation)。

  var module1 = (function (mod){

mod.m3 = function () {
//…
};

return mod;

})(module1);

上面的代码为module1模块添加了一个新方法m3(),然后返回新的module1模块。

五、宽放大模式(Loose augmentation)

在浏览器环境中,模块的各个部分通常都是从网上获取的,有时无法知道哪个部分会先加载。如果采用上一节的写法,第一个执行的部分有可能加载一个不存在空对象,这时就要采用”宽放大模式”。

  var module1 = ( function (mod){

//…

return mod;

})(window.module1 || {});

与”放大模式”相比,"宽放大模式"就是”立即执行函数”的参数可以是空对象。

六、输入全局变量

独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。

为了在模块内部调用全局变量,必须显式地将其他变量输入模块。

  var module1 = (function ($, YAHOO) {

//…

})(jQuery, YAHOO);

上面的module1模块需要使用jQuery库和YUI库,就把这两个库(其实是两个模块)当作参数输入module1。这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显。这方面更多的讨论,参见Ben Cherry的著名文章《JavaScript Module Pattern: In-Depth》

这个系列的第二部分,将讨论如何在浏览器环境组织不同的模块、管理模块之间的依赖性。

(完)

文档信息

2012年09月21日 5:13 下午 fisher 分类: HTML5, 知识原野

关于微数据

HTML5 微数据规范是一种标记内容以描述特定类型的信息,例如评论、人物信息或事件。每种信息都描述特定类型的项,例如人物、事件或评论。例如,事件可以包含 venue、starting time、name 和 category 属性。

微数据使用 HTML 标记(常为 <span> 或 <div>)中的简单属性为项和属性指定简要的描述性名称。以下示例是一个简短的 HTML 代码段,显示的是王富强的基本联系信息:

<div>
  我的名字是王富强,但大家叫我小强。我的个人首页是:
  <a href="http://www.example.com">www.example.com</a>
  我住在上海市富贵新村。我是工程师,目前在财富科技公司上班。
</div>

以下是用微数据标记的同一 HTML 内容:

<div itemscope itemtype="http://data-vocabulary.org/Person">
  我的名字是<span itemprop="name">王富强</span>,
  但大家叫我<span itemprop="nickname">小强</span>。
  我的个人首页是:
  <a href="http://www.example.com" itemprop="url">www.example.com</a>
  我住在上海市富贵新村。我是<span itemprop="title">工程师</span>,
  目前在<span itemprop="affiliation">财富科技公司</span>上班。
</div>

下面对此示例进行了详细说明:

  • 第一行中的 itemscope 表示,<div> 中所含的内容描述了某一项,而 itemtype="http://data-vocabulary.org/Person 表示该项是人物。
  • 人物项的每个属性均使用 itemprop 属性进行标识。例如,itemprop="name" 描述人物的姓名。

嵌套实体

上例显示了王富强的联系信息,但是不包含他的地址。下例则要显示同一段 HTML 内容,但是包含 address 属性。

<div itemscope itemtype="http://data-vocabulary.org/Person">
   我的名字是<span itemprop="name">王富强</span>,
   但大家叫我<span itemprop="nickname">小强</span>。
   我的个人首页是:
   <a href="http://www.example.com" itemprop="url">www.example.com</a>。
   我住在
   <span itemprop="address" itemscope
      itemtype="http://data-vocabulary.org/Address">
      <span itemprop="region">上海市</span>
      <span itemprop="locality">富贵新村</span>。
   </span>
   我是<span itemprop="title">工程师</span>,
   目前在<span itemprop="affiliation">财富科技公司</span>上班。
</div>

下面对此示例进行了详细说明:

  • address 属性自身便是一个项,包含它自己的属性集。它将 itemscope 属性放在声明 address 属性的项中,并使用 itemtype 属性来指定所描述的项类型,例如:<span itemprop="address" itemscope itemtype="http://data-vocabulary.org/Address">

如需更多示例,请参见嵌套项

日期和时间信息

若要明确指定日期和时间,请使用 time 元素及 datetime 属性。在该例中,startDate 属性指示了事件的开始日期。datetime 属性中的值使用 ISO 日期格式进行指定。这样,您可以为搜索引擎提供 ISO 格式的详细日期、时间和时区(“2009-10-15T19:00-08:00”),其中时区是可选信息;同时,可以通过用户易于理解的方式在网页上显示日期(“2009 年 10 月 15 日晚上 7 点”)。

<time itemprop="startDate" datetime="2009-10-15T19:00-08:00">2009 年 10 月 15 日晚上 7 点</time>

隐藏的内容

一般情况下,Google 不会显示隐藏的内容。也就是说,不向用户显示某些内容,而是使用隐藏文本为搜索引擎和网络应用程序单独标记信息。您应该标记用户访问您的网页时实际看到的文本。

本规则有几个例外情况。在某些情况下,向搜索引擎提供更详细的信息有很多好处,即使您不希望访问您网页的人看到这些信息。例如,如果餐馆的评分为 8.5 分,用户(而不是搜索引擎)会认为评分范围为 1 到 10 分。在该例中,您可以使用 meta 元素表示此信息,如下所示:

<div itemprop="rating" itemscope itemtype="http://data-vocabulary.org/Rating">
   评分:<span itemprop="value">8.5 分</span>
   <meta itemprop="best" content="10" />
</div>

下面对此示例进行了详细说明:

  • meta 标记用于指定不在网页上显示的其他信息,在该例中,最高得分实际上是 10 分。该属性值使用 content 属性进行指定。

同样,以 ISO 持续时间格式提供事件持续时间也可以确保此信息正确显示在搜索结果中,如下所示:

持续时间:
<span>1.5 小时<meta itemprop="duration" content="PT1H30M" />
</span>

下面对此示例进行了详细说明:

  • 使用 meta 标记可以指定属性的值(在该例中是持续时间)。这样,您就可以使用 content 属性的值(“PT1H30M”)以 ISO 8601 持续时间格式指定此持续时间,同时仍以用户易于理解的方式在网页上显示持续时间(“1.5 小时”)。
  • Google 会查看 meta 元素的父元素,以识别 meta 标记中以其他方式表示的信息。因此,在该例中,请务必确保meta 标记的直接父节点位于文字“1.5 小时”的外围。

对于特定词汇和示例,请参见:

要检查此类标记,请使用丰富网页摘要测试工具

已更新 07/23/2011