网站性能优化

最近在对一个项目进行优化,后端方面,因为程序主要逻辑已经定型,所以只能对目前的部分代码进行重构,不能进行大规模的重写。主要包括减少数据库的访问,使用memcached缓存ajax轮询请求数据;而也并不是每个页面或功能点都需要对数据进行memcached缓存的,根据用户访问量与产品业务逻辑的分析只需针对几个特定的页面,如专题页面,视频播放页面,直播视频简介页面。例如大规模的流量入口集中于专题页面,而该页面存在大量的数据库查询,很多操作都是通过ajax获取对应的视频信息,而这些信息在发布后一般是不会变动的,所以直接对视频数据缓存于memcached中。这样需要修改的代码较少且能很好的减轻数据库服务器的压力。不过这里主要谈下前端数据请求传递的优化。

前端方面优化的话则肯定要参考雅虎的yslow优化法则了。
在未优化前使用firefox的yslow附加组件给网站打分结果为“D” 或“C”,下面几项优化完成后,得分为“A”或“B”;可能普通用户在网速很好的时候体验上与之前没有什么不同,不过对于带宽有限的用户体验有了很大的改进。

Make fewer HTTP requests
This page has 8 external Javascript scripts. Try combining them into one.
This page has 3 external stylesheets. Try combining them into one.
This page has 21 external background images. Try combining them with CSS sprites.

1、js有公用的也有只有当前页面采用的,全部合并受困于cms独立的js文件,且自定义的js合并工作量大且需要再次调试完成,主要成员是当初这样制作时考虑的是对应页面加载对应javascript。其中有两个是网站分析相关的。
2、js文件工作量大且不利于调试,不过css就没有太多这方面的顾虑且便于修改调试。经过3天的努力把整站的34个css样式表全部合并为一个css文件了。还好当初做过css模块化重用的考虑,不过即使这样也还是删除了许多重复的代码。总大小160kb没要太大的变化,不过css样式表只有一个了。节约了很多连接请求啊。
3、这里当初构建前端页面的时候没有太考虑sprites,所以以至于有太多的琐碎css小图需要请求连接。只是现在css结构完全成形,修改起来会很麻烦,需要重新切图,修改css等等。这里暂时不做修改。

Grade F on Use a Content Delivery Network (CDN)
xxxx.net: 71 components, 5619.0K
s25.cnzz.com: 1 component, 6.6K
c.cnzz.com: 1 component, 0.5K
player.pplive.cn: 1 component, 276.5K
wwwimages.adobe.com: 1 component, 1.7K
icon.cnzz.com: 1 component, 0.4K

使用内容分发网络,不过对于非大型高并发的网站来说这点暂时还是能容忍的。

Grade F on Add Expires headers
对文件添加缓存过期时间,apache需要mod_expires.c模块的支持,对于网站上的静态内容可以设置为never expire,动态内容按图片/js/css的更新时间来设定缓存时间。用户第一次访问你的网站页面意味着需要很多次http请求,通过使用Expires文件头可以让内容具有缓存性。它避免接下来的页面访问中不必要的http请求,浏览器或代理使用缓存来减少http的请求次数与大小以加快页面的响应速度,而服务器在http响应中的Expires文件头信息则告诉客户端内容需要缓存多久。
ExpiresActive On
ExpiresDefault A600
ExpiresByType image/x-icon A2592000
ExpiresByType application/javascript A2592000
ExpiresByType text/css A604800
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType text/plain A86400
ExpiresByType application/x-shockwave-flash A2592000
ExpiresByType video/x-flv A2592000
ExpiresByType application/pdf A2592000
#ExpiresByType text/html A600
另外,当点击浏览器上的刷新,客户端发送的请求中均是max-age=0,表示validate操作,发送请求到服务器
要求检查cache,再更新cache,一般得到的是304 Not Modified,表示没变动。

Grade F on Compress components with gzip
gzip数据压缩传递,用户70%-80%的时间都是在等待数据从服务器上下载。gzip对数据的压缩率很高可以达到70%以上,可以很大程度的压缩数据,减少加载的时间。
且可传递的数据包括文档,css、js、图片、xml等数据都能通过gzip方式进行压缩传递。如上文的160kb的css文件通过apache deflate压缩传递回来只有32kb了。所以压缩数据进行传输对节省用户等待时间,提高用户的体验有很大的帮助。不过gzip需要浏览器与服务器同时支持,即服务器能够对数据进行压缩,浏览器能支持识别压缩的数据内容。好在现在主流的浏览器都是支持gzip与deflate压缩的,最常见的apache iis nginx等都是能够实现的。
Apache1.x 使用的是第三方的mod_gzip模块,Apache2.x则考虑到了传输数据压缩的问题,直接内置的mod_deflate模块,可以在httpd.conf中开启,重启服务器即可。
LoadModule deflate_module modules/mod_deflate.so
Nginx 开启Gzip

#nginx gzip
# ngx_http_gzip_module 模块支持
# output compression saves bandwidth
gzip              on;
gzip_proxied      any;
gzip_http_version 1.1;
gzip_min_length   1100;
gzip_comp_level   5;
gzip_buffers      8 16k;
gzip_types        text/plain text/xml text/css application/x-javascript application/xml application/xml+rss text/javascript application/atom+xml;
gzip_vary        on;
#gzip_disable     “MSIE [1-6]\.”;

Grade C on Put JavaScript at bottom
javascript主要是依赖cms原来的。所以对于这部分在页面构建是没有进行变动,不过现在javascript可以直接放到</body>上面了。

Grade E on Avoid CSS expressions
什么危害可以直接参考yahoo的解答
CSS表达式是一个强大的(危险)的方式动态设置CSS属性。他们支持在Internet Explorer版本5起,但与IE8开始被废弃。作为一个例子,可以设置的背景颜色交替每隔一小时,使用CSS表达式:

