易栈网-膘叔

浏览模式: 标准 | 列表 | 图文
yii CActiveRecord 中的一点小注意事项

yii CActiveRecord 中的一点小注意事项

纯笔记,在使用ActiveRecord的时候一点注意事项。
本来在处理缓存的时候想对一些数据做强制缓存的,但结果预想的目标和我不一样。
我的$cachekey = md5(serialize($model).$parameter);
然后在调用的时候发现$model对象中的一些信息都消失了。起初以为参数没有传递,但测试了一下之后发现全部正常,那问题出在哪里呢?
再一步步的调试,发现出在serialize后对象就变了。于是看了一下CActiveRecord的源码,果然发现了源码中有定义__sleep(),纠结啊。
看来以后要注意一下,不能随便把model给序列化了。

PHP调用不存在的类时自动创建相应类

PHP调用不存在的类时自动创建相应类

在项目中,难免会在项目中调用一个不存在的类(偶尔,偶尔,当这个类的类名是程序生成的时候,偶尔会出现这种情况啦),在new 这个类时,都会直接报fatal错误,然后程序就终止了,怎么办?怎么避免这种情况发生?

注:下面的例子其实是指有autoload的情况下所触发的。如果没有autoload,也就相当于不会触发一个include文件的操作。直接就报FATAL错误了。而如果有autoload,则是报include文件的错误,这个时候才能被捕获,多谢神仙的指正

于是看手册set_error_handler,调用一个callback,处理完后,在这个方法里重新生成一个空类就OK了。看了一下手册上的例子

<?php
// error handler function
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}

switch ($errno) {
case E_USER_ERROR:
echo "<b>My ERROR</b> [$errno] $errstr<br />\n";
echo " Fatal error on line $errline in file $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
echo "Aborting...<br />\n";
exit(1);
break;

case E_USER_WARNING:
echo "<b>My WARNING</b> [$errno] $errstr<br />\n";
break;

case E_USER_NOTICE:
echo "<b>My NOTICE</b> [$errno] $errstr<br />\n";
break;

default:
echo "Unknown error type: [$errno] $errstr<br />\n";
break;
}

/* Don't execute PHP internal error handler */
return true;
}

看了一下,结果,发现只有$errstr中才有类名出现,但还是文件名,难道我要用正则?又仔细看了一下手册,发现callback还有一个第五个参数

errcontext
The fifth parameter is optional, errcontext, which is an array that points to the active symbol table at the point the error occurred. In other words, errcontext will contain an array of every variable that existed in the scope the error was triggered in. User error handler must not modify error context.

输入第五个参数,原来,这是一个数组,如果我是类的话,里面就有className这个下标数组,直接就是类名了

同时还有一个很重要的问题,如果callback return false的话,会自动调用原来的出错处理。这 其实是影响我们的操作的。

最终代码如下:

set_error_handler(function($errno,$errstr,$errfile,$errline,$clsname){
if(isset($clsname['className'])&&$errno == 2&&!class_exists($clsname['className'])){
$clsname = $clsname['className'];
eval("class ".$clsname ." { static public function model(){return null;} }");
}
return true;
},7);
$result = mmmm::model();
restore_error_handler();

在最后一行恢复了原来的出错处理,不影响原先程序结构。

终于可以直接用了。

ubuntu下最简单的更改时区

ubuntu下最简单的更改时区

  一般情况下,我们刚装好的ubuntu时区都是US(默认语言为英文时),而且,它本身就是使用UTC格式作为标准时间格式,如果在Linux下运行程序,且在程序中指定了与系统不一样的时区的时候,可能会造成时间错误。 如果是Ubuntu的桌面版,可以直接在图形模式下修改时区信息,如果是Server版呢,则需要通过tzconfig来修改时区信息了。只是这样的方式会相对比较麻烦,
