phpcms v9代码解读

一、数据库加载:
数据库配置文件:安装时填写的数据库配置数据存储在caches/configs/database.php

(1)index.php入库文件,并加载phpcms/base.php。
(2)index.php文件:pc_base::creat_app();
(3)phpcms/libs/classes/application.class.php:$controller = $this->load_controller();
默认加载:phpcms\modules\content\index.php
(4)phpcms\modules\content\index.php:$this->db = pc_base::load_model('content_model');
加载文件:phpcms/model/content_model.class.php
(5)phpcms/model/content_model.class.php:$this->db_config = pc_base::load_config('database');
(6)加载配置文件:caches/configs/database.php

二、模板解析:
文件:phpcms/libs/functions/global.func.php
调用:include template($module,$template);

模板缓存文件:phpcms/libs/classes/template_cache.class.php
template_compile:模板编译函数
------------------------------ edit in 2011-05-07 ------------------------------
三、用户登录模块(phpsso关联)
1、phpcms/modules/member/index.php
登陆操作:login()
...
$status = $this->client->ps_member_login($username, $password);//phpsso中判断用户登陆,正确返回用户数据array
...//如果本地用户信息不存在,则插入数据,保持数据一致。
...
$synloginstr = $this->client->ps_member_synlogin($r['phpssouid']);//phpsso用户同步登陆函数
//==========其余分析至[phpsso通信]==========

四、用户注册模块(phpsso关联)
1、phpcms/modules/member/index.php
注册操作:register()
$this->_session_start();//加载phpcms/libs/classes/session_mysql.class.php
...
$member_setting = getcache('member_setting');//加载用户配置
...
$siteid = isset($_REQUEST['siteid']) && trim($_REQUEST['siteid']) ? intval($_REQUEST['siteid']) : 1;//默认siteid为1
...
$this->_init_phpsso();//加载phpcms/modules/member/classes/client.class.php
//phpcms/base.php中load_app_class()函数的defined("ROUTE_M")来至于phpcms/libs/classes/application.class.php
...
$status = $this->client->ps_member_register($userinfo['username'], $userinfo['password'], $userinfo['email'], $userinfo['regip'], $userinfo['encrypt']);//phpsso中添加注册用户,返回phpssouid
...
$userid = $this->db->insert($userinfo, 1);//本地用户数据添加。密码加密存储

五、后台部分整理
1、口令卡(移除)
配置文件:caches/configs/system.php

后台登陆/退出:phpcms/modules/admin/index.php
后台管理:phpcms/modules/admin/admin_manage.php

口令卡类:phpcms/modules/admin/classes/card.class.php
管理员类:phpcms/modules/admin/classes/admin.class.php

语言文件:phpcms/languages/zh-cn/admin.lang.php
phpcms/languages/zh-cn/system_menu.lang.php

模板文件:phpcms/modules/admin/templates/admin_list.tpl.php
phpcms/modules/admin/templates/login_card.tpl.php
phpcms/modules/admin/templates/admin_card.tpl.php

2、后台登陆
phpcms/modules/admin/classes/admin.class.php
常规下加载phpcms/libs/classes/session_mysql.class.php
...session_start();//开启session

phpcms/modules/admin/classes/admin.class.php
状态判断:check_admin()

phpcms/modules/admin/index.php
登陆操作:login()
...
$_SESSION['userid'] = $r['userid'];
...
$cookie_time = SYS_TIME+86400*30;
...
param::set_cookie('userid', $r['userid'],$cookie_time);
...
//设置session和cookie

六、phpsso通信机制
1、用户登陆/注册模块中调用phpcms/modules/member/classes/client.class.php
private function _ps_send(){//调用phpsso接口地址
return $this->_ps_post($this->ps_api_url."/index.php?m=phpsso&c=index&a=".$action,500000,$this->auth_data($data));//socket方式提交post数据
}
------------------------------ edit in 2011-05-11 ------------------------------

private function _get_url() {
$sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://';
$php_self = $_SERVER['PHP_SELF'] ? $this->_safe_replace($_SERVER['PHP_SELF']) : $this->_safe_replace($_SERVER['SCRIPT_NAME']);
$path_info = isset($_SERVER['PATH_INFO']) ? $this->_safe_replace($_SERVER['PATH_INFO']) : '';
$relate_url = isset($_SERVER['REQUEST_URI']) ? $this->_safe_replace($_SERVER['REQUEST_URI']) : $php_self.(isset($_SERVER['QUERY_STRING']) ? '?'.$this->_safe_replace($_SERVER['QUERY_STRING']) : $path_info);
return $sys_protocal.(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '').$relate_url;
}



private function _ps_post($url, $limit = 0, $post = '', $cookie = '', $ip = '', $timeout = 15, $block = true) {
$return = '';
$matches = parse_url($url);//解析URL
$host = $matches['host'];//主机名
$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';//路径及查询字符串
$port = !empty($matches['port']) ? $matches['port'] : 80;//端口
$siteurl = $this->_get_url();//获取当前页面完整URL地址
if($post) {//post方式提交
$out = "POST $path HTTP/1.1\r\n";
$out .= "Accept: **\r\n";
$out .= "Referer: ".$siteurl."\r\n";
$out .= "Accept-Language: zh-cn\r\n";
$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n";
$out .= "Cookie: $cookie\r\n\r\n";
}
$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);//用socket方式打开一个文件指针
if(!$fp) return '';

stream_set_blocking($fp, $block);//设置阻塞模式
stream_set_timeout($fp, $timeout);//设置连接时间
@fwrite($fp, $out);//把数据写入文件指针中,即发送请求头信息
$status = stream_get_meta_data($fp);//从封装协议文件指针中取得报头/元数据,即返回写入的相关状态

