Skip to content

Tutorial.Introduction And Installation II.zh_cn

linzongshu edited this page Jul 4, 2013 · 1 revision

English

  1. Pi Engine的目录结构

查看Pi Engine的代码包,可以看到,整个Pi框架的源码主要存放在4个文件夹下:

  • lib
  • usr
  • var
  • www

这4个文件夹分别有不同的作用。下面我将会逐一介绍这几个文件夹及文件夹下文件的作用。

5.1 lib

lib文件夹存放的是Pi的所有库文件,这也是和框架开发者相关的一个文件夹。这里面主要由四部分组成,Pi库,Zend库,vendor和Pi.php文件。

其中Pi.php定义了一个Pi类,是整个框架最核心的部分。在PHP框架的概念里,它相当于前端控制器,所有外部的请求都需要通过它作相应的处理。也就是这个类负责将外部请求所需要的所有资源集中起来,并作统一处理,最终解析成浏览器能识别的标标签并呈现给用户。这里需要介绍一个概念:单例模式,即在整个程序运行的过程中只有一个实例,采用单例模式可以这样理解,一个请求其实需要的是一份数据,这一份数据不应该由多个总控制器来操作,否则对于同一份资源,在不同的实例中的结果就不一样。Pi这个类就很好地采用了单例模式。打开Pi.php可以看到,它里面所有的变量和方法都定义成了static:

lib/Pi.php
...
protected static $engine = null;
...

public static function init()
{
    ...
}
...

静态的意思就是这些变量和方法只与类相关,而跟实例化后的对象无关。即不论你将类实例化多少次,分别在里面调用这些变量或方法的话,它们在内存都指向同一地址。关于Pi类内部的方法,在后面的章节里会详细介绍。

Zend库就是Zend framework 2.0库,之前已经介绍过,Pi Engine是对Zend Framework的扩展。也就是整个框架的主体逻辑及流程都是来自Zend。

Pi库就是对Zend库部分功能的继承和扩展,使用其符合Pi系统,同时这里面也定义Pi Engine运行时所需要的其他类库。如Pi/Application/Host.php里就提供了获取系统主要目录的URL的方法,Pi/Application/Config.php提供了获取系统配置的方法等。这些类库在Zend里没有定义,需要自己扩展。也就是这里的类库实现了Pi Engine自己的逻辑。

vendor文件夹定义为include path,可以在Pi.php的init()方法里看到:

lib/Pi.php
...
public static init()
{
    ...
    $options = array(
        ...
        'includepath' => !empty($paths['vendor']) ? $paths['vendor'] : static::path('lib') . 'vendor',
    );
    ...
}

这样include(), require()等函数就可以在这里面查找文件了。这个文件夹主要存放第三方代码包,用于对系统的扩展。

5.2 usr

usr文件夹是与模块开发者(包括前端开发和后端开发)紧密相关的一个文件夹。这个文件夹里主要由三部分组成:locale, module和theme。

locale存放的是本地化文件,也就是系统语言至本地语言的翻译文件,这是一个全局的本地化,因为对于模块或主题都分别有自己的本地化文件。对于系统的一些语言的本地化就可以放在这个目录下。

module文件夹存放的就是所有模块代码,从Zend 2.0开始就支持模块化,这也实现了不同功能块之间的解耦,方便代码维护。而每一个模块也是一个独立的功能块,可以根据情况添加或删除,而不影响其他功能块。比如我们在网上写文章的时候会看到有添加文章标签的选项,这样就可以把文章和标签分别作为一个模块:article和tag。文章添加标签时,只需要调用tag模块的相关对外接口,而标签的管理都在tag模块进行。这样如果有一天要去掉标签功能,只需要注释掉article模块里调用tag模块的接口就可以了。而标签模块化后,它也可以为其他的模块提供服务,而不仅仅是文章的一部分。

theme文件夹存放着系统或者模块所需要的主题,这目录主要由前端开发者负责开发的。一个主题也是一个文件夹的形式存在,主题也是支持安装和卸载的,用户可以根据自己的情况开发主题并更换。

模块开发这部分的具体内容在下面的章节里都会详细介绍。

5.3 var

var文件夹主要与运维人员相关,里面存放了系统的配置文件,缓存文件和日志文件等。这个文件夹在安装之后可以放置到其他地方进行管理,但在安装时需要设置这个文件夹更改后的url和路径,或者安装后去var/config/host.php里更改。即

fig1-9

图1-9 var目录路径配置

