在本实践中,将使用PHP7+MongoDB3+Bootstrap3开发一个新闻网站,共有3个功件,名称为Start、User、News,分别对应程序启动、用户管理、新闻管理等3个方面的业务功能,以下将以3篇文章分别予以介绍。
在一些编程语言中,都有一个main方法作为程序必须实现的入口方法;面向功件编程也是如此,一个使用功件组合形成的软件产品,也应有一个启动功件或开始功件,即Start功件。Start功件为必要功件,其既是程序的入口,也基本定义了其所属软件产品的技术架构,包括开发语言、开发框架、技术组件、数据库、运行环境,以及相关的版本限制等。
如上图所示,Start功件包括Start.php和start目录下的所有文件,其中Start.php为功件主文件,start目录下包含了images、jslib、phplib等三个子目录;images子目录包含了Start功件以及整个网站使用的所有Logo图标、公共图;jslib子目录为整个网站需要的前端框架和js组件;phplib子目录包含了服务器端所使用的PHP公共类库,其中包括PHP Library for MongoDB,所有功件均使用这个类库访问MongoDB。
为使得Start.php成为整个网站的入口,需修改Apache或Nginx服务器的URLRewrite相关配置部分,将所有网页请求均经过Start.php的处理转发至相应功件和功件方法。
针对Apache服务器,首先在网站程序根目录下创建.htaccess文件,注意开启http.conf中的“LoadModule rewrite_module modules/mod_rewrite.so”模块,并修改AllowOverride None 为 AllowOverride All。.htaccess文件的内容如下:
Start.php中的源码见Functree中的PhpWebBoot_Mongo功件树,下面截取部分主要代码分别介绍。
本网站的访问网址类似如下:http://localhost/PhpWebBoot_Mongo/User/login,其中“http://localhost/PhpWebBoot_Mongo/”后面的部分,为功件名称和功件方法,通过上述代码,将用户访问的网址分解为功件以及其下的功件方法,即$requestFuncName和$requestMethodName变量,从而定位到某个具体的php网页,以完成Http请求和响应的相关处理。
上述代码,将遍历功件所在目录:f,获取所有功件主文件名称作为功件名称,并缓存到名称为FUNCTREE_FUNC_LIST的功件列表常量中,以供整个网站中的所有功件使用。
上述代码,将所有功件主文件引入,由于require引入机制,所以应尽量保持功件主文件的内容简捷,使其仅完成Http请求的分发,详细的响应处理应使用include方法,交给某个具体的PHP处理页面来完成。
上述代码,将遍历所有功件主类中的b_permissionMap方法,获取该功件定义的相关权限,并缓存到名称为FUNCTREE_PERMISSION_MAP的系统权限列表常量中,供整个网站中的所有功件使用。因此,所有需要权限控制机制的功件,均应实现b_permissionMap方法,返回其定义的权限,并实现权限控制机制;而权限的分配和授权机制,则由另一个必要功件,User功件来完成。
上述代码,将遍历所有功件主类的b_menuList方法,获取该功件定义的菜单列表,并缓存到$_SESSION["FUNCTREE_MENU_LEFT_LIST"]和isset($_SESSION["FUNCTREE_MENU_RIGHT_LIST"]的会话变量中,即每个用户对应一个独立的左侧菜单列表和一个独立的右侧菜单列表,在用户登录前和登录后,由于用户授权状态的变化,这2个菜单列表也将随之发生变化;下述代码即为通过User功件的b_authUserId方法和b_authPermissionList方法,获取授权用户ID和授权用户所具有的权限列表:
上述代码中,由Start功件调用User功件的b_authUserId和b_authPermissionList方法,获取授权用户的相关信息,其他功件也可以用类似方式调用这两个方法,完成用户授权信息的获取和使用。
到这里,Start功件的所有准备工作基本完成,下面将根据URI解析出来的$requestFuncName和$requestMethodName变量,进行Http请求的分发和响应处理,并将Http响应内容组合为Html返回给用户。Html内容如下:
上述Html代码为上、左、右、下的布局,所有功件和功件方法返回的Http响应内容字符串,将被放置到指定位置中。下述代码首先判断功件是否存在,如果存在,则调用该功件的请求方法,获取Http响应内容字符串,并被放置到指定位置index_top中:
上述响应分枝由被请求的功件来完成,当请求功件名称为空时,视为请求首页内容,下述响应分枝为首页内容生成部分:
上述代码,通过调用所有功件的b_homeContentList方法,获取其自定义的首页内容,并根据其自定义的position信息,将相关内容放置于指定位置,从而完成首页内容的生成。
Start功件,作为网站入口页面,还担负着整个网站页面的整体布局功能,因此,所有Http请求的响应页面的页头和页尾,也在Start.php中实现,具体代码略,详见PhpWebBoot_Mongo功件树:http://120.27.237.45/PhpWebBoot_Mongo/。