PHP的页面控制器和前端控制器

读过《企业应用架构模式》(一本归纳总结了企业应用开发中的架构和模式的书)的读者都会知道书中提到过两种对立的模式,页面控制器和前端控制器模式,那么这两种模式有什么区别呢?

页面控制器和前端控制器模式的区别在于前端请求的地址不同,前端控制器是只有一个请求地址,而页面控制器是请求多个地址。而这造成了两种模式的本质区别,那就是需不需要路由。

在PHP中,我们初学这门语言的时候,大多是从页面脚本入门,这时候使用的就是PHP的页面控制器模式。而在框架中,我们需要切换到前端控制器模式,理解路由的概念。

在前端控制器模式中,路径参数有url字符串,url参数,request method。
而在页面控制器中,不同文件本身就是一种路径参数,当然除此之外可以叠加上诉的url字符串等其他参数。

所以,前端控制器模式中,路由分发实现是由一个路由分发器来进行dispatch。
而在页面控制器中,路由分发实现不仅通过用户请求不同文件,而且需要在文件中进行进一步的分发来实现。

后面,我会改造Slimphp框架成为页面控制器模式的版本,未完待续。

React入门思路

首先我们来看一段代码:

var element1 = React.DOM.h1({id: "myH1"}, 'content');
ReactDOM.render(
  element1,
  document.getElementById('test1')
);

上面这段代码相信大家都看得懂吧!React有一个关键在于把所有DOM Element都用Virtual Element进行声明,然后就可以把Virtual Element用ReactDOM渲染出来。然后我们来看渲染嵌套的Virtual Element的方法:

var element2 = React.DOM.h1({id: "myH1"}, 
    React.DOM.span({id:"mySpan"}, 'span content'),
    'content');
ReactDOM.render(
  element2,
  document.getElementById('test2')
);

Virtual Element嵌套Virtual Element应该不是很难理解,毕竟DOM Element也是这样一环嵌一环的嵌套的。
这边通过嵌套Virtual Element产生了一个组合Element,但是如果我多处需要这个组合Element的话,每次都得写一遍创建代码,岂不是麻烦死了。
React里面因此诞生了Component的概念,Component和组合Elemnent的关系类似OOP中类和对象的关系。
不过首先!我们换一种新的方式来取代React.DOM.*来产生Element,来看下面代码:

var element2 = React.createElement("h1",{id: "myH1"}, 
    React.createElement("span", {id:"mySpan"}, 'span content'),
    'content');
ReactDOM.render(
  element2,
  document.getElementById('test2')
);

上面的代码仅仅是替换了React.DOM.为React.createElemnet(),但是这种方式更具有适普性,如果我们自定义了component,那么也可以通过这种方式产生Element。
行,那么我们就可以尝试搭建Component了,见如下代码:

var element2 = React.createElement("h1",{id: "myH1"}, 
    React.createElement("span", {id:"mySpan"}, 'span content'),
    'content');
var component3 = React.createClass({
    render: function() {
        return React.createElement("h1",{id: "myH1"}, 
            React.createElement("span", {id:"mySpan"}, 'span content'),
            'content');
    }
});
var element3 = React.createElement(component3);
ReactDOM.render(
  element2,
  document.getElementById('test2')
);

看了上面的代码,关于为什么要有React.createElement和React.createClass的由来想必都有所思路了吧。

安装php-fpm和nginx

以前一直用Apache Httpd和mod_php的组合的,现在来了解一下nginx+php-fpm的组合。

安装参考了这个网页:https://www.sitepoint.com/setting-up-php-behind-nginx-with-fastcgi/

除了存在默认的localhost的站点外,我还新建了一个站点,贴一下diff(diff sites-enabled/nginx.zhudekui.com sites-enabled/default)的内容。

< listen 80;
< #listen [::]:80 default_server ipv6only=on;


  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;

24c24
< root /var/www/html;


  root /usr/share/nginx/html;

28c28
< server_name nginx.zhudekui.com;


  server_name localhost;

54,55c54,55
< location ~ .php$ {
< fastcgi_split_path_info ^(.+.php)(/.+)$;


  #location ~ \.php$ {
  #       fastcgi_split_path_info ^(.+\.php)(/.+)$;

61,64c61,64
< fastcgi_pass unix:/var/run/php5-fpm.sock;
< fastcgi_index index.php;
< include fastcgi_params;
< }


  #       fastcgi_pass unix:/var/run/php5-fpm.sock;
  #       fastcgi_index index.php;
  #       include fastcgi_params;
  #}

此外,还了解了一下FastCGI:
在CGI的时代,每个请求都是由CGI创建一个process(进程),而且会在完成后销毁。
要知道,虽然*nix的创建销process的开销比Windows好很多,但是还是比较weight,这导致网站并发量很难提高。
而FastCGI,有点类似于进程池的概念,FastCGI将多个线程不断重用,基本没有了创建销毁process的开销。

Linux下如何查找某个目录下包含指定字符串的文件

本来我是记得这个查找某个目录下包含指定字符串的文件这个命令的,但是今天在使用的时候出现了一个严重的问题。这个问题以前也出现过,但是没什么影响就没有关注。但是这次我得解决这个问题!
我记得的命令是这样的:
find /path/to/directory -type f | xargs grep 'xxx'
但是一直会出现这种类型错误提示:.config/google-chrome/Default/Local:No such file or directory
怎么会这样呢?我仔细一看,沿着目录去找提示的文件,发现该名称的路径不存在,但是存在"Local XXX"这样的目录。
问题很明显了,是pipe(管道)传递时空格惹的祸,那么怎么解决这个问题呢?
我只能求助于搜索引擎了,使用关键词“Linux find xargs grep space”搜索,结果中有个stackoverflow的链接,标题是“How can I make xargs handle filenames that contain spaces?”。果然stackoverflow不愧是程序员的圣地之一,连这个都有。
排在前面的有几种方案,我试了
find /path/to/directory -type f -print0 | xargs -0 grep 'xxx'
这条命令搜索成功并且没有报错。
接下来,我该想想办法怎么把这个常用的搜索语句写成脚本方便以后使用了。

servlet项目如何添加和使用第三方jar

在Java Web中,我们用到第三方类库的机会很多,那么当我们手动管理依赖的时候,我们该如何添加和使用第三方jar文件。

在此,我们用于举例的第三方jar是普及程度极高的slf4j。

1、前往slf4j官网下载slf4j的zip压缩包,这边下载的是slf4j-1.7.21.zip。解压缩文件夹,待用。

2、在已有的servlet代码里面加上以下几句:
import org.slf4j.LoggerFactory;

`LoggerFactory.getLogger({className}.class).info("Hello World");
注:{className}需要替换成你的servlet类的名称

3、编译servlet文件,需要在-classpath参数里面加上slf4j-api.1.7.21.jar。
比如原来的-classpath参数是"/path/to/servlet-api.jar",现在需要改成"/path/to/servlet-api.jar:/path/to/slf4j-api.1.7.21.jar"。
注:/path/to/需要替换成具体的路径

4、tomcat之类的容器不会像java这个命令一样可以方便的加上-classpath参数,所以有个专门用来放jar文件的路径:WEB-INF/lib/。当tomcat启动的时候,类似于java命令自动添加了-classpath参数。
你需要复制slf4j-api-1.7.21.jar和slf4j-simple-1.7.21.jar两个jar文件到该路径。

5、添加了jar文件之后,不要忘记重启tomcat,此时添加了第三方的servlet就可以正常运行了。