fig1-10

图1-10 var/config/host.php文件里的var路径

这个目录下主要有三个文件夹:cache, config和log。

cache目录主要是存放缓存数据,如果安装时选择了缓存方式为File system,缓存的数据将会保存在这个目录里,其他缓存方式则不会。这个目录不需要人工干预。

config目录系统运行时的配置信息,如application.front.php会保存用户访问前台(简单理解,前台就是给用户浏览的,后台用于管理员管理的)页面时需要加载的资源,服务等,配置信息在一个请求的时候将会被写入变量里。

需要说明的是:engine.php, host.php和service.database.php这三个文件在安装完之后会被更改,因为这三个文件分别存放缓存机制、主要目录的路径和URL、数据库配置信息,这些数据是安装时用户填选的。

5.4 www

www目录相当于服务器的根目录,这里面的文件都可以被任意用户读取,因些这里面存放的是请求的入口文件、css, js等静态文件以及用户上传的文件。这个目录的主要文件有:

  • asset
  • script
  • setup
  • static
  • upload
  • .htaccess
  • admin.php
  • boot.php
  • feed.php
  • app.php
  • index.php

index.php文件是网站的默认入口,也就是如果单单访问一个域名的话,比如:www.eefocus.com,其实默认访问的就是www.eefocus.com/index.php,只是后面的index.php被省略掉。这个文件里主要是对带有index.php的url进行处理。而这个入口也被设置为访问前台的入口。

.htaccess为Apache服务器中的一个配置文件,它负责相关目录下的网页配置。在这里通过它的Rewrite规则来判断是将所访问的url分配到哪个入口。比如:www.eefocus.com/admin分配置到admin.php,www.eefocus.com/feed分配到feed.php等。

admin.php为后台的入口,它也告诉程序这个url是要访问后台(admin)。

feed.php为feed的入口,feed和前台(front)、后台(admin)同样,都是一个(区)section。这个区目前实现的功能有RSS订阅。

app.php是当之前的admin、feed以及index.php都没匹配到,所使用的入口,这个入口也默认为前台(front)入口。

boot.php文件是一个中间入口,文件的内容决定了是要跳转到安装页面还是继续访问用户请求的页面,这个文件在安装之后将会被更改。同时这个文件开始调用前端控制器(Pi),执行用户请求。

asset目录存放的是模块的静态文件如js/css/image等,这些静态文件在模块安装后会自动发布到这个目录下,当然用户也可以到后台手动将模块的静态文件发布过来。

fig1-11

图1-11 Pi后台重新发布静态文件界面

script目录和static目录都可以放系统的静态文件,目前存放规则没有要求,因为这些文件的调用都需要用户自己用代码实现。

setup目录存放了系统安装的所有库文件,若用户没安装Pi,则会跳到这个目录里的index.php执行安装。

upload目录存放用户上传的文件。

这些目录里,upload和static文件夹可以部署到其他路径下,同样也需要在安装的时候更改其路径和url。或者安装后去var/config/host.php里更改。

fig1-12

图1-12 静态文件目录配置

  1. 总体流程概要

Pi的核心思想继承自Zend,因此其运行机制也与Zend相似,当然Pi作为一个平台式开发系统,还需要对Zend进行扩展。下面是一次请求的总体流程图,我们将会结合这个图先大概了解下基本的运行机制。

fig1-13

图1-13 Pi Engine框架的程序框图

这个图描述了系统运行的大致流程,当一个请求过来时,在htaccess文件里确定请求的入口文件,也就在入口文件里定义了请求的区(section),之后就将执行权交给前端控制器(Pi类)。

前端控制器先从配置里获取主要文件的路径和URL并保存到静态变量里,之后会定义文件自动加载机制以及其他配置文件,完成这些后,第一步数据初始化也就完成了。

接下来,前端控制器会定义一个engine的句柄(也就是一个实例,这里套用C++的概念),然后将控制权交给这个句柄,这个句柄将会完成接下来的数据初始化和系统运行。也就是这个句柄将会成为调用系统初始化数据的入口。在下面的操作中,该句柄将会加载系统需要的服务、资源以及将系统后面要执行的函数作为事件写入事件驱动机制。

完成所有的初始化后,engine句柄将会调用event对象并接优先及触发所有事件,执行之前加载的函数,并最终将数据输出。 从这个流程可以看出,整个Pi系统的执行可分为两大步,数据初始化和系统运行。

Clone this wiki locally