2009 年 04 月

浏览模式: 标准 | 列表 | 图文
扩展JQuery Ajax请求错误机制

扩展JQuery Ajax请求错误机制

如何对ajax的错误进行更好的处理?本文给出了一个简单的解决方案。想当于类的扩展和继承一样。有新意,一直以来,对于框架我们要么是扩展,要么是写新方法,就从来没有想过要继承这些方法。所以,作者这个给了我很多启发。

原文:http://www.cnblogs.com/lyk831216/archive/2009/04/24/1442791.html

JQuery使我们在开发Ajax应用程序的时候提高了效率,减少了许多兼容性问题,但时间久了,也让我们离不开他。比如简单的Jquery Ajax请求的封装让我们忘却了最原始的XmlHttpRequest对象和他的属性,方法,也让我们远离事情的真相。

在Ajax项目中,经常遇到需要服务器端返回错误的消息提示,或者消息码之类的数据。查过一些帮助,解决方案,很多网站是返回错误的消息JSON数据或者 脚本,这种方式当我们用JQuery.ajax()的时候出现了问题,jquery.ajax()回调函数success(data)的data参数可能 是 xmlDoc, jsonObj, html, text, 等等...这取决于我们dataType设置和MIME.很多时候我们的错误处理都是统一的处理,不管你请求的是XML,JSON...。不光不好统一, 还容易出现解析错误等等情况。

参考了Prototyp框架的做法,做了一个Jquery的错误扩展。

原理:Prototype思路是把服务器处理结果状态信息写在Header里面,这种方式既保证了reponse body的干净,同时适应XML,JSON,HTML,Text的返回情况。

   服务器端只需要 Response.AddHeader("Error-Json", "{code:2001,msg:'User settings is null!',script:''}");

实现:为了不影响原有的Jquery.ajax方法,同时不破坏jquery库源文件,做了如下扩展,代码很简单都能看懂:

;(function($){
var ajax=$.ajax;
$.ajax=function(s){
var old=s.error;
var errHeader=s.errorHeader||"Error-Json";
s.error=function(xhr,status,err){
var errMsg = window["eval"]("(" + xhr.getResponseHeader(errHeader) + ")");
old(xhr,status,errMsg||err);
}
ajax(s);
}

})(jQuery);

使用方法:

  服务器端:我们是对错误进行扩展,如果要让jquery.ajax破获[膘叔:应该为捕获]错误,必须要服务器端返回非200的错误码,由于Opera浏览器下面对 400以上的错误码,都无法获得请求的Header,建议如果要支持Opera,最好返回30*错误,这是Opera能接受Header的错误范围。没有 做包装,可以再单独把Catch内容出来。

try {
context.Response.Write(GetJson(context));
throw new Exception("msg");
}
catch {
context.Response.ClearContent();
context.Response.StatusCode = 300;
context.Response.AddHeader("Error-Json", "{code:2001,msg:'User settings is null!',script:''}");
context.Response.End();
}

 客户端:

$.ajax({
url: this.ajaxUrl,
type: "POST",
success: callback,
error: function(xhr,status,errMsg){
alert(errMsg.code+"<br/>"+errMsg.msg);
}
});

也许不是最好的,但觉得用起来很方便,忘了个写新增参数errorHeader:"Error-Json",这个header头key根据你后台设定配置。

phpoo.com实验中

phpoo.com实验中

phpoo.com目前已经用supesite架设起来了。原来的uchome功能迁移到了home.phpoo.com
资料我也在逐步转移,然后仍然会收集一些相关的资料
同时也欢迎大家去投稿,只是我会审核一下,因为这样才能保证文章的质量。

希望phpoo.com能够走的更远吧。
如果你有什么新的想法,也可以告诉我。我目前已经有一些小的想法,正在想办法实现和尝试

[知道分子]Linux 省电十招

[知道分子]Linux 省电十招

我的笔记本装上ubuntu后,只能使用4小时不到,但使用xp可以将近7小时。所以看到这个标题的时候就激动的记录了下来。。

原文:http://hutuworm.blogspot.com/2009/04/linux.html