if($status['timed_out']) return ''; //等待数据流超时
while (!feof($fp)) {//循环读取响应头信息,直到文件指针到达文件结束的位置
if(($header = @fgets($fp)) && ($header == "\r\n" || $header == "\n")) break;//从文件指针中读取一行
}

$stop = false;
while(!feof($fp) && !$stop) {//控制是否读取完成
$data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
$return .= $data;
if($limit) {
$limit -= strlen($data);
$stop = $limit <= 0;
}
}
@fclose($fp);//关闭一个已打开的文件指针

//部分虚拟主机返回数值有误,暂不确定原因,过滤返回数据格式
$return_arr = explode("\n", $return);
if(isset($return_arr[1])) {
$return = trim($return_arr[1]);
}
unset($return_arr);

return $return;
}
七、php-socket相关
1、创建流:fopen()、fsockopen()、pfsockopen()
2、stream_set_blocking($resource,$flag)
$flag:0非阻塞,1阻塞
某个函数读取一个网络流,当没有未读取字节时:
阻塞:一直等待,直到下一个未读取的字节出现。
非阻塞:立即告诉调用者当前没有新内容。
阻塞的好处是,排除其它非正常因素,阻塞的是按顺序执行的同步的读取。
3、stream_set_timeout($resource,$responseTimeout)//设置返回的超时时间
4、stream_get_meta_data($resource)
//从封装协议文件指针中取得报头/元数据
(1)timed_out (bool) - 如果在上次调用 fread() 或者 fgets() 中等待数据时流超时了则为 TRUE。
(2)blocked (bool) - 如果流处于阻塞 IO 模式时为 TRUE。参见 stream_set_blocking()。
(3)eof (bool) - 如果流到达文件末尾时为 TRUE。注意对于 socket 流甚至当 unread_bytes 为非零值时也可以为 TRUE。要测定是否有更多数据可读,用 feof()替代读取本项目的值。
(4)unread_bytes (int) - 当前在 PHP 自己的内部缓冲区中的字节数。
5、stream_get_contents($resource)//取得返回的数据流内容
6、相关函数:fwrite()、fgets()、feof()、fread()、fclose()
读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符数组中,函数调用的形式为: fgets(字符数组名,n,文件指针);其中的n是一个正整数。表示从文件中读出的字符串不超过 n-1个字符。在读入的最后一个字符后加上串结束标志'\0'。例如:fgets(str,n,fp);的意义是从fp所指的文件中读出n-1个字符送入字符数组str中。
fread是用于整块数据的读写函数,可用来读写一组数据,如一个数组元素,一个结构变量的值等。读数据块函数调用的一般形式为: fread(buffer,size,count,fp),其中buffer是一个指针,在fread函数中,它表示存放输入数据的首地址。 size 表示数据块的字节数。count 表示要读写的数据块块数。fp 表示文件指针。
eg:fread(fa,4,5,fp); 其意义是从fp所指的文件中,每次读4个字节(一个实数)送入实数组fa中,连续读5次,即读5个实数到fa中。
7、$_POST、HTTP_RAW_POST_DATA、php://input
(1)HTTP_RAW_POST_DATA仅在碰到未识别MIME类型的数据时产生。对于enctype="multipart/form-data"表单数据不可用。
(2)访问原始POST数据的更好方法是php://input
(3)php://input 允许读取 POST 的原始数据。和 $HTTP_RAW_POST_DATA 比起来,它给内存带来的压力较小,并且不需要任何特殊的 php.ini 设置。php://input 不能用于 enctype="multipart/form-data"。

基本上$GLOBALS['HTTP_RAW_POST_DATA'] 和 $_POST是一样的。但是如果post过来的数据不是PHP能够识别的,你可以用 $GLOBALS['HTTP_RAW_POST_DATA']来接收,比如text/xml或者soap等等。

PHP默认识别的数据类型是application/x-www.form-urlencoded标准的数据类型
因此,对型如text/xml的内容无法解析为$_POST数组,故保留原型,交给$GLOBALS['HTTP_RAW_POST_DATA'] 来接收。
eg.
(1)phpcmsv9中phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php
if(isset($GLOBALS['HTTP_RAW_POST_DATA'])){
$this->data['avatardata'] = $GLOBALS['HTTP_RAW_POST_DATA'];
...
}
(2)phpsso_server/phpcms/modules/phpsso/index.php
file_put_contents($filename,$this->data['avatardata']);//把数据写入文件
eg.
<form action="test.php" method="post">
<input type="text" name="user">
<input type="password" name="password">
<input type="submit">
</form>
test.php
<? echo file_get_contents("php://input"); ?>
八、http协议
1、特点
简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。
灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
2、php-socket中http的请求和响应
========== 请求头信息 ==========
Host:localhost
User-Agent:Mozilla/5.0 (Windows NT 5.1; rv:2.0) Gecko/20100101 Firefox/4.0
Accept:application/json, text/javascript, */*
Accept-Language:zh-cn,zh;q=0.5
Accept-Encoding:gzip, deflate
Accept-Charset:GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive:115
Proxy-Connection:keep-alive
Content-Type:application/x-www-form-urlencoded
X-Requested-With:XMLHttpRequest
Referer:http://localhost/
Cookie:---cookie相关---
---请求发送数据---
========== 响应头信息 ==========
Proxy-Connection:Keep-Alive
Connection:Keep-Alive
Content-Length:112
Via 1.1 WALKISA
Date:Tue, 17 May 2011 03:26:18 GMT
Content-Type:text/html; charset=gbk
Server:nginx/0.7.67
X-Powered-By:PHP/5.2.13
------------------------------ edit in 2011-05-18 ------------------------------
阅读更多
个人分类: phpcms
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