background-color: expression( (new Date()).getHours()%2 ? “#B8D4FF” : “#F08A00” );

在这里,表达方法接受一个JavaScript表达式。 CSS属性设置根据JavaScript表达式计算出来的结果。expression的表达方法在非ie浏览器没有效果,因此在跨浏览器设计中只针对Internet Explorer。

css表达式的问题是,他们比大多数人预期的更加频繁地计算。他们不仅在页面呈现和调整大小,滚动页面时,甚至当用户在页面上移动鼠标都会重新计算一次。给CSS表达式添加计数器能够跟踪表达式的计算频率。在页面上移动鼠标,可以很容易地产生超过10,000的计算量。

一个减少CSS表达式计算的方法之一是使用一次性的表达,他在第一个表达式求值时将结果赋值给指定的样式属性,用这个属性取代了CSS表达式。如果样式属性必须设置动态页面的整个生命周期,使用事件句柄来代替CSS表达式是一种方法。如果您必须使用CSS表达式,请记住,他们可能会评估了数千次,并可能会影响你的页面的性能。

Grade F on Configure entity tags (ETags)
配置ETags,简单点说ETags就是服务器与浏览器之间用于判断浏览器缓存与服务器端的数据是否匹配的机制。ETag实体是比last-modified-date更加灵活的机制。ETag是识别内容版本的唯一字符串,服务器通过还有ETag的响应头信息指定加载文件的ETag。
浏览器要验证一个文件,就用if-none-match文件头把ETag传回给服务器,如果ETag匹配,就会返回一个304状态码,这样就节省这个文件对应大小的字节数了。ETag格式限制就是字符串必须在双引号内,IIS的ETag格式是,Filetimestamp:ChangeNumber;Apache1.x和Apache2.x的ETag格式是Inode-size-timestamp。不过ETag存在的一个问题是,它是根据网站所在服务器的唯一属性来生成的,当浏览器请求的这文件即使目录,权限,大小,修改日期等一模一样但存在与另一台服务器上,ETag也不会匹配的。
如果你没有使用ETag验证,那么就去掉好了。而文件认证则是采用last-modified文件头了。Apache在.htaccess中加入 FileETag None 即可。有关IIS的ETag信息查看http://support.microsoft.com/?id=922733

此外还有
1、外域过多,dns查找时间过长。
页面中存在太多站外域名了,这样加大了dns查找的时间,其中完全可以规避掉的有adobe图片logo,另cnzz域名太多了,icon都独立为一个域名请求。可以考虑替换一个网站数据分析。google分析就很不错。

2、引用不存在的文件
如图片/css/js/ico等,特别是引用不存在的javascript文件,服务器会提示该文件不存在,而浏览器则还是会继续把它返回的数据当作javascript执行。加大浏览器的负担。

3、图片进行了缩放,如1000pxX500px的图片缩放为200pxX100px。img图片位显示的图片最好不要缩放。

4、html标签必须属性要添加上。如img的alt

5、还有如css/js 使用压缩工具进行文件压缩,推荐 yui compressor

上面的很多东西都是参考来自于yahoo 优化法则的,这里有份中文pdf,Yahoo-Web网站性能优化最佳实践

****文档参考****
http://www.cnblogs.com/yuyii/archive/2008/10/16/1312238.html
http://kangzj.net/how-to-enable-gzip-for-ur-website/
http://developer.yahoo.com/performance/rules.html
http://httpd.apache.org/docs/2.2/mod/mod_expires.html
http://wiki.nginx.org/NginxChsHttpGzipModule

yui compressor Error missing variable name identifier is a reserved word

yui compressor 是一个很好用的css、js文件压缩工具。在昨天使用过程中出现了这样的问题。

missing variable name 缺少变量名称,以及接下来的identifier is a reserved word 定义了保留字。google搜索之,在stackoverflow看到这样一篇文章  Javascript YUICompressor error

不过还好提示有行号,31:11 ,31行,看看我这段的代码片段是

[javascript]

var goto = ”; // 第31行
if( location.hash){
goto = location.hash;
}else{
var hash = goto = "index";
hash = ‘#’ + hash;
location.replace( location.href + hash);
jQuery.cookie(‘wall_hash’, ‘index’, {
expires: new Date( 2100, 10, 1),
path: ‘/’
});
}
$.constrDom( goto);

[/javascript]

可以看到关键字是goto

第一回答的即“使用了私有的保留字”链接指向 reserved word 不过并没有看到goto的关键字,不过还是尝试修改了,修改后再次执行 yui compressor后,顺利执行,完成压缩!

再次搜索goto javascript保留字看到了这样的一个表格

可以清楚的看到goto关键确实存在,不过为什么firefox MDN为什么没有写入goto关键字呢?

不过还是自己无知了,对于javascript未来的保留字不是很熟悉,虽然在javascript执行过程中没有问题,但是还是要尽量的规避这些保留字了。

paypal支付开发解析(二)

在注册完成开发账户,虚拟的买家账户以及卖家账户后,即可准备开始开发,不过在此需要明白IPN与PDT是什么。

IPN(Instant Payment Notify) 即时付款传输

什么事即时付款通知,pdf文档里面说得很明白,一张图更加的有助于理解。

其中1到5这个动作过程就是即时付款通知的整个流程。详细解释如下

注意这里的IPN,是由paypal服务器主动把数据post到你指定的url页面,这里的url怎么设置?即IPN是如何启用的呢?

pdf文档里面说明了有两种方法,一是在卖家paypal登录账户后,在“用户信息”右边列表栏“即时付款通知习惯设定”点击那个“选择框” 输入通知的url地址

二是在表单中加入name为notify_url的隐藏域地址来启用IPN。

在这里我们采用第二种方法。

直观的示例代码:

// paypal发送至的$_POST数据
if(!empty($_POST)) {
$notify = $_POST;
$location = TRUE;
} else {
exit('Access Denied');
}
// 加上cmd命令 数据原样返回
$tmpAr = array_merge($_POST, array("cmd" => "_notify-validate"));
$postFieldsAr = array();
foreach ($tmpAr as $name => $value) {
$postFieldsAr[] = "$name=$value";
}
// $custom 自定义值
$customs = explode( '|', $notify['custom']);
// 订单编号
$orderid = $customs[1];
// 使用curl 发送至paypal服务器,返回VERIFIED或者是INVALID
$ppResponseAr = PPHttpPost(PAYPAL_URL, implode("&", $postFieldsAr), false);

$notifydata= array();
if( strcmp($ppResponseAr['httpResponse'], 'VERIFIED') == 0){
         // 数据验证成功,检测处理的订单数据,如订单状态是否完成,卖家商户邮箱是否一致,此次订单货币是否与表单提交一致等
if( ($notify['payment_status'] == 'Completed') && ($notify['receiver_email'] == DEFAULT_EMAIL_ADDRESS) && ($notify['mc_currency'] == 'USD') ){
$notifydata= array(
'validator'    => TRUE,
'status'    => 'completed',
'order_no'     => $orderid,
'price'     => $notify['mc_gross'] ? $notify['mc_gross'] : $notify['payment_gross'],
'trade_no'    => $notify['txn_id'],
'notify'    => 'success',
'location'    => $location
);
}
}else if( strcmp($ppResponseAr['httpResponse'], 'INVALID') == 0) {
$notifydata= array(
'validator'    => FALSE,
'notify'    => 'fail',
'location'    => $location
);
}

    /**
     * 结合discuzx的具体业务逻辑实现数据内容的更新
     */

// 订单数据paypal验证成功情况下
if($notifydata['validator']) {

$orderid = $notifydata['order_no'];
$postprice = $notifydata['price'];
$order = DB::fetch_first("SELECT o.*, m.username FROM ".DB::table('forum_order')." o LEFT JOIN ".DB::table('common_member')." m USING (uid) WHERE o.orderid='$orderid'");
if($order && floatval($postprice) == floatval($order['price']) ) {
        // 更新订单状态
if($order['status'] == 1) {
DB::query("UPDATE ".DB::table('forum_order')." SET status='2', buyer='$notifydata[trade_no]\tpaypal', paytype='paypal', confirmdate='$_G[timestamp]' WHERE orderid='$orderid'");
            // 更新用户的虚拟货币
updatemembercount($order['uid'], array($_G['setting']['creditstrans'] => $order['amount']), 1, 'AFD', $order['uid']);
updatecreditbyaction($action, $uid = 0, $extrasql = array(), $needle = '', $coef = 1, $update = 1, $fid = 0);
            // 清理过期的订单
DB::query("DELETE FROM ".DB::table('forum_order')." WHERE submitdate<'$_G[timestamp]'-60*86400");

$submitdate = dgmdate($order['submitdate']);
$confirmdate = dgmdate(TIMESTAMP);
            // 向用户发送充值成功的消息
notification_add($order['uid'], 'credit', 'addfunds_d', array(
'orderid' => $order['orderid'],
'price' => $order['price'],
'value' => $_G['setting']['extcredits'][$_G['setting']['creditstrans']]['title'].' '.$order['amount'].' '.$_G['setting']['extcredits'][$_G['setting']['creditstrans']]['unit']
), 1);
}

}

}

// 充值成功,跳转
if($notifydata['location']) {
$url = rawurlencode('home.php?mod=spacecp&ac=credit');

dheader('location: '.$_G['siteurl'].'forum.php?mod=misc&action=paysucceed');
} else {
    // 充值失败,显示提示信息
exit($notifydata['notify']);
}

至此IPN作用完成,同时整个充值过程也就完成了,不过用户这时还停留在paypal的支付完成的页面,不会自动跳转至商户或者用户已充值记录页面。这时,PDT的作用就出现了。

PDT(Payment Data Transfer)付款数据传输

同样PDT示意图

怎样启用PDT呢,方式一需要卖家账户登录,在“用户信息”; “网站付款习惯设定”; 设置auto return 为“on”;同时在return url中设置返回的url地址;设置“Payment Data Transfer”为“on” ;点击“save”保存,这时“身份标记”就永久的显示在网页上面了。

方式二 订单或充值表单中添加hidden隐藏域

代码显示


// PDT 付款数据传输 ,DEFAULT_IDENTITY_TOKEN为刚才点击“save”生成的token值,这个值可以保存到数据库中
if( DEFAULT_IDENTITY_TOKEN){
// 获取返回的tx 交易流水号
$url = PAYPAL_URL;
$postFields =    "cmd=".urlencode("_notify-synch").
"&tx=".urlencode(htmlspecialchars($_GET["tx"])).
"&at=".urlencode(DEFAULT_IDENTITY_TOKEN);

// 请求paypal或者 付款信息明细
$ppResponseAr = PPHttpPost($url, $postFields, true);

// 不存在该交易付款信息明细
if( !$ppResponseAr['status']){
$ppResponseAr["error_msg"] = '抱歉,支付失败';

}else {
// 存在该交易
$response = $ppResponseAr['httpParsedResponseAr'];
// var_dump( $response);exit;
$tradeno = $response['txn_id'];        // paypal的交易订单

// paypal存在交易订单,且为完成状态
if( ($response['payment_status'] == 'Completed') && (urldecode($response['receiver_email']) == DEFAULT_EMAIL_ADDRESS)){

$query = DB::query("SELECT * FROM ".DB::table('forum_order')." WHERE orderid='$orderid'");

//判断数据库中是否存在该订单
if(DB::num_rows($query)) {
// 处理订单,更新用户的积分
$order = DB::fetch($query);

// 订单为未处理状态,则进行处理
if( $order['status'] == '1'){
// 设置订单
DB::query("UPDATE ".DB::table('forum_order')." SET status='2', buyer='{$tradeno}\tpaypal', paytype='paypal', confirmdate='$_G[timestamp]' WHERE orderid='$orderid'");
// 更新积分
updatemembercount($order['uid'], array($_G['setting']['creditstrans'] => $order['amount']), 1, 'AFD', $order['uid']);
updatecreditbyaction($action, $uid = 0, $extrasql = array(), $needle = '', $coef = 1, $update = 1, $fid = 0);
DB::query("DELETE FROM ".DB::table('forum_order')." WHERE submitdate<'$_G[timestamp]'-60*86400");

$submitdate = dgmdate($order['submitdate']);
$confirmdate = dgmdate(TIMESTAMP);

notification_add($order['uid'], 'credit', 'addfunds', array(
'orderid' => $order['orderid'],
'price' => $order['price'],
'value' => $_G['setting']['extcredits'][$_G['setting']['creditstrans']]['title'].' '.$order['amount'].' '.$_G['setting']['extcredits'][$_G['setting']['creditstrans']]['unit']
), 1);
}  // end

}
// 有待执行
}else if( $response['payment_status'] == 'Pending'){
$ppResponseAr['error_msg'] = '款项等待支付,请前往paypal确认接受';
}

}

}else {
$ppResponseAr["status"] = FALSE;
$ppResponseAr["error_msg"] = '正在处理,请稍后';
}

// 提示用户交易完成
showmessage( '感谢您的付款。您的交易已经完成,您可以在www.paypal.com/c2 上登录您的账户查看此次交易情况。 '.$response['payment_status'], 'home.php?mod=spacecp&ac=credit&op=log');

不过这里测试与debug调试表现的都比较简陋,其实可以在充值记录过程中,把一些状态信息都可以进行写入log文件,这样便于监测与管理。主要的逻辑结合处就是程序根据paypal支付返回的数据进行本地的业务进行处理,如充值完成后,通知店主发货,或者增加虚拟货币,积分等。discuzx把这些都api模块化了,很方便,paypal的开发也主要就是按照此处进行修改开发的。

 

paypal支付开发解析(一)

paypal开发在未接触之前感觉无从下手,不过在理解业务逻辑的实现,具体实现开发后,再次查看具体代码则可以很好的理解。要开发paypal的支付相关,paypal官方的sandbox平台是不可或缺的。这个很好对于开发者有很大的帮助。

我所理解的支付相关业务逻辑,主要包含两个部分一、用户使用在线支付平台进行表单提交,提交完成进而返回支付状态。二、根据支付返回的状态进而对网站的积分或者虚拟货币的业务逻辑具体实现,更新当前用户的信息状态。

帮助文档是关键,developer.paypal.com 上面都有下载,我主要用到的就是

PayPal_Sandbox_Guide_V1.0.pdf   paypal的sandbox测试指南,主要包括创建开发者账户,通过开发者账户创建虚拟卖家账户与虚拟的买家账户,并验证邮箱等完善信息。(注意这里的虚拟账户都不要填写真实的信息,包括邮箱)其中的“为卖家账户申请api”这个在我的代码开发中没有用到。

PayPal_IPN&PDT_Guide_V1.0.pdf  IPN(Instant Payment Notification)即时付款通知 这个是关键,主要的功能作用是用户在使用paypal表单提交充值或付款后,这时paypal会自动(不是网站的业务逻辑动作)请求你网站的一个页面,把此次的支付信息已经订单数据返回到你指定的这个页面。

PayPal_WPS_Guide_V1.0.pdf  主要内容是集成“buy now” 示例代码,测试等。

PP_PHP_WPS_Toolkit.zip  是一个简单的代码示例,包含表单提交支付,IPN,PDT,这个代码详细内容接下来介绍。

代码打包存放在百度网盘上面,需要的可以在这里下载 (qq中转站只有三十天)

无题

最近工作不算忙,也不算闲。事也不算多,话说入职快一年多大部分时间都挂在这个项目上了了。一般的功能开发,bug修改。但是心态上老是消极怠工。

公司近两星期三人离职了,来来走走很正常;不过像我这样的又不免一阵唏嘘了。其中一位是技术总监,没谈上关系有多好,但是也还是从他那里学到一些东西。不过可惜没有共事过一个项目,我想那样学到的可能会更多一点。

 

昨天把笔记本上的ubuntu重装一下,但是很不小心的把盘符删除错误了,E盘被华丽丽的格式化了。4、50G的东东没有了,当然像我这样不爱学习的人,一般以上是电影、音乐等。还有一半呢是些程序、图片、各种学习资料以及以前工作中的项目,可能是许久没有动过了,都不知道丢了哪些东西,一点都不心疼。即时这样,我也是知道这里面很多都是读书时的练习笔记,老师的课件,曾经做过的一些项目…现在都华丽丽的不见了,就当是从头开始了,数据备份真的很重要。

 

额。还有一点,wordpress现在的这个主题太丑了,也不想去另找其他的主题,正在写一款主题,争取下个星期前换上来。

Mysql: Too many connections in …Session:Failed to write session data(files).两个问题的解决

近日在网上发现了这样一个问题,以前没有碰到过,如下图

问题一

mysql_connect(); too many connections in …connRadio.php错误信息,这个是mysql的运行错误问题,目前这个mysql也就是挂起状态的,这个错误是因为mysql的连接数超过了它设置的最大连接数。整个网站也就处于崩溃状态了。网上查找原因说是my.cnf(windows下为my.ini)文件里面的max_connections设置值太小的问题,直接更改为更大的值,如1000就行了。默认的linux上安装的mysql配置文件里面的max_connections 为100(本人暂未证实,来源于网上)mysql默认的my-medium.cnf,中型服务器配置。

[code]
[mysqld]
port = 3306
socket = /tmp/mysql.sock
skip-locking
key_buffer = 160M
max_allowed_packet = 1M
table_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
max_connections=1000

[/code]

不过这个也与整体程序有关,很可能是mysql_connect()连接多次创建打开后,并没有使用mysql_close()进行关闭,导致连接越来越多,最后崩溃。上面的修改max_connections值,重启mysql服务器也只是权宜之计。真正需要修改的还有程序代码。目前普遍的开源cms或者blog都没有发现过这样类似的问题,一般对于数据库实例的实现是采用单例模式或者mysql_pconnect()永久连接(通常设计存在于一对一的分布而设计的,如单http服务器对于单mysql服务器,下面附php manual中对数据库永久链接的说明)。

 

问题二

failed:  No space left on device (28) 意思就是说磁盘空间不够用了。。。Failed write to session data(files) session文件不可写,如果没有空间了当然也就不可写了。我们知道php默认的session信息时写在服务器的临时目录中的,如/var/tmp,C:\WINDOWS\Temp,上面的使用的是系统默认的临时文件夹,所以应该不是权限问题导致不可写。至于空间不够用的问题,也可能随着短时间访问量暴增会增加很多session文件。而结合上面的mysql_connect()连接次数过多,出现这样的问题可能是短时间访问量过大导致

session可以通过gc_maxlefttime设置最大的生存周期,而php自身的GC(Garbage Collector)垃圾回收处理方式,防止内存溢出。当一个PHP线程结束时,当前占用的所有内存空间都会被销毁,当前程序中所有对象同时被销毁。GC进程一般都跟着每起一个SESSION而开始运行的。gc目的是为了在session文件过期以后自动销毁删除这些文件。

引用:http://developer.51cto.com/art/200912/168020.htm

有关详细的session与gc的运行关系

由于PHP的工作机制,它并没有一个daemon线程来定期的扫描Session信息并判断其是否失效,当一个有效的请求发生时,PHP 会根据全局变量 session.gc_probability和session.gc_divisor的值,来决定是否启用一个GC, 在默认情况下,session.gc_probability=1, session.gc_divisor =100也就是说有1%的可能性启动GC(也就是说100个请求中只有一个gc会伴随100个中的某个请求而启动).

PHP垃圾回收机制的工作就是扫描所有的Session信息,用当前时间减去session最后修改的时间,同session.gc_maxlifetime参数进行比较,如果生存时间超过gc_maxlifetime(默认24分钟),就将该session删除。
但是,如果你Web服务器有多个站点,多个站点时,GC处理session可能会出现意想不到的结果,原因就是:GC在工作时,并不会区分不同站点的session.

那么这个时候怎么解决呢?

1. 修改session.save_path,或使用session_save_path()让每个站点的session保存到一个专用目录,
2. 提供GC的启动率,自然,PHP垃圾回收机制的启动率提高,系统的性能也会相应减低,不推荐。
3. 在代码中判断当前session的生存时间,利用session_destroy()删除.

 

数据库永久连接

引用至php manual
永久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个永久连接的请求时。PHP 将检查是否已经存在一个(前面已经开启的)相同的永久连接。如果存在,将直接使用这个连接;如果不存在,则建立一个新的连接。所谓“相同”的连接是指用相同的用户名和密码到相同主机的连接。

对 web 服务器的工作和分布负载没有完全理解的读者可能会错误地理解永久连接的作用。特别的,永久连接不会在相同的连接上提供建立“用户会话”的能力,也不提供有效建立事务的能力。实际上,从严格意义上来讲,永久连接不会提供任何非永久连接无法提供的特殊功能。

为什么?

这和 web 服务器工作的方式有关。web 服务器可以用三种方法来利用 PHP 生成 web 页面。

第一种方法是将 PHP 用作一个“外壳”。以这种方法运行,PHP 会为向 web 服务器提出的每个 PHP 页面请求生成并结束一个 PHP 解释器线程。由于该线程会随每个请求的结束而结束,因此任何在这个线程中利用的任何资源(例如指向 SQL 数据库服务器的连接)都会随线程的结束而关闭。在这种情况下,使用永久连接不会获得任何地改变——因为它们根本不是永久的。

第二,也是最常用的方法,是把 PHP 用作多进程 web 服务器的一个模块,这种方法目前只适用于 Apache。对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实际生成 web 页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个永久连接后,所有请求 SQL 服务的后继页面都能够重新使用这个已经建立的 SQL Server 连接。

最后一种方法是将 PHP 用作多线程 web 服务器的一个插件。目前 PHP 4 已经支持 ISAPI、WSAPI 和 NSAPI(在 Windows 环境下),这些使得 PHP 可以被用作诸如 Netscape FastTrack (iPlanet)、Microsoft’s Internet Information Server (IIS) 和 O’Reilly’s WebSite Pro 等多线程 web 服务器的插件。永久连接的行为和前面所描述的多过程模型在本质上是相同的。注意 PHP 3 不支持 SAPI。

如果永久连接并没有任何附加的功能,那么使用它有什么好处?

答案非常简单——效率。当客户端对 SQL 服务器的连接请求非常频繁时,永久连接将更加高效。连接请求频繁的标准取决于很多因素。例如,数据库的种类,数据库服务和 web 服务是否在同一台服务器上,SQL 服务器如何加载负载等。但我们至少知道,当连接请求很频繁时,永久连接将显著的提高效率。它使得每个子进程在其生命周期中只做一次连接操作,而非每次在处理一个页面时都要向 SQL 服务器提出连接请求。这也就是说,每个子进程将对服务器建立各自独立的永久连接。例如,如果有 20 个不同的子进程运行某脚本建立了永久的 SQL 服务器永久连接,那么实际上向该 SQL 服务器建立了 20 个不同的永久连接,每个进程占有一个。

注意,如果永久连接的子进程数目超过了设定的数据库连接数限制,系统将会产生一些缺陷。如果数据库的同时连接数限制为 16,而在繁忙会话的情况下,有 17 个线程试图连接,那么有一个线程将无法连接。如果这个时候,在脚本中出现了使得连接无法关闭的错误(例如无限循环),则该数据库的 16 个连接将迅速地受到影响。请查阅使用的数据库的文档,以获取关于如何处理已放弃的及闲置的连接的方法。

Warning
在使用永久连接时还有一些特别的问题需要注意。例如在永久连接中使用数据表锁时,如果脚本不管什么原因无法释放该数据表锁,其随后使用相同连接的脚本将会被永久的阻塞,使得需要重新启动 httpd 服务或者数据库服务。另外,在使用事务处理时,如果脚本在事务阻塞产生前结束,则该阻塞也会影响到使用相同连接的下一个脚本。不管在什么情况下,都可以通过使用 register_shutdown_function() 函数来注册一个简单的清理函数来打开数据表锁,或者回滚事务。或者更好的处理方法,是不在使用数据表锁或者事务处理的脚本中使用永久连接,这可以从根本上解决这个问题(当然还可以在其它地方使用永久连接)。

以下是一点重要的总结。永久连接是为通常连接建立一对一的分布而设计的。这意味着必须能够保证在将永久连接替换为非永久连接时,脚本的行为不会改变。使用永久连接将(非常)有可能改变脚本的效率,但不改变其行为!

常用的clearfix对于ie8的影响


.clearfix:after { clear: both; visibility: hidden; content: '. '; display: block; height: 0;} /* 加点 与不加点 作用于ie8得区别 */
.clearfix { display: inline-block; }
* html .clearfix { height:1%; } /* 兼容于ie6 或者使用 *zoom: 1; 让ie6自动清除浮动包裹里面的元素 */

如上的clearfix是我常用的清除浮动的代码,用过许多次了,感觉没有什么问题;不过前几天突然发现clearfix在ie8下有特别的显示。demo请点击clearfix_ie8,在firefox、chrome、opera、ie7、ie6都是如下的图形

但是在ie8模式下,你会看到明显的格式区别item之间有大约10px的间隙。

我们知道最初浮动的清除采用的是在浮动的子div同级加空div的方式,即<div style=”clear:both”></div> 这样既可自动撑开父div,达到清除浮动的效果。

而clearfix原理同样如此,after伪类可以在使用clearfix的容器之后新建一个空的容器,这容器高度为0、visibility不可见,clear单独在一行显示,display为块级元素,content包含一个“.”。

after伪类在ie7以上、firefox、chrome、opera等浏览器都支持,但ie6以及ie6内核的其他浏览器都是不支持这个的。所以让ie6支持可以采用


* html .clearfix { height:1%; } /* 兼容于ie6 或者使用 *zoom: 1; 让ie6自动清除浮动包裹里面的元素 */

不过ie8 clearfix多出10px的原因还没说明。我偶然的实验发现,原来问题就在这个content,

content 属性与 :befor 及 :after 伪元素配合使用,来插入生成内容。

该属性用于定义元素之前或之后放置的生成内容。默认地,这往往是行内内容,不过该内容创建的框类型可以用属性 display 控制。

而ie8的10px多出来的,就是content: ‘.’; 这个句点所产生的,所以建议不要加上句点,直接采用content: ‘ ‘;空格即可,修改后的效果clearfix_ie8_2

kohana3.2部署到新浪SAE平台所需要的修改

近日学习用kohana框架,写了一个在线查字的小应用。在本地测试良好,效果图

主要实现的是按部首、按拼音查检索文字,搜索汉子查询。

主要业务逻辑很简单。预览地址请点击这里 现在部署在SAE平台上面。一些问题的参考文档来自这里

正常运行

本地测试完成代码,刚刚部署到SAE平台上时会出现这样的错误。

ErrorException [ Warning ]: Set the ini directive 'unserialize_callback_func' without permission

可以看到kohana完善的错误信息提示已经指向了APPPATH/bootstrap.php中得这一行

[code]

ini_set(‘unserialize_callback_func’, ‘spl_autoload_call’);

[/code]

这个是因为SAE平台禁用了ini_set()函数的原因,已经没有权限执行了。

解决办法就是直接注释,这个注释的影响是

“代码中使用了unserialize(),并且其解析的结果是一个对象,同时这个对象对应的类还没有定义。这种情况下就会导致一个错误。”来自上面那篇参考文章。

第二个错误则是日志、文件cache不能正常写入了。

Kohana_Exception [ 0 ]: Directory APPPATH/logs must be writable

这个是因为SAE平台禁止了程序对本地的文件进行操作,所以也就没有权限了。“唯一可以直接使用并提供了写入权限的是一个虚拟目录SAE_TMP_PATH。但是这个目录会在php脚本执行完后销毁,所以实际上并不能真正起到缓存的作用。”

解决办法 同样注释掉

[code]

Kohana::$log->attach(new Log_File(APPPATH.’logs’));

[/code]

这样则禁用了日志功能了,不过对于一般的程序来说没有太大的影响。

加入SAE的缓存目录常量

[code]

Kohana::init(array(
‘base_url’   => ‘/’,
‘index_file’ => ‘index.php’,
‘cache_dir’ => SAE_TMP_PATH // 这里
));

[/code]

至此如果你的程序不用缓存,那么配置好SAE平台的数据库连接参数等,程序就能正常访问了。

提示一下:

SAE的数据库参数hostname的常量,这个一定要注意,最好把SAE_MYSQL_PORT这个端口常量加上去,否则出现数据库连接不上的问题,但这个问题不容易被注意到,好吧,我就是好不容易才注意到的。SAE云平台的mysql端口不是默认的3306所以我刚开始时没有加上这个端口常量,想不出问题原因,最后登录sae后天,进入管理mysql数据库才看到,原来sae的mysql端口是3307

于是加上了这个端口常量,果然好了。。

[code]

‘hostname’   => SAE_MYSQL_HOST_M.’:’.SAE_MYSQL_PORT,
‘database’   => SAE_MYSQL_DB,
‘username’   => SAE_MYSQL_USER,
‘password’   => SAE_MYSQL_PASS,
‘persistent’ => FALSE,

[/code]

因为还有考虑到本地环境运行的问题;所以我再bootstrap.php中加入了SAE常量,值为true或false,true为sae,false为本地

最后bootstrap.ph的代码修改为

[code]

// 添加sae的环境控制,也能让程序在本地正常运行
define(‘SAE’, TRUE);

if( ! SAE){
define(‘SAE_TMP_PATH’, APPPATH.’/cache’);
}

/**
* 本地环境,非SAE平台的独立设置

*  注意这一段必须在 spl_autoload_register(array(‘Kohana’, ‘auto_load’)); 之后

*  否则Kohana类未加载情况下,调用$log会出错
*/
if( ! SAE ){

// SAE不支持ini_set函数的运行
ini_set(‘unserialize_callback_func’, ‘spl_autoload_call’);
// SAE暂不支持对文件夹进行文件写入,暂时关闭日志
Kohana::$log->attach(new Log_File(APPPATH.’logs’));

define(‘SAE_MYSQL_HOST_M’, ‘localhost’);
define(‘SAE_MYSQL_PORT’, ‘3306’);
define(‘SAE_MYSQL_DB’, ‘xhzd’);
define(‘SAE_MYSQL_USER’, ‘root’);
define(‘SAE_MYSQL_PASS’, ‘root’);

}

[/code]

使用SAE memcache 缓存

不过我的这个查字程序在部首;拼音列表,以及部首拼音相关的文字这些操作都用了缓存的。所以在sae上文件缓存是用不了了,但是还有memcache缓存啊。

因为SAE平台的memcache缓存启用不是原生的new memcache,而是memcache_init()所以程序还得改下。要改的地方比较简单。大致思路就是重写Kohana_Cache_Memcache的构造函数,重写初始化_memcache

modules\cache\classes\cache\memcache.php

[code]

class Cache_Memcache extends Kohana_Cache_Memcache {

public function __construct(array $config) {

parent::__construct($config);
// SAE平台则初始化sae平台memcache
if( SAE ){
$this->_memcache = memcache_init();
}

}

}

[/code]

不过还是有问题,在SAE平台上会显示 modules\cache\classes\kohana\cache\memcache.php

call undefined function   $this->_memcache->addServer() 估计也是被禁掉了。

那也好办注释掉就好了

[code]

/**
* 区别sae平台以及本地环境
*/
if( ! SAE){

// Add the memcache servers to the pool
foreach ($servers as $server)
{
// Merge the defined config with defaults
$server += $this->_default_config;

if ( ! $this->_memcache->addServer($server[‘host’], $server[‘port’], $server[‘persistent’], $server[‘weight’], $server[‘timeout’], $server[‘retry_interval’], $server[‘status’], $server[‘failure_callback’]))
{
throw new Cache_Exception(‘Memcache could not connect to host \’:host\’ using port \’:port\”, array(‘:host’ => $server[‘host’], ‘:port’ => $server[‘port’]));
}
}
}

[/code]

因为kohana默认采用的是文件缓存

所以在调用Cache::instance();前应当Cache::$default = 'memcache';

至此,memcache缓存就能正常的运行了。Kohana框架在SAE平台上的主要修改也完成,不过肯定还有一些不知道的问题,主要是对于SAE平台的不熟悉以及SAE平台处于安全考虑禁用的一些函数、方法等。

最后宣传下个人在sae上的这个应用地址欢迎访问http://xhzd.sinaapp.com/


centos6安装包过程中出现的问题

今天安装centos6后,准备测试下mysql的主从配置。因为centos6采用的是最小安装方式,所以好到安装包都没有。刚才也不知道是什么原因。

好久没有用了,linux命令又都快忘光了。首先还是网卡设置

更新yum源

其中默认是官方的源,不过我用的一般是163网易的源。

[code]

# CentOS-Base.repo
#
# This file uses a new mirrorlist system developed by Lance Davis for CentOS.
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#

[base]
name=CentOS-$releasever – Base
baseurl=http://mirrors.163.com/centos/6/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6

#released updates
[updates]
name=CentOS-$releasever – Updates
baseurl=http://mirrors.163.com/centos/6/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6

#packages used/produced in the build but not released
#[addons]
#name=CentOS-$releasever – Addons
#baseurl=http://mirrors.163.com/centos/$releasever/addons/$basearch/
#gpgcheck=1
#gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6
#additional packages that may be useful
[extras]
name=CentOS-$releasever – Extras
baseurl=http://mirrors.163.com/centos/6/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever – Plus
baseurl=http://mirrors.163.com/centos/6/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-6

[/code]

 

 

因为centos是最小化安装所以很多命令库都没有,要一一安装比如

-bash: wget: command not found 安装 wget
-bash: make: command not found 安装 make

还有编译工具如gcc等。这下就可以直接yum  install … 了。

不过总是有这个错误

/repomd.xml: [Errno 14] PYCURL ERROR 6 - ""】想不到原因,搜索得到一篇文章。centos yum 源 问题解析

其中的解释说了很清楚了“

此时聪明的我马上想到了是不是服务器解析不了域名了,导致repomd.xml下载不下来呢?

然后我就ping了一下mirrors.ustc.edu.cn , 果然出现错误:ping: unknown host mirrors.ustc.edu.cn。显然是DNS配置问题了,DNS域名服务器IP地址配的不对。”

解决办法:1、在其他机器上ping源镜像地址,把/etc/hosts里面 加了一行 mirrors.ustc.edu.cn  202.38.95.110,不过这是权宜之计 。2、推荐使用,需要配置正确的DNS。方法是:打开/etc/resolv.conf 文件,加入一行 nameserver ip。此处把ip换成IDC运营商给的DNS的地址就可以了。我的加上了google的dns地址 nameserver 8.8.8.8

这样yum 就可以正常下载,自动安装了。

然后就继续安装vsftpd,这里就是遇上了,执行make时,遇上command not found的问题;经查make包没有安装,yum直接安装上便好。

 

其中vsftd安装成功后,遇上553 Could not create file问题。经搜索得知。

可能一、是文件目录中的写入权限不够或者是目录所有者及用户组不对。可能二、/etc/vsftpd.conf 中write_enable属性是否为write_enable = yes

以新添加的username为例。

useradd -d /opt/ftp -g ftp-s /sbin/nologin username

1、其中 /opt/ftp的写入权限没有;chmod 755 /opt/ftp 即可

2、owner应该是username,group应该是ftp组;chown -v username:ftp /opt/ftp

 

在编译mysql中欧make时,遇到了

【/depcomp: line 571: exec: g++: not found】 这样的问题,查找gcc的已安装包

再查看一下本机上与gcc相关的安装包有哪些,缺少gcc-c++包
[code]

yum install gcc-c++ -y

[/code]

安装之后

再次进入mysql目录,make clean 再重新编译。

不过又碰到问题了。

【../include/my_global.h:1099: 错误:对 C++ 内建类型 ‘bool’ 的重声明】搜索得来的解决方案

“再次make && make install 后出现错误
../include/my_global.h:1099: 错误:对 C++ 内建类型 ‘bool’ 的重声明

这个错误 是不是你 先./congfigure 又 装的GCC 又make 的?

是的话 重新./configure  在make clean  make make install  就解决了”  网上好东西就是多,确实如此,真是要多分享啊。

 

还是mysql编译中,遇见了【xmalloc.h:29:31: 错误:readline/rlstdc.h】这样的问题,不过没有搜索到对应的解决方法。个人觉得刚才多次make && make install 后可能出现安装了,但部分内容没有卸载清除干净的问题,于是执行

[code]

[root@localhost mysql-5.0.81]# make uninstall

[root@localhost mysql-5.0.81]# make clean

[root@localhost mysql-5.0.81]# make && make install

[/code]

这次执行便成功了,没有问题了。

通过yuicompressor-2.4.7压缩css或js的php应用文件

yuicompressor这是个很好的工具,通过java库编译css或js文件进行压缩。压缩css或者js文件的好处是很多的,减少数据请求量,可以更快的进行数据传输,防止其他人进行窥探或整体直接挪用等等。。。

首先你要去下载一个yuicompressor现在最新版本是2.4.7 下载地址: yuicompressor  使用方法怎么工作在这里都有详细的说明,就不一一介绍了。

最常用的yuicompressor语法就是

[code]
java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js –charset utf-8
[/code]

其中需要注意的地方就是 如果不在yuicompressor-x.y.z.jar这个文件目录下,需要采用绝对的路径比如 E:/compressor/yuicompressor/build/yuicompressor-x.y.z.jar 这样的。同样需压缩文件myfile.js和压缩后输出的文件myfile-min.js 也是一样的采用绝对的路径。

好了,有了yuicompressor后;就要首先有一个java环境,不知道是否已安装java环境的可以通过 运行 ->cmd 输入


java -version

如果看到

java的版本结果就说明java的运行环境是ok的了。如果没有这个结果,不用担心可以去oracle官网去下载。如果觉得下载比较慢可以直接百度搜索java jdk下载,下载完成后下一步,下一步安装完成即可。

不出问题,你现在就可以正常的运行yuicompressor了,能够进行完成压缩文件了。

但是这样就出现了一个问题每次通过这样来执行,只能执行一个文件。我们的css和js文件通常有很多,不能一下完全执行,所以就写了一个小应用,直接输入本地的css和js目录就可以直接遍历压缩完成,这样就很省事了。

三个文件index.php ,index.tpl.html , do.php 很小

好吧,直接上码。

index.php


<?php
/**
* @author alex
* @time 2011年12月1日
* @todo php通过yuicompressor批量压缩css和js文件
* @email leiyu_ai@qq.com
*/
session_start();
require_once 'index.tpl.html';
?>

index.tpl.html


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>compressor js/css</title>

<style type="text/css">
body { font: 12px Microsoft Yahei, Verdana, Geneva, sans-serif, "宋体"; }
h1,h2,h4 { margin: 0; padding: 0; font-weight: normal;  }
input { border: 1px solid #eee; }

form span { display: inline-block; width: 80px; }
form h4 { margin-bottom: 10px; }
.go { border-color: #000; }
</style>
</head>

<body>
<?php
$_SESSION['rand'] = mt_rand(100,999);
?>
<form action="do.php" method="post">
<h4><span>css文件目录</span><input type="text" name="cssdir" /></h4>
<h4><span>js文件目录</span><input type="text" name="jsdir" /></h4>
<h4><input type="submit" name="go" value="提交" /><input type="hidden" name="rand" value="<?php echo $_SESSION['rand'];?>" /></h4>
</form>
</body>
</html>

do.php


<?php
/*
* 示例:我的yuicompressor-2.4.7.jar是放在这个地址下的,所以在运行前请更改为你的存放地址
* $cmd = "java -jar E:/compressor/yuicompressor-2.4.7/build/yuicompressor-2.4.7.jar --type js --charset utf-8 -o E:/tmp/js/home.min.js".
* " E:/tmp/js/home.js";
*/
session_start();
header('Content-type:text/html; charset=utf-8');

$rand = $_POST['rand'];
$srand = isset($_SESSION['rand'])? $_SESSION['rand']: '';
$submit = $_POST['go'];

if ($rand == $srand ){
if ($submit){
$jsdir = $_POST['jsdir'];
$cssdir = $_POST['cssdir'];
if ( !empty($jsdir) || !empty($cssdir)){
// 获取所有的文件集合
$jslist = getFileList($jsdir);
$csslist = getFileList($cssdir);
// 压缩js、css文件内容
$bool = doIt($jslist);
$boolc = doIt($csslist);

if ( $bool || $boolc){
echo $jsdir.'|'.$cssdir.' 目录执行成功';
}else{
echo $jsdir.'|'.$cssdir.' 目录执行失败';
}
}else {
echo '请输入css或js的文件目录';
}
echo '  <a href="'.$_SERVER['HTTP_REFERER'].'">返回首页</a>';
}
unset($_SESSION['rand']);
}

function getExt($file){
return strrev(substr(strrev($file), 0, strpos(strrev($file),'.')));
}

function getName ($file){
return strrev(substr(strrev($file), strpos(strrev($file),'.')+1 ));
}

function getPathFile($dir, $file){
return $dir.DIRECTORY_SEPARATOR.$file;
}

function doIt($list){

$tfile = $list[0][0];
$ext = getExt($tfile);
foreach($list as $key=>$val){
$cmd = "java -jar E:/compressor/yuicompressor-2.4.7/build/yuicompressor-2.4.7.jar --type {$ext} --charset utf-8 -o {$val[1]}".
" {$val[0]}";
exec($cmd, $output, $rv);
// 执行成功
if ( $rv == 0){
// 删除源文件
unlink($val[0]);
// 重命名新的压缩文件
rename($val[1], $val[0]);
}else {
$str .= $val[0].',';
}
}
if (!empty( $str)){
echo $str.' 执行失败';
return false;
}else {
return true;
}
}

function getFileList($dir){
$filelist = array();
if (is_dir($dir)){
$handle = opendir($dir);
while(($file = readdir($handle)) !== false){
if ( $file == '.' || $file == '..') continue;
$tmpdir = getPathFile($dir, $file);
if ( is_dir( $tmpdir)){
$rs = getFileList( $tmpdir);
if ( !empty($rs)){
$filelist = array_merge($filelist, $rs);
}

}else {
$filename = getName($file);
$ext = getExt($file);
$file = getPathFile($dir, $file); // 源文件完整路径
$minname = getPathFile($dir, $filename.'.min.'.$ext); // 压缩目标文件名称完整路径
$filelist[] = array($file, $minname);

}
}
closedir($handle);
return $filelist;
}else{
return false;
}
}

?>

ok完成。现在展示下我的测试结果

css文件

压缩前:                                                                            压缩后:

js 文件

压缩前:                                                                                    压缩后:

效果还是很明显的~~ ^_^

useless setInterval call (missing quotes around argument?) setInterval 参数错误

在写javascript过程中使用到setInterval时,需要传递一个类似于 main.check()这样的参数时,出现了这样的错误信息。

Firefox错误信息:useless setInterval call (missing quotes around argument?)

ie错误信息: 参数无效,42行。

[javascript]

<script language="javascript">
jQuery.noConflict();
jQuery(function($){
$(document).now();
});

jQuery.fn.extend({

now: function(){
var main = this;
this.extend({
gettime: function(){
var date = new Date();
jQuery(‘body’).html(date.getTime());
}
});
// setInterval( main.gettime(), 1000);    // 错误产生地方
setInterval( function(){ main.gettime() }, 1000);    // 修改为这样既可
}
});

</script>

[/javascript]

解决方法很简单。在网上搜索到的。在很多时候比如setTimeout等这样的参数或者自定义的回调函数调用时,都有可能会遇到这样的问题,

主要是因为“main.method()”这样的格式方法所导致的,无法作为一整个函数体来执行,所以在外嵌套一个function(){ } 匿名函数体,这样就可以正常执行了。

原文地址是:useless setInterval call (missing quotes around argument?)

有关html Object标签播放flash的AllowScriptAccess与allowNetworking 属性 [转]

原文:AllowScriptAccess 与allowNetworking

最近在测试网站api视频播放时,播放器swf上可以支持全屏但是点击却没有效果。还有在视频播放完毕后,播放器直接无反应,没有推荐内容或重播按钮。只好搜索下,找寻结果。

1,AllowScriptAccess

参数:

sameDomain:仅当 SWF 文件和网页位于同一域中时才允许执行外出脚本访问。这是 AVM2 内容的默认值。
never:外出脚本访问将始终失败。
always:外出脚本访问将始终成功。

AllowScriptAccess 参数可以防止从一个域中承载的 SWF 文件访问来自另一个域的 HTML 页面中的脚本。
对从另一个域承载的所有 SWF 文件使用 AllowScriptAccess=”never” 可以确保位于 HTML 页面中的脚本的安全性。

2,allowNetworking

参数:

“all”(默认值)― SWF 文件中允许使用所有网络 API。
“internal”― SWF 文件可能不调用浏览器导航或浏览器交互 API,但是它会调用任何其它网络 API。
“none”― SWF 文件可能不调用浏览器导航或浏览器交互 API,并且它无法使用任何 SWF 到 SWF 通信 API。

可以控制 SWF 文件对网络功能的访问。调用被禁止的 API 会引发 SecurityError 异常。

当 allowNetworking 设置为 “internal” 时,以下 API 被禁止:

navigateToURL()
fscommand()
ExternalInterface.call()

当 allowNetworking 设置为 “none” 时,除了上面列出的那些 API 外,还会禁止以下 API:

sendToURL()
FileReference.download()
FileReference.upload()
Loader.load()
LocalConnection.connect()
LocalConnection.send()
NetConnection.connect()
NetStream.play()
Security.loadPolicyFile()
SharedObject.getLocal()
SharedObject.getRemote()
Socket.connect()

3,allowFullScreen

参数:

启用全屏模式设置为”true”,否则设置为”false”(默认值)

仅当在响应鼠标事件或键盘事件时才会调用启动全屏模式的 ActionScript。如果在其它情况中调用,Flash Player 会引发异常。

在全屏模式下,用户无法在文本输入字段中输入文本。所有键盘输入和键盘相关的 ActionScript 在全屏模式下均会被禁用,但将应用程序返回标准模式的键盘快捷键(例如按 Esc)除外。

当内容进入全屏模式时,程序会显示一条消息,指导用户如何退出和返回标准模式。该消息将显示几秒钟,然后淡出。

如果某个调用方与 Stage 所有者(主 SWF 文件)没有位于同一安全沙箱,则调用 Stage 对象的 displayState 属性会引发异常。

管理员可以通过在 mms.cfg 文件中设置 FullScreenDisable = 1 对浏览器中运行的 SWF 文件禁用全屏模式。

在浏览器中,必须在 HTML 页面中包含 SWF 文件,才能进入全屏模式。

在独立的播放器或放映文件中始终允许全屏模式。

实例代码:

[sourcecode language=”html”]

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" width="100%" height="100%">
<param name="movie" value="falsh.swf" />
<param name="quality" value="high" />
<param name="AllowScriptAccess" value="sameDomain" />
<param name="allowNetworking" value="all" />
<param name="allowFullScreen" value="true" />
<embed src="falsh.swf" width="100%" height="100%" quality="high" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash"
type="application/x-shockwave-flash" allowscriptaccess="sameDomain" allownetworking="all" allowfullscreen="true"></embed>
</object>

[/sourcecode]

这么大一串代码记住不容易,可以直接使用dreamweaver新建页面,插入swf 然后自动生成这样的代码,还有ie与非ie的不同参数设置代码。不过常用的就是这么几个了

<param name=”allowFullScreen” value=”true” />   <!– 全屏 –>
<param name=”allowNetworking” value=”internal” />  <!– 调用swf内部api–>
<param name=”wmode” value=”opaque” /> <!– 是否透明 –>
<param name=”PLAY” value=”false” /> <!– 是否自动播放,默认为是 –>
<param name=”LOOP” value=”false” /> <!– 是否循环播放,默认为是 –>

强大的jquery弹出层插件blockUI

之前工作中每次需要用到弹出层时,就满地的找。上次也不例外,也这样了。

不过这次发现了一个好东西,jquery的弹出层插件blockUI。

原文介绍地址:强大的jQuery弹出层插件–BlockUI

blockUI官网:http://jquery.malsup.com/block

blockUI GitHub :

先导入jQuery的库文件(小提示:使用Google服务器的压缩版jQuery库文件加载速度会更快),然后再导入BlockUI的库文件

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="images/jquery.blockUI.js" type="text/javascript"></script>

导入库文件后,就可以调用BlockUI了,BlockUI的调用挺简单的,看下面这段代码

 $(function(){
$(‘#box_btn’).click(function(){   //给box_btn绑定一个鼠标点击的事件
        $.blockUI({    //当点击事件发生时调用弹出层
             message: $(‘#box’),    //要弹出的元素box
             css: {    //弹出元素的CSS属性
                 top: ‘50%’,
         left: ‘50%’,
         textAlign: ‘left’,
         marginLeft: ‘-320px’,
         marginTop: ‘-145px’,
                 width: ‘600px’,
                 background: ‘none’
            }
        });
    $(‘.blockOverlay’).attr(‘title’,’单击关闭’).click($.unblockUI);   //遮罩层属性的设置以及当鼠标单击遮罩层可以关闭弹出层
    $(‘.close’).click($.unblockUI);  //也可以自定义一个关闭按钮来关闭弹出层
});
});

看了上面的代码,其实你会发觉BlockUI的使用很简单,有2个重要的方法分别是调用弹出层($.blockUI)和关闭弹出层($.unblockUI)。

$.blockUI定义了一个message属性的,该属性的值就定义了要弹出的元素,比如要弹出一个id为box的div元素,就可以这样写:message: $(‘#box’),对应了上面的第4行代码。需要注意的是,要弹出的那个元素在弹出之前要将其在页面中隐藏即设置该元素的CSS样式为display:none。

$.blockUI还定义了一个css属性,该属性可以对弹出层的样式进行再定义。细心的同志可能会打开BlockUI的库文件查看,其实在库文件中也默认定义了一个弹出层的样式,如果你在页面中定义的样式效果并不是很理想,最好是看看库文件中的$.blockUI.defaults的CSS属性。

如果你想了解一些BlockUI的更高级的用法你可以去该插件的官网看看说明文档

BlockUI的下载地址是:hhttp://jquery.malsup.com/block/#download

 

 

 

2011年末总结系列之个人情感篇

好了,2011年总结系列的最后一部大片终于要上映了,这篇相对于前几篇比较简单,但是个人还是感觉很有难度,因为这个的主题是恋爱。

 

谈恋爱,首先要有一个对象,而且还必须是女对象,这个是前提。但,悲催的是我没有这个对象,虽然我很想为了这个将来的这个对象亲亲爱爱,为了她加油努力,为了她言听计从,为了她改掉不好的习惯……但是这一切目前也只能是我的空想,就如同js对象的属性,它必须存在于对象之上才能可能被使用,不然就总是会报"未找到该属性"的错误内容。我的那个她还没有出现,所以这一切的一切也只能存在于我的脑海中了。

 

在之前的生活篇里面也提到了,2012年龙年,第二个本命年里,我最大的期望与理想就是找到一位适合的、相爱的、谈婚论嫁的女朋友!这一目标在2012年里要坚定不移的执行实施!立字为证,明年这个时候,写文汇报。

 

千里姻缘一线牵,百年修得同船渡。让我遇见你吧。

祝各位朋友新春快乐,龙年吉祥!!!新春快樂!龍年大吉!!!

2011年末总结系列之个人的生活篇

快过年了,几篇总结拖拖拉拉,都快忘记了,当初想写的一些东西了。个人性格有关,就是喜欢拖拖拉拉。。

但还是要写啊。不能说了不写,君子耻其言而过其行,最近某麦说韩寒是人造的,呵呵长篇大论啊。某天要是也有人说我的文章是背后团队策划(别飘起来了啊,说的就你),那就不好了。

要说2011年的个人生活,虽不是很糟糕,但也没什么太多的惊喜,差强人意。。工作上的进步也没有太多,更多的是往专业化的方向更靠近了一点,比起10年还是要好的。下班后的生活也没有太多的改变,上班,下班,余外活动不多。公司里面组织活动,吃吃饭,ktv里面吼两嗓子,不过不多;自己就是看看电影,然后去下博物馆,熏陶熏陶。除这之外的很多时候,找不到理由出去,你出去干啥呢?

几个要好的朋友都不在武汉,所以武汉的朋友圈子几乎没有,只有同事圈子,同事与同学与朋友;怎么说能完全不在一个重量级别上。只要是工作了的人都应该明白和知道的,这就是为什么只有生意场,职场的称呼,没有说朋友场的。朋友在一起,不会因为你的代码写的不好看,或者这个业务逻辑你没有理解做不出来等等顾虑。还有就是职场能交心的人不多,当然也有的,少。在我看了公司就是大家为了一个共同的目的——赚钱而走到一起的,其他的所谓文化,技术,能力等等内容都是虚无飘渺的,不过也不排除职场朋友的存在,虽然都是为了RMB到一起的,但还是有缘分,能够为了共同的RMB而组建为一个团队,为能做一些事情而感到高兴。当然朋友圈子里面也并不是什么问题都没有的,就像宝莱坞电影三傻里面的一句台词“朋友失败,你很伤心;朋友成功,你更伤心”呵呵,事实就是如此,我的朋友们,都是大学时的同学,大家在一起喝过酒,吃过肉,一起玩过游戏,一起出找工作。现在都各地各自忙着,不过还好,都过得不算太坏,吃饭不成问题,但是现今这个社会,只管吃饭还不行。朋友之间也有上有下,有的管理的10多人的团队,有的在辛苦的跑销售,有的在做程序,我呢,一个人苦逼的写一些破代码,直到今天,到公司快一年了,老板还不记得我的名字,我的能量究竟有多小,您始终不记得我的名字,哎,fk。也是与个人原因有关的,这样的我,不善言辞,不善社交,技术不出众,总是做些细碎的工作。我记得和老板说的最多的话,居然是他当初面试我时的交流。额。确实很操蛋。

这一年里,个人的技术风格以及定位有一个初步的认识,但并没有完全做好打算去怎样怎样,这也是自己不自信的原因。没错,你是做了很多事,但是这些事情都是他人可以直接替代的,你的特长时什么?你的风格是什么?你未来的道路是什么?现在我还不能完全答复。这也是要在2012年里面更加的清晰和明了的。很多事情充满了变数,又有很多事情难以改变的。比如你的性格,我的强迫症。

我不知道什么时候起,有了一个动作强迫症,额,这个是我自己命名的,不知道是否真的有这个名词。反正不知道怎么地,就是这样了,比如关门的时候,明明已经锁好了,但是还是得打开,再次的锁一遍,如此反复几次;还有就是上下车的时候,能够很轻松的下车时,总是要摸一下那个车门的扶手;比如关灯时,总是关掉一次,在打开,再关掉,如此如此。比如…还有很多时候老是这个样子,我知道这样不好,想改,可是没几天就又这样了。。真是麻烦,有时候嘴里还念念有词的反复几遍。所以在2012年里,我就想彻底的改掉这毛病。fk强迫症!

24了,老大不小了。朋友们都已经经历或正在经历着恋爱,只有我这棍子,还是这样一直一个这样矗立着。现在父母也开始催了,催你找女朋友,现在只是暂时的催你找女朋友,但是过两年呢?那就是催你结婚了,结婚!女朋友的都没有,去哪结怎么结,我又不搞基。现在就觉着烦了,如果还迟点,那就不是烦人的问题了。没办法文化传统是这样。成家立业,成家立业。所以2012年里,最大的目标和最大的收获就是希望能找到一个女朋友,甚至更好的发展为开始谈婚论嫁(明年双春啊!好年头!加油!!)

好像没什么内容了额,好吧那就先到这里吧。呵呵,对了祝各位新春快乐!龙年大吉!!!

2011年末总结系列之工作篇

毕业至今,算正式的上班工作,只有两个,一个是之前的,一个是现在的。

在2011年过完年,到2月的时候,个人真的是实在无法忍受各种各样的不满意了;于是辞职了了,然后就到了现在所在的这家公司了。所以今年一年的大部分时间也就是在我目前所在的这个公司里面度过的。那么就小小的总结一下吧。

 

印象

在3月初的时候正式的来上班了,可能由于是在之前的公司里面待的太过于不满(这些内容可以写N篇值得吐槽的文章了,暂时不提)所以对现在的这家公司工作氛围感觉很满意,大家都没有那种架子,有什么就说什么,在认识问题上都有自己的专业见解,而且老板也是亲自编程的一线程序员,有了真正的专业感觉了。这大概就是我的第一印象了。

 

还记得我第一天来这上班的时候,是星期一,恰巧是公司的周会;全体人员都参加,等到全员会议室坐满的时候,二十来号人呢,我也参加了,有点紧张,开始时公司副总joy说要新人来自我介绍一下,“我的名字叫ll,初次见面还请各位前辈多多指教”,然后他们就哄的笑了一下,额,为什么要笑了?之后我怎么也想不明白,不管你多么的牛x,但是在一个新的公司,你就是菜鸟,而这个哄笑可能是老鸟对菜鸟的一种认识吧。

 

我想在这里的工作可以分为几个阶段吧,第一个阶段是初适应公司,第二的阶段是融入,第三个阶段是有点厌倦想远离,第四个阶段是平和。

第一阶段  新鲜

初入公司,在适应了一个星期后,joy突然跑过来问我你的前端水平怎么样,我说还行吧。然后就把以前写得几个站的东西给她看了看,她觉得还行,就分发了一个项目组里的前端页面psd给我做。于是就开始接受了我的第一个任务,不是php程序编写,是前段html页面制作。这段时间主要是做一个小的企业站和一个drupal站点的维护。在开始的时候一些都是新鲜感的,做事情谨慎小心,但是也由于对于新的体系不熟悉的问题,所以在流程以及问题的处理上有点麻烦,比如虽然是一个小站点,但是还是有具体的需求,比如分类,比如网站定位。还就是网站的框架结构,采用什么cms直接改,以及网站的原型,设计等等内容都需要考虑到。毕竟不是找一套模板就套上去就完了,事事都要做的。

在一个新的环境里面,要很好的适应,有一位领路人很重要,态度最关键,能力也很重要。

 

第二阶段  融入

在经过一段磨合时期后,接下来新同事也认识了,各个同事之间的交流特别是技术部方面的比如顶头上司的rain,同事chen,项目部的he、angess,技术部的pan和wu,还有设计部的li、wei和huang,以及销售部的liu、yang和人事方面的lian、huan。其中要很感谢销售部的liu,教会了我作为一个新人在公司里面要熟悉的问题,以及公司里面各个人员的一个情况介绍,相当于我的领路人了。当然还有技术部,项目部,人事部以及设计部的各位同事都给予了我很多的帮助和鼓励,在此也要很感谢各位亲爱的同事^_^!

这个时候大家也没有什么隔阂,所以有什么项目的头脑风暴,我都很希望去和大家讨论,热烈的讨论,说出自己的想法。这期间我感觉公司里面人很团结,比如下班了都是等着一起出公司,虽然回家的方向都大都是不一样的。还有同事的交流很交心,没有隔阂,下班了一起去吃饭啊,真正的没有让人感觉没有压力。但是到了5月份,公司的人员流动性变大了,很多人都离职了,一下子我的心情感觉失落了不少,因为这么好的同事,不能在一起共事了,但是老板说“公司里面要进行大的调整了,一部分人不适合现在的公司进度和职位了”不过有一部分是自己辞职了的,总体的感觉是这个时候的公司没有一种之前那种轻松的感觉了,而是让我重新定义了公司,这里是公司,就算同事在好,您能从他那里学到很多,但是毕竟是公司,每个人都有自己的想法,公司也有公司的想法。所以不能强求,做好自己。

这段时间主要在忙公司的网站改版问题,有discuz搭建了一个站,没怎么大改,只是静态页面;然后就是之前一些项目站点的维护,不过期间老板有了做产品的想法,然后以及公司马上要发展壮大,可能还有搬到北京去,扩大公司的人员,但是,老板还是很清楚的做这件事情需要的条件,比如核心的三要素,运维,资本运作,技术产品;其中最简单的还是技术方面的问题,就是出好的产品。但是这个要求就是要一个技术牛人,任何问题都有对应的解决办法的人!但是老板问我们除了他,你们有谁能站出来承担这个责任时,我们答不出,更不用说更需要关系的运维以及更牛x的资本运作的人了。所以,也只是停留在纸上了。

 

第三阶段   厌倦

在7月份的时候,新入一个项目mf,三个人搭档来做,一个项目经理,两个程序员(包括我);这也是一个很吐血的项目,或者说这是一个与客户经验不足所导致纠结过程,其实从6月开始就开始做原型图了,待原型图完成后,提交至客户方,但是最后不知道由于什么原因,没有回应了。于是就暂时搁置了,在忙公司的网站代码编写,和一个新的小项目去了和chen搭档,我还是写html;原计划7月底8月初开始上线公司网站的新版的,在7月底的时候开发大部分已完成,但是却还有几个页面没用上,但又找不到最初设计这个想法的人(其人已离职)所以延后到了8月中旬上线;期间发现一个很大的问题,就是一个项目的具体负责人是没有的!具体的负责人居然没有!!!好吧,我虽然是写这个的,但是有什么项目需要就拉过去,你手上的公司内部项目暂停,好没问题去做了,但是老板过问了这个项目,事情临头了负责人应该找谁?!还有就是一个类似于项目经理但更像是一个监工的人来配合你做?这到底有什么意义呢?他挑的问题你得改,但是出了问题谁负责呢?这个我也有责任,畏首畏尾的明白的太晚了,应该早点自己打算,自己说了算!

而后到了8月份,项目mf方有了回应了,是由他们提供psd设计图,但是对方的设计真的很差,完全没有依赖我们的设计原型,给出的理由是那个是参考,以psd设计图为准,但是我真怀疑mf方的SB美工是不是做网页设计的,真个页面设计的花里胡哨,一层搭着一层,且背景上整个渐变色,不考虑你的页面长度以及边缘的过度,标题文字居然用他妈的的渐变色!!字体用的大量的雅黑,其他字体,你只能切图做图片!!!真是服了!!!但是更让人崩溃的是,他们不改;于是就这样30多个页面,而且都不怎么重样的,从8月底切图做到了10月中旬,都写疯了。。。而且还要不时写下其他的html,这时公司里面的前端人员没有,只有我一个,而且还是半路出家,但整天都在做这个事情,所以做的也很厌倦了,期间joy找我谈过一次,大概就是你想往哪个方向发展,我明白她的意思,她想让我直接全部到前端上面去,但是我不是很想,我觉得,这个你必须要会,但不是我所追求的全部,虽然回绝了她,不过公司的意思我明白,"还顶一下,公司也不是没有招人,但老板眼光高,很难照进来“。另一个程序员主要负责的是代码编写,ps这个站也是二次开发用的是discuzX2.0

虽然这个阶段感觉很厌倦,但是全html的磨练还是有很大的提高的,html5、css3等概念的接触,以及构建的网页ff/chrome/opera/ie系列全兼容。还有就是对自己的一个路有了一个初步的认识。

 

第四阶段  心态平和

10月中旬到11月初,由于psd页面已全部完成,开始投入到程序的开发。到11月份中旬时,mf方又没有了消息了,理由是他们的项目需求逻辑出现了问题。于是再次停滞了,但这次我们都已经任由他们去闹了(但此时我还是忽略了一个重要的问题,下面详说),没有搭理,项目暂停。

11月初到11月中旬手上比较闲,期间完善了一些以前的代码;看看javascript的有关内容;把LNMP的平台内容重新搭建了一遍,但是没有深入,长时间不用就生疏了。。。不进则退。

 

11月中旬,由于mf项目暂停了,手上也暂时空了起来,老板新联系了一个小项目,人员也是2个程序员(包括我),1个项目联系人员,facebook的站内应用,一个类似于幸运星座测算的,同样这个项目也没有一个项目经理,也就是总负责的。当那个项目监工(在我理解内应该就是这样,不懂项目业务流程跟一定技术都不懂的项目参与人员)问我这个项目的开发时间,我想了一下,1、facebook这类的站内应用开发之前没坐过,熟悉程度不够;2、靠谱的星座数据库内容没有;3、项目的设计图稿也是由客户方提供的;这几点问题,所以我的答复是10个工作日左右,于是老板知道了,老板不高兴了,“你们两个人,还要两个星期,人家做个应用两三天就搞定了。”额。好吧,那就尽快吧。我要说的是,总时间还是在两个星期左右,其中除了设计图稿由客户方提供所占用的时间比较长,其他两点都没有预估对,由于数据库内容没有,所以我和另一位程序员liu在程序实现上走了很多弯路,最后还是以采集sina的星座数据解决的。主要分工是这样的,liu主要用他比较熟悉的框架来写程序实现,我则对应的学习使用facebook的api调用以及项目的设计前端。最后还是算顺利完成了。

这次的项目由于有了公司网站的教训,所以这次完全我自己主导,主要的角色内容相当于与项目监工,程序员,客户的沟通,项目的需求和需要改进的bug或者UI等问题进行一个协调沟通。程序代码方面则是参与决定一个主体执行方案,前端的内容。

 

12月初到12月中旬  mf项目客户方终于知道了还有一个网站没有做完的事了。然后就是我们所预料不及的内容了,他们的需求变更极其的大,而且上线的时间不能更改(之前也提过几个上线的日子,但是都是他们自己往后推了),但这次他们铁定了;所以这样的情况下只好两边博弈了,我们要考虑时间以及制作成本,他们希望越多的功能满足越好。但是由于他们的需求变更实在太大,可以另起一个做专门的电子票务网站了,而且这些变更的需求内容不是最初合同需求里面的内容,和他们谈过好几次,大家都想各种理由说明来说服客户,坐过技术分析文档,和他们商讨过折中方案等,mf的项目经理agness受不了了,只好把joy拉过来和他们谈,当然joy也很不高兴,对我们这个组很不满意,发了脾气,同时教了我们很多如何与客户面对很沟通的东西,但还是很努力的与客户沟通,大家谈的也很激烈,有争论,互相都想说服对方,但是这个大家都不接受。最后只好互相退让,客户方部分新的需求变更以及无理由的页面重新制作等内容砍掉,我们则尽量在上线日期前完成我们所保证的部分需求变更内容,还有未完成的则请走商务流程,付费下单。

 

在与客户会议沟通的这段时间里面,想了很多问题,以前那种消极逃离以及在公司里面的具体位置是什么的迷茫感觉少了些,更多的是通过joy处理客户的需求变更的事情明白的一些内容,如果你还能正常的待在某一个公司,那表明公司肯定是看中了你的哪一点,所以其他的事情就不用多想了,你要做的那就是好好的完成你的工作任务,保持好的工作状态。但同时joy也给了人一种很有压力的感觉,认识这么久第一次的这种感觉。你能想象这样一个严肃正经与可爱搞怪完美结合起来的女上司么?。

 

这个项目算是今年最纠结的项目内容了。首先不谈技术内容,光需求分析原型图等内容都不人搞昏了头,其实现在想一想也没有必要搞得这么复杂,这也是与个人的工作经验不足有关的。总结起来有几点

1、沟通是很有必要的高效的,不管是与客户或者与公司的同事之间。不沟通则会陷入一个隔阂,他们的意思你没有领会,你的体现他们看不懂,特别是这种不依靠原型设计,完全凭感觉走的客户。一个明确的做法,或者我就这样做的说明有一个很好的体现,这方面我们吃了大亏。

2、需求分析的理解,需求分析只是对方的一个初步意思或者说是雾里看花的一个东西,只是客户当时的所想,并不是能保证一定完成的,特别是那些半懂不懂的合作客户,用制作广告的经验思维来做网站这样行么?所以要站在客户的角度去理解需求方案,能做的东西给予承诺,不能做的内容必须挡回去。必要的时候必须以你的专业立场以及拿出解决方案,用你的话向客户去描述这个项目内容,也就是最后项目做出来是这个样子的。

3、解决方案,需求分析原型图等等那都是初步阶段,关键的关键是你拿出具体的解决方案,有具体的效果;所以,解决方案不是你的任务完成则可,而是要站在客户角度去想。

 

现在这个项目也正在进行,希望年前能顺利完成并进入验收流程。

 

时间总是那么的快,2011年早已过去了,有很多遗憾和未完成,有很多的不明白和不理解,也有很多的新学习的知识,新认识的同事,新理解的朋友。2011年半数的时间在写后端台,半数的时间在写前端,个人感觉后端的技术水平没有多大的进步,反而感觉前度的认识感和使用感更得心应手写。但,未来的路和选择现在还不敢轻易的做出,未来就是现在,总体的方向一定是明确的,技术体系,技术优势,技术特长等等内容都需要一一明确,这样才能更好的成长。2012加油吧!!!

 

 2012-1-9 22:46

 LLALEX

 

 

 

 

 

2011年末总结系列之我看电影篇

年底了!!年底了!!!年末总结又大行其道了。

自从去年在前公司搞了个年终工作总结内容,发现总结还是很有必要的。所以几年我也想搞个总结系列,不过说来惭愧,第一想总结的内容却是与工作无关,但是与生活密切相关滴。。。那就是看电影!!!(ps:个人不是什么骨灰级的电影迷,很多经典片或者大片都没看过,很多烂片或者小片也看过,专业人士请静静的飘过~)所以接下来的几天lz将逐渐的推出,总结工作篇总结生活篇,总结个人情感篇等多部大片,推送给自己,给各位认识的不认识的朋友!!下面首先进入电影篇的点评总结!!!

以下所有电影点评都属于个人感受,仅以供交流之用,您喜欢就看,不喜请按右上角的X。谢谢。

 

2011走进电影院看的电影算是我工作以来看的比较多的一次(切,你也才工作两年好不,不是第一就是第二)不过说实话今年看电影还是比去年的感受好些,去年总是一个人看电影,但是别人却是成双成对的,哎,悲催的一个人,详细情况在接下来的个人情感总结篇里面细说吧。今年感觉好了些,我进入影院是去看电影,不是去约会场所耗时间的。还用在意么?

好,正式开始。

从2011年元月到十二月,目前看过的且还留有电影院票根的电影总共有十一部;分别如下:

2011年1月2日   《让子弹飞》

姜文导演作品,不过之前我没看过一部姜文导演的片,额,的确是这样。看这个片的时候,印象挺深的一个是,六子为了证明自己确实已经付了米粉钱而把自己给破开了。那时个人感觉是,那种为证明自己而不惜舍生取义的上古中国人精神又体现出来了。确实很震撼。

2011年1月8日  《非诚勿扰2》

说实话,非诚勿扰2比非1就喜剧感而言差了不少,但小刚导演却在谈爱情的故事里面加入了生命、人生的感悟,本来跑去看喜剧的却被导演结结实实的上了一堂人生哲理课,这样一来,额,毁誉参半咯。至少我觉得孙红雷塑造的这个角色还是值回了票钱。同样,剧中的那首小诗也是别致而富有哲理。

2011年3月26日  《洛杉矶之战》

典型的好莱坞灾难战争片,不过场面还是不错的。一路看下来要忍受的除了电影里面摇摇晃晃的镜头,还有就是那氛围感全无的国语配音!!!恭喜这部电影,这是第一部摇晃镜头看的我快要吐的电影。这个电影就是现实版的战地游戏指南,外加拯救世界。

2011年5月7日   《倩女幽魂87版》

原本计划是看其他片的,额,好吧,忘了。这个在以前就在电视电脑上面看过了,最精彩的无疑是王祖贤的惊艳,张国荣的痴情,午马的侠义。87年的时候就能拍出这样的经典,牛啊!!电影本身所描述的一个世界很有真实感,比如午马为了逃离官场是非,而专门跑去与妖,怪打交道,这样反而显得更单纯。当然还有宁采臣和聂小倩至死不渝的爱情!最喜欢的一个感觉就是最后小倩要走了,但宁采臣不知道,还拼命的挡着太阳不照进来,但直到燕赤霞说“她已经走了”,宁采臣那种失落与木讷,完全不能用语言描述啊。情。

2011年5月21日 《速度与激情5》

速度与激情,不得不说很激情!!!看过这个系列的第3部东京漂移。好像男性都比较喜欢这类发动机,机械,速度方面的东西,看的你肾上腺素急速分泌啊!!!最后他们成功把$$$掉包,打开那保险柜的一刹那,电影院里面想起了羡慕的欢呼声啊!!!为什么我没去开车抢他一把啊!!吼吼!!!

2011年6月12日   《功夫熊猫2》

梦工厂的动画大片,不逊色与功夫1;老美的想象力与使用各民族的素材转化为$的能力真是强悍啊。。。在这个星球上还有什么能够阻挡好莱坞的制作电影的能力。ps:nnd!!!好不容易看个电影,播放电影时屁孩吵死人!!!做个家长也不管管!尼玛你以为这是你家啊!!靠!!

2011年7月31日   《变形金刚3》

错过了前两集在大荧幕上的欣赏!!!怎能错过第3集呢!!!华丽丽的视觉盛宴啊!!!不为别的只为小时候的渴望与幻想!额,其实女主角换了,只是性感缺失点(貌似这样的女主角除了性感还需要展示什么么?)还过得去了咯。反正都是华丽丽的陪衬。

2011年8月21日   (时间挺多的啊,一天看两部)

《哈利波特与死亡圣器下》

额。错过了,哈利波特的,我数数,1,2,3…7部大荧幕了。从这也可以看出我不是真正的波特迷,不过第一次看的是密室,那是在高中的时候,原来还有这样的魔幻世界,还记得还是在过年的时候看,屋外静静下着雪,安静的看着哈利波特的电影。那种感觉好温暖。十年不容易!

《窃听风云2》

在电脑上看的1,那时候觉得很酷。所以2上映还是很期待的,电影的节奏很快,一点不迟疑,剧情快速而紧凑;但你又是猜得中开头,猜不中结尾,看的还是很过瘾的。不过评论褒贬不一,有的说这个题材上,庄麦没有继续深挖;有的说这是近几年很好的港产片了等等,不过这也不是我所操心的事了,我认为这是一部好看的片。

2011年11月12日《铁甲钢拳》

热血!!热血!!!好莱坞比起日漫里面的热血毫不逊色!!机器人的钢铁碰撞,爱情亲情的温暖救赎等等很多内容都涵盖进去了,额,除了小男孩与机器人真情交流,或许无声的对视比语言对白更显得相互的珍惜对方吧。让你为之振奋的片!

2011年12月17日  《龙门飞甲3D》

最近的一部片子,徐克+李连杰+各大女星 还是很有卖点的,至少稳赚不赔;事实证明确实如此,3D效果为华语电影竖起一座里程碑,不输于好莱坞,还有徐克式的江湖潇洒儿女情。电影的配乐以及特技效果很出彩,不过剧情的话不能比新龙门客栈了,只能算是一次不完美也不失败的续尾了。期待下一部徐克出品!

其实接下来还有一部要看,那必须是老谋子的《金陵十三钗》啊!看完再评。

 2012-1-7 22:36 ps

《金陵十三钗》早看完了,不过等了这么久才更新;这个片褒贬不一,不过这次还是有更多的人挺老谋子;金陵在人物的刻画以及人性的挣扎上我觉得做的很好,而且张艺谋也在做不同于以往的尝试,至少这次我觉得比较成功。好片子是经得住时间考验的。

综述

lz这一年进入电影院一共看了十二部电影,平均每月一部,华语与外语对半。主要看片的集中时间在1月,5月-8月,11月-12月。这几个时间点也是华语大制作与好莱坞大片狂轰滥炸的时间,所以lz还是很跟风的,主要是看口碑与个人的兴趣。这也说明中国电影的市场还是很大的嘛,比如像lz这样的人,还有好几个月一部电影都不去电影院看呢,当然更需要好电影,好的国产电影,不要随便搞几个明星上个烂剧本搞个糊弄人的片子来套现钱,这样的片晾干都没人看的。

lz2011年所看的十二部(直接包括十三钗)电影,其中有华语电影6部,英语片6部旗鼓相当,不过总体质量上,好莱坞的要优于华语电影;华语电影里面又有两部港产片,去除一部重新上映的倩女幽魂,只有一部窃听风云2,哎,港产片真是没落了(其中也有大陆GDJ不准上映的问题)。于是还剩下4部国产片,票房虽然都不错,但导演每年也都是那几位,中国的青年导演还是真不容易出来啊。(宁浩的无人区估计没戏了)中国电影繁华浮云的背后却被体制所牢牢的束缚,各导演都去拍古代去了,现实题材没人碰。万恶的gdj。

lz 古装的有2部(龙门,倩女),现代的2部(非2,速5,窃听2),科幻的3部(变3,铁甲,洛杉矶),动画的1部(功夫熊猫2),魔幻的1部(哈7下)民国的2部(金陵,让子弹飞)看来lz各种题材都有涉猎,兴趣广泛哦。

好的,总体的情况就是这些,不知不觉中看了这么些电影,我的宗旨,为了自己看电影,为了快乐看电影,为了生活看电影。

2012全面起航!

看行尸走肉的感觉

最近在迷行尸走肉,一个星期断断续续的看完了。恩,真得不错,挺好看。但就是一点一季才几集啊,现在也进入冬歇期了。难等啊。现在又多了一个跟的剧咯。

 

话说我也不是什么美剧迷,还是好莱坞看得多。第一次迷美剧的时候还是几年前的越狱。这次的女主角原来还是越狱里面的sara,呵呵,熟人。

行尸走肉里,人员就那么几个,但就是一个小的社会体现,有正义,有邪恶;有人为自己而活,有人为他人而活;剧情我觉得还是不错的,每一集的剧情走向都是不同的,现在的连续这样的看,少了点思考等待的时间,这样自己可以猜猜剧情。这样也是蛮好玩啊。比如他们终于叫开疾控中心的大门的时候,还以为他们就此找到了一点医疗头绪呢。但是只是剧情铺设而已啊。

 

现在第二季这几集,关于索菲亚到底在哪的这个问题,我觉得剧情体现出来的真是很有那种悲伤与荒凉,而且是从人的内心里面彻底的悲凉;法赫尔的精神支柱坍塌,卡罗尔最后的一点希望也没有了,达里尔的希冀也落空了。向自己受感染的亲人和朋友开枪,能有那么容易么?他们仅仅是“病了”,他们还是人,这也是法赫尔、摩根明知道他们也被感染且有很大的危害但是却始终没有“解决”掉他们的原因。肖恩等面对法赫尔的亲人、朋友毫不留情的开枪。但是面对卡罗尔的女儿索菲亚,却没有抬起枪口,最后还是瑞克站出来,他自己来顶着这个愧疚。

 

行尸走肉不愧是ss片,大段大段的“身体”特写,x淋淋的片段到处都是,body分解那也是很多的,一枪爆头也是小意思了。所以还是很重口味的,不过ss只是一个载体而已,真正可怖的却还是人,就像那句台词一样“世界上最毒的药是什么?人心。”

 

人物还是最喜欢瑞克和达里尔,格伦也不错哦。瑞克是顾全大局的非完美人,一位称职的领导者。达里尔与他哥哥莫尔完全是不一样的一个人,有一颗善良与正义的心,一个坚持自己的内心的人。格伦很好玩,刚开始我也以为是他是“中国仔”,但是他是韩国人。很机灵,很乐于助人。

 

现在的人物里面的人都多少有能耐啊,当警察的瑞克和肖恩,送匹萨的格伦,丛里追踪者达里尔,能开车修车的戴尔和吉姆等等。。。所以要是我在那个里面,OMG,不会在丛林里面搜索,不会舞刀弄枪,不会骑马,不会开车,于是瑞克问我“你是干什么的?”,“做网站的”。哦麦雷迪嘎嘎!“都世界末日了,网站估计没人要你做了。来跟我学怎么用枪吧。“哦,我想瑞克这么说,但是,靠!我不会口语啊~够残酷的还得从口语学起呢。现实很残酷,行尸走肉里面更残酷。fk。

 

行尸走肉里面的世界就是一个堕落的世界,规则与体系全部没有了;堕落的人必须有,如肖恩之流,坚守的人也必须有,如瑞克、达里尔之势;所以,不同的理想与价值观,不同的人性的人之间还是会有大大的冲突,于是戏剧的效果就出现了,于是这个剧还是有不少看点的哦,关键还是漫画画得好,导演拍的好!

 

套用戴尔的一句话”但至少凭良心说,当这个世界陷入深渊时,我没有和它一起堕落“其实这句话在现实中的你我也可以共勉。

 

LNMP搭建中可能出现的一些问题及解决方法


在搭建的过程中出现很多问题,尽管以前装过几次,但也并不轻松。

首先系统安装好。这次我采用的是Centos5.6VM7.0环境

 

刚开始就出现了一个问题,系统安装好后,ssh竟然无法连接,照理说应该是默认已经安装好了的。

Ps –ef | grep ssh

也有程序运行。22端口也开了。网络连接dhcp自动分配地址,也是可以ping通的,telnet通信也是正常的。但ssh客户端就是怎么也连接不上。

 

我的错误状态和这位童鞋说的一模一样。

问题一   问题二

 

具体原因还是没有明白,最后系统重装,但依然如此,可能就是我机器的问题?!叫同事机器连接,果然就连接上了。很不明白。于是系统再次替换为Centos6.0

 

总结:ssh连接问题

1、  保证网络连接正常能ping

2、  Sshd服务器是启动状态

3、  22端口是打开的,或者暂时关闭防火墙测试

4、  采用telnet测试下

5、  多用几种客户端工具测试如putty,xshell等,多用其他的机器测试下。

6、  那就只好悲催的重装咯。。。

 

安装过程中可能产生的错误

 

Ps:在安装nginx或者php等得过程中,主要出现的问题都是缺少依赖包问题。一部分是程序数据路径错误等的问题,还有一部分是读写权限不够的问题。还有查找错误的时候不要只看报出来的错误信息,要多看更深层次的日志信息。

Tail –f  /var/log/messages

Tail –f  /var/log/mysqd.log

less /var/log/messages 

 

Nginx

安装加载ssl错误

***[/usr/local/ssl/.openssl/include/openssl/ssl.h] Error 2

 

with-pcre Nginxrewrite功能需要使用pcre库才能工作,而Nginx的编译参数里面的这个选项并不是像常规的那样指定pcre的安装目录,而是指定pcre源代码的目录。

参考

 

 

Mysql

error: Nocurses/termcap library found

解决:需要安装依赖库ncurses-5.2.tar.gz

 

[ERROR]Fatal error: Can’t open and lock privilege tables: Table ‘mysql.host’ doesn’texist

数据库的数据文件未找到所以无法找到打开权限表了。

解决:

mysql源目录中,运行初始化权限表的时候使用增加参数–datadir ,命令格式为:

scripts/mysql_install_db–user=mysql –datadir=/u01/mysql/data

参考 


 

libexec/mysqld:Can’t create/write to file ‘/var/run/mysqld/mysqld.pid’

无法创建或写入mysqld.pid文件。

解决:创建写入权限问题,如果没有mysqld目录则建立

mkdir/var/run/mysqld

chmod g+w /var/run/mysqld/

参考 


 

mysql启动错误

Startingmysqld daemon with databases from /var/lib/mysql
STOPPING server from pid file /var/run/mysqld/mysqld.pid
071112 00:22:06 mysqld ended

 

bin/mysqladmin:connect to server at ‘localhost’ failed

error:’Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)

Checkthat mysqld is running and that the socket: ‘/tmp/mysql.sock’ exists!

分析:是/tmp/mysql.sock 不存在

解决:

# cd/var/lib/mysql/

由于mysql 默认的mysql.sock 是在/var/lib/mysql/mysql.sock,创建符号连接:

# ln -s/var/lib/mysql/mysql.sock /tmp/mysql.sock

 

参考  

 

 

GD库安装产生错误

GD库需要fontconfig依赖包所以需要安装

make[3]:*** [fcfreetype.lo] Error 1

../fontconfig/fcfreetype.h:27:22:error: ft2build.h: No such file or directory

解决:

./configure–with-freetype-config=/usr/local/freetype/bin/freetype-config,应该用freetype下的可执行程序来编译!

参考 

 

 

errorwhile loading shared libraries: libiconv.so.2: cannot open shared object file:No such file or directory

解决:

但是在/usr/local/lib下却能找到libiconv.so.2,解决方法是将/usr/local/lib路径添加到/etc/ld.so.conf文件中,然后用sudo ldconfig命令加载,再重新输入sudo make install命令就可以了。

参考一   参考二 


 

PHP

libxml2未找到

Consideradjusting the PKG_CONFIG_PATH environment variable if you

installedsoftware in a non-standard prefix.

 

Alternatively,you may set the environment variables LIBXML2_CFLAGS

andLIBXML2_LIBS to avoid the need to call pkg-config.

See thepkg-config man page for more details.

解决:

已经安装好了