1. Linux Kernel 2.6.21 开始支持 Tickless(此前的内核默认设置为 1000Hz timer tick),于是系统空闲时不再无故骚扰 CPU,可以节省大量能耗。Fedora 7+ 以及目前的 Ubuntu Linux 发行版都含有 Tickless 特性,而 RHEL 则要到版本 6 才会随新版本内核正式支持该特性(预计 2010年上市)。检查你的 Linux 系统是否支持 Tickless: watch --interval=1 cat /proc/interrupts ,若 timer 中断值并非以 1000 为步进单位增加,则说明该内核支持 Tickless。

2. 编译内核(make menuconfig):

  • 启用 Tickless: Processor type and features -> [*] Tickless System (Dynamic Ticks)
  • 启 用 CONFIG_USB_SUSPEND: Device Drivers -> USB support -> [*] USB selective suspend/resume and wakeup (自动禁用 UHCI USB,可以节省约 1 watt)

3. PowerTOP 可以找出计算机闲置时哪些进程耗电最多。(Kernel Hacking -> [*] Collect kernel timers statistics) 详见: http://www.lesswatts.org/projects/powertop/

4. 启用 power aware CPU scheduler(Scheduler Power Saving Mode): echo 1 > /sys/devices/system/cpu/sched_mc_power_savings

5. RHEL 5.3 支持 Intel Core i7 (Nehalem) 的电源管理功能。