使用方式 (如将时区设置成Asia/Chongqing):
sudo tzconfig
然后按照提示选择 Asia对应的序号,选完后会显示一堆新的提示—输入城市名,如Shanghai或Chongqing,最后再用 sudo date -s “” 来修改本地时间。

但事实上,并不需要这么复杂的处理,一个偷懒的方法就是,直接:cp /usr/share/zoneinfo/Asia/ShangHai /etc/localtime,用shanghai的时区文件覆盖localtime。灰常方便,这时候看一下date,时间是不是正确了?

元旦记事

元旦记事

元旦其实过的很快,不上班比上班还累,这是有小孩的人都会这么想的吧?
元旦期间,手被烫伤
小孩很听话,只是偶尔问他,爸爸对你凶不凶,在想了一会之后都是很坦然的说:很凶
最近一直在尝试改变,对小孩不要那么凶,确实没有什么太大的意义。何必呢?毕竟大我时候,都是丈母娘他们在带着孩子。
元旦带小孩去买了点衣服,想着过年回家的时候可能会穿。
元旦还处理了一些旧书,40多斤的书,只折成了20多块钱,原价大约600多吧。想想也确实可惜,买不如借,借不如租,租不如偷,袁枚当初就是这样说的吧?他当然不会说租不如偷。所幸卖掉的这些书,我都看完了。否则心更痛。
整理书的时候发现原来我有那么多书没有看完过。大于等于10本书没有看全,只看了几章的也有。这时候就在迷惘我是该慢慢看完,还是确实就扔在那里?想看的时候再看?
带着孩子还去了游乐场,小孩子其实没玩多少,反而都是我和我老婆在玩。好象有点不太厚道。。。。

新的一年初始,还算是不错,唯一就是半夜小孩起来尿尿的时候,尿了一床,嗯,没对准塑料面盆,有点纠结。总体还是不错。

元旦快乐

元旦快乐

如果真象所有的电视、电影里说的。那么还只剩300多天了。所以,各位,可以开始倒记时了,但没关系,至少今天还是快乐的。
元旦快乐。
感谢去年、前年以及以前有帮助过我的朋友们、师长们、长辈们。感谢你们。(如果真有2012,还是先早点说吧,省得以后没机会说出口)

转:php变量连接函数短路操作($f) && f(),$condition && function()用法意思解释说明

转:php变量连接函数短路操作($f) && f(),$condition && function()用法意思解释说明

其实我是真想自己写这一段内容的,只是后来找了找手册,居然不知道在哪一章了。
短路操作符,很容易让人误解是if条件中的 && 或者 ||,但实在不知道从何说起(至于是不是叫短路操作符,我也记不清了,先这么命名吧)
其实这个玩意大家都见过,只是大家都忽略了。想起很久很久以前,所有的参考书上有一段连接数据库的代码:
$conn = mysql_connect(localhost,root,123456) or die('could not connect db');
这段代码,就是一个很简单的例子。
如果能够连接上,就返回$conn,否则直接输出。。。。无非就是将||换成了 or,于是很多人就不认识了罢了。
然后,国内用的最多的这种代码的是某一个论坛,在他们的代码里大量充斥了这种操作符,很多人在第一次看他们的源码时都会比较郁闷。。。这个论坛叫phpwind。
好了,我不多说了,上原文吧:http://feihu.cd00.cn/itweb/index.php/php-duanlu-condition-function

什么是php短路操作,先看下面代码
($f) && f(); 或者
$condition && function();
这是什么用法
短路操作,什么意思呢

如果$f为真,就执行f()函数调用
如果$condition为真,就执行function()函数调用
if ($f) {
f();
}

另找了篇文章来详细说明之
mysql_query($sql) or die(’Execute failed!’);
!file_exists($cache_file) && @update_cache($id);

这两句很像是条件语句,但是准确的说,他们是利用了短路运算符的运算特点来实现的条件语句:
or、||、and、&& 都是短路运算符
&&(and)运算符检查第一个表达式是否返回“flase”,如果是“false”则结束语句并返回“false”,否则检查第二个表达式。
or(||)运算符检查第一个表达式是否返回“true”,如果是“true”则结束语句并返回“true”,否则检查第二个表达式。
该用法正是利用了短路运算符这种特性实现了条件的判断和执行

