让Kohana直接支持python——client篇

December 12th, 2011

最后,是让php和python”对接“起来
我们在php的auto_load的时候也让python加载对应的模块

  1. <?php defined('SYSPATH') or die('No direct script access.');
  2.  
  3. Socket_Instance::$client = new Socket_Client('127.0.0.1', 1990);
  4.  
  5. class Python_Env_Init extends Kohana{
  6.     /**
  7.      * add auto_load to create php local classes associate to remote python classes
  8.      */
  9.     public static function auto_load($class){
  10.         try{
  11.                 $data = Socket_Instance::find_class($class, self::$_paths);
  12.                 $code =
  13.                     'class '.$class.' extends Socket_Instance
  14.                         {
  15.                             protected static $_class="'.$class.'";
  16.                             function __construct(){
  17.                                 $args = func_get_args();
  18.                                 parent::__construct(self::$_class,$args);
  19.                             }
  20.                             static function __callStatic($func, $args){
  21.                                 return self::_rpc_call(self::$client,
  22.                                     array(
  23.                                             "class" => self::$_class,
  24.                                             "func" => $func,
  25.                                             "args" => $args, )
  26.                                 );                                                   
  27.                             }
  28.                     }';
  29.                 eval($code);
  30.                 return true;
  31.         }catch(Exception $ex){
  32.                 return false;
  33.         }
  34.     }
  35. }
  36.  
  37. spl_autoload_register(array('Python_Env_Init', 'auto_load'));

Read more…

月影 Python, 前端技术

让Kohana直接支持python——RPC篇

December 12th, 2011

上一篇中,我们实现了基础的TCP Server,数据通过json协议进行传输

接下来,我们需要处理RPC请求的核心部分。
我们来看,在PHP代码中写:

  1. $myObj = new Foo_Bar();
  2. $myObj->test();

我们要python端做哪些事情

Read more…

月影 Python, 前端技术

让Kohana直接支持python——Server篇

December 9th, 2011

