手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

yii CActiveRecord 中的一点小注意事项

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

Tags: cactiverecord, __sleep, serialize

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

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

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

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

PHP代码
  1. <?php  
  2. // error handler function  
  3. function myErrorHandler($errno$errstr$errfile$errline)  
  4. {  
  5.     if (!(error_reporting() & $errno)) {  
  6.         // This error code is not included in error_reporting  
  7.         return;  
  8.     }  
  9.   
  10.     switch ($errno) {  
  11.     case E_USER_ERROR:  
  12.         echo "<b>My ERROR</b> [$errno] $errstr<br />\n";  
  13.         echo "  Fatal error on line $errline in file $errfile";  
  14.         echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";  
  15.         echo "Aborting...<br />\n";  
  16.         exit(1);  
  17.         break;  
  18.   
  19.     case E_USER_WARNING:  
  20.         echo "<b>My WARNING</b> [$errno] $errstr<br />\n";  
  21.         break;  
  22.   
  23.     case E_USER_NOTICE:  
  24.         echo "<b>My NOTICE</b> [$errno] $errstr<br />\n";  
  25.         break;  
  26.   
  27.     default:  
  28.         echo "Unknown error type: [$errno] $errstr<br />\n";  
  29.         break;  
  30.     }  
  31.   
  32.     /* Don't execute PHP internal error handler */  
  33.     return true;  
  34. }  

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

XML/HTML代码
  1. errcontext  
  2.     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的话,会自动调用原来的出错处理。这  其实是影响我们的操作的。

最终代码如下:

PHP代码
  1. set_error_handler(function($errno,$errstr,$errfile,$errline,$clsname){  
  2.     if(isset($clsname['className'])&&$errno == 2&&!class_exists($clsname['className'])){  
  3.         $clsname = $clsname['className'];  
  4.         eval("class ".$clsname ." { static public function model(){return null;} }");  
  5.     }  
  6.     return true;  
  7. },7);  
  8. $result = mmmm::model();  
  9. restore_error_handler();  
  10.  

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

 

终于可以直接用了。

 

Tags: php, eval

转: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 操作符,这样程序的可读性更好而且不会强迫你在列表操作符上使用圆括弧。它们也是短路的。

Tags: 短路操作

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手册是一定要带评论,对于我们这些初学者来说,那是相当的有用啊

Tags: yii, namespace

花了半小时写完了RSS输出

大约在半年前,hightman给了个array2xml的代码(以前在liba的时候自己写过,但代码不见了),改了一下,支持了attributes,而且在支持Attributes时候,也支持字符串了。
黑黑:

输出就更方便了,直接:
die(xmlapi::generateEmptyXml(xmlapi::array2xml($rssdata)));

爽。

Tags: rss, hightman, liba