Servelt如何判断用户首次访问站点是否需要进行URL重写?

看到《Head First Servlet&JSP》的URL重写的时候,对这边就有疑问了。

Servlet如何判断客户端不支持Cookie而进行URL重写呢?毕竟用户的第一次访问站点都是不可能带Cookie的,那么如何判断这个是用户首次访问站点还是因为用户的浏览器不支持Cookie?

然后,找到了一篇文章:http://dk05408.iteye.com/blog/2103257,发现这个问题Servlet处理的太简单了。简单的来说,就是不处理,所有的用户第一次访问站点的情况都当成不支持Cookie处理,进行URL重写。等到下次访问的时候,就能正确判断支持不支持Cookie了。

这样的话,那么Servlet就会对每一个不支持Cookie的请求都会尝试设置Cookie,这也是一种没办法的办法。

SlimPHP框架运行原理

SlimPHP主要有两个大的部分,路由(Router)部分和中间件(Middleware)部分。
首先,我们需要了解的是路由部分。
其实路由部分没什么难度,Route对象主要存储的是来自map()方法的内容。
Router是一个控制器,所有对Route的操作都要经手Router,职责有创建Route对象和dispatch(Request)到匹配的Route。
匹配的Route将会被放到Request里面,Route中的Closure(其中有业务逻辑代码)在中间件部分执行。

然后,我们来了解一下中间件部分。
所有中间件会形成一个栈(stack)结构,从最外层的中间件到最里层的中间件依次执行。
当然,最里层的中间件会继续调用$next,那么这个$next是何方神圣呢?
其实这个$next就是App对象,在PHP中,有一个魔术方法__invoke()可以把一个对象当成函数来用。
这边的App类就有一个__invoke()方法,当调用到最里层的中间件的时候,就相当于会调用$app($request, $response)。
在这个__invoke()方法里面,将会调用路由部分存储在Request中的Route中携带的Closure业务逻辑。
具体怎么执行的,请查看相关代码。

差不多就这些内容。

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的开销。