活在当下

我的一位叔叔为给妻子治病卖了车,卖了房子,卖了公司,倾家荡产,孩子都只能寄居奶奶家。妻子过世的时候,连手表都没了,借钱办了丧事。以前我不能理解的,为什么妻子过世后一年他就再婚了。每次遇到什么事,我都会想,如果自己遇到了,会怎么办,怎么做。刚才聊这事,我问他“想不想小婶?”他想了一会儿,笑着问我“我想她能怎么着?我能怎么办?!能做的,我都做了。”问的我不知道怎么回答,只好诺诺的说“我以为你对她感情很深。”他说“是感情深呀!可是以后的日子还得接着过呀!”家里长辈说“你觉得感情深应该怎么样?他拉着小宇一家三口团圆去?!人有时候不能太执着,走投无路得放自己一条生路。”
我问他的孩子怎么想,出乎我意料的,孩子很平静的说“这是我爸的事,我觉得都行!”我问他对这件事的看法,他说“作为丈夫,他尽全力给老婆看病,照顾老婆,医生放弃他都没放弃!作为爸爸,虽然家里这么多事,他还是让我吃饱穿暖,有地方住,家长会一次没落。作为家人,他做什么决定我们都应该支持他。”我问他有没有什么担心,孩子不好意思的笑笑说“我妈刚办完事挺担心的,觉得没钱了,以后我俩怎么办呀?觉得他会不会受不了打击,出什么事。后来我问我爸有没有什么打算,他说他挣点钱,先把房赎回来,让我好好念书,别耽误高考。我突然就不担心了,觉得他挺有规划的。后来赎房子,他让我一块去,写上我名字,回来他带我出去吃饭。说他要娶一媳妇,给我娶一后妈。我问他是不是因为家里老人说怕我没人照顾,他说我都能搞对象的岁数了,不需要人照顾了。我说这你的事,你自己看着办吧!我祝福你,支持你。他说你这样我都不好意思了,想吃什么自己点吧!”
我把这事发到广播里,大家纷纷回复自己的看法,有人说“我觉得可以理解。重要的是:做好自己的事,不需要别人的理解!”有的说“为妻子尽心尽力做过了最后没能救回来,以后才可以心无愧疚不留遗憾的开始新生活,再婚也没什么,总要好好生活啊。”有的说“有些时候执着,只为不留人生遗憾,虽然钱用尽了,但至少以后的日子没有什么心理负担。这位大叔的解脱是精神层面,他在金钱上并不执着。”有的说“只要这人问心无愧就好了,他人如何评判都是瞎扯”。
一位友邻的回复让我很有启发,他说“这是一个把当下认真做好、尽人事不留遗憾的人。别人没权利随便judge他的生活(生命)”他当初把“当下”认真地尽力地做了,等平静之后,心里干干净净的接纳了另外一个人。因为问心无愧,才能坦坦荡荡的开始新的生活,重新开始自己的幸福。活在当下,是尽力的爱自己的家人,这样不留遗憾,不会后悔。也是认真的爱自己,生活的更好。
看萧秋水的《这一生,静待时光检验》关于当下、放下的描述:人生的每个阶段都会有丧失,我有时候看着人们痛苦,心存悲悯,然而无计可施,因为要走出来唯有靠自己,很难借助外力。
书、电影都是外力,它们是一种提醒,让人懂得,过去、现在、未来都有无数的人与自己命运相同。生命脆弱,意外无法阻挡,然而生命的基调,应该还是坚强、乐观。只不过这些提醒是否能够发挥作用,还是看它是否在人们的内心中真正产生影响和作用力,以及,人是否愿意付诸行动。
当下并不是孤立的存在,它是时间长河中人的生命里的一段,如果没有明确的人生目标来作为依托,单纯地活在当下,不仅无益,反而有害。人生目标是 do right things,而“活在当下”是 do things right。如果没有前者,只强调活在当下,那么有可能做的事情都偏离了人生的航向,放短了时间(当下)来看,是正确的,但放长了时段(一周、一月、一年、一生),却未必是正确的。

关于 php 截取中文的问题

众所周知,php 自带的 strlen 与 substr 函数没法处理中文字符,于是,我们会用 mb_ 系列函数替代。但是,没有 mbstring 库怎么办?这就需要我们自己写一个来替代了,废话不多说,先上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
if ( !function_exists('mb_strlen') ) {
function mb_strlen ($text, $encode) {
if ($encode=='UTF-8') {
return preg_match_all('%(?:
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)%xs',$text,$out);
}else{
return strlen($text);
}
}
}