6. 启用 irqbalance 服务,既可以提升性能,又可以降低能耗。irqbalance 用于优化中断分配,它会自动收集系统数据以分析使用模式,并依据系统负载状况将工作状态置于 Performance mode 或 Power-save mode。处于 Performance mode 时,irqbalance 会将中断尽可能均匀地分发给各个 CPU core,以充分利用 CPU 多核,提升性能。处于 Power-save mode 时,irqbalance 会将中断集中分配给第一个 CPU,以保证其它空闲 CPU 的睡眠时间,降低能耗。(详见:http://www.irqbalance.org/documentation.php )

7. 禁用 pcscd,该进程会阻碍 USB 子系统进入 Power-save mode。

8. 将 VM dirty writeback time 延长至 15 秒: echo 1500 > /proc/sys/vm/dirty_writeback_centisecs

9. 启用 noatime 文件系统选项: mount -o remount,noatime / (noatime 禁止更新 atime,可以节省大量 I/O,但为了避免 atime 相关应用程序出现问题,建议启用 relatime 代之: mount -o remount,relatime / ,relatime 自 Kernel 2.6.29 起为默认设置。)

10. 禁止 hal 轮询你的 cdrom: hal-disable-polling --device /dev/cdrom

* 关于 Linux 节能的更多信息,请看: http://www.lesswatts.org

[向东]简单的PHP的任务队列

[向东]简单的PHP的任务队列

来自向东:http://www.xiangdong.org/blog/post/1743/

文章太长,不作过多介绍,反正,文章的头部就说明了大概的意思。。。
原文如下:
写了一个简单的队列任务处理。多进程任务,异步任务可能会用到这个(主要是命令行应用)
比如,任务的某个一个环节速度十分不稳定,可能执行几秒,也可能执行几分钟,
我就可以把那个环节包括前面的部分扔进队列,多跑几个进程,同时往队列里面写。
然后后面比较快的环节只跑一个处理任务就OK了。让整体速度达到更好的效果。

write.php: 将任务写入队列

<?php
/*
产生队列
*/
//用微秒生成队列文件名。因为会有多个队列,所以加了一个identifier来区分各个队列
function mt($identifier='default')
{
return sprintf("%.6f.%s",strtok(microtime(),' ')+strtok(''),$identifier);
}

while(1) //实际中尽量不要while(1) 非要while(1)记得任务完成要break
{
if(count(glob('./queue/*.identifier'))>=10) //队列最大长度,不限制的话硬盘可能会受不了哦。
{
sleep(1);//记住这里要sleep,否则队列满了cpu占用很高
continue;
}
$url = 'www.'.time().'.com'; //随便举个例子,我用时间戳生成了一个网址
echo "$url\r\n";
$fp = fopen('./queue/'.mt('identifier'),'w');
fwrite($fp,$url);
fclose($fp);
sleep(1);//这里不需要sleep,我sleep是因为我的任务太简单。
}
?>

read.php:

<?php
/*
处理队列
*/

while(1) //实际程序最好不要while(1)如果while(1),记得处理完任务要break
{
if($queue = glob('./queue/*.identifier'))
{
$q = array_shift($queue);
$url = file_get_contents($q);
echo $url."\r\n";
unlink($q);
}
sleep(1);//这里要不要sleep或sleep多久自己凭感觉来。
}
?>

相关的资料:双向队列

baidu和google上没有查到PHP双向队列的资料,搜索到java的双向队列定义如下:双向队列(双端队列)就像是一个队列,但是你可以在任何一端添加或移除元素。
而双端队列是一种数据结构,定义如下:
A deque is a data structure consisting of a list of items, on which the following operations are possible.
* push(D,X) -- insert item X on the rear end of deque D.
* pop(D) -- remove the front item from the deque D and return it.
* inject(D,X) -- insert item X on the front end of deque D.
* eject(D) -- remove the rear item from the deque D and return it.
Write routines to support the deque that take O(1) time per operation.

翻译:双端队列(deque)是由一些项的表组成的数据结构,对该数据结构可以进行下列操作:
push(D,X) 将项X 插入到双端队列D的前端
pop(D) 从双端队列D中删除前端项并将其返回
inject(D,X) 将项X插入到双端队列D的尾端
eject(D) 从双端队列D中删除尾端项并将其返回
编写支持双端队伍的例程,每种操作均花费O(1)时间

百度百科:(deque,全名double-ended queue)是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。

转贴一个使用Php数组函数实现该功能的代码:

<?php
//Input limit double-ende queue
class DoubleEndedQueue1 {
var $queue = array();
function add($var){
return array_push($this->queue, $var);
}
function frontRemove(){
return array_shift($this->queue);
}
function rearRemove(){
return array_pop($this->queue);
}
}

//Output limit double-ende queue
class DoubleEndedQueue2 {
var $queue = array();
function remove(){
return array_pop($this->queue);
}
function frontAdd($var){
return array_unshift($this->queue, $var);
}
function rearAdd($var){
return array_push($this->queue, $var);
}
}

//Test code
$q = new DoubleEndedQueue1;
$q->add('aaa');
$q->add('bbb');
$q->add('ccc');
$q->add('ddd');

echo $q->frontRemove();
echo "<br>";
echo $q->rearRemove();
echo "<br>";
print_r($q->queue);
?>
array_push -- 将一个或多个单元压入数组的末尾(入栈)
array_unshift -- 在数组开头插入一个或多个单元
array_pop -- 将数组最后一个单元弹出(出栈)
array_shift -- 将数组开头的单元移出数组

// 来自 PHP5 in Practice (U.S.)Elliott III & Jonathan D.Eisenhamer
<?php
// A library to implement queues in PHP via arrays
// The Initialize function creates a new queue:
function &queue_initialize() {
// In this case, just return a new array
$new = array();
return $new;
}
// The destroy function will get rid of a queue
function queue_destroy(&$queue) {
// Since PHP is nice to us, we can just use unset
unset($queue);
}
// The enqueue operation adds a new value unto the back of the queue
function queue_enqueue(&$queue, $value) {
// We are just adding a value to the end of the array, so can use the
// [] PHP Shortcut for this. It's faster than using array_push
$queue[] = $value;
}
// Dequeue removes the front of the queue and returns it to you
function queue_dequeue(&$queue) {
// Just use array unshift
return array_shift($queue);
}
// Peek returns a copy of the front of the queue, leaving it in place
function queue_peek(&$queue) {
// Return a copy of the value found in front of queue
// (at the beginning of the array)
return $queue[0];
}
// Size returns the number of elements in the queue
function queue_size(&$queue) {
// Just using count will give the proper number:
return count($queue);
}
// Rotate takes the item on the front and sends it to the back of the queue.
function queue_rotate(&$queue) {
// Remove the first item and insert it at the rear.
$queue[] = array_shift($queue);
}
// Let's use these to create a small queue of data and manipulate it.
// Start by adding a few words to it:
$myqueue =& queue_initialize();
queue_enqueue($myqueue, 'Opal');
queue_enqueue($myqueue, 'Dolphin');
queue_enqueue($myqueue, 'Pelican');
// The queue is: Opal Dolphin Pelican
// Check the size, it should be 3
echo '<p>Queue size is: ', queue_size($myqueue), '</p>';
// Peek at the front of the queue, it should be: Opal
echo '<p>Front of the queue is: ', queue_peek($myqueue), '</p>';
// Now rotate the queue, giving us: Dolphin Pelican Opal
queue_rotate($myqueue);
// Remove the front element, returning: Dolphin
echo '<p>Removed the element at the front of the queue: ',
queue_dequeue($myqueue), '</p>';
// Now destroy it, we are done.
queue_destroy($myqueue);
?>
猪流感来袭,网友们小心

猪流感来袭,网友们小心

03年的SARS,05年左右的禽流感,今年爆发的猪流感
每隔几年总要有点新鲜的病毒出来

网友们,注意身体,没事跑跑步健健身啥的
不该去的地方不要去,以防万一啊

当年SARS是隔离。如今老美的病例几乎是中一个倒一个。
坚持啊

征集PHPOO.COM的未来走向

征集PHPOO.COM的未来走向

PHPOO.com目前纯粹是用作UCHOME,原本我的想法也是类似于当成一个多用户博客来运作的。
但事实上,效果并不明显。

所以,我现在在考虑,是否使用supesite之类的CMS,把它打造成一个PHP的资讯、学习站点。
征集一下意见。。。

我现在的博客上的一部分资料转移过去,同时,收集一些比较经典、常用的资料。
再进行细分,不知道是否可行。

几个ZendStudio使用教程

Zendstudio.net,看这个网站的名称就知道,它是专注于zs工具的。
事实上也确实是这样的。站长还提供了一些KEY的生成工具,阿弥陀佛,罪过罪过。。

站长不但对ZS有研究,同时还本着开源的心态,把自己的一些心得整理出来,是flash的哦。大家可以在线观看。。
站长把一些5.5和6.1的使用教程都列出来了。
如果您是使用6.1的话,那就比较方便了。。。直接打开:http://www.zendstudio.net/zend-studio-tutorial/,就可以看到教程。

  1. zend studio 6.1中文视频教程-快速入门
  2. Zend Studio For Eclipse 6.1 视频教程-调试php程序
  3. 让zend studio for eclipse支持xdebug(视频教程)
  4. 在zend studio for eclipse中使用xdebug调试php程序
  5. 在zend studio for eclipse中寻找消失了的zend studio 5.5特色功能(筹备中…)
  6. 使用profile来优化你的php程序性能,提高程序效率(筹备中…)

新站上只有6.1的教程,如果你还在使用ZS 5.5,不用担心,这里也有:

  1. 基础部分:
    1. ZDE的初级安装教程(图)
    2. Zend Studio 5.5.1 界面详细介绍及菜单、工具栏功能详解(图)
    3. Zend Studio 首选项(preferences)功能、设定详解(图)
    4. Zend Studio的特色功能——模板(templates)
    5. zend studio的特色功能——代码片段(code snippets)
    6. Zend Studio快捷键一览表
    7. zend studio 5.5无法打开主界面故障解决方法一例
    8. 修改zend studio 的默认字体 让编辑器看起来更舒服
    9. 用Zend Studio管理数据库—zde的SQL管理器功能介绍

  2. 提高部分:
    1. 服务器调试——Zend Debugger 的安装教程
    2. Zend Studio的远程调试(服务器调试)技术 Zend Debugger(一)
    3. Zend studio的项目管理和服务器调试(视频教程)

-EOF-
写了这么多,也贴了N多链接,就再贴一下zendstudio.net站长的资料吧。。。
大家随便YY去吧

  • 昵称:徐徐
  • 英文名:gently
  • MSN:my-msn
  • 身高:跟姚明没得比
  • 三围:您所在的用户组无权查看该信息
  • 介绍:目前处于IT食物链底层,若在万恶的旧社会,那就是被剥削被压迫的那个阶层。
  • 人生关键词:积极、自信、踏实。
SSH连接时的乱码解决方法

SSH连接时的乱码解决方法

ssh连接时,发现屏幕上一堆乱码,恐怕这种事情谁都遇到过吧。(我是使用SSH secure shell登录的)
这种情况的发生大多是安装时,语言包选择为中文导致的。一般有以下几种解决方法

1、RH(估计centOS也行)
vim /etc/sysconfig/i18n
内容改为:
LANG="zh_CN.GB18030"
LANGUAGE="zh_CN.GB18030:zh_CN.GB2312:zh_CN"
SUPPORTED="zh_CN.GB18030:zh_CN:zh:en_US.UTF-8:en_US:en"
SYSFONT="lat0-sun16"

2、UBUNTU
中文版的ubuntu遇到这种问题,可以尝试使用putty,因为putty可以通过修改 font, character set 设置来解决。
设置:
Window -> Appearance -> Font settings 选择宋体或新宋体:
Window -> Translation -> Character set translation on received data 选择 UTF-8:
然后基本就没有问题了,

或者尝试使用secureCRT登录,这款软件也能够自动识别。

再或者尝试把语言换为英文?
修改Ubuntu的命令行语言环境的2个步骤:

1、修改/etc/default/locale
如不存在则新建一个
如下:
LANG='en_US' #中文可以用zh_CN
LANGUAGE='en_US:en' #中文可以用zh_CN:zh

2、reboot即可
locale命令可以列出当前系统所用的所有语言设置

即使你搜索google,基本上也只有这几种解决方案了。呵呵,全部列出来,希望有用

数组非数字键名引号的必要性

数组非数字键名引号的必要性

风雪之隅的网站上大多是对PHP的底层进行关注的文章,如果对PHP的核心内容有兴趣不妨多翻阅一下他的网站。

本文的标题,其实是一个老问题了。
大家都知道,PHP对于没有引号的字符串,会当成常量来处理,如果该常量不存在,则直接输出该字符串。也就是多做了几步处理。
事实上,上面的这个知识点,很早就知道,但,不是我自己研究出来的。虽然自己写过代码进行测试过。

雪候鸟则直接从OPCODE上进行查看,给你一个直观印象。好,我们来看看原文吧
地址:http://www.laruence.com/2009/04/24/695.html
内容:
我看到过很多人操作数组的时候, 对于数组中的非数字键名不使用引号,

$array[key] = $value;

我可以理解有些人可能会觉得这样的代码很”整洁”, 并且也能正常执行.
更甚至,如果他很”幸运的”php配置的好:

error_reporting = ~E_NOTICE

他也许永远都沉浸在自己的”整洁”风格中, 看不到任何的NOTICE提示, 也不会意识到, 他这么做, 能损失多少的性能~

来, 我们一起来看看:

good.php:
<?php
$array = array();
$i = 0;
while(++$i < 1000){
$array['good'] = 2;
}
?>

bad.php:
<?php
$array = array();
$i = 0;
while(++$i < 1000){
$array[good] = 2;
}
?>
分别看运行时间(多次平均时间):
加引号的:
$ time php -f good.php

real 0m0.013s
user 0m0.005s
sys 0m0.007s
不加引号的:
$ time php -f bad.php

PHP Notice: Use of undefined constant bad - assumed 'bad' in /home/huixinchen/tmp/bad.php on line
(此处省略999行NOTICE)
real 0m0.100s
user 0m0.020s
sys 0m0.029s
看看,差别有多大?
哦, 或许我们应该模拟一下那些”幸运的”人们的情况, 去掉花费在记录NOTICE的开销, 看看~
$ time php -f bad.php

real 0m0.037s
user 0m0.018s
sys 0m0.018s
我们可以看出, 基本上, 使用引号,和不使用引号的效率损失在3倍以上

那么, 这些效率损失到哪里去了呢?

我们分别看下, 俩个文件生成的OPCODE序列:

good.php :

filename: /home/huixinchen/tmp/good.php
compiled vars: !0 = $array, !1 = $i
line # op fetch ext return operands
-------------------------------------------------------------------------------
2 0 INIT_ARRAY ~0
1 ASSIGN !0, ~0
3 2 ASSIGN !1, 0
4 3 PRE_INC $3 !1
4 IS_SMALLER ~4 $3, 1000
5 JMPZ ~4, ->9
5 6 ZEND_ASSIGN_DIM !0, 'good'
7 ZEND_OP_DATA 2, $6
6 8 JMP ->3
8 9 RETURN 1
10* ZEND_HANDLE_EXCEPTION
bad.php :
filename: /home/huixinchen/tmp/bad.php
compiled vars: !0 = $array, !1 = $i
line # op fetch ext return operands
-------------------------------------------------------------------------------
2 0 INIT_ARRAY ~0
1 ASSIGN !0, ~0
3 2 ASSIGN !1, 0
4 3 PRE_INC $3 !1
4 IS_SMALLER ~4 $3, 1000
5 JMPZ ~4, ->10
5 6 FETCH_CONSTANT ~5 'bad'
7 ZEND_ASSIGN_DIM !0, ~5
8 ZEND_OP_DATA 2, $7
6 9 JMP ->3
8 10 RETURN

我们可以看出(其实,根据NOTICE的提示也知道), PHP会把没有引号引起来的键名当作是常量去获取, 当找不到的时候, 抛出一个NOTICE, 然后再根据”常量明”生成一个字符串, 然后再讲这个字符串做为键名继续~

聪明的你一定会想到, 可能会出现如下不可预期的错误:

define('key_name' , 'laruence');
....
//省略很多行代码
$array[key_name] = 2; //变成了 $array['laruence'] = 2;
//这样的错误, 你会很郁闷吧?
明白了么? 数组中的非数字键的键名一定要有引号啊~
哦, 还记得有人会说, 那在字符串变量替换的时候, 写引号会导致错误,
恩, 标准写法:
$string = "variable value is {$array['key']}"

我很赞同:”be lazy”, 但是, lazy也是应该有原则的.

最后, 好的代码,不应该通过关闭error_reporting来伪装.

附注, FETCH_CONSTANT OPCODE中找不到常量的相关逻辑:

....
if (!zend_get_constant(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
opline->op2.u.constant.value.str.val,
opline->op2.u.constant.value.str.val);
EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;//获取"常量"名字符串
zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);//分配空间,生成字符串
}
....