最近写php用的是Kohana(http://kohanaframework.org/) MVC框架。这个框架用的人不是很多,不过确实是一个相当不错的轻量级PHP MVC框架。
php用于web开发还是很方便的,这门语言专注于web开发,作为前端工程师,非常喜欢这种简单的脚本语言。
不过有些后端的服务,如一些对异步要求较高的服务,用php写就稍稍有点费劲,而用python则是不错的选择。
因此,我自然开始考虑是否能将kohana和python结合起来。
我的设想是:在kohana中能直接new python写的class,就像php的原生方法那样简单

例如:
在koahan中,如果要直接加载一个php的类clas Foo_Bar,那么要求这个类定义放在 classes/foo/bar.php 文件中
现在如果我定义在classes/foo文件夹下的是一个python文件 bar.py,里面定义了一个python的类Foo_Bar
我希望也能用kohana调用这个类
即——

Read more…

月影 Python, 前端技术

show一段用Lafe写的代码

July 18th, 2011
  1. class Layout_My_Layout extends Base_Layout{
  2.     function build(){
  3.         if($ua->isPc) $this->pc->display();
  4.         else if($ua->isPad) $this->pad->display();
  5.         else if($ua->isPhone) $this->phone->display();
  6.     }
  7.     public function layout_pc(){
  8.         $main_body = "left_2_right_3_5.Right";
  9.         $side_bar = "left_2_right_3_5.Left";
  10.  
  11.         if($ua->userReverse){
  12.             $main_body = "left_3_right_2_5.Left"; //用户选择把side_bar放在右边的设置
  13.             $side_bar = "left_3_right_2_5.Right";
  14.         }
  15.  
  16.         $this->{'Header common_header'} = $headder_data;
  17.         $this->{"Body $main_body main_panel"} = $side_data;
  18.         $this->{"Body $side_bar side_panel"} = $right_data;
  19.         $this->{'Footer common_footer'} = $footer_data;
  20.     }
  21.     public function layout_pad(){
  22.         ......
  23.     }
  24.     public function layout_phone(){
  25.         ......
  26.     }
  27. }

月影 Uncategorized

LAFE——基于Layout的前端开发方式简介

July 18th, 2011

LAFE是个神马东东呢?听起来像个新鲜玩艺儿吧?
要解释这个还蛮费劲的。而我这个人又比较懒,不喜欢长篇大论。(看我前一篇文章是啥时候更新的就知道我有多懒了=.=)
为什么我不经常更新呢,一是我比较懒,二是我一般不喜欢经常码字的,特别是比较忙的时候,如果废话就会被老大发现我工作不饱和,然后说不定就有更多的活要做了……

额……
还是言归正传,谈谈LAFE吧
好吧,我们天天说模块化模块化,但是没有人真正说清楚,一般的开发过程中,如果我们要把前端设计成模块化开发,究竟应该肿么写代码才比较爽。如果只是简单把页面分成一块块的,然后把这些模块一一载入进来,拼成页面,那再简单也不过了。

但是现实没这么理想化,如果一个页面足够复杂,那么可能包含一个头部、一个底部、中间包含一个边拦,一个主栏,主栏里边可能又嵌套包含一个有头、身子、底的复杂结构,然后这种结构还能多重嵌套,这时候你就知道有多烦了。

模块化不仅仅只是拆,更烦的是拼装,如何把一个复杂页面很快速拼装出来呢,好吧,我们看看传统的方式是如何工作滴——

最初的办法是全部写在views下的模板中,例如php有include和require,smarty有include,假如一个a模板要引入b和c,那么就在a中直接写

  1. <?php include('b.php')?>
  2. <?php include('c.php')?>

这种做法当然可以,但是在页面复杂的时候不可取,理由首先是不够灵活,现在我的a页面要套b和c,但是随着需求改变,如果我要新增一个把c换成d的页面,那么得重新写一个模板,写多了很难管理。另外页面模块加载会非常散乱,假如a引入b、c,b引入d、c引入e、f,一个维护网站的开发人员,如果不熟悉这个模块,他要改的东西在e中,得从页面开始找到a,从a找到b、c,从c找到e,才能定位到模板所在,在模块非常多的情况下,这会让维护人员抓狂。另外,联调的时候让写php的工程师拼页面本来就是一件繁琐的工作,而这种简单粗暴的模块拆分方式,无疑加重了他们的麻烦,拼接页面的时候找来找去,相信会让非常多工程师受不了。

那么有没有聪明的做法?当然有,例如,可以事先把模块规划成对象,然后利用php封装,采用搭积木的方式在统一的地方进行拼接,例如——
(以下代码参考某框架,感谢曾经有幸一起共事的几位开发者,感谢某优秀前端开发团队,我以曾经是团队中一员为荣!)

  1. $page = new Page($data);               
  2.     $page->add('header',new xHeader($hd));
  3.     $page->add('search',new xBase($b3search, 'search'));
  4.     $page->add('list',new xBase($show_list, 'list'));
  5.     $page->add('pager',new xBase($pager, 'pager'));
  6.     $page->add('footer',new xFooter());
  7.         $page->extJs('piao/ext/switchcity.js');

我们会看到,这种方式下,有了页面、层和模块的概念,而这些布局、模块和内容,可以在一段php代码中build出来,易于统一管理和维护。而且这种代码方式,对php程序员来说更亲切(这样,在忙的时候,我们就更容易骗他们为我们干活),页面像搭积木一样,这多简单~

不过这也有一些不足之处,首先你必须先约定Header、Footer和其他容器的命名和相互关系,其次,你必须封装和扩展对应的类,第三,在页面比较复杂的时候,比如层嵌套的时候,这种描述也不那么直观,你很难直接看出数据与结构模块之间的关联关系。最后,它并没有想象中的那么灵活,在不额外开发的情况下,你不能随意配置和使用各种Layout结构和模块。

那么,我们有什么解决方案呢?先看下面一段代码——

  1. $layout->{'Header hd'} = $hd;
  2. $layout->{'Header search'} = $b3search;
  3. $layout->{'Body list'} = $showlist;
  4. $layout->{'Body pager'} = $pager;
  5. $layout->{'Footer footer'} = $footer;
  6. $layout->{'Footer extJs'} = $extJs;

这段代码结构简单,它把页面分成Layout容器和模块两个层级,{}之间是结构和模块的描述,模块是可以对应到views下面的module目录的文件,可以设定一个查找目录的规则,例如先找模板当前目录下的module目录,找不到,再去找views下面的module目录,这样就建立起模板管理的层级依赖关系来。=右边是赋给模板的变量,在module中可以用到。这种写法和上面一种写法的不同在于,它不用事先准备对象,所有的模块一律同样对待。它形式上只做简单直观的赋值操作,但定义了一套描述模块位置的语法。它足够灵活,不限制你构建任何模块,它只负责将这些模块找到,拼接到页面中去。它能做到足够灵活,看下面的代码:

  1. $layout->{'Header hd'} = $hd;
  2. $layout->{'Header search'} = $b3search;
  3. $layout->{'Body layer_gride_3_5.Left list'} = $showlist;
  4. $layout->{'Body layer_gride_3_5.Left pager'} = $pager;
  5. $layout->{'Body layer_gride_3_5.Right list'} = $rightside;
  6. $layout->{'Footer footer'} = $footer;
  7. $layout->{'Footer extJs'} = $extJs;

在这里,我们在模板中嵌套了另一层Layout,也就是layer_gride_3_5,它至少有Left和Right两个结构,这样我们就做到了Layout的层级嵌套。
用这套东西还能写出很多好玩的代码来,比如我可以在{}里面用变量,等等等等,还有很多可以想象的事情,这些在下一篇文章里我在详细介绍吧(=.=不过不知道下一篇啥时候更新)

最后,无码无真相,放上代码—— https://github.com/akira-cn/lafe

谢谢观赏~

月影 Uncategorized

[偷懒]本地web开发的一体化解决方案

June 9th, 2011

最近在新公司研究PHP开发的前端方案,考虑用CodeIgniter+Smarty3的方案。研究了一下nginx+PHP+CI+Smarty的配置。

感谢明城(@gracecode)同学提供的Farseer,真是个方便实用的好东东~

整合的Farseer-QWDIY,windows下解压到任意目录就可以直接使用,集成CI和Smarty3,脚本库集成QWrap,无需修改配置,直接访问
http://localhost
就可以看到欢迎界面啦~

月影 Uncategorized

【广告】《程序员成长的烦恼》

March 22nd, 2011

【小技巧】QWrap核心中的几个不起眼小方法使用技巧(一)

March 16th, 2011

http://www.qwrap.com/

1. ObjectH.dump

用ObjectH.dump 方法可以将非枚举类型的方法从原生对象中“提取”出来

  1. QW.ObjectH.mix(window, QW);
  2.  
  3. var ah = ObjectH.dump(Array, ["join","reverse","push","pop","concat","slice","splice"]); //提出Array的以上方法
  4. ah.toString = function(arr){
  5.     return arr.toString();
  6. }
  7.  
  8. var List = function(arr){
  9.     this.items = arr;
  10. }
  11.  
  12. ah = HelperH.methodize(ah, "items");
  13. ObjectH.mix(List.prototype, ah, true);
  14.  
  15. var myList = new List([1,2,3,4]);
  16. myList.push(5);
  17. alert(myList); //[1,2,3,4,5]

Read more…

月影 javascript, 前端技术

“你懂的”——三言两语说清QWrap核心模式精髓(二)

March 16th, 2011

http://www.qwrap.com/

什么是Wrap机制

Wrap其实只是一个”壳”,它的定义很简单,任何一个对象A,只要将它赋给另一个对象B的某个属性,我们就可以说,B是A的一个Wrap。
例如:

  1. var o = {};
  2. function oWrap(o){
  3.     this.core = o;
  4. }
  5. var ow = new oWrap(o); //ow是o的一个Wrap

Read more…

月影 javascript, 前端技术

”你懂的“——三言两语说清QWrap核心模式精髓(一)

February 26th, 2011

http://www.qwrap.com/

什么是methodize?

methodize基本上就是把一个静态函数变成一个对象方法。这里要用纯静态语言的眼观去看待对象方法和静态函数的区别。
我们说静态函数是没有”Owner”的,也就是说它的语义中没有”this”的概念,而对象方法自然有”this”语义。
例如:

  1. function add(x, y){
  2.     return x+y;
  3. }

这是一个最最基本的静态函数,它只是对两个数相加然后求和。
Read more…

月影 javascript, 前端技术