/* from Internet, author unknown */
if (!function_exists('mb_substr')) {
function mb_substr($str, $start, $len = '', $encoding="UTF-8"){
$limit = strlen($str);

for ($s = 0; $start > 0;--$start) {// found the real start
if ($s >= $limit)
break;

if ($str[$s] <= "\x7F")
++$s;
else {
++$s; // skip length

while ($str[$s] >= "\x80" && $str[$s] <= "\xBF")
++$s;
}
}

if ($len == '')
return substr($str, $s);
else
for ($e = $s; $len > 0; --$len) {//found the real end
if ($e >= $limit)
break;

if ($str[$e] <= "\x7F")
++$e;
else {
++$e;//skip length

while ($str[$e] >= "\x80" && $str[$e] <= "\xBF" && $e < $limit)
++$e;
}
}

return substr($str, $s, $e - $s);
}
}

以上代码摘自 wp-utf8-excerpt 插件,效果可以见本站首页,所有文章摘要都是该插件负责截取的。

关于 Shellshock

相信各位应该早就知道了。。。昨天一大早起床就看到俩负责的国外厂商发的邮件
Screenshot_2014-09-27-19-59-33
之所以只有国外的,当然不是想说国内的厂商不负责,只是因为我个人不喜欢用国内的而已。咳咳扯远了。随手点开其中一封看了下:
Screenshot_2014-09-27-20-00-21
附上邮件中的原文链接: https://www.digitalocean.com/community/tutorials/how-to-protect-your-server-against-the-shellshock-bash-vulnerability
接下来说说应该怎么确定这个 bug

首先,在你的 shell 中执行以下语句

1
env VAR='() { :;}; echo Bash is vulnerable!' bash -c "echo Bash Test"

如果输出

1
2
Bash is vulnerable!
Bash Test

就代表漏洞存在
如果输出类似