——EOF——

膘叔最受不了的,就是discuz,特别是模版中的变量,全部是不含单引号的。写起来是方便啊。但是性能不敢恭维。所以common.inc.php的前面几句就是error_reporting了。。隐藏掉,看你怎么办,有本事你咬我呀。。

我还能怎么办?

SSH Client 会话空闲超时的解决办法

SSH Client 会话空闲超时的解决办法

摘抄这一篇文章的内容,是因为这两天正好用到。
SSH连接上服务器后,人走开了,或者去忙其他事情了,结果回来一看,光标不动了。原来已经断却了连接。
看到这篇文章是24号,遇到问题是27号,因为对文章有印象,所以继续打开一看,原来我已经打上星标了。所以,摘抄下来。希望给其他使用UBUNTU的人也多一次GOOGLE搜索的命中率。

原文链接:SSH Client 会话空闲超时的解决办法

原文内容:

最近工作时经常要同时维护 3 台 Ubuntu 的主机,但当 SSH Client 窗口在几分钟没有键盘操作的时候,会话就会超时断线,特别对于 SFTP 管理时会更加烦躁 :(

找了一些关于 SSH Server 的资料,发现通过修改 sshd 的配置文件,能够让 SSH Server 发送“心跳”信号来维持持续连接,下面是设置的内容

打开服务器 /etc/ssh/sshd_config,我在最后增加一行

ClientAliveInterval 60
ClientAliveCountMax 1

这 样,SSH Server 每 60 秒就会自动发送一个信号给 Client,而等待 Client 回应,(注意:是服务器发心跳信号,不是客户端,这个有别于一些 FTP Client 发送的 KeepAlives 信号哦~~~),如果客户端没有回应,会记录下来直到记录数超过 ClientAliveCountMax 的值时,才会断开连接。

当然也可以开启 top 命令,还可以监测机器状态。