----------
再看这一篇:http://biancheng.dnbcw.info/perl/241992.html

和C类似,Perl提供 &&(逻辑 AND)和 ||(逻辑 OR)操作符。它们从左向右计算( && 比 || 的优先级稍稍高一点点),测试语句的真假。这些操作符被认为是短路操作符,因为它们是通过计算尽可能少的操作数来判断语句的真假。例如,如果一个 && 操作符的左操作数是假,那么它永远不会计算右操作数,因为操作符的结果就是假,不管右操作数的值是什么。

例子 名称 结果
$a && $b And 如果$a为假则为$a,否则$b
$a || $b Or 如果$a为真则为$a,否则$b

这样的短路不仅节约时间,而且还常常用于控制计算的流向。比如,一个经常出现的Perl程序的俗语是:

open(FILE, "somefile") || die "Can't open somefile: $!\n";

在这个例子里,Perl 首先计算 open 函数,如果值是真(somefile 被成功打开),die 函数的执行就不必要了,因此忽略。你可以这么读这句文本“打开文件,要不然就去死!”。

&& 和 || 操作符和 C 不同的是,它们不返回 0 或 1,而是返回最后计算的值。如果是 ||,这个特性好就好在你可以从一系列标量数值中选出第一个为真的值。所以,一个移植性相当好的寻找用户的家目录的方法可能是:

$home = $ENV{HOME}
|| $ENV{LOGDIR}
|| (getpwuid($<)) [7]
|| die "You're homeless!\n";

另一方面,因为左参数总是在标量环境里计算,所以你不能把 || 用于在两个集群之间选择其一进行赋值:

@a = @b || @c;      # 这样可不对
@a = scalar(@b) || @c; # 上面那句实际上是这个意思,@a 里只有 @b 最后的元素
@a = @b ? @b : @c; # 这个是对的

Perl 还提供优先级比较低的 and 和 or 操作符,这样程序的可读性更好而且不会强迫你在列表操作符上使用圆括弧。它们也是短路的。

转:lua 5.2 的 _ENV

转:lua 5.2 的 _ENV

这篇文章是云风的博客上的文章,知道云风是在做游戏,也知道他一直在做lua、C的开发。
我也是最近才刚刚开始看lua,主要是看了一眼之后就发现,原来lua,连函数的写法,对象的格式(tabledata),几乎都一样。所以,在开始关注着。
今天看到这篇文章,转贴是因为,看到云风写的这段代码:

function foobar(env)
return setfenv(
function()
local ret = {}
function ret.foo()
...
end
function ret.bar()
...
end
return ret
end , env) ()
end

超级象javascipt,比如可以写成:

function foobar(env){
return setfenf(function(){
var ret = {};
ret.foo = function(){};
ret.bar = function(){};
return ret;
},env)();
}

感觉有点超象。。。
上原文了。地址:http://blog.codingnow.com/2011/12/lua_52_env.html

lua 5.2 正式发布了,对于 lua 语言本身的修改,重中之重就是对 environment 这个概念的修改。

可以说, 5.1 以前的 environment 已经没有了。environment 对于制造一个安全的沙盒(或是实现 DSL)是一个很重要的语言特性,我以前很喜欢使用,但也很容易用错。这次的修改我认为是一个谨慎的决定,并使得 lua 语言更为精简和严谨了。

我这样理解 5.2 中的 environment 。本质上,lua 取消了原有意义上的 environment 。所以我们可以看到 C Function 不再有环境了。function 、在 lua 中称为 closure ,仅仅只是函数体和 upvalue 的联合体。这简化了 lua 语言本身。全局变量实际上只是一个语法糖,编译时再前面加上了 _ENV. 的前缀。这样,从 load 开始,第一个 chunk 就被加上了 _ENV 这个 upvalue ,然后依次传递下去。