1
2
3
bash: warning: VAR: ignoring function definition attempt
bash: error importing function definition for `VAR'
Bash Test

则不存在漏洞

修复漏洞:
APT-GET: Ubuntu / Debian
Update Bash to the latest version available via apt-get:

1
sudo apt-get update && sudo apt-get install --only-upgrade bash

Now check your system vulnerability again by running the command in the previous section (Check System Vulnerability).

YUM: CentOS / Red Hat / Fedora
Update Bash to the latest version available via the yum:

1
sudo yum update bash

Now check your system vulnerability again by running the command in the previous section (Check System Vulnerability).

大功告成

P.S. 坑爹的腾讯电脑管家闹笑话了
Screenshot_2014-09-27-19-55-19
Screenshot_2014-09-27-19-55-29
69b019d1gw1ekq1gfouswj20n80efwfu

javascript 使用四舍六入五成双法规范数字

最近因为一些特殊原因,要用到使用 四舍六入五成双 的规则进行有效数字的规范。百度了半天没找到解决方法,居然还有人说 Math.round 是用这种方法的,简直坑爹。。。于是我自写了个算法,要是有什么 bug 欢迎各位帮忙指正,谢谢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function get_significant_figure(num,len) {
var num=parseFloat(num);
var len=parseInt(len);
var _len=len;
if (parseFloat(num)==0) {
return num;
}
var yxsz=parseInt(String(num).replace(/[^\d]/g,""));
if (String(yxsz)[0]>=8) {
len-=1;
}
if (len<=0) {
len=1;
}
if (len>=String(yxsz).length) {
return num.toPrecision(len);
} else {
var tmp=String((Math.floor(yxsz/Math.pow(10,(String(yxsz).length-len))*100)/100).toFixed(2)).split(".");
for (var i=0;i<tmp.length;i++) {
tmp[i]=parseInt(tmp[i]);
}
if (tmp[1]/100>0.5) {
tmp[0]++;
} else if (tmp[1]/100==0.5) {
if (parseInt(String(tmp[0])[String(tmp[0]).length-1])%2==1) {
tmp[0]++;
}
}
}
return (tmp[0]*(Math.pow(10,(String(yxsz).length+(parseInt(String(yxsz)[0])>=8?1:0)-String(tmp[0]).length)))*(num/yxsz)).toPrecision(_len);
}

原理是取出所有的有效数字,并截取要求截取的长度 +2,两位用来判断是否需要进位。最后填充 0 直至结果整数与开始时获取到的有效数字长度一致,并根据最初的有效数字与输入数字的比来还原结果,如果长度不符合要求就继续填充 0。例如 3.16501 要求保留三位有效数字,那就是这样的 3.16501–>316501–>31650–>316.50–>316–>3161e(4-3)(3.165/3165)–>3160–>3.16。

P.S. 我们还要求首位有效数字如果大于等于 8 则多看一位。

怎样输入完美的TeX公式

不要以为有了 TeX 你的公式就完全无可挑剔,TeX
输入的公式虽然不假思索就可以比其它程序来的漂亮,但是我们的目的不是跟其它程序比较。我们的目的是用最优雅的方式来表达我们的思想。TeX 只是一个工具,用它能创造出一流的数学书,也能写出一堆漂亮的垃圾。我见到过的最好和最糟的讲义都是用 TeX 写的。
下面来看看为了得到无懈可及的公式,几个需要注意的细节。这些好主意都来自 “The TeXbook”,我或多或少是在翻译,你有兴趣可以自己看看这本书。

  1. 手动调整公式中的字符间据

    在“TeX释疑”里我们遇到这个公式:

    我说是这样打出来的: $$\sum_{p\rm\;prime}f(p) = \int_{t>1}f(t)d\pi(t).$$

    其实为了避免引起不必要的复杂,我撒了一个谎 :) 你用这个方法输入的公式其实是这个样子:

    看不出区别吗?仔细看着 f(t) 和 dPi(t) 之间的间隔,是不是小了一点?
    上面的公式其实少了一个地方,它本来应该是: $$\sum_{p\rm\;prime}f(p) = \int_{t>1}f(t)\,d\pi(t).$$

    “\,” 是一个 thinspace, 如果没有它 f(t) 和 dPi(t) 就会靠的太近,\, 的大小是 1/6 quad, 一个 quad 的长度跟字体大小有关系,是一个 “M” 的宽度(1em)。看到了?TeX 的公式是非常考究的,有时你必须自己手动调整公式里字符的间距,否则你的公式就只是 99% 的完美,而不是 100%.
    还有一种情况,双重积分号如果这样输入: $$\int\int_D dx\,dy$$ 就会变成这样:

    显然那两个弯离得太远。你应该这样输入: $$\int\!\!\!\int_D dx\,dy$$ 结果才会是你想要的:

    两个积分号之间距离减少了3个thinspace. 因为 ! 就是 -1/6 quad.
    另外,花括号也需要特别注意: 如果表示一个序列,你可以这样写: $\{1,2,\ldots,n\}$

    结果是正确的:

    但是,如果你想把一个集合

    用这种方法打出来: $\{x\mid x>5\}$

    就会得到这种结果:

    因为中间的 “|” 两旁有比较大的间隙,花括号两端里面的空间显得小了点。用 \, 在两端加上 thinspace 就更加好看了。
    如果你想用 $|-x|=|+x|$

    表示

    其实你得到的是

    因为 TeX 实际上不理解数学,它认为你想把 “|” 和 “x” 相加减,结果在它们之间插入了过多的空间。为了消除这个误解,你必须说: $\left|-x\right|=\left|+x\right|$

    \left 和 \right 告诉 TeX,”|” 是一个分界符而不是一个操作数。这是对付一台“试图变得聪明的电脑”的小窍门。
    看到这些你是不是觉得“怎么TeX并不是我想象中的那么聪明?”对。TeX 绝对没有你聪明,机器就是机器,它其实不理解数学。在这种时候只有人的判断才是正确的。
    其实这只是一个视觉才能感受到的东西,你不可能记住所有这些。开始时你不用过于专心于这些细节,当你发现一个公式看起来确实有问题时才去做这些细节的调整。久而久之你就会积累很多经验,直接就可以得到最好的效果。

    想一想应该怎样输入以下公式?特别注意间隔。


  2. 两种不同的逗号。


    一个 TeX 的初学者可能会打出这样的公式: for $x = a, b$, or $c$.
    这样的结果是图中上面那一个。 比较一下下面的那个,它是这样打出来的: for $x = a$, $b$, or $c$.

    第一种作法中,逗号被作为了公式中的逗号,就像 “f(a,b)” 里的;而第二种写法中,逗号被作为了文章里的普通逗号,这两种逗号是不同的。公式里的逗号后面的间距比文章里的要小,这样第一个公式里出现两种不同大小的间隔,这是很不好看的。

    而且公式里的逗号处不可能被断行,因为你明显不希望 “f(a,b)” 这样的结构被自动分开。这样第一个公式的逗号处不可能被断开,这会影响断行的效果。在这个句子里,那个逗号明显应该是文章中的普通逗号,它不应该在数学公式里,所以第二种做法才是完全正确的。

    实际上 100% 完美的做法应该是这样: for $x = a$, $b$, or~$c$.

    加了一个 “~”. “or” 和 “$c$” 在断行时不应该被分断,这样你的文章看起来逻辑才会联贯。要是那个 “$c$” 出现在一行的开头,读者的注意力很容易被分散。

  3. 不同的省略号


    看到上面两行有什么不同吗?它们是分别用以下两行打出来的。 $x_1+x_2+\cdots+x_n$\quad and \quad $x_1,\ldots, x_n$ $x_1+x_2+\ldots+x_n$\quad and \quad $x_1,\cdots, x_n$

    哪一行好看一些?当然是上面的了,通常应该把 \cdots 用在 +,-,= 这类“高脚符号”之间,而把 \ldots 用在逗号这样的“矮子”符号之间。不幸的是我发现很多书籍错用了这两种符号,或者是因为它的作者使用的程序无法区分这两种符号。
    看看下面这些情况应该用哪个标点?

祝贺你看到了这里 :)
不过其实这页的标题根本就是错误的。知道这些“完美的细节”远远不够保证你写出“完美的公式”,虽然你很仔细的对你的公式精雕细琢,以至于没有一个书法家能对它的美观性有所异议,但是有可能你的思想要用完全不同的另一个公式写出来才能让人明白。

转载自 http://www.math.zju.edu.cn/ligangliu/LaTeXForum/tex_formula.htm

PHP 异常处理

异常(Exception)用于在指定的错误发生时改变脚本的正常流程。

什么是异常?

PHP 5 提供了一种新的面向对象的错误处理方法。
异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常。
当异常被触发时,通常会发生:

  • 当前代码状态被保存
  • 代码执行被切换到预定义的异常处理器函数
  • 根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本

我们将展示不同的错误处理方法:

  • 异常的基本使用
  • 创建自定义的异常处理器
  • 多个异常
  • 重新抛出异常
  • 设置顶层异常处理器

异常的基本使用

当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 “catch” 代码块。
如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 “Uncaught Exception” (未捕获异常)的错误消息。
让我们尝试抛出一个异常,同时不去捕获它:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
//create function with an exception
function checkNum($number)
{
if($number>1)
{
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception
checkNum(2);
?>

上面的代码会获得类似这样的一个错误:

1
2
3
4
Fatal error: Uncaught exception 'Exception' 
with message 'Value must be 1 or below' in C:\webfolder\test.php:6
Stack trace: #0 C:\webfolder\test.php(12):
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6

Try, throw 和 catch

要避免上面例子出现的错误,我们需要创建适当的代码来处理异常。
正确的处理程序应当包括:

  1. Try - 使用异常的函数应该位于 “try” 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
  1. Throw - 这里规定如何触发异常。每一个 “throw” 必须对应至少一个 “catch”
  1. Catch - “catch” 代码块会捕获异常,并创建一个包含异常信息的对象

让我们触发一个异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
//创建可抛出一个异常的函数
function checkNum($number)
{
if($number>1)
{
throw new Exception("Value must be 1 or below");
}
return true;
}
//在 "try" 代码块中触发异常
try
{
checkNum(2);
//If the exception is thrown, this text will not be shown
echo 'If you see this, the number is 1 or below';
}
//捕获异常
catch(Exception $e)
{
echo 'Message: ' .$e->getMessage();
}
?>

上面代码将获得类似这样一个错误:

1
Message: Value must be 1 or below

例子解释:

上面的代码抛出了一个异常,并捕获了它:

  1. 创建 checkNum() 函数。它检测数字是否大于 1。如果是,则抛出一个异常。
  1. 在 “try” 代码块中调用 checkNum() 函数。
  1. checkNum() 函数中的异常被抛出
  1. “catch” 代码块接收到该异常,并创建一个包含异常信息的对象 ($e)。
  1. 通过从这个 exception 对象调用 $e->getMessage(),输出来自该异常的错误消息

不过,为了遵循“每个 throw 必须对应一个 catch”的原则,可以设置一个顶层的异常处理器来处理漏掉的错误。

创建一个自定义的 Exception 类

创建自定义的异常处理程序非常简单。我们简单地创建了一个专门的类,当 PHP 中发生异常时,可调用其函数。该类必须是 exception 类的一个扩展。
这个自定义的 exception 类继承了 PHP 的 exception 类的所有属性,您可向其添加自定义的函数。
我们开始创建 exception 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "someone@example...com";
try
{
//check if
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
//throw exception if email is not valid
throw new customException($email);
}
}
catch (customException $e)
{
//display custom message
echo $e->errorMessage();
}
?>

这个新的类是旧的 exception 类的副本,外加 errorMessage() 函数。正因为它是旧类的副本,因此它从旧类继承了属性和方法,我们可以使用 exception 类的方法,比如 getLine() 、 getFile() 以及 getMessage()。

例子解释:

上面的代码抛出了一个异常,并通过一个自定义的 exception 类来捕获它:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  1. 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一条错误消息
  1. 把 $email 变量设置为不合法的 e-mail 地址字符串
  1. 执行 “try” 代码块,由于 e-mail 地址不合法,因此抛出一个异常
  1. “catch” 代码块捕获异常,并显示错误消息

多个异常

可以为一段脚本使用多个异常,来检测多种情况。
可以使用多个 if..else 代码块,或一个 switch 代码块,或者嵌套多个异常。这些异常能够使用不同的 exception 类,并返回不同的错误消息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "someone@example.com";
try
{
//check if
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
//throw exception if email is not valid
throw new customException($email);
}
//check for "example" in mail address
if(strpos($email, "example") !== FALSE)
{
throw new Exception("$email is an example e-mail");
}
}
catch (customException $e)
{
echo $e->errorMessage();
}
catch(Exception $e)
{
echo $e->getMessage();
}
?>

例子解释:

上面的代码测试了两种条件,如何任何条件不成立,则抛出一个异常:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  1. 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一个错误消息。
  1. 执行 “try” 代码块,在第一个条件下,不会抛出异常。
  1. 由于 e-mail 含有字符串 “example”,第二个条件会触发异常。
  1. “catch” 代码块会捕获异常,并显示恰当的错误消息

如果没有捕获 customException,紧紧捕获了 base exception,则在那里处理异常。

重新抛出异常

有时,当异常被抛出时,您也许希望以不同于标准的方式对它进行处理。可以在一个 “catch” 代码块中再次抛出异常。
脚本应该对用户隐藏系统错误。对程序员来说,系统错误也许很重要,但是用户对它们并不感兴趣。为了让用户更容易使用,您可以再次抛出带有对用户比较友好的消息的异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = $this->getMessage().' is not a valid E-Mail address.';
return $errorMsg;
}
}
$email = "someone@example.com";
try
{
try
{
//check for "example" in mail address
if(strpos($email, "example") !== FALSE)
{
//throw exception if email is not valid
throw new Exception($email);
}
}
catch(Exception $e)
{
//re-throw exception
throw new customException($email);
}
}
catch (customException $e)
{
//display custom message
echo $e->errorMessage();
}
?>

例子解释:

上面的代码检测在邮件地址中是否含有字符串 “example”。如果有,则再次抛出异常:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  1. 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一个错误消息。
  1. 把 $email 变量设置为一个有效的邮件地址,但含有字符串 “example”。
  1. “try” 代码块包含另一个 “try” 代码块,这样就可以再次抛出异常。
  1. 由于 e-mail 包含字符串 “example”,因此触发异常。
  1. “catch” 捕获到该异常,并重新抛出 “customException”。
  1. 捕获到 “customException”,并显示一条错误消息。

如果在其目前的 “try” 代码块中异常没有被捕获,则它将在更高层级上查找 catch 代码块。

设置顶层异常处理器 (Top Level Exception Handler)

set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数。

1
2
3
4
5
6
7
8
<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>

以上代码的输出应该类似这样:

1
Exception: Uncaught Exception occurred

在上面的代码中,不存在 “catch” 代码块,而是触发顶层的异常处理程序。应该使用此函数来捕获所有未被捕获的异常。

异常的规则

  • 需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。
  • 每个 try 或 throw 代码块必须至少拥有一个对应的 catch 代码块。
  • 使用多个 catch 代码块可以捕获不同种类的异常。
  • 可以在 try 代码块内的 catch 代码块中再次抛出(re-thrown)异常。

简而言之:如果抛出了异常,就必须捕获它。

转载自 http://www.w3school.com.cn/php/php_exception.asp

深圳男子状告中国联通封锁Google 法院受理了

6106a4f0gw1ek1gd73kw0j20c80hadhm
发布:2014-09-05 11:51:50 作者:互联网的那点事

【深圳男子状告中国联通封锁Google 法院受理了】26岁的汪龙自称是独立记者、民间法律工作者。他表示,从5月开始通过中国联通的网络无法访问Google、Gmail等网站,随后将中国联通深圳分公司和中国联通告上法庭。深圳福田法院接受了这项被称为“封锁Google全球第一案”的诉讼,并于9月4日开庭审理。

转载自 http://world.kankanews.com/device/2014-09-05/5343605.shtml

博主评: 其实不只中国联通,我大天朝想上 Google 都得用特别的方法。对于这一状,我觉得会败诉,封锁 Google 的不是联通,而是我大天朝。但是,这则消息在网上能够传播,也说明了大天朝的互联网还是相对自由的,只是,不知 zf 下一步会做什么。

在 wordpress 上使用 mailgun 发信

前几天研究多说插件的评论回复邮件通知(修改多说插件,实现评论邮件通知自定义样式)的时候,发现本博客用的主机封了 fsockopen 和 pfsockopen 两个函数,导致邮件无法正常发送,同时也不能连接 smtp 服务器发送邮件,只有 curl 可用。于是,想起了以前转过的一篇文章,免费超大量邮件发送服务Mailgun提供SMTP和API支持。将其替换了 wordpress 自带的邮件模块,发现效果还不错。虽然 QQ 邮箱有时候会拒收 = =|||

阅读全文

修改多说插件,实现评论邮件通知自定义样式

其实一开始改插件不是因为想自定义邮件样式,只是因为收不到提醒邮件让我以为多说不发提醒邮件呢(好吧我到现在多说的提醒邮件一封都没收到过)。另外,好久以前有过改插件的想法,但是因为当时技术不行只能作罢。博客太小,没什么人看,最终渐渐的也就忘记了。直到最近几个月,一直有个神经病来骚扰,让我认识到了能够及时的知道博客的最新评论是有多好(删掉然后把 IP 扔黑名单比较方便) = =
Screenshot_2014-09-01-07-09-42
虽然设置里有。
Screenshot_2014-09-01-07-11-16Screenshot_2014-09-01-07-11-28
但就是收不到,不是只有我一个人。

好了,接下来说说怎么改的吧。
无意之间访问了博客后台的评论区,发现本地数据库与多说的数据库是同步的,想必,这一定是多说插件干的,去官网看了下开发者文档,果然如此。附链接 http://dev.duoshuo.com/docs/50037b11b66af78d0c000009
有回调,那就好办了。现在需要知道的就是它被回调时调用的函数在哪里就行了。打开 ./plugins/duoshuo/WordPress.php,发现了第 991 行有这样一个函数:

1
2
3
4
5
6
	/**
* 从服务器pull评论到本地
*
* @param array $posts
*/
public function createPost($post){

直觉告诉我应该改这个函数。
于是在其 1066 行之后,插入了一行代码,仅用来测试验证我的想法

1
wp_mail("admin@imjs.work","new reply",var_export($data,1));

结果的确收到了邮件,之后,要做的就是对内容分析并且写入邮件通知功能的代码了。
感谢小蒋,邮件样式是从他这里扒的。当然要改成别人的邮件样式我也没意见。完全原创的小清新邮件样式:云端,放出源码
上源码,依旧是 1066 行以后加入:

1
2
3
4
5
6
7
8
   if ($data['comment_parent'] && $data['comment_author_email']!==trim(get_comment($data['comment_parent'])->comment_author_email)) { //当父级评论存在时并且父级评论作者不是当前评论作者时发送通知邮件
$send_mess='<div style="background:#fff;zoom:1;position:relative;z-index:1;margin:50px auto;"><!--小蒋原创!--><table width="556" cellspacing="0" cellpadding="0" border="0" align="center" style="margin: 0 auto; font: normal 12px/1 微软雅黑,Tahoma,Helvetica,Arial,sans-serif; background: #fff; line-height: 20px;"><tbody><tr><td height="115" background="http://apps.qiniudn.com/cloud-mail/header.jpg"><!--小蒋博客!--><div style="padding: 0 30px 40px;"><h2 style="color:#fff;font-size:14px;font-weight:normal;padding:0;"><span style="color: #ED5224">&gt;&nbsp;</span>您在&nbsp;<!--小蒋原创!--><a style="text-decoration:none;color: #ED5224;" href="' . get_option('home') . '" title="' . get_option('blogname') . '" target="_blank">' . get_option('blogname') . '</a>&nbsp;中的留言有回复啦!</h2></div><!--小蒋博客!--></td></tr><tr><td valign="top" background="http://apps.qiniudn.com/cloud-mail/body.jpg" style="padding: 0 25px;"><table width="100%"><tbody><tr><td><div style="font-size:12px;color:#777;padding:0px 6px 1px;"><!--小蒋博客!--><p>' . trim(get_comment($data['comment_parent'])->comment_author) . '&nbsp;同学,您曾在《&nbsp;' . get_the_title($data['comment_post_ID']) . '&nbsp;》中发表评论:</p><p style="color: #777;border: 1px solid #DDD;padding: 5px 8px 5px 8px;background-color: #FCFCFC;border-radius: 3px 3px 3px 3px;font-size: 12px;line-height: 22px;font-family: Consolas,Courier,minispace,Lucida Console;">' . nl2br(get_comment($data['comment_parent'])->comment_content) . '</p><!--小蒋原创!--><p>' . trim($data['comment_author']) . '&nbsp;给您的回复如下:</p><p style="color: #777;border: 1px solid #DDD;padding: 5px 8px 5px 8px;background-color: #FCFCFC;border-radius: 3px 3px 3px 3px;font-size: 12px;line-height: 22px;font-family: Consolas,Courier,minispace,Lucida Console;">' . nl2br($data['comment_content']) . '</p><p>您可以点击&nbsp;<a style="text-decoration:none; color:#12addb" href="' . htmlspecialchars(get_comment_link($data['comment_parent'])) . '" title="单击查看完整的回复内容" target="_blank">&nbsp;查看完整的回复內容</a><!--小蒋原创!-->,欢迎回访&nbsp;<a style="text-decoration:none; color:#12addb" href="' . get_option('home') . '" title="' . get_option('blogname') . '" target="_blank">' . get_option('blogname') . '</a>&nbsp;!</p></div></td></tr></tbody></table></td></tr><tr><td height="15" background="http://apps.qiniudn.com/cloud-mail/footer.jpg"></td></tr></tbody></table></div><!--小蒋博客!-->';
wp_mail(trim(get_comment($data['comment_parent'])->comment_author_email),'您在 [' . get_option("blogname") . '] 的留言有了回复',$send_mess,"Content-Type: text/html;charset=utf-8");
}
if (get_the_author_meta('user_email',get_post($data['comment_post_ID'])->post_author)!==$data["comment_author_email"] && trim(get_comment($data['comment_parent'])->comment_author_email)!==get_the_author_meta('user_email',get_post($data['comment_post_ID'])->post_author)) { //当评论用户不是本文作者并且被回复的父级评论作者不是本文作者时发送邮件,后面一个条件为了防止发送两封邮件
$send_mess_2='<div style="background:#fff;zoom:1;position:relative;z-index:1;margin:50px auto;"><!--小蒋原创!--><table width="556" cellspacing="0" cellpadding="0" border="0" align="center" style="margin: 0 auto; font: normal 12px/1 微软雅黑,Tahoma,Helvetica,Arial,sans-serif; background: #fff; line-height: 20px;"><tbody><tr><td height="115" background="http://apps.qiniudn.com/cloud-mail/header.jpg"><!--小蒋博客!--><div style="padding: 0 30px 40px;"><h2 style="color:#fff;font-size:14px;font-weight:normal;padding:0;"><span style="color: #ED5224">&gt;&nbsp;</span>您发表的文章&nbsp;<!--小蒋原创!--><a style="text-decoration:none;color: #ED5224;" href="' . htmlspecialchars(get_comment_link($data['comment_ID'])) . '" title="' . get_the_title($data['comment_post_ID']) . '" target="_blank">' . get_the_title($data['comment_post_ID']) . '</a>&nbsp;有回复啦!</h2></div><!--小蒋博客!--></td></tr><tr><td valign="top" background="http://apps.qiniudn.com/cloud-mail/body.jpg" style="padding: 0 25px;"><table width="100%"><tbody><tr><td><div style="font-size:12px;color:#777;padding:0px 6px 1px;"><p>' . trim($data['comment_author']) . '&nbsp;给您的回复如下:</p><p style="color: #777;border: 1px solid #DDD;padding: 5px 8px 5px 8px;background-color: #FCFCFC;border-radius: 3px 3px 3px 3px;font-size: 12px;line-height: 22px;font-family: Consolas,Courier,minispace,Lucida Console;">' . nl2br($data['comment_content']) . '</p><p>您可以点击&nbsp;<a style="text-decoration:none; color:#12addb" href="' . htmlspecialchars(get_comment_link($data['comment_ID'])) . '" title="单击查看完整的回复内容" target="_blank">&nbsp;查看完整的回复內容</a></p></div></td></tr></tbody></table></td></tr><tr><td height="15" background="http://apps.qiniudn.com/cloud-mail/footer.jpg"></td></tr></tbody></table></div><!--小蒋博客!-->';
wp_mail(get_the_author_meta('user_email',get_post($data['comment_post_ID'])->post_author),'您的文章 ['.get_the_title($data['comment_post_ID']).'] 有了回复',$send_mess_2,"Content-Type: text/html;charset=utf-8");
}

OK,大功告成。

效果:
QQ图片20140901075808

理解Linux系统中的load average(图文版)

一、什么是load average?
linux系统中的Load对当前CPU工作量的度量 (WikiPedia: the system load is a measure of the amount of work that a computer system is doing)。也有简单的说是进程队列的长度。
Load Average 就是一段时间 (1 分钟、5分钟、15分钟) 内平均 Load 。
我们可以通过系统命令”w”查看当前load average情况

1
2
[root@CNC-BJ-5-3N1 ~]# w
20:01:55 up 76 days, 8:20, 6 users, load average: 1.30, 1.48, 1.69

上面内容显示系统负载为“1.30, 1.48, 1.69”,这3个值是什么意思呢?

  • 第一位1.30:表示最近1分钟平均负载
  • 第二位1.48:表示最近5分钟平均负载
  • 第三位1.69:表示最近15分钟平均负载

PS. linux系统是5秒钟进行一次Load采样

二、load average值的含义
2.1 单核处理器
假设我们的系统是单CPU单内核的,把它比喻成是一条单向马路,把CPU任务比作汽车。当车不多的时候,load <1;当车占满整个马路的时候 load=1;当马路都站满了,而且马路外还堆满了汽车的时候,load>1
2173a04d-e43f-35bb-8933-22727960d54f

Load < 1

10ab4026-b112-39df-8ad1-21b5b5b5de1a

Load = 1

59162f56-18e2-33d3-80bc-b8ec7045b30d

Load >1

2.2 多核处理器
我们经常会发现服务器Load > 1但是运行仍然不错,那是因为服务器是多核处理器(Multi-core)。
假设我们服务器CPU是2核,那么将意味我们拥有2条马路,我们的Load = 2时,所有马路都跑满车辆。
2da046b5-0f2a-3519-b41f-f61fe56ee443

Load = 2时马路都跑满了

1
2
#查看CPU core 
grep 'model name' /proc/cpuinfo | wc -l

3. 什么样的Load average值要提高警惕
0.7 < load < 1: 此时是不错的状态,如果进来更多的汽车,你的马路仍然可以应付。 load = 1: 你的马路即将拥堵,而且没有更多的资源额外的任务,赶紧看看发生了什么吧。 load > 5: 非常严重拥堵,我们的马路非常繁忙,每辆车都无法很快的运行

4. 三种Load值,应该看哪个?
通常我们先看15分钟load,如果load很高,再看1分钟和5分钟负载,查看是否有下降趋势。
1分钟负载值 > 1,那么我们不用担心,但是如果15分钟负载都超过1,我们要赶紧看看发生了什么事情。所以我们要根据实际情况查看这三个值。

5. 通过Nagios配置Load监控告警
见文:http://heipark.iteye.com/blog/1340190

参考:
Understanding Linux CPU Load - when should you be worried?
http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages

Unix/Linux 的 Load 初级解释
http://www.dbanotes.net/arch/unix_linux_load.html

– heipark

转载自 http://heipark.iteye.com/blog/1340384