- 浏览: 416638 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
lanlansnss:
说真的。 木有看懂哇。
【辞职】你谂清楚未? -
fei441544558:
isset($_SESSION['submit_tim ...
PHP防止用户刷新页面,重复提交表单内容 -
ngn9999:
天下文章一大抄
flash遮盖div层在IE和FF下解决办法 -
阳光空气水:
嗯,原来是道友。
FireBug - Javascript 的調試工具 [轉載] -
osacar:
楼主的头像里人物是不是史艳文里的?
PHP程序如何防止站外提交数据
这里所说的“大型”应用不是说像Google、eBay、Yahoo这类大型网站的具体实施,我也没有意图劝说读者放弃自己的概念和信仰,只是希望大家的系统可以运行得更快更流畅,可以承载更多的用户在线,希望可以给PHP的初学者一点帮助。
关于PHP的执行效率,网上的专题文章很多,多以PHP、Java几个阵营的争论开始,以一个不确定的期待结束,很少看见一个明确的结论。确实,程序的执行效率是很难从比较中得出的。应用的方面不同,执行环境不同,效率的差别会差得比较大。而且效率也是需要权衡的,大家都知道汇编语言很底层,可以写出非常高效的程序,但是我还很少,应该说是几乎没看过有人用汇编做Web开发,而且有能力用汇编写出高效程序的人似乎都是值得大家仰视的,哈哈~我们没有必要去讨论PHP和汇编到底差多少,只要知道自己的PHP和别人的PHP差多少就可以了。
首先,先要明确这篇文章的前提:必须有一台或更多的可以被自己操纵的服务器,而不是虚拟主机空间。毕竟可以在虚拟主机上运行的通用系统已经有了很多经典的作品和成熟的框架,效率挖掘已经被前辈们做得非常出色了,它们的很多理念也被现在很多PHP用户继承和发展,越来越多的所谓“框架”也像满天繁星一样,我也不想再去写那个,因为第一我自己的水平也不怎么样,写不出什么新鲜玩意来,写出来也招人笑,第二是写这个的文章太多了,说法也太多了,混乱是造成很多富有激情的未来天才程序员夭折的最大元凶。
在独立服务器上执行的程序和在虚拟主机上可以运行的程序在效率优化方面有着很大差别。您当然可以把一套discuz不加修改地安装在一台甚至一堆独立服务器上,不过,它真的得到最大的性能优化吗,您真的对得起这一堆服务器吗?
独立服务器指的是,使用者对这台机器有完全的控制权,包括安装、删除软件,配置系统参数甚至修改源代码。基于这样一个开放的硬件平台,性能也不仅仅是体现在速度上,还包括安全性、稳定性等。和虚拟主机不同,用户必须自己配置Web服务器参数,安装和配置PHP、数据库,以及安装各种乱七八糟的东西(我喜欢这么说),当然还要对它们负责。
首先提出几个名词:执行时间、模板、数据库封装、Cache、Buffer、Hash、守护进程、crontab。
执行时间,谁都知道,就是一个程序从执行开始到执行结束所用的时间。因为Web是瞬时的、无状态的,所以执行时间是Web程序执行效率的一个指标,它并不适合衡量C/S程序或者后台守护的程序,因为它们很多都是持续运行的。页面执行时间的一个典型例子就是Discuz论坛页面最下方的时间显式,通常Discuz都是几毫秒到几十毫秒,和所用的平台、数据量和当前系统压力有关。
模板大家再熟悉不过,虽然有很多人只是在用,但是不知道为什么在用。模板在传统上来说是划分逻辑层的一种途径,在MVC上结构里,它把表示层和下层分离,在实际使用中,它方便程序员和界面设计人员分工合作。然而,现在很多场合中,由于模板的不当使用,它非但没有起到促进程序员和界面设计人员分工合作,反倒成为程序员和美工互相仇视的罪魁(我好像在以前的帖子里这样说过),很多人在抱怨他们不得不花很多时间在整理模板上。
数据库封装似乎和Java的关系更大,它对多种数据库系统提供一个统一调用接口,通常是一些封装好的类,这些类有时也完成一些比如SQL检查、过滤等工作。PHPLIB里的DB封装、PEAR DB、Adodb等都很有名,用的人也很多。
Cache和Buffer看起来好像是一种东西,Cache叫做缓存而Buffer叫做缓冲。在硬件概念中,Cache的用途是连接两种速度不同的设备,比如寄存器和内存、CPU和PCI-Bus、IDE总线和硬盘。Buffer的原意是类似弹簧的一种缓冲器,用来减轻或吸收冲击的震动的东西。Buffer是一种数据预存取的方式,它用于临时存储数据并以与接收速度不同的速度传输。Buffer的更新方式可以是按时间间隔自动刷新,而Cache则更讲究“命中率”,将当前时间段使用频繁的少量数据放到高速设备中方便读写。在程序开发中,固然没有什么高速、低速设备,不过数据源是可以有不同读写效率的。对于少量数据,文本文件的读写通常就要比数据库存取效率好,而同样是文本文件读写,在tmpfs上的效率就要比直接的磁盘IO效率好。Buffer更多地体现在进程通信和队列上,很多时候并不是因为接收方没有能力更快地读取,而是没有必要更快地读取。
守护进程是一种在后台连续执行的程序,它通常是起到监视、控制流程、对外提供服务等作用。比如Apache本身就可以被理解成一个守护进程,虽然它实际上是由很多个经常更新的进程组成(主进程是固定的)。
Crontab是UNIX/Linux的定时程序,有点像Windows的“计划任务”,它设定在多少个时间间隔后或者是某一个时间点执行特定的程序。它通常用来完成自动更新、清除临时数据等一段时间自动执行一次的操作。
另外一个比较特别的概念(说它特别是相对于习惯了通用系统开发的人来说),是当我们拥有了一台独立的服务器之后,完全没必要把自己局限在PHP所能提供的功能范围内,当我们不知不觉地成为系统的主人后,要努力发现到这一点,我们有很多东西可以用的。PHP不是万能的(这简直是一定的),对于它的功能上的不足,完全可以用Perl来弥补,Perl做为一种通用语言,可以提供更多的功能选择,砂砾一样密的模块给这个随意得有些变态的语言提供了无穷的能量。对于PHP性能上的不足,完全可以用C来补充。PHP的根本就是由C继承来,PHP本身也是由C开发,用C来做PHP的扩展是完全合理的。
Linux本身就是由C和Perl在支撑(我这样说完全不是为了夸大Perl的地位,大家可以去看看一个标准的Linux中有多少Perl脚本,离开Perl之后这个系统是不是觉得像个残疾人)。PHP从C中继承了大部分的语法,从Perl中学习了大部分Web特性、函数和那个貌似与开源很矛盾的“$”符号(PHP早期就是一个Perl脚本)。
我发现我很能写废话,哈哈……
下面来分析我在使用的一些代码(注:Linux独立服务器适用。我好像已经放弃对Windows和虚拟主机做大型开发很长时间了)。里面使用了一些也许很熟悉也许很陌生也许很变态的方法。我的系统是RedHat AS3,没有什么特别的,PHP版本是4.4.0,MySQL是4.1。我从来没有刻意地去写一些必须用到PHP5的新特性的代码,除非真的必须用到。
我的Web根目录在/www下,Apache、PHP都是默认安装在/usr/local/下,MySQL是下载的编译好的二进制版本,我也一样把它丢在那里。因为只是用于测试,我不想它看起来很乱,至于在实际项目中,尤其是多台服务器的情况下,需要好好地部署一下你的系统。
为了使系统的结构清晰一些,我把需要使用的文件都放在了二级目录下面。
下面是通用头文件/includes/kernel/common.inc.php的一些片断:
if (!
defined
(
'IN_BSG'
)) {
exit;
}
?>
list(
$usec
,
$sec
) =
explode
(
" "
,
microtime
());
$page_time_start
=
$usec
+
$sec
;
?>
error_reporting
(
E_ERROR
|
E_WARNING
|
E_PARSE
);
// This will NOT report uninitialized variables
//error_reporting(E_ALL);
set_magic_quotes_runtime
(
0
);
// Be paranoid with passed vars
if (@
ini_get
(
'register_globals'
)) {
foreach (
$_REQUEST
as
$var_name
=>
$void
) {
unset(${
$var_name
});
}
}
?>
if (!
get_magic_quotes_gpc
()) {
if (
is_array
(
$_GET
)) {
while (list(
$k
,
$v
) =
each
(
$_GET
)) {
if (
is_array
(
$_GET
[
$k
])) {
while (list(
$k2
,
$v2
) =
each
(
$_GET
[
$k
])) {
$_GET
[
$k
][
$k2
] =
addslashes
(
$v2
);
}
@
reset
(
$_GET
[
$k
]);
}
else {
$_GET
[
$k
] =
addslashes
(
$v
);
}
}
@
reset
(
$_GET
);
}
if (
is_array
(
$_POST
)) {
while (list(
$k
,
$v
) =
each
(
$_POST
)) {
if (
is_array
(
$_POST
[
$k
])) {
while (list(
$k2
,
$v2
) =
each
(
$_POST
[
$k
])) {
$_POST
[
$k
][
$k2
] =
addslashes
(
$v2
);
}
@
reset
(
$_POST
[
$k
]);
}
else {
$_POST
[
$k
] =
addslashes
(
$v
);
}
}
@
reset
(
$_POST
);
}
if (
is_array
(
$_COOKIE
)) {
while (list(
$k
,
$v
) =
each
(
$_COOKIE
)) {
if (
is_array
(
$_COOKIE
[
$k
])) {
while (list(
$k2
,
$v2
) =
each
(
$_COOKIE
[
$k
])) {
$_COOKIE
[
$k
][
$k2
] =
addslashes
(
$v2
);
}
@
reset
(
$_COOKIE
[
$k
]);
}
else {
$_COOKIE
[
$k
] =
addslashes
(
$v
);
}
}
@
reset
(
$_COOKIE
);
}
}
define
(
'STRIP'
, (
get_magic_quotes_gpc
()) ?
true
:
false
);
?>
下面的部分是对系统的初始化。之前的部分,可能和普通的程序没什么两样,但是下面这一段,我保证你没见过。
// Init System
require(
'../../includes/kernel/config.inc.php'
);
// First Startup? Init the tmpfs
if (!
is_dir
(
$data_root
) || !
is_dir
(
$includes_root
)) {
if (!
is_writable
(
$tmpfs_root
))
die (
'TMPFS FAILED!!!'
);
require_once(
'../../includes/kernel/pkg.inc.'
.
$phpEx
);
@
mkdir
(
$data_root
);
@
mkdir
(
$includes_root
);
$pkg
= new
BsmPkg
();
$pkg
->
target_dir
=
$data_root
;
$pkg
->
filename
=
$tmpfs_pkg_data_filename
;
$pkg
->
unpack_into_dir
();
$pkg
->
target_dir
=
$includes_root
;
$pkg
->
filename
=
$tmpfs_pkg_includes_filename
;
$pkg
->
unpack_into_dir
();
}
?>
tmpfs是Linux里的一种特殊分区格式。区别于ext3等,tmpfs创建于内存和交换区上。Linux有一个默认的shm就是tmpfs类型,通常mount在/dev/shm上。tmpfs和ramfs有些相似,不同的是它会用到交换区。
tmpfs的最大好处是IO速度。毕竟纯粹的物理磁盘操作效率无法和内存相比,而且tmpfs使用起来也很方便,它基本不需要做什么其它设置就可以像普通的物理硬盘一样使用,它对程序来说是透明的。
tmpfs的使用方法与Linux挂载其它类型的分区格式一样,可以用mount命令来挂载,也可以在fstab中设置。
* * * * * *
当系统检测到$tmpfs_root确实存在且可写,而$data_root和$include_root不存在,表示这是系统第一次在运行,它会用内置的一个压缩/解压文件的一个类来把事先准备好的data和includes压缩文件解压到$tmpfs_root中,这个类处理的格式是我自创的,它保持了源目录结构,并保存了文件的属性。它也会对每一个文件做文件长度和MD5校验。这个类位于/includes/kernel/pkg.inc.php
这里提及一个细节,我学习了PHPBB中的$phpEx的概念,整个系统中除了调用common.inc.php和config.inc.php外,其它调用php文件的地方都没有写“.php”扩展名,而是用了一个$phpEx变量代替,这个变量的值在config文件中可以修改,这样做的好处是我们随时可以把系统中的php程序改换扩展名。比如我们修改了Apache配置,让php解释器来解释一种叫做.hello的文件,就可以方便地把整个系统的所有被include的php程序扩展名改成.hello,再把config中的$phpEx的值改成“hello”,这样你的系统看起来就像是使用一种没人见过的Hello语言编写的了,哈哈……
includes这个压缩文件中包含了/includes目录中的所有内容,它被解压到$tmpfs_root(我的系统中是/opt/tmp/)中,这样,在/opt/tmp/includes中就有我们想要的所有include文件了,调用它比直接调用/includes要快很多。
下面的部分就是调用已经解压好的一些include文件
// Include Kernel file
require(
$includes_root
.
'db/'
.
$global_db_dbms
.
'.'
.
$phpEx
);
require(
$includes_root
.
'kernel/constants.inc.'
.
$phpEx
);
require(
$includes_root
.
'kernel/template.inc.'
.
$phpEx
);
require(
$includes_root
.
'kernel/session.inc.'
.
$phpEx
);
require(
$includes_root
.
'kernel/cache.inc.'
.
$phpEx
);
require(
$includes_root
.
'kernel/log.inc.'
.
$phpEx
);
require(
$includes_root
.
'kernel/shm.inc.'
.
$phpEx
);
require(
$includes_root
.
'function/basic.function.'
.
$phpEx
);
require(
$includes_root
.
'function/file.function.'
.
$phpEx
);
?>
// Init the DB Connection
$db
= new
$sql_db
;
// Connect to DB
$db
->
sql_connect
(
$global_db_host
,
$global_db_user
,
$global_db_pass
,
$global_db_name
,
$global_db_port
,
false
);
?>
// We do not need this any longer, unset for safety purposes
unset(
$global_db_pass
);
?>
// Init Log
$log
= new
BsmLog
(
'bsg'
);
?>
// Init the Shared Memory
$shm
= new
BsmShm
;
if (
$shm
->
shm_id
) {
define
(
'SHM_SUPPORT'
,
true
);
}
?>
if (
defined
(
'SHM_SUPPORT'
) && !@
$shm
->
get_var
(
SHM_VAR_SYS_RUN
)) {
$shm
->
put_var
(
SHM_VAR_SYS_RUN
,
true
);
}
?>
发表评论
-
高级PHP应用程序漏洞审核技术
2014-07-16 23:14 1251高级PHP应用程序漏洞审核技术 高级PHP应用程序 ... -
Apache服务器使用.htaccess实现图片防盗链教程
2011-10-24 16:45 1176所谓盗链,是指其他网 ... -
使用PHP 開源類來分析HTML
2011-07-20 17:43 1076Sourceforge上有一个PHP的分析类,可以从这里下载 ... -
启用Xdebug 和使用WinCacheGrind分析PHP腳本执行情況
2011-03-02 11:51 1417一、安装xdebug模块 1、去www.xdebug.org ... -
使用 mb_detect_encoding() 函数来判断字符串是什么编码的。
2011-02-19 21:06 1550原理: 使用 mb_detect_encoding() 函数 ... -
Cache_Lite 使用说明
2011-01-12 11:48 1438Cache_Lite (作者FabienMARTY . 译 ... -
PHP之中使用共享内存进行高速数据更新的一种方案 [转]
2010-12-29 22:14 1472作者:HonestQiao 如果在你 ... -
PHP 函数和过滤器(Filter)[转]
2010-12-28 15:55 1050http://www.w3school.com.cn/ph ... -
高级PHP应用程序漏洞审核技术 [转]
2010-12-26 23:22 1420[目录] 1. 前言 2. 传 ... -
10位顶级PHP大师的开发原则 【轉】
2010-12-22 14:47 8431. 在合适的时候使用PHP – Rasmus Lerdo ... -
windows下php curl 的支持
2010-08-24 09:23 1824上次帮一个朋友安装Zen Cart, 发现需要curl的支持, ... -
PHP自动检测客戶端是否Mobile [轉載]
2010-04-21 11:56 1194<?php $mobile_browser ... -
pear安装及除错 [转]
2010-03-30 22:35 1666安装过程: 方法一: windows xp下安装pear ... -
支持中文的截取字符函数,不同编码下中文字符的范围一目了然
2009-08-18 09:19 1041这是一个简单的函数,或许对你我都有用吧。 以前也有类似的文章, ... -
APC(Alternative PHP Cache)學習文章收集
2009-04-16 11:24 1617I. 概述: Alternative Php Cache(AP ... -
php字符串处理函数讲解
2009-03-16 16:55 1406addcslashes —— 为字符串 ... -
php函数call_user_func和call_user_func_array函數使用
2009-03-10 17:35 3231call_user_func函数类似于一种特别的调用函数的 ... -
在PHP中處理xml文件
2009-03-09 15:40 1305<?php $xml = simplexml_lo ... -
PHP中的ob_start()_输出缓冲函數
2009-02-02 10:39 1497在PHP编程中, 我们经常会遇到一些直接产生输出的函数, 如p ... -
一些在php中使用header函数设置http头的示例方法
2009-01-14 10:30 5204// ok header('HTTP/1.1 200 O ...
相关推荐
16.5.4 Web应用的商业主机服务 16.6 数据库服务器的安全性 16.6.1 用户和权限系统 16.6.2发送数据至服务器 16.6.3 连接服务器 16.6.4 运行服务器 16.7 保护网络 16.7.1 安装防火墙 16.7.2使用隔离区域(DMZ) 16.7.3...
16.5.4 Web应用的商业主机服务 16.6 数据库服务器的安全性 16.6.1 用户和权限系统 16.6.2发送数据至服务器 16.6.3 连接服务器 16.6.4 运行服务器 16.7 保护网络 16.7.1 安装防火墙 16.7.2使用隔离区域(DMZ) 16.7.3...
16.5.4 Web应用的商业主机服务 16.6 数据库服务器的安全性 16.6.1 用户和权限系统 16.6.2发送数据至服务器 16.6.3 连接服务器 16.6.4 运行服务器 16.7 保护网络 16.7.1 安装防火墙 16.7.2使用隔离区域(DMZ) 16.7.3...
PHP Web 开发工具入门首先,让我们从 PHP 的介绍开始。 首先阅读此参考资料,了解 PHP 最佳实践、公认... MySQL 是一种用于网络的数据库系统MySQL是一个运行在服务器上的数据库系统MySQL 是小型和大型应用程序的理想选
关于LaravelLaravel是一个Web应用程序框架,具有表达力强,优雅的语法。 我们认为,发展必须是一种令人愉快的,富有创造力的经历,才能真正实现。 Laravel减轻了许多Web项目中使用的常见任务,从而减轻了开发过程中...
Yii是一个基于组件、用于开发大型 Web 应用的高性能 PHP 框架。Yii提供了今日Web 2.0应用开发所需要的几乎一切功能。Yii是最有效率的PHP框架之一。
介绍 本书将教你使用现代工具流内置一个类似微博的应用。 通过本书,你将会学到如HTML,CSS,JavaScript,PHP,ThinkPHP等Web开发的相关基础知识。...ThinkPHP 5.1教程-Web入门开发实战是一个为了解决大多数新手开发者
介绍Yii 是一个基于组件、纯OOP的、用于开发大型 Web 应用的高性能 PHP 框架。它将 Web 编程中的可重用性发挥到极致,能够显著加速开发进程。Yii适合大流量的应用,如门户、BBS、CMS及B2B系统等,功能
Yii 是一个基于组件、用于开发大型 Web 应用的高性能 PHP 框架。 注:文件格式为.docx 打不开此类文件的用户请不要下载,浪费积分。
这一部分主要讲述如何使用JSP进行大型Web应用的开发,为了方便读者学习,本书还专门讲述了SUN公司的J2SDKEE和B趴公司的Webloglc应用服务器的基本使用方法。 JSP可以在各种操作系统和各种Web服务器下使用,其代码基本...
#Laravel 4 Bootstrap 3 入门网站这是优秀的我创建了这个入门应用程序,因为我需要一个简单的框架来支持内部数据库支持的 Web 应用程序,其中包含用户、角色,当然还有 Laravel - 但没有面向公众的网页。 我还想卷起...
关于LaravelLaravel是一个具有表达力,优雅语法的Web应用程序框架。 我们认为,发展必须是一种令人愉悦的创造力,才能真正实现。 Laravel通过减轻许多Web项目中使用的常见任务来减轻开发工作的痛苦,例如: 。 。 ...
Laravel是一个具有表达力,优雅语法的Web应用程序框架。 我们认为,发展必须是一种令人愉悦的创造力,才能真正实现。 Laravel通过减轻许多Web项目中使用的常见任务来减轻开发工作的痛苦,例如: 。 。 用于和存储...
Laravel PHP框架 Laravel是一个具有表达力,优雅语法的Web应用程序框架。 我们认为,发展必须是一种令人愉快的,富有创造力的经历,才能真正实现。 Laravel试图通过减轻大多数Web项目中使用的常见任务(例如身份验证...
例如,在讲授参照完整性约束时,如果从概念的角度讲授会说明这时一个表中的列值必须总是由另一个表中的列值提供,并解释这一约束出现在关系定义的上下文中的方式,以及DBMS或应用程序如何强制执行这一约束。...
关于LaravelLaravel是一个具有表达力,优雅语法的Web应用程序框架。 我们认为,发展必须是一种令人愉快的,富有创造力的经历,才能真正实现。 Laravel减轻了许多Web项目中使用的常见任务,从而减轻了开发过程中的...
Laravel是一个具有表达力,优雅语法的Web应用程序框架。 我们认为,发展必须是一种令人愉快的,富有创造力的经历,才能真正实现。 Laravel减轻了许多Web项目中使用的常见任务,从而减轻了开发过程中的痛苦,例如: ...
Laravel是一个具有表达力,优雅语法的Web应用程序框架。 我们认为,发展必须是一种令人愉快的,富有创造力的经历,才能真正实现。 Laravel减轻了许多Web项目中使用的常见任务,从而减轻了开发过程中的痛苦,例如: ...
Laravel 是一个具有表现力、优雅语法的 Web 应用程序框架。 我们相信发展必须是一种愉快和创造性的体验,才能真正实现。 Laravel 通过简化许多 Web 项目中使用的常见任务来减轻开发的痛苦,例如: 。 。 用于和...
Laravel是一个具有表达力,优雅语法的Web应用程序框架。 我们认为,发展必须是一种令人愉悦的创造力,才能真正实现。 Laravel通过减轻许多Web项目中使用的常见任务来减轻开发工作的痛苦,例如: 。 。 用于和存储...