这个设计基本可以取代以前使用 getfenv/setfenv 改变函数环境的方法。但是又不完全等价。总体来说,增加了一些限制,但不太容易写出 bug 的代码了。

比如说,现在想给返回一个独立环境的函数,可以这样写:

function foobar(env)     local _ENV = env     return function() ... end end

而以前大约是这样:

function foobar(env)     return setfenv(function() ...  end, env) end

这不太看得出好坏,但是如果是一组函数,就有区别了。5.2 中是这样:

function foobar(env)     local _ENV = env     local ret = {}     function ret.foo()         ...          end     function ret.bar()         ...     end     return ret end

5.1 的等价代码大约是这样:

function foobar(env)     local old = getfenv()     setfenv(1,env)     local ret = {}     function ret.foo()         ...          end     function ret.bar()         ...     end     setfenv(1,old)     return ret end

或者这样更函数式一点:

function foobar(env)     return setfenv(     function()         local ret = {}         function ret.foo()             ...              end         function ret.bar()             ...         end         return ret     end , env) () end

getfenv/setfenv 更灵活,却更容易出错。

对于制作沙盒来说,我感觉 lua 5.2 会更为鼓励使用 load 这种运行时的编译行为。即一定程度上的鼓励元编程。(因为取消了 setfenv ,所以给了 load 显式的参数来制定给 chunk 一个新的环境)

btw, 这个语言设计变更的同时也增强了函数式编程的性能。因为 lua 现在可以更方便的合并那些有相同 upvalue 的 closure 了。(从前除了 upvalue 还有 environment ,合并行为更为复杂)


12 月 30 日补充:

如果非要类似 setfenv 的功能, 修改一组函数的 _ENV 大概需要这样做了:

function getfuncs()   local _ENV = _ENV   local ret = {}   function ret.foo()     ...   end   function ret.setfenv(env)     _ENV = env   end   return ret  end
瞎折腾:程序员什么时候效率最高

瞎折腾:程序员什么时候效率最高

有人说:
"有句还挺受欢迎的话是,程序员就是把咖啡变成代码的机器。随便问一个程序员什么时候效率最高,很有可能他们会说大多是深夜的时候(中文)。 有些早点,有些晚点。常见的是:在凌晨4点起床,赶在吵闹的一天开始前完成一些工作。另外一些喜欢在凌晨4点睡觉。这种做法的目的是避免干扰。但是你可以 锁上门啊,为什么夜晚这么特别呢?swizec 的博主认为可以归结为三件事:员工的时间表、疲惫的大脑和明亮的电脑屏幕。"

其实想想不完全是这样,白天的时候在单位各种各样的事情,都有可能会导致写代码的时候被打断,这种打断其实很影响写代码,思路一断,很可能半小时一小时都不会恢复。晚上没人,外面也很安静,虽然说真的是避免干扰,但其实晚上和清晨人的大脑好象很容易集中(所以我们小时候背书一般都在凌晨,当然也有深夜)。【传说,屙扁扁的时候人的记忆力是最好的,所以那个时候看书其实很容易记得牢,无科学依据,纯粹说说】。

果然有中文版的(上面斜体字中的中文版,我复制过来了,但不复制图,要看原文请移步:http://blog.jobbole.com/10797/)

有句还挺受欢迎的话是,程序员就是把咖啡变成代码的机器。

果然,随便问一个程序员什么时候效率最高,很有可能他们会说大多是深夜的时候。有些早点,有些晚点。常见的是:在凌晨4点起床,赶在吵闹的一天开始前完成一些工作。另外一些喜欢在凌晨4点睡觉。这种做法的目的是避免干扰。但是你可以锁上门啊,为什么夜晚这么特别呢?

我认为可以归结为三件事:员工的时间表、疲惫的大脑和明亮的电脑屏幕。

员工的时间表

Paul Graham在2009年写过关于员工的时间表的问题 —— 基本上,在世界上有两种类型的时间表。传统管理者的时间表是分散地切割成小时和一个个十分钟的方式绩效,通常是按一个小时的价值给你报酬。

另一种,叫做员工的时间表——针对我们这些程序员。工作于大型虚拟系统时,需要把所有涉及的事都记在脑子里——有人曾经比喻这就像用昂贵的水晶建造房子,一旦有人打扰,房子就一股脑塌落并碎成一片。

这就是为什么当有人打断程序员的思路时,他们那么恼火。

由于这种巨大的精力投入,使得我们无法简单地开始工作,直到我们能连续几小时不被分散注意力才行。刚在脑中构建了整个模型,结果半小时后就毁了可不值得。

事实上,跟很多员工交谈后你会发现,他们感觉根本不能在白天完成任何工作。接连不断地被打扰、关注重要的事物和回复邮件都不能让他们安心工作。所以他们选择在别人睡觉的深夜来完成大部分的工作。

疲惫的大脑

就算是程序员,晚上也应该睡觉。我们不是超人。也会感到白天更机敏。

那为什么我们要在大脑想睡觉的时候做最复杂的工作,而在大脑最敏锐和灵活的时候做简单的任务呢?

与巴尔默峰值类似,疲劳让我们更易集中精力,因为当你的大脑疲劳时,它就必须集中精力!没有多余的脑力让你不集中精力。(《“10倍效率”程序员/开发人员的习惯》第5点:集中精力)

我似乎在喝茶过多或不合适的时间喝能量饮料后完成的工作最少。这些让我很活跃,一会儿查看Twitter,一会儿看看Hacker News,我似乎一直在到处浏览。

你应该在想我能很好地工作——这么有精力,这么有脑力。但是相反,我一直在阻绊自己因为我不能集中精力超过两秒。

然而,当我微感疲倦时,我就能坐下来编码了。用有点疲劳的大脑,我能一小时又一小时地编码,甚至都不想查看Twitter或者FaceBook。就好像互联网不存在了。

我觉得这适用于大多数程序员。我们有太多的精力去完成80%的工作——面对现实吧,一个好的算法,需要用10倍的代码量来营造使用它的环境。即使你做的是最高级的机器学习(或者是其他的),很多工作也仅仅只是清理数据和将结果以友好的方式呈现出来。

当你的大脑并不是竭尽全力地工作时,它就会找其他的事做。疲劳使你愚钝,从而使你只能顾及手头上的工作。

明亮的电脑屏幕

这条非常简单。在夜晚一直盯着明亮的光源并且使你的睡眠周期延后。你直到凌晨3点才感到疲倦。然后中午11点起床,当夜晚来临时你并不感到疲劳,因为,呵呵,你中午11点才起床!

经过足够多的反复,本质上是把你带到了不同的时区。更有趣的是,它会保持相对稳定,一旦你进入凌晨3、4点睡觉的节奏中,你就会一直保持那样。

结语

综上所述,程序员晚上工作是因为没人强制规定你必须什么时候停止工作,这可以给你更轻松的方式,你的大脑不再一直寻找分心的事并且明亮的屏幕使你保持清醒。
转:mysql语句最大长度

转:mysql语句最大长度

我自己没注意过,但有人遇到了,就找找这方面的资料。
所以,纯转,有问题不要找我,http://bbs.zaopai.com/read-htm-tid-386.html:

max_allowed_packet用来限制mysql客户端和服务器通信数据包的长度的,mysql的默认限制1M。

所以,WIN32的, 请在你的系统目录下查找my.ini

在Linux下你查找my.cnf

在里面加入
set-variable = max_allowed_packet=6M
set-variable = net_buffer_length=4K

=========================

mysql有一个max_allowed_packet变量,可以控制其通信缓冲区的最大长度。要想为mysql将max_allowed_packet变量的值设置为16MB,使用下面的任何一个命令:

shell> mysql --max_allowed_packet=16777216shell> mysql --max_allowed_packet=16M第1个命令以字节指定值。第2个命令以兆字节指定值。变量值可以有一个后缀K、M或者G(可以为大写或 小写)来表示千字节、兆字节或者十亿字节的单位。

在选项文件中,变量设定值没有引导破折号:

[mysql]max_allowed_packet=16777216或:

[mysql]max_allowed_packet=16M

注:max_allowed_packet参数是在mysql4以后才有的,在mysql4以前版本,还没有这个参数

yii 与 namespace

yii 与 namespace

Yii在import方面已经做的很好了,很多人都说Yii无法导入命名空间,事实上官方很早就给出过意见,如这里:http://www.yiiframework.com/doc/guide/1.1/zh_cn/basics.namespace,当然,这是中文版的

4. Namespace

不要将路径别名和名字空间混淆了,名字空间是指对一些类名的一个逻辑组合,这样它们就可以相互区分开,即使有相同的名字。 而路径别名是用于指向一个类文件或目录。路径别名与名字空间并不冲突。

提示: 由于 5.3.0 版本之前的 PHP 本质上不支持名字空间,你无法创建两个具有相同名字但不同定义的类的实例。 鉴于此,所有的 Yii 框架类都以字母 'C'(意为 'Class') 作前缀,这样它们可以区分于用户定义的类。我们建议前缀 'C' 只保留给 Yii 框架使用,用户定义的类则使用其他的字母作前缀。

5. 使用命名空间的类

使用命名空间的类是指一个在非全局命名空间下声明的类。比如说,类application\components\GoogleMap 在命名空间application\components下的类。使用命名空间需要 PHP 5.3.0 或者以上版本。

从1.1.5开始,可以无需显式引入而使用一个包含命名空间的类。比如说,我们可以创建一个application\components\GoogleMap 的实例而无需去处理引入的路径,这样就增强了Yii的自动导入机制。

若要自动导入使用命名空间的类,命名空间的格式必须和路径别名相似。比如说,类application\components\GoogleMap 所对应的路径必须和别名application.components.GoogleMap一致。

----------
如果仅看中文版,或许你还是看不懂,但你应该看英文版的,下面还有评论,你就知道怎么用了
评论是这个样子的,LOOK,http://www.yiiframework.com/doc/guide/1.1/en/basics.namespace:

Namespaces in a nutshell

Namespaces in php are like directory paths in console (bash, dos etc)
When you use namespace php keyword like this

namespace a\random\namespace;   class Foo {     static function bar(){}    }

is like executing cd a\specific\directory except that the namespace is created if not exists.
Now everything follows is belonging to that namespace. This means that if you want to instantiate, extend or call a static method from eg foo class on another namespace you have to

//The leading backslash '\' here denotes the global namespace that //is the root folder or C:\ counterpart from console environment  $baz= new \a\random\namespace\Foo;  class Fighter extends \a\random\namespace\Foo {} \a\random\namespace\Foo::bar();

Yii imports a very intuitive convention here that the namespace structure (if implemented) should be reflected on the physical directory structure and additionally makes its Path Alias convenience available for that purpose.
Please be my guest to follow these steps:
1. Create a new web app 2. Go to protected\components and create a folder foo 3. Move Controller.php in foo folder and open it with an editor 4. At line 6, at Controller class declaration import this:

namespace application\components\foo; class Controller extends \CController //Note the leading backslash here
  1. Now open protected\controllers\SiteController.php for editing
  2. Replace the SiteController class declaration with this
class SiteController extends \application\components\foo\Controller

As you will see, your new web app still working fine and application path alias will point properly at protected folder.
You can find more about php namespaces here
Enjoy coding :>

--------
果然,这年头,英文版的资料比中文版多多了,手册上也是,不过PHP手册是一定要带评论,对于我们这些初学者来说,那是相当的有用啊