我在硬盘装Debian9后,启动分区时出现两个硬盘:minimal bash-like...

如果debian9取消了cd 应该下载哪个版本呢【linux吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:176,601贴子:
如果debian9取消了cd 应该下载哪个版本呢收藏
dvd1就要3.72g
太大了 最小的那个是网络安装版本我发现还有个livecd的版本 有1g不到的
不知道这个不联网能不能安装
安装后 中文支持好不好ubuntu在下载上做的比debian好很多 没有大文件也没有小文件 正合适
断网下就能安装 而且驱动都弄好了
安全牛课堂linux基础培训,内容全面,体系完整,系统掌握安全基础技能,课程讲解深入浅出,
live不联网可以不过不可能把NETINST干掉吧
netinst网络安装然而现在debian仍然保留着debian-stretch-DI-alpha7-amd64-xfce-CD-1.iso
下载Arch或Gentoo的cd
听说过jigdo吗= =,debian.org/CD/jigdo-cd/
CD和DVD版有区别麽-----------------------------------------------------
--来自骗经验的XX贴吧客户端(^_^)
一般 livecd 是最基本的安装,浏览器和播放器都有。中文是没问题的。但是搭配的播放器如果不是vlc,就不能播放私有格式的视频和音频。linux mint 默认搭配 vlc,不用安装的硬盘,试用就可以播放视频了。我用 openSUSE 和 fedora 的 livecd,第一时间更新系统,然后下载 gcc-c++ 和 vlc播放器,默认的播放器统统干掉。然后是 emacs,最后是各种配置。
取消了cd就可以无限放技能了
dvd比较好,适合断网使用,debian并不是arch这种不停更新的发行版。
登录百度帐号推荐应用小站会根据您的关注,为您发现更多,
看到喜欢的小站就马上关注吧!
下一站,你会遇见谁的梦想?
php学习站点
6个常见的 PHP 安全性攻击
了解常见的PHP应用程序安全威胁,可以确保你的PHP应用程序不受攻击。因此,本文将列出 6个常见的 PHP 安全性攻击,欢迎大家来阅读和学习。
1、SQL注入
SQL注入是一种恶意攻击,用户利用在表单字段输入SQL语句的方式来影响正常的SQL执行。还有一种是通过system()或exec()命令注入的,它具有相同的SQL注入机制,但只针对shell命令。
01$username = $_POST['username'];
02$query = "select * from auth where username = '".$username."'";
03echo $query;
04$db = new mysqli('localhost', 'demo', &demo', &demodemo');
05$result = $db-&query($query);
06if ($result && $result-&num_rows) {
07&&&&echo "&br /&Logged in successfully";
08} else {
09&&&&echo "&br /&Login failed";
上面的代码,在第一行没有过滤或转义用户输入的值($_POST['username'])。因此查询可能会失败,甚至会损坏数据库,这要看$username是否包含变换你的SQL语句到别的东西上。
防止SQL注入
使用mysql_real_escape_string()过滤数据
手动检查每一数据是否为正确的数据类型
使用预处理语句并绑定变量
使用准备好的预处理语句
分离数据和SQL逻辑
预处理语句将自动过滤(如:转义)
把它作为一个编码规范,可以帮助团队里的新人避免遇到以上问题
01$query = 'select name, district from city where countrycode=?';
02if ($stmt = $db-&prepare($query) )
04&&&&$countrycode = 'hk';
05&&&&$stmt-&bind_param("s", $countrycode);&&
06&&&&$stmt-&execute();
07&&&&$stmt-&bind_result($name, $district);
08&&&&while ( $stmt ($stmt-&fetch() ){
09&&&&&&& echo $name.', '.$district;
10&&&&&&& echo '&br /&';
12&&&&$stmt-&close();
2、XSS攻击
XSS(跨站点脚本攻击)是一种攻击,由用户输入一些数据到你的网站,其中包括客户端脚本(通常JavaScript)。如果你没有过滤就输出数据到另一个web页面,这个脚本将被执行。
接收用户提交的文本内容
02if (file_exists('comments')) {
03&&&&$comments = get_saved_contents_from_file('comments');
04} else {
05&&&&$comments = '';
08if (isset($_POST['comment'])) {
09&&&&$comments .= '&br /&' . $_POST['comment'];
10&&&&save_contents_to_file('comments', $comments);
输出内容给(另一个)用户
1&form action='xss.php' method='POST'&
2Enter your comments here: &br /&
3&textarea name='comment'&&/textarea& &br /&
4&input type='submit' value='Post comment' /&
5&/form&&hr /&&br /&
7&?php echo $comments; ?&
将会发生什么事?
烦人的弹窗
刷新或重定向
损坏网页或表单
窃取cookie
AJAX(XMLHttpRequest)
防止XSS攻击
为了防止XSS攻击,使用PHP的htmlentities()函数过滤再输出到浏览器。htmlentities()的基本用法很简单,但也有许多高级的控制,请参阅 。
3、会话固定
会话安全,假设一个PHPSESSID很难猜测。然而,PHP可以接受一个会话ID通过一个Cookie或者URL。因此,欺骗一个受害者可以使用一个特定的(或其他的)会话ID 或者钓鱼攻击。
4、会议捕获和劫持
这是与会话固定有着同样的想法,然而,它涉及窃取会话ID。如果会话ID存储在Cookie中,攻击者可以通过XSS和JavaScript窃取。如果会话ID包含在URL上,也可以通过嗅探或者从代理服务器那获得。
防止会话捕获和劫持
如果使用会话,请确保用户使用SSL
5、跨站点请求伪造(CSRF)
CSRF攻击,是指一个页面发出的请求,看起来就像是网站的信任用户,但不是故意的。它有许多的变体,比如下面的例子:
1&img src='/single_click_to_buy.php?user_id=123&item=12345'&
防止跨站点请求伪造
一般来说,确保用户来自你的表单,并且匹配每一个你发送出去的表单。有两点一定要记住:
对用户会话采用适当的安全措施,例如:给每一个会话更新id和用户使用SSL。
生成另一个一次性的令牌并将其嵌入表单,保存在会话中(一个会话变量),在提交时检查它。
6、代码注入
代码注入是利用计算机漏洞通过处理无效数据造成的。问题出在,当你不小心执行任意代码,通常通过文件包含。写得很糟糕的代码可以允许一个远程文件包含并执行。如许多PHP函数,如require可以包含URL或文件名,例如:
01&form&Choose theme:
02&&&&&select name = theme&
03&&&&&&& &option value = blue&Blue&/option&
04&&&&&&& &option value = green&Green&/option&
05&&&&&&& &option value = red&Red&/option&
06&&&&&/select&
07&&&&&input type = submit&
10&&&&if($theme) {
11&&&&&&& require($theme.'.txt');
在上面的例子中,通过传递用户输入的一个文件名或文件名的一部分,来包含以"http://"开头的文件。
防止代码注入
过滤用户输入
在php.ini中设置禁用allow_url_fopen和allow_url_include。这将禁用require/include/fopen的远程文件。
其他的一般原则
1. 不要依赖服务器配置来保护你的应用,特别是当你的web服务器/ PHP是由你的ISP管理,或者当你的网站可能迁移/部署到别处,未来再从别处迁移/部署在到其他地方。请在网站代码中嵌入带有安全意识的检查/逻辑(HTML、JavaScript、PHP,等等)。   2. 设计服务器端的安全脚本: &例如,使用单行执行 - 单点身份验证和数据清理   &例如,在所有的安全敏感页面嵌入一个PHP函数/文件,用来处理所有登录/安全性逻辑检查 3. 确保你的代码更新,并打上最新补丁。 &
漫谈社区PHP业务开发 提高效率缩短开发周期
在当前这个互联网业务飞速发展时期,新的产品如雨后春笋般涌出,老产品线新业务也在不断突破和尝试。这就对快速开发迭代提出了更高的要求。
一、基础运行环境针对新产品的开发,必须能够快速搭建一套LAMP架构。那么无外乎选择一个webserver,选择一个php版本,选择一个mysql版本,再选择一个PHP开发框架和选择一些php通用扩展和基础库等。这个过程读者可能觉得已经很快了,能不能更快?选 择的过程要求研发同学对相关技术方向有一定的积累,权衡利弊和优先点,又是一番调研和学习。如果有一键安装程序,提供自动化安装 webserver,php,mysql,以及携带高性能灵活的php开发框架,并提供标准化、安全、常用的配置文件,可以大大缩短产品线LAMP系统调 研的成本,缩短工作周期。
一键安装四步骤:(1)下载;(2)少量配置;(3)(4)(当然有end啦,简单的运维工具),运行环境OK。
二、业务开发框架社 区产品线各自为政,封闭得开发各自的业务逻辑。而事实上,各个产品线之间存在很多通用业务逻辑处理,如session验证、权限判断、参数验证、日志打印 等。不同产品线,所有请求都需要做这些处理,能不能不重复开发?无线业务开发和PC上的业务逻辑有很多的不同,但不同产品线之间也有很多通用性。能不能不 重复开发?产品线在内部通常对这些通用逻辑的处理做了一定的抽象,设计为ActionChain的形式或者通过基类的方案。框架将更彻底:将这些所有请求都要处理的通用逻辑以业务逻辑框架的形式提供,研发同学只需要关注用户请求专有的逻辑处理。一 个用户请求的处理逻辑如下图:蓝色部分是控制器框架处理流程,绿色部分和控制器框架相结合,处理所有请求通用的业务逻辑。而真正需要研发同学关注和开发的 该用户请求专有的业务处理,即黄色部分(当然一个不仅仅是一个Action脚本,一个请求的处理会横向做mvc分层,这块后续会有涉及。)
业务逻辑框架继承在一键安装程序中提供,简简单单就可以获得。原 生的PHP业务和模板耦合很深,没有做任何的分层设计,其结果是代码的复用性差。这样的原始的PHP系统现在已几乎消亡。PHP开发框架统一处理路由、渲 染、AutoLoad,通用业务逻辑的抽象和基础库的抽象,专有业务MVC分层,已大大加快了产品线业务逻辑的开发。如下图所示:
从上而下,分别是接入层(高性能webserver),PHP开发框架(路由、自动加载、视图引擎等),应用和基础库,存储引擎。
三、通用服务社区产品线存在很多共同的需求,如日志处理、配置文件的处理、字符串处理、数据库交互、网络交互等。这些算法和工具封装成phplib给产品线使用已比较成熟。社区类产品线的业务功能存在很多的通用性,诸如评论功能、Tag功能、好友功能、图册、任务系统等,在众多社区产品线都有类似的新功能新需求,各自设计开发?这些需求在各产品线的UI上有个性化需求,但是后端实现方案大同小异,具有一定的通用性。功能服务化,提供API接口给不同产品线使用,产品线只需要关注展现逻辑和私有数据的处理逻辑即可,且服务统一运维,降低产品下的系统复杂度。
四、垂直拆分子系统那 么随着我们业务的拓展,单个应用内部的ui和module的数量越来越多,Action和Logic(对应MVC中的M层,内部可以再进一步做分层处理, 此次不详述)的交互,logic和logic之间的交互变得越来越复杂。开发同学需要了解整个应用的逻辑,某个logic的升级,需要排查整个应用下是否 存在其他ui或logic的反向依赖。在快速开发的要求下,开发同学对logic之间的相互耦合关系的梳理不清楚,势必引发越来越多的问题,影响项目质 量,难以开始开发。单 一系统的问题暴露越来越多,就到了系统拆分的时候了。如何拆?按业务逻辑垂直拆分。将功能独立的业务逻辑剥离出来,做成独立的子系统。这个时候还需要考虑 业务的通用性,是否可以服务化?应用已有相同需求的通用服务?此时通用业务逻辑封装成通用服务或使用了通用服务,旁路的业务逻辑独立成子系统,如此一来就 将原先单一庞大的系统做了大量减负。完成此阶段的重构后,系统加入变成如下
单一系统被拆分成多个APP(APP内部仍然有横向的MVC分层),并复用大量的通用服务。如此一来研发团队在人员分工并行开发上都得到了极大提高。
五、跨系统调用框架然而真实的现状,在拆分后的子系统之间并不能完全消除依赖。为了解决多个子系统之间数据依赖的关系,需要一套统一的解决方案:API框架。子系统成为独立的应用(APP),APP之间存在相互的数据依赖,这些依赖以API的形式对外提供。如下图
当 APP1依赖APP2或APP3的数据后,APP2和APP3会将一部分数据接口以API的形式提供,数据做统一的打包,通过标准规范的URL提供产品线 内部其他APP调用。这种形式非常类似于一个产品对外开放API(对第三方开放API,我们称为openAPI,遵守统一的协议,并经过必要的权限验 证),而解决内部子系统之间数据依赖的API接口可以进一步简化。APP 提供的API解决提供接口描述(输入、输出),处理API的URL,Logic的转发实现。API_LIB统一来管理所有的API接口,并提供统一的 API_Server::call接口供调用。完全对上屏蔽内部的转发和实现细节。通常产品线内部为了达到运维的简化和统一,所有的子系统是同机部署 的,API接口的会带来额外的网络消耗,以及增大qps。在此部署前提下,API_Server的实现方式可以通过HTTP调用或优化为直接 PHPRequire方式实现。优势:(1)框架统一,接口收敛,业务解耦;(2)性能提升,易用性高,扩展性高;
六、UI拆分模型此 时独立出来的子系统可以专注做其业务逻辑了,核心的系统也得到减负。但是核心系统的升级更新频率是最高的,业务逻辑也最复杂。到了一定时期,核心系统又变 得臃肿,难以维护。此时可以通过一些设计模式来降低程序的可扩展性和可维护性。但即便是如此,还是有一定的学习成本,在一个App内部,开发同学或多或少 需要关注其他模块的代码,逐渐发展为升级一点就需要排查很多点。这时候又到了进一步减负的时候。如果减负?分为两部:第一步:异步模型页面渲染分为两个阶段:主题页面数据和其他非主题页面数据。根据页面的不同部分由不同的数据源提供数据。按此逻辑将app进一步做垂直拆分。
PHPService是由PHPmodule+一层很薄的UI,返回格式化数据。第二步:同步模型Module做拆分,不同业务逻辑拆分为不同的Module,区分为多个数据源,分别提供不同数据内容,由统一的UI调度不同的数据源后,统一进行渲染页面返回响应。
如此持续减负后,产品线内部的子系统和模块将越来越多,需要维持部署和运维的统一。对团队成员的分工很细,业务理解很专注和深入,合作、并行的效率也会更高,从而使整个开发周期缩短。
七、 小结随 着业务逻辑的不端壮大,每个子系统或模块的业务功能如果过于臃肿就需要不断做减分,以保持在可控的规模内。如此随着产品的发展,产品线内部的子系统和模块 将越来越多,需要维持部署和运维的统一,保持简单。对团队成员的分工更细,业务理解保持专注和深入,合作、并行的效率也会更高,从而使整个开发周期缩短。原文链接:
安装PHP常见问题汇总
、作者信息和本声明。否则将追究法律责任。
Cnfigure: error: XML configuration could not be found 错误
通过安装libxml2-devel解决
php & configure: error: Can&t find OpenSSL&s evp.h&
原因如下:
1. 确认安装了
a. yum list openssl 如果没有安装之 yum install openssl
b. yum list openssl-devel 如果没有安装之 yum install openssl-devel
2. 修改路径为 /usr/sbin 或者 /usr/include/openssl
3. 去掉路径 直接 &with-openssl
解决configure: error: Please reinstall the libcurl distribution &
checking for cURL in default path... not found
configure: error: Please reinstall the libcurl distribution -
easy.h should be in /include/curl/
其实就是curl的dev包没有安装, 解决方案:
# yum -y install curl-devel
configure: error: libjpeg.(a|so) not found.
,configure一般的搜索编译路径为/usr/lib/下,因为php默认就在/usr/lib/下找相关库文件,而x64机器上是在:/usr/lib64.这时你就可以直接把需要的库文件从/usr/lib64中拷贝到/usr/lib/中去就可以了
configure: error: libjpng.(a|so) not found
其实也是和刚才的一样.
cp -frp /usr/lib64/libpng* /usr/lib/
configure: error: Cannot find ldap libraries in /usr/lib.
cp -frp /usr/lib64/libldap* /usr/lib/
ln -s /usr/lib64/libjpeg.so /usr/lib/libjpeg.so
configure: error: No curses/termcap library found
yum -y install ncurses-devel
debian: apt-get install libncurses5-dev
configure: error: xml2-config not found
yum -y install libxml2-devel
debian:apt-get install libxml2-dev
configure: error: Cannot find OpenSSL's&
yum -y install openssl-devel
configure: error: libjpeg.(a|so) not found
yum -y install gd
yum -y install gd-devel
debian:apt-get install libjpeg-dev
configure: error: libpng.(a|so) not found.
apt-get install libpng12-dev
configure: error: cannot
yum -y install flex
configure: error: mod_deflate has been requested but can not be built due to&prerequisite failures
yum -y install zlib-devel openssl-devel
debian:apt-get install zlib1g-dev
configure: error: libXpm.(a|so) not found.
apt-get install libxpm-dev
onfigure: error: freetype.h not found.
apt-get install libfreetype6-dev
configure: error: ...No recognized SSL/TLS toolkit detected
apt-get install libssl-dev&
configure: error: Cannot find ldap.h
yum install openldap
yum install openldap-devel
1) Configure: error: xml2-config not found. Please check your libxml2 installation.
Solutions :
yum install libxml2 libxml2-devel (For Redhat & Fedora)&
# aptitude install libxml2-dev (For ubuntu)
2) Checking for pkg-config& /usr/bin/pkg-config
configure: error: Cannot find OpenSSL&s&
Solutions :
yum install openssl openssl-devel
3) Configure: error: Please reinstall the BZip2 distribution
Solutions :
yum install bzip2 bzip2-devel
4) Configure: error: Please reinstall the libcurl distribution -
easy.h should be in /include/curl/
Solutions :
yum install curl curl-devel (For Redhat & Fedora)&
# install libcurl4-gnutls-dev (For Ubuntu)
5) Configure: error: libjpeg.(also) not found.
Solutions :
yum -y install gd
yum -y install gd-devel
yum install libjpeg libjpeg-devel
6) Configure: error: libpng.(also) not found.
Solutions :
yum install libpng libpng-devel
apt-get install libpng12-dev
7) Configure: error: freetype.h not found.
Solutions :
yum install freetype-devel
Configure: error: Unable to locate gmp.h
Solutions :
yum install gmp-devel
9) Configure: error: Cannot find MySQL header files under /usr.
Note that the MySQL client library is not bundled anymore!
Solutions :
yum install mysql-devel (For Redhat & Fedora)&
# apt-get install libmysql++-dev (For Ubuntu)
10) Configure: error: Please reinstall the ncurses distribution
Solutions :
yum install ncurses ncurses-devel
11) Checking for unixODBC support& configure: error: ODBC header file&
&/usr/include/sqlext.h& not found!
Solutions :
yum install unixODBC-devel
12) Configure: error: Cannot find pspell
Solutions :
yum install pspell-devel
13) configure: error: mcrypt.h not found. Please reinstall libmcrypt.
Solutions :
yum install libmcrypt libmcrypt-devel (For Redhat & Fedora)&
# apt-get install libmcrypt-dev
14) Configure: error: snmp.h not found. Check your SNMP installation.
Solutions :
yum install net-snmp net-snmp-devel
15)开启LDAP服务还需要
yum -y install openldap-devel openldap-servers openldap-clients
16)configure: error: No curses/termcap library found
网上有的说法是:
&with-named-curses-libs=/usr/lib/libncursesw.so.5
其实是不对的,虽然能解决configure的错误,但是make的时候会提示错误,正确的做法应该是
yum -y install ncurses-devel (for redhat)
apt-get install libncurses5-dev(for debian)
17)configure: error: cannot
yum -y install flex
18)configure: error: mod_deflate has been requested but can not be built due to&prerequisite failures
yum -y install zlib-devel openssl-devel
debian:apt-get install zlib1g-dev
19)configure: error: libXpm.(a|so) not found.
apt-get install libxpm-dev
本文出自 && 博客,请务必保留此出处
浅谈PHP代码设计结构
编码多年,各种代码日夜相伴,如何跟代码友好的相处,不光成为职业生涯的一种回应,也是编写者功力的直接显露。
如何看待程序和代码呢?那就让我们从程序定义来谈起,如果从业务最终呈现来看,一个程序可以看成是一个真实业务需求的逻辑代码映射。如果从程序逻辑结构看,程序就是数据结构加算法的结合。&这样看,为满足更多的业务需求,更好的满足这些需求,就需要更多的程序代码,当程序代码堆积达到一定数量后,如何管理好,整理好已有的代码将会成为一个只管重要的问题。这个也是一个编程3~5后,从中级向更高级别探索的一个瓶颈。满足需要可工作的代码是好的,可被多个需求不断复用的代码,就是更好的了。随着软件设计的发展,代码的集合,功能逻辑不断向下沉淀封装的趋势越来越 明确。使用好一个工具很快,掌握好一种设计思想就要不断的尝试和改进了。有专门处理数据的代码,有专门处理呈现的代码,如何在业务流程中管理配置他们?这 些逻辑如何更好的被封装,被复用。&其实对于PHPer来说,这些思想在处理具体业务来说有些麻烦,这也是PHP的最大优势非常的自由方便,自由简单随意的基本语法,方便的连内存资源都不用考虑,很快就可以hello一个,但这也正是PHP一个先天的重大劣势,没有一个系统的成脉络的设计体系。PHP出生时就是一个单一的满足业务的语言,并没有像JAVA一样有很系统设计体系和原则。在JAVA有三个最基础的设计原则:1,不支持全局变量。2,不写万能类。3,代码必须是类封装。JAVA的第一个,第三个原则是在语法上就限制了,第二个原则是评判一个JAVA程序员是否入门的标准。PHP相对来说就没什么这样的语法上的设计原则限制,可接触了一些大公司,真没有体系原则呀,哎。但在我们设计思想里可不能真的没有原则呀!PHP程序其实是怎么方便怎么来,解释器很强大,可以屏蔽包容各种思路的程序代码,只要语法OK,不在乎代码设计。正因早期的PHP太随意了,入门 很容易,不用很好的对代码进行有效的管理和方便的复用。随着PHP的发展,PHP已经告别在PHP3~PHP4时代动态标记语言,但因为向上兼容原 则,PHP还是一个语法宽松的语言,系统化的程序设计原则还没有强制融入到语言核心中来。这样并不代表我们不需要使用成熟的设计思想来完善和编写我们的程序代码。JAVA的程序设计原理和代码积累,是JAVA的精髓,随着时间的积累越发明显。将JAVA的程序设计思想,引入到PHP的编程过程中来。是一个完善PHP代码的很好的方法。1.&代码分级封装2. 文件灵活调用加载,资源随用随创建3. 平整抗老化的目录结构解决这些能为程序编写过程,带来非常多的益处。&
如何解决呢?可以通过对于MVC设计思想进行的拆解封装,来实现清晰,有效,一致性的程序设计思想。一个程序从逻辑结构上可看做是模型(Model),视图(View)和控制Controller)三个逻辑块。在JAVA中Model层实现系统中的业务逻辑,通常可以用JavaBean或EJB来实现。 View层用于与用户的交互,通常用JSP来实现。Controller层是Model与View之间沟通的桥梁,通常是router servlet向应用端的扩展。可 PHP 没有这样清晰的划分,所以需要将设计思想揉入到程序代码中去。&
1、程序代码类封装对于一个应用需求(ex: similar相似商品页),将需求先分为3个文件:similar.controller.similar.model.php.similar.view.php通过名字我们也可以看出各文件中的代码用途,剩下就是要给各个文件中的类进行命名。因为是这对一个应用的不同操作类,所以需要给各个类加不同的类目后缀,例如similar.controller.php
//controller 控制程序类& 完成此类中的方法是程序各页面流程,每一个方法对应一个同步请求页面(以配合页面的调用规则)
class similar{
//相似商品页的展现
functio do_opensearch($_param){
//请求参数过滤
//请求商品数据
//根据呈现规则处理商品数据
//渲染商品数据获取呈现html
//展示呈现html
对应的请求就是/similar/opensearch/similar.model.php
//model 数据操作程序类& 完成对此应用的数据请求封装,返回结果的结构解析处理
class similarMODEL{
similar.view.php
//model 呈现操作程序类& 完成对此应用的数据呈现封装,返回给已经处理好的
class similarVIEW{
&&&&function view_getDetail($_goodDataArr){
&&&&&&&&return $html;
2、类调用我们很清晰的将各个逻辑将不同代码封装在了不同文件和类中了。如何灵活的调用呢?PHP是一个解释语言,没有像JAVA和C一个的编译过程,无法享受编译语言,在预编译过程中的自动连接功能。其实现在PHP解释器也已经意识到这个问题,并在5.3.1以后提出了autoload方法来解决,当解释器遇到一个非声明类或者函数时会自动运行autoload去再加载一次,如果还没有才报错。详情参见 http://php.net/manual/en/language.oop5.autoload.php但这样还是一个被动解决方案。下面提供一个主动动态加载方案。加入资源系统调动类在讲解这个类的使用之前先看一下我们之前加载并使用一个类文件的过程:文件:similar.controller.php
require_once PATH."similar.model.php";
$sModelObj = new similarMODEL;
$goodsData = $sModelObj-&getGoodsInfoByNid($nid);
这是在过程中调用,如果在controller类内调用的话就需要写成这样,
require_once PATH."similar.model.php";
class similar{
public $_modelObj;
function __construct(){
$this-&_modelObj = new similarMODEL;
//相似商品页的展现
functio do_opensearch($_param){
//请求商品数据
$goodsInfoArr = $this-&_modelObj-&getGoodsInfoByNid($nid);
}//end class
如果controller类需要使用另一个MODEL,例如forest,ha3什么的就要声明多个类内元素变量。如果利用PHP 的变量传导特性,建立一个资源调度类,来统一加载和调度需要的类并声明,使用起来就会方便很多。下面我们来详细的分解下这个资源调度类的设计,
public static function getObj($_appName,$_typeStr='class') {
if($_typeStr=='class'){
$className = $_appName;
$className = $_appName.strtoupper($_typeStr);
//资源对象已创建 直接返回使用
if( isset(self::$_modelObjArr[$className]) && is_object(self::$_modelObjArr[$className]) ){
return self::$_modelObjArr[$className;
//加载文件资源类文件
$file = dirname(__FILE__)."{$_appName}/{$_appName}.{$_typeStr}.php";
if( file_exists($file) ){
require_once $file;
if( class_exists($className) ){
return self::_createObj($className);
$errStr =& "no class {$className} in file {$file}"; //类名错误
$errStr = "no class file {$file}"; //类文件错误
self::_showErr($errStr);
//创建资源对象
public static function _createObj($_className){
if( isset(self::$_modelObjArr[$_className]) && is_object(self::$_modelObjArr[$_className]) ){
return self::$_modelObjArr[$_className];
self::$_modelObjArr[$_className] = new $_className();
return self::$_modelObjArr[$_className];
//错误提示
public static function _showErr($_errTypeStr=''){
echo $_errTypeStr;& exit;
//errorlog($_errTypeStr);
}//end class
改用Box资源调度类,加载类程序文件:similar.controller.php
&* 加载指定类型的类程序
&class Box {
&//声明一个进程内资源对象池
&public static $_modelObjArr;
&//获取一个资源对象
&class similar{
function __construct(){
&//相似商品页的展现
&functio do_opensearch($_param){
&//请求商品数据
&$goodsInfoArr = Box::getObj('similar','model')-&getGoodsInfoByNid($nid);
&$html = Box::getObj('similar','view')-&view_getDetail($goodsInfoArr);
&//其他已封装好的数据逻辑
&$hotHtml = $this-&_getHotHtml();
&function do_search($_param){
&$goodsInfoArr = Box::getObj('similar','model')-&getGoodsInfoByNid($nid);
&$html = Box::getObj('similar','view')-&view_getDetail($goodsInfoArr);
&function _getHotHtml(){
&$hotInfoArr = Box::getObj('similar','model')-&getGoodsInfoByNid($nid);
&$html = Box::getObj('similar','view')-&view_getDetail($goodsInfoArr);
&return $hotInfoArr;
&}//end class
这样在一个响应进程内 &similar.model.php&; 文件只会被加载一次,similarMODEL 也只会被创建一次, 随使随调用。不用提前声明,不用考虑重复加载,重复创建。Box解决了类与类间资源的调用和创建。那如何让一个controller类文件中的function 运行呢?我们需要一个请求调度类 Bin。之前我们的请求响应都市通过websearch的io model来完成。吧请求的path映射到实际文件中。 例如:/similar/opensearch/index.php 或者是 /similar/opensearch.php 这样的文件,websearch将host替换成实际文件系统的path。这样外部程序可以各种扫描我们的目录,一旦疏忽就会把一些常用方法暴露出来,ex:/tools/info.php 什么的,有风险隐患。当然加一些过滤条件是可以屏蔽这样的问题,但会增减webserver的逻辑,一旦有改动就会改动webserver的conf。麻烦。索性我们就webserver踏踏实实的做好io和http打包解包,让app server来过滤和灵活配置请求调用。再webserver中将所有的访问都映射(rewitre)到host/dispatch.php,由Bin类来实现调度和分配。实现应用逻辑单一入口调用结构。dispatch.php完成一个平台分配,性能监控,配置加载,应用启动,分类型输入(同步,异步,PC,mobile),等平台级功能。Bin类就需要如下功能: 解析请求,将webserver传递的环境变量传递到响应的实际处理应用来完成分解,提出similar 应用名称,opensearch 方法名称,还有GET,POST请求参数,组装成请求参数数组,
$this-&_paramArr = explode( '/', trim(strtok( urldecode($_SERVER["REQUEST_URI"]),'?'),'/'));
&$this-&_paramArr = array_merge($this-&_paramArr,$_GET);
这样$this-&_paramArr[0]就是appname应用名称这样$this-&_paramArr[1]就是function方法名称平台流程就可以装载appname.class.php 文件并执行 appname-&do_function($this-&_paramArr);方法。这样也支持/similar/opensearch/sort/这样的传参,sort是$this-&_paramArr[2]的一个参数如果$this-&_paramArr[0]等于ajax也就是对于的这是一个js发起的异步请求,要装载的就是appname.ajax.php,并执行appnameAJAX-&ajax_function();将同步和异步请求分文件。减少加载大文件对内存的占用。同时也可以将可访问目录跟应用目录物理上分类,让扫描程序无用。例如:/home/website/host/ 这个目录只放index.php一个文件,和css,js,images一些没有加入cdn的呈现渲染文件。将webserver的docmentroot 或者laction 设置在这个目录/home/website/app/ 这个目录来存放编写的类程序文件,配置,由/host/index.php程序加载app目录下的类程序文件一个应用好办,一堆应用我们怎么办呢?下面我们来说说多应用的目录结构。&
3、目录结构 (抗衰老很重要)PHP的设计理念这是少又少,连个包的概念都没有。只好我们自己用目录来包装包概念。从访问结构,开发结构,部署结构上来分别介绍目录结构的作用.&
3a、访问结构将访问目录host,和应用程序目录app可以看成是一个website,这个site下面的应用可以这样的可以这样建立/website/host/website/app/similaer/website/app/cmp/website/app/srp/website/app/&..假如管理工具也可以再website下同另起一个目录/website/admin/firebox/website/admin/seoAny这样,所有的请求都会到/website/host/index.php由index.php在根据请求规则,加载响应的逻辑程序。跟/webiste/host并行的有一个system目录,/website/system/,将box.class.php,bin.class.php,base.class.php等平台文件存放其中。一个响应的执行流程就是 webserver query -&[ /website/host/index.php include /website/system/box,bin,base (应用架构)] 平台-& [ /website/app/ (应用流程) | /website/admin/]页面&
3b、开发结构在开发和维护过程中,会有一些同样地php库文件,如curl通信,xml解析,log,timer,template(appview),等自己开发的类程序,也有像smarty,big2gb等第三方类库。各个项目都通用,比价,主搜,我的一淘,那就可以统一建立一个PHPLIBS目录与website平级/website/host//website/app//website/system//PHPlibs/etao/ 自己的类库/PHPlibs/other/ 第三方类库每一个website一个svnPHPlibs/独立一个svn 专人维护,多快好省精深专将template文件从website/中分离出来建立一个webtemplate/目录 跟ued同学共享一个svn, 让ued同学按前段template类的规则书写模板文件。按应用分目录存储。如:webtemplate/srpwebtemplate/cmpwebtemplate/opensearchwebtemplate/frame 统一呈现模板,页头尾webtemplate/&..website/app中的程序通过template类方法来调用以上模板文件。同时在开发和维护过程中也会遇到需要shell来执行的php script ,如定时生成公共页头尾,定时取mysql库中的epid数据等。或者临时做一个算法的程序。 那我们就可以在/website/app/的相关应用中加入app.sh.php程序文件,如/website/app/similar/similar.sh.php 这个文件的类程序similarSH是通过/website/script/run.php 来执行的。 script/run.php是一个shell端的控制器响应CLI请求,host/index.php是一个web端的控制器响应CGI请求还可以在script/run.php 外包装一个debug.bat的文件,可已经在dos,或者包装一个debug.sh 程序再shell下直接交互调试。具体参考代码还有一些程序处理文件,如由vm文件转换成的php模板的公共页头尾文件,会有一个跟website平行的webdata文件,/website/&./webdata/pageframe等目录中,在app中直接调用&
3c、部署结构通过上线脚本分别checkout/website//PHPlibs//webtemplate/ svn资源库然后打包rpm,推送上线。单独上线,也是使用上线脚本配置检查出相应文件,推送到前段生产机。&
4、代码规范关于代码格式规范,看之前大家也都积极的讨论了很久了。代码格式规范,我们在IDE中配置一下,自动使用,并通过不断的review和提醒中培养好的书写易读代码的习惯就好了。代码设计规范,是需要根据架构指定,并坚持执行的。下面谈到代码设计都是基于刚刚谈到的,资源调用,请求分配来制定的。&
4a、关于目录//应用程序/website/app/&.//对外访问目录/website/host/index.php/website/host/css/website/host/js/website/host/images//平台系统文件/website/host/images//调试,维护脚本/website/script///模板库 对应/website/app/下的目录/webtemplate/&.//程序类库/PHPlibs///数据文件目录/webdata没什么好说的,大家体会。&
4b、关于文件文件的命名规范主要是指定内部调用,和请求调用website/app/appname/appname.apptype.phpapptype: class,model,view,ajax,api,sh ,&.调用:Box::getObj(appname,apptype)-&function();appname.class.php文件为controller文件,类中的方法做同步请求响应。appname.ajax.php文件也是controller文件,类中的方法做异步请求响应。appname.sh.php文件也是controller文件,类中的方法做CLI响应。appname.api.php文件可以看成是controller文件,类中的方法是对一个公共,或通用逻辑的封装,如获取图片完整路径。&
4c、关于类和方法类命名:除class文件中的直接以appname命名,其他的类文件都是appname+APPTYPE命名,APPTYPE需要大写。好做语法区分。方法命名:在方法声明中加前缀,说明方法的作用,如view类中的方法加html_getSimilarList(), model方法中加入db_getData()从数据库取,file_getData()从文件取,url_getData()从引擎或者远端取&
4d、关于变量和注释类内变量, 参数入口变量 加_前缀, 跟过程中使用的局部变量,加以区分,增加可读性。&
class similar{
&public $_obj;
&function do_getpage($_param){
文件注释 = 类注释
&在文件开头加入,说明这个类的功能:
&* @package:
&* @access: MixrenSystemBox.inc.php
&* Summary: 系统 应用模板控制分配程序; 完成请求分析; 模块加载; 请求处理(执行);
&* @Created: Fri Dec 25 16:41:02 CST 2009
&* @Author: Zhurong
&* @Generator: EditPlus2 & Dreamweaver & Zend & eclipse
&* 初始化请求
&* param参数说明
&private function _parseApp(){
&$this-&_queryStr = urldecode($_SERVER["REQUEST_URI"]);
&$this-&_paramArr = explode( '/', trim(strtok($this-&_queryStr,'?'),'/'));
&//分配请求模块
&$appName = DEFAULT_APP_NAME;
&$this-&_className = $appName;
&$this-&_appFile = APP_PATH . "{$appName}/{$appName}.controller.php";
&$this-&_method = empty($this-&_paramArr[0]) ?& DEFAULT_APP_METHOD : $this-&_paramArr[0];
&$this-&_method = "do_{$this-&_method}";
类结尾注释
&class Bin{
&}//end class
&为主要过程,算法,加入注释,方便维护和阅读。在上线前会通过上线脚本对文件进行 php -w 去注释过程,所以注释写的长不占用程序执行过程中的加载内存。&
5、代码监测专门的代码扫描脚本。扫描/website/app/下的目录,文件,方法,注释量。出报告,多少应用目录; 多少同步响应类;多少异步响应类;多少同步页面;多少异步接口;多少逻辑接口;多少model接口;多少模板;各个文件的代码注释率;等等。基于以上设计思想建立了从文件夹-》分段类文件-》功能模块方法 的树形结构设计程序架构,最大化实现CAP原则 consistency(一致性),availability(可复用),Partition(有效划分)让PHP代码更好的积累。模板(纯html文件,呈现配置),程序数据配置文件是被加载到程序中,而不是现在将程序加载到html中一段段解释执行。
LNMP 一键安装包 0.9 发布
LNMP一键安装包是一个用Linux Shell编写的可以为CentOS/RadHat、Debian/Ubuntu VPS(VDS)或独立主机安装LNMP(Nginx、MySQL、PHP、phpMyAdmin)生产环境的Shell程序。 LNMP一键安装包是一个用Linux Shell编写的可以为CentOS/RadHat、Debian/Ubuntu VPS(VDS)或独立主机安装LNMP(Nginx、MySQL、PHP、phpMyAdmin)生产环境的Shell程序。
  LNMPA是在LNMP的基础上产生的新的扩展,目前LNMP一键安装包的用户可以直接升级到LNMPA(Nginx、MySQL、PHP、 Apache),由Nginx作为前端处理静态页面、js、图片等,Apache作为后端处理PHP,解决高并发时php-cgi的502问题,提高服务 器处理动态内容的能力及稳定性。
  LNMP一键安装包 0.9 & LNMPA已经在(感谢提供测试VPS)、(感谢提供测试VPS)、(感谢提供测试VPS)、、、、、、、、、、等多家美国VPS的CentOS、Debian、Ubuntu的32位和64位系统上测试通过。(Debian5系统源目前有问题,请使用Debian6!)
LNMP安装教程:
LNMPA安装教程:
使用交流论坛:
LNMP相关软件版本:&
Nginx 1.0.15
MySQL 5.1.60
PHP 5.2.17
PHPMyAdmin 3.4.8&
相关更新:&
优化安装过程及错误处理;
MySQL安装增加InnoDB选项(可选);
修复eaccelerator和ionCube的PHP版本判断错误的问题;
修复memcached pid创建失败的问题
修复pdo_mysql安装方法;
PHP增加部分禁用函数;
优化Nginx升级脚本;
去除vsftpd安装脚本;
修正访问不存在的PHP时返回404;
更新Nginx版本;
更新PHP探针;
增加phpwin伪静态;
升级过程增加停止LNMP相关服务;
修正Nginx log_format问题;&
状态管理 LNMP状态管理: /root/lnmp {start|stop|reload|restart|kill|status}
Nginx状态管理:/etc/init.d/nginx {start|stop|reload|restart}
PHP-FPM状态管理:/etc/init.d/php-fpm {start|stop|quit|restart|reload|logrotate}
PureFTPd状态管理: /etc/init.d/pureftpd {start|stop|restart|kill|status}
MySQL状态管理:/etc/init.d/mysql {start|stop|restart|reload|force-reload|status}
Apache状态管理:/etc/init.d/httpd {start|stop|restart|graceful|graceful-stop|configtest|status}
Memcached状态管理:/etc/init.d/memcached {start|stop|restart}
相关图形界面程序 phpinfo : http://前面输入的域名或IP/phpinfo.php
phpMyAdmin : http://前面输入的域名或IP/phpmyadmin/
PHP探针 : http://前面输入的域名或IP/p.php
PureFTP管理界面:http://前面输入的域名或IP/ftp/
Memcached测试页面:http://前面输入的域名或IP/memcached.php
LNMP相关目录 Nginx目录: /usr/local/nginx/
MySQL目录: /usr/local/mysql/
PHP目录: /usr/local/php/
网站目录: /home/wwwroot/
Nginx日志目录:/home/wwwlogs/
Nginx虚拟主机配置文件所在目录:/usr/local/nginx/conf/vhost/
LNMP相关配置文件 Nginx主配置文件:/usr/local/nginx/conf/nginx.conf
MySQL配置文件:/f
PHP配置文件:/usr/local/php/etc/php.ini
php-fpm配置文件:/usr/local/php/etc/php-fpm.conf
PureFtpd配置文件:/usr/local/pureftpd/pure-ftpd.conf
PureFtpd MySQL配置文件:/usr/local/pureftpd/pureftpd-mysql.conf
Nginx配置文件:/usr/local/nginx/conf/nginx.conf
Nginx虚拟主机配置文件:/usr/local/nginx/conf/vhost/域名.conf&技术支持: LNMP官网:&更新记录:&技术交流及反馈论坛:
原文及评论:
PHP工程师面临的成长瓶颈
 作为Web开发中应用最广泛的语言之一,PHP有着大量的粉丝,那么你是一名优秀的程序员吗?在进行自我修炼的同时,你是否想过面对各种各样的问题,我该如何突破自身的瓶颈,以便更好的发展呢?  PHP工程师面临成长瓶颈  先明确这里所指的PHP工程师,是指主要以PHP进行Web系统的开发,没有使用其的语言工作过。工作经验大概在3~4年,普通的Web系统(百万级访问,千成级数据以内或业务逻辑不是特别复杂)开发起基本得心应手,没有什么问题。但他们会这样的物点:  ◆除了PHP不使用其它的语言,可能会点shell 脚本。  ◆对PHP的掌握不精(很多PHP手册都没有看完,库除外)。  ◆知识面比较窄(面对需求,除开使用PHP和mysql ,不知道其它的解决办法)。  ◆PHP代码以过程为主,认为面向对象的实现太绕,看不懂。  这些PHPer在遇到需要高性能,处理高并发,大量数据的项目或业务逻辑比较复杂(系统需要解决多领域业务的问题)时,缺少思路。不能分析问题 的本质,技术判断力比较差,对于问题较快能找出临时的解决办法,但常常在不断临时性的解决办法中,系统和自己一步步走向崩溃。那怎么提高自己呢?怎么可以 挑战难度更高的系统?  更高的挑战在那里?  结合我自己的经验,我列出一些具体挑战,让大家先有个感性的认识。  高性能系统的挑战在那里?  ◆如何选择Web服务器?要不要使用fast-cgi 模式;  ◆要不要使用反向代理服务?选择全内存缓存还是硬盘缓存?  ◆是否需要负载均衡?是基于应用层,还是网络层? 如何保证高可靠性?  ◆你的PHP代码性能如何,使用优化工具后怎么样? 性能瓶颈在那里? 是否需要写成C的扩展?  ◆用户访问有什么特点,是读多还是写多?是否需要读写分离?  ◆数据如何存储?写入速度和读出速度如何? 数据增涨访问速读如何变化?  ◆如何使用缓存? 怎么样考虑失效?数据的一致性怎么保证?  高复杂性系统的挑战在那里?  ◆能否识别业务所对应的领域?是一个还是多个?  ◆能否合理对业务进行抽象,在业务规则变化能以很小的代价实现?  ◆数据的一致性、安全性可否保证?  ◆是否撑握了面向对象的分析和设计的方法  这里所列出的问题,你都能肯定的回答,说明在技术上你基本已经可能成为架构师了。如何你还不能回答,你需要在以下几个方向加强。  怎么样提高,突破瓶颈  如何你还不能回答,你需要在以下几个方向加强:  ◆分析你所使用的技术其原理和背后运行的机制,这样可以提高你的技术判断力,提高你技术方案选择的正确性;  ◆学习大学期间重要的知识, 操作系统原理,数据结构和算法。知道你以前学习都是为了考试,但现在你需要为自己学习,让自己知其所以然;  ◆重新开始学习C语言,虽然你在大学已经学过。这不仅是因为你可能需要写PHP扩展,而且还因为,在做C的应用中,有一个时刻关心性能、内存控制、变量生命周期、数据结构和算法的环境;  ◆学习面向对象的分析与设计,它是解决复杂问题的有效的方法。学习抽象,它是解决复杂问题的唯一之道。
十个超级有用的PHP代码片段
1. 发送短信调用 API。
//&Include&the&TextMagic&PHP&lib &
require('textmagic-sms-api-php/TextMagicAPI.php'); &
//&Set&the&username&and&password&information &
$username&=&'myusername'; &
$password&=&'mypassword'; &
//&Create&a&new&instance&of&TM &
$router&=&new&TextMagicAPI(array( &
&&&&'username'&=&&$username, &
&&&&'password'&=&&$password&
//&Send&a&text&message&to&'999-123-4567' &
$result&=&$router-&send('Wake&up!',&array(),&true); &
//&result:&&Result&is:&Array&(&[messages]&=&&Array&(&[]&=&&&)&[sent_text]&=&&Wake&up!&[parts_count]&=&&1&)&
2. 根据IP查找地址
function&detect_city($ip)&{ &
&&&&&&&&$default&=&'UNKNOWN'; &
&&&&&&&&if&(!is_string($ip)&||&strlen($ip)&&&1&||&$ip&==&'127.0.0.1'&||&$ip&==&'localhost') &
&&&&&&&&&&&&$ip&=&'8.8.8.8'; &
&&&&&&&&$curlopt_useragent&=&'Mozilla/5.0&(W&U;&Windows&NT&5.1;&en-US;&rv:1.9.2)&Gecko/&Firefox/3.6&(.NET&CLR&3.5.30729)'; &
&&&&&&&&$url&=&'/ip_locator.php?ip='&.&urlencode($ip); &
&&&&&&&&$ch&=&curl_init(); &
&&&&&&&&$curl_opt&=&array( &
&&&&&&&&&&&&CURLOPT_FOLLOWLOCATION&&=&&1, &
&&&&&&&&&&&&CURLOPT_HEADER&&&&&&=&&0, &
&&&&&&&&&&&&CURLOPT_RETURNTRANSFER&&=&&1, &
&&&&&&&&&&&&CURLOPT_USERAGENT&&&=&&$curlopt_useragent, &
&&&&&&&&&&&&CURLOPT_URL&&&&&&&=&&$url, &
&&&&&&&&&&&&CURLOPT_TIMEOUT&&&&&&&&&=&&1, &
&&&&&&&&&&&&CURLOPT_REFERER&&&&&&&&&=&&'http://'&.&$_SERVER['HTTP_HOST'], &
&&&&&&&&); &
&&&&&&&&curl_setopt_array($ch,&$curl_opt); &
&&&&&&&&$content&=&curl_exec($ch); &
&&&&&&&&if&(!is_null($curl_info))&{ &
&&&&&&&&&&&&$curl_info&=&curl_getinfo($ch); &
&&&&&&&&} &
&&&&&&&&curl_close($ch); &
&&&&&&&&if&(&preg_match('{&li&City&:&([^&]*)&/li&}i',&$content,&$regs)&)&&{ &
&&&&&&&&&&&&$city&=&$regs[1]; &
&&&&&&&&} &
&&&&&&&&if&(&preg_match('{&li&State/Province&:&([^&]*)&/li&}i',&$content,&$regs)&)&&{ &
&&&&&&&&&&&&$state&=&$regs[1]; &
&&&&&&&&} &
&&&&&&&&if(&$city!=''&&&&$state!=''&){ &
&&&&&&&&&&$location&=&$city&.&',&'&.&$state; &
&&&&&&&&&&return&$location; &
&&&&&&&&}else{ &
&&&&&&&&&&return&$default; &
&&&&&&&&} &
3. 显示网页的源代码
&?php&//&display&source&code &
$lines&=&file('/'); &
foreach&($lines&as&$line_num&=&&$line)&{ &
&&&&//&loop&thru&each&line&and&prepend&line&numbers &
&&&&echo&"Line&#&b&{$line_num}&/b&&:&"&.&htmlspecialchars($line)&.&"&br&\n"; &
4. 检查服务器是否使用HTTPS
if&($_SERVER['HTTPS']&!=&"on")&{ &
&&&&echo&"This&is&not&HTTPS"; &
&&&&echo&"This&is&HTTPS"; &
5. 显示Facebook粉丝数量
function&fb_fan_count($facebook_name){ &
&&&&//&Example:&/digimantra &
&&&&$data&=&json_decode(file_get_contents("/".$facebook_name)); &
&&&&echo&$data-& &
6. 检测图片的主要颜色
$i&=&imagecreatefromjpeg("image.jpg"); &
for&($x=0;$x&imagesx($i);$x++)&{ &
&&&&for&($y=0;$y&imagesy($i);$y++)&{ &
&&&&&&&&$rgb&=&imagecolorat($i,$x,$y); &
&&&&&&&&$r&&&=&($rgb&&&&16)&&&0xFF; &
&&&&&&&&$g&&&=&($rgb&&&&&&&0xFF; &
&&&&&&&&$b&&&=&$rgb&&&0xFF; &
&&&&&&&&$rTotal&+=&$r; &
&&&&&&&&$gTotal&+=&$g; &
&&&&&&&&$bTotal&+=&$b; &
&&&&&&&&$total++; &
$rAverage&=&round($rTotal/$total); &
$gAverage&=&round($gTotal/$total); &
$bAverage&=&round($bTotal/$total);&
7. 获取内存使用信息
echo&"Initial:&".memory_get_usage()."&bytes&\n"; &
/*&prints &
Initial:&361400&bytes &
//&let's&use&up&some&memory &
for&($i&=&0;&$i&&&100000;&$i++)&{ &
&&&&$array&[]=&md5($i); &
//&let's&remove&half&of&the&array &
for&($i&=&0;&$i&&&100000;&$i++)&{ &
&&&&unset($array[$i]); &
echo&"Final:&".memory_get_usage()."&bytes&\n"; &
/*&prints &
Final:&885912&bytes &
echo&"Peak:&".memory_get_peak_usage()."&bytes&\n"; &
/*&prints &
Peak:&&bytes &
8. 使用 gzcompress() 压缩数据
$string&= &
"Lorem&ipsum&dolor&sit&amet,&consectetur &
adipiscing&elit.&Nunc&ut&elit&id&mi&ultricies &
adipiscing.&Nulla&facilisi.&Praesent&pulvinar, &
sapien&vel&feugiat&vestibulum,&nulla&dui&pretium&orci, &
non&ultricies&elit&lacus&quis&ante.&Lorem&ipsum&dolor &
sit&amet,&consectetur&adipiscing&elit.&Aliquam &
pretium&ullamcorper&urna&quis&iaculis.&Etiam&ac&massa &
sed&turpis&tempor&luctus.&Curabitur&sed&nibh&eu&elit &
mollis&congue.&Praesent&ipsum&diam,&consectetur&vitae &
ornare&a,&aliquam&a&nunc.&In&id&magna&pellentesque &
tellus&posuere&adipiscing.&Sed&non&mi&metus,&at&lacinia &
augue.&Sed&magna&nisi,&ornare&in&mollis&in,&mollis &
sed&nunc.&Etiam&at&justo&in&leo&congue&mollis. &
Nullam&in&neque&eget&metus&hendrerit&scelerisque &
eu&non&enim.&Ut&malesuada&lacus&eu&nulla&bibendum &
id&euismod&urna&sodales.&"; &
$compressed&=&gzcompress($string); &
echo&"Original&size:&".&strlen($string)."\n"; &
/*&prints &
Original&size:&800 &
echo&"Compressed&size:&".&strlen($compressed)."\n"; &
/*&prints &
Compressed&size:&418 &
//&getting&it&back &
$original&=&gzuncompress($compressed);&
9. 使用PHP做Whois检查
function&whois_query($domain)&{ &
&&&&//&fix&the&domain&name: &
&&&&$domain&=&strtolower(trim($domain)); &
&&&&$domain&=&preg_replace('/^http:\/\//i',&'',&$domain); &
&&&&$domain&=&preg_replace('/^www\./i',&'',&$domain); &
&&&&$domain&=&explode('/',&$domain); &
&&&&$domain&=&trim($domain[0]); &
&&&&//&split&the&TLD&from&domain&name &
&&&&$_domain&=&explode('.',&$domain); &
&&&&$lst&=&count($_domain)-1; &
&&&&$ext&=&$_domain[$lst]; &
&&&&//&You&find&resources&and&lists &
&&&&//&like&these&on&wikipedia: &
&&&&//&http://de.wikipedia.org/wiki/Whois &
&&&&$servers&=&array( &
&&&&&&&&"biz"&=&&"whois.neulevel.biz", &
&&&&&&&&"com"&=&&"whois.internic.net", &
&&&&&&&&"us"&=&&"whois.nic.us", &
&&&&&&&&"coop"&=&&"whois.nic.coop", &
&&&&&&&&"info"&=&&"", &
&&&&&&&&"name"&=&&"whois.nic.name", &
&&&&&&&&"net"&=&&"whois.internic.net", &
&&&&&&&&"gov"&=&&"whois.nic.gov", &
&&&&&&&&"edu"&=&&"whois.internic.net", &
&&&&&&&&"mil"&=&&"rs.internic.net", &
&&&&&&&&"int"&=&&"whois.iana.org", &
&&&&&&&&"ac"&=&&"whois.nic.ac", &
&&&&&&&&"ae"&=&&"whois.uaenic.ae", &
&&&&&&&&"at"&=&&"whois.ripe.net", &
&&&&&&&&"au"&=&&"whois.aunic.net", &
&&&&&&&&"be"&=&&"whois.dns.be", &
&&&&&&&&"bg"&=&&"whois.ripe.net", &
&&&&&&&&"br"&=&&"whois.registro.br", &
&&&&&&&&"bz"&=&&"whois.belizenic.bz", &
&&&&&&&&"ca"&=&&"whois.cira.ca", &
&&&&&&&&"cc"&=&&"whois.nic.cc", &
&&&&&&&&"ch"&=&&"whois.nic.ch", &
&&&&&&&&"cl"&=&&"whois.nic.cl", &
&&&&&&&&"cn"&=&&"", &
&&&&&&&&"cz"&=&&"whois.nic.cz", &
&&&&&&&&"de"&=&&"whois.nic.de", &
&&&&&&&&"fr"&=&&"whois.nic.fr", &
&&&&&&&&"hu"&=&&"whois.nic.hu", &
&&&&&&&&"ie"&=&&"whois.domainregistry.ie", &
&&&&&&&&"il"&=&&"whois.isoc.org.il", &
&&&&&&&&"in"&=&&"whois.ncst.ernet.in", &
&&&&&&&&"ir"&=&&"whois.nic.ir", &
&&&&&&&&"mc"&=&&"whois.ripe.net", &
&&&&&&&&"to"&=&&"whois.tonic.to", &
&&&&&&&&"tv"&=&&"whois.tv", &
&&&&&&&&"ru"&=&&"whois.ripn.net", &
&&&&&&&&"org"&=&&"whois.pir.org", &
&&&&&&&&"aero"&=&&"rmation.aero", &
&&&&&&&&"nl"&=&&"whois.domain-registry.nl" &
&&&&if&(!isset($servers[$ext])){ &
&&&&&&&&die('Error:&No&matching&nic&server&found!'); &
&&&&$nic_server&=&$servers[$ext]; &
&&&&$output&=&''; &
&&&&//&connect&to&whois&server: &
&&&&if&($conn&=&fsockopen&($nic_server,&43))&{ &
&&&&&&&&fputs($conn,&$domain."\r\n"); &
&&&&&&&&while(!feof($conn))&{ &
&&&&&&&&&&&&$output&.=&fgets($conn,128); &
&&&&&&&&} &
&&&&&&&&fclose($conn); &
&&&&else&{&die('Error:&Could&not&connect&to&'&.&$nic_server&.&'!');&} &
&&&&return&$ &
10. 通过Email发送PHP错误
//&Our&custom&error&handler &
function&nettuts_error_handler($number,&$message,&$file,&$line,&$vars){ &
&&&&$email&=&" &
&&&&&&&&&p&An&error&($number)&occurred&on&line &
&&&&&&&&&strong&$line&/strong&&and&in&the&&strong&file:&$file.&/strong& &
&&&&&&&&&p&&$message&&/p&"; &
&&&&$email&.=&"&pre&"&.&print_r($vars,&1)&.&"&/pre&"; &
&&&&$headers&=&'Content-type:&text/&charset=iso-8859-1'&.&"\r\n"; &
&&&&//&Email&the&error&to&someone... &
&&&&error_log($email,&1,&'',&$headers); &
&&&&//&Make&sure&that&you&decide&how&to&respond&to&errors&(on&the&user's&side) &
&&&&//&Either&echo&an&error&message,&or&kill&the&entire&project.&Up&to&you... &
&&&&//&The&code&below&ensures&that&we&only&"die"&if&the&error&was&more&than &
&&&&//&just&a&NOTICE. &
&&&&if&(&($number&!==&E_NOTICE)&&&&($number&&&2048)&)&{ &
&&&&&&&&die("There&was&an&error.&Please&try&again&later."); &
//&We&should&use&our&custom&function&to&handle&errors. &
set_error_handler('nettuts_error_handler'); &
//&Trigger&an&error...&(var&doesn't&exist) &
echo&$somevarthatdoesnotexist;&
原文:http://www.oschina.net/question/28_36708
提高PHP代码质量36计
1.不要使用相对路径常常会看到:&
require_once('../../lib/some_class.php');&
该方法有很多缺点:它首先查找指定的php包含路径, 然后查找当前目录.因此会检查过多路径.如果该脚本被另一目录的脚本包含, 它的基本目录变成了另一脚本所在的目录.另一问题, 当定时任务运行该脚本, 它的上级目录可能就不是工作目录了.因此最佳选择是使用绝对路径:
define('ROOT'&,&'/var/www/project/'); &
require_once(ROOT&.&'../../lib/some_class.php'); &
//rest&of&the&code&
我们定义了一个绝对路径, 值被写死了. 我们还可以改进它. 路径 /var/www/project 也可能会改变, 那么我们每次都要改变它吗? 不是的, 我们可以使用__FILE__常量, 如:&
//suppose&your&script&is&/var/www/project/index.php &
//Then&__FILE__&will&always&have&that&full&path. &
define('ROOT'&,&pathinfo(__FILE__,&PATHINFO_DIRNAME)); &
require_once(ROOT&.&'../../lib/some_class.php'); &
//rest&of&the&code&
现在, 无论你移到哪个目录, 如移到一个外网的服务器上, 代码无须更改便可正确运行.
2. 不要直接使用 require, include, include_once, required_once可以在脚本头部引入多个文件, 像类库, 工具文件和助手函数等, 如:&
require_once('lib/Database.php'); &
require_once('lib/Mail.php'); &
require_once('helpers/utitlity_functions.php');&
这种用法相当原始. 应该更灵活点. 应编写个助手函数包含文件. 例如:
function&load_class($class_name) &
&&&&//path&to&the&class&file &
&&&&$path&=&ROOT&.&'/lib/'&.&$class_name&.&'.php'); &
&&&&require_once(&$path&); &
load_class('Database'); &
load_class('Mail');&
有什么不一样吗? 该代码更具可读性.將来你可以按需扩展该函数, 如:
function&load_class($class_name) &
&&&&//path&to&the&class&file &
&&&&$path&=&ROOT&.&'/lib/'&.&$class_name&.&'.php'); &
&&&&if(file_exists($path)) &
&&&&&&&&require_once(&$path&); &
还可做得更多:为同样文件查找多个目录能很容易的改变放置类文件的目录, 无须在代码各处一一修改可使用类似的函数加载文件, 如html内容.
3. 为应用保留调试代码在开发环境中, 我们打印数据库查询语句, 转存有问题的变量值, 而一旦问题解决, 我们注释或删除它们. 然而更好的做法是保留调试代码.在开发环境中, 你可以:
define('ENVIRONMENT'&,&'development'); &
if(!&$db-&query(&$query&) &
&&&&if(ENVIRONMENT&==&'development') &
&&&&&&&&echo&"$query&failed"; &
&&&&&&&&echo&"Database&error.&Please&contact&administrator"; &
在服务器中, 你可以:
define('ENVIRONMENT'&,&'production'); &
if(!&$db-&query(&$query&) &
&&&&if(ENVIRONMENT&==&'development') &
&&&&&&&&echo&"$query&failed"; &
&&&&&&&&echo&"Database&error.&Please&contact&administrator"; &
4. 使用可跨平台的函数执行命令system, exec, passthru, shell_exec 这4个函数可用于执行系统命令. 每个的行为都有细微差别. 问题在于, 当在共享主机中, 某些函数可能被选择性的禁用. 大多数新手趋于每次首先检查哪个函数可用, 然而再使用它.更好的方案是封成函数一个可跨平台的函数.&
&&&&Method&to&execute&a&command&in&the&terminal &
&&&&Uses&: &
&&&&1.&system &
&&&&2.&passthru &
&&&&3.&exec &
&&&&4.&shell_exec &
function&terminal($command) &
&&&&//system &
&&&&if(function_exists('system')) &
&&&&&&&&ob_start(); &
&&&&&&&&system($command&,&$return_var); &
&&&&&&&&$output&=&ob_get_contents(); &
&&&&&&&&ob_end_clean(); &
&&&&//passthru &
&&&&else&if(function_exists('passthru')) &
&&&&&&&&ob_start(); &
&&&&&&&&passthru($command&,&$return_var); &
&&&&&&&&$output&=&ob_get_contents(); &
&&&&&&&&ob_end_clean(); &
&&&&//exec &
&&&&else&if(function_exists('exec')) &
&&&&&&&&exec($command&,&$output&,&$return_var); &
&&&&&&&&$output&=&implode("\n"&,&$output); &
&&&&//shell_exec &
&&&&else&if(function_exists('shell_exec')) &
&&&&&&&&$output&=&shell_exec($command)&; &
&&&&&&&&$output&=&'Command&execution&not&possible&on&this&system'; &
&&&&&&&&$return_var&=&1; &
&&&&return&array('output'&=&&$output&,&'status'&=&&$return_var); &
terminal('ls');&
上面的函数將运行shell命令, 只要有一个系统函数可用, 这保持了代码的一致性.&
5. 灵活编写函数
function add_to_cart($item_id , $qty)
$_SESSION['cart']['item_id'] = $qty;
add_to_cart( 'IPHONE3' , 2 );
使用上面的函数添加单个项目. 而当添加项列表的时候,你要创建另一个函数吗? 不用, 只要稍加留意不同类型的参数, 就会更灵活. 如:
function&add_to_cart($item_id&,&$qty) &
&&&&if(!is_array($item_id)) &
&&&&&&&&$_SESSION['cart']['item_id']&=&$qty; &
&&&&&&&&foreach($item_id&as&$i_id&=&&$qty) &
&&&&&&&&{ &
&&&&&&&&&&&&$_SESSION['cart']['i_id']&=&$qty; &
&&&&&&&&} &
add_to_cart(&'IPHONE3'&,&2&); &
add_to_cart(&array('IPHONE3'&=&&2&,&'IPAD'&=&&5)&);&
现在, 同个函数可以处理不同类型的输入参数了. 可以参照上面的例子重构你的多处代码, 使其更智能.
6. 有意忽略php关闭标签我很想知道为什么这么多关于php建议的博客文章都没提到这点.
echo&"Hello"; &
//Now&dont&close&this&tag&
这將节约你很多时间. 我们举个例子:一个 super_class.php 文件
class&super_class &
&&&&function&super_function() &
&&&&&&&&//super&code &
//super&extra&character&after&the&closing&tag&
require_once('super_class.php'); &
//echo&an&image&or&pdf&,&or&set&the&cookies&or&session&data&
这样, 你將会得到一个&Headers already send error. 为什么? 因为&&super extra character& 已经被输出了. 现在你得开始调试啦. 这会花费大量时间寻找&super extra 的位置.因此, 养成省略关闭符的习惯:
class&super_class &
&&&&function&super_function() &
&&&&&&&&//super&code &
//No&closing&tag&
这会更好.&
7. 在某地方收集所有输入, 一次输出给浏览器这称为输出缓冲, 假如说你已在不同的函数输出内容:
function&print_header() &
&&&&echo&"&div&id='header'&Site&Log&and&Login&links&/div&"; &
function&print_footer() &
&&&&echo&"&div&id='footer'&Site&was&made&by&me&/div&"; &
print_header(); &
for($i&=&0&;&$i&&&100;&$i++) &
&&&&echo&"I&is&:&$i&&br&/&'; &
print_footer();&
替代方案, 在某地方集中收集输出. 你可以存储在函数的局部变量中, 也可以使用ob_start和ob_end_clean. 如下:
function&print_header() &
&&&&$o&=&"&div&id='header'&Site&Log&and&Login&links&/div&"; &
&&&&return&$o; &
function&print_footer() &
&&&&$o&=&"&div&id='footer'&Site&was&made&by&me&/div&"; &
&&&&return&$o; &
echo&print_header(); &
for($i&=&0&;&$i&&&100;&$i++) &
&&&&echo&"I&is&:&$i&&br&/&'; &
echo&print_footer();&
为什么需要输出缓冲:&&可以在发送给浏览器前更改输出. 如&str_replaces 函数或可能是&preg_replaces 或添加些监控/调试的html内容.&&输出给浏览器的同时又做php的处理很糟糕. 你应该看到过有些站点的侧边栏或中间出现错误信息. 知道为什么会发生吗? 因为处理和输出混合了.
8. 发送正确的mime类型头信息, 如果输出非html内容的话.输出一些xml.
$xml&=&'&?xml&version="1.0"&encoding="utf-8"&standalone="yes"?&'; &
$xml&=&"&response& &
&&&code&0&/code& &
&/response&"; &
//Send&xml&data &
echo&$xml;&
工作得不错. 但需要一些改进.
$xml&=&'&?xml&version="1.0"&encoding="utf-8"&standalone="yes"?&'; &
$xml&=&"&response& &
&&&code&0&/code& &
&/response&"; &
//Send&xml&data &
header("content-type:&text/xml"); &
echo&$xml;&
注意header行. 该行告知浏览器发送的是xml类型的内容. 所以浏览器能正确的处理. 很多的javascript库也依赖头信息.类似的有 javascript , css, jpg image, png image:JavaScript
header("content-type:&application/x-javascript"); &
echo&"var&a&=&10";&
header("content-type:&text/css"); &
echo&"#div&id&{&background:#000;&}";&
9. 为mysql连接设置正确的字符编码曾经遇到过在mysql表中设置了unicode/utf-8编码,&&phpadmin也能正确显示, 但当你获取内容并在页面输出的时候,会出现乱码. 这里的问题出在mysql连接的字符编码.
//Attempt&to&connect&to&database &
$c&=&mysqli_connect($this-&host&,&$this-&username,&$this-&password); &
//Check&connection&validity &
if&(!$c)& &
&&&&die&("Could&not&connect&to&the&database&host:&&br&/&".&mysqli_connect_error()); &
//Set&the&character&set&of&the&connection &
if(!mysqli_set_charset&(&$c&,&'UTF8'&)) &
&&&&die('mysqli_set_charset()&failed'); &
一旦连接数据库, 最好设置连接的&characterset. 你的应用如果要支持多语言, 这么做是必须的.
10. 使用 htmlentities 设置正确的编码选项php5.4前, 字符的默认编码是ISO-8859-1, 不能直接输出如&A &等.
$value&=&htmlentities($this-&value&,&ENT_QUOTES&,&CHARSET);&
php5.4以后, 默认编码为UTF-8, 这將解决很多问题. 但如果你的应用是多语言的,&仍然要留意编码问题,.
11. 不要在应用中使用gzip压缩输出, 让apache处理考虑过使用 ob_gzhandler 吗? 不要那样做. 毫无意义. php只应用来编写应用. 不应操心服务器和浏览器的数据传输优化问题.使用apache的mod_gzip/mod_deflate 模块压缩内容.
12. 使用json_encode输出动态javascript内容时常会用php输出动态javascript内容:
$images&=&array( &
&'myself.png'&,&'friends.png'&,&'colleagues.png'&
$js_code&=&''; &
foreach($images&as&$image) &
$js_code&.=&"'$image'&,"; &
$js_code&=&'var&images&=&['&.&$js_code&.&'];&'; &
echo&$js_code; &
//Output&is&var&images&=&['myself.png'&,'friends.png'&,'colleagues.png'&,];&
更聪明的做法, 使用 json_encode:
$images&=&array( &
&'myself.png'&,&'friends.png'&,&'colleagues.png'&
$js_code&=&'var&images&=&'&.&json_encode($images); &
echo&$js_code; &
//Output&is&:&var&images&=&["myself.png","friends.png","colleagues.png"]&
13. 写文件前, 检查目录写权限写或保存文件前, 确保目录是可写的, 假如不可写, 输出错误信息. 这会节约你很多调试时间. linux系统中, 需要处理权限, 目录权限不当会导致很多很多的问题, 文件也有可能无法读取等等.确保你的应用足够智能, 输出某些重要信息.
$contents&=&"All&the&content"; &
$file_path&=&"/var/www/project/content.txt"; &
file_put_contents($file_path&,&$contents);&
这大体上正确. 但有些间接的问题.&file_put_contents 可能会由于几个原因失败:&&父目录不存在&&目录存在, 但不可写&&文件被写锁住?所以写文件前做明确的检查更好.
$contents&=&"All&the&content"; &
$dir&=&'/var/www/project'; &
$file_path&=&$dir&.&"/content.txt"; &
if(is_writable($dir)) &
&&&&file_put_contents($file_path&,&$contents); &
&&&&die("Directory&$dir&is&not&writable,&or&does&not&exist.&Please&check"); &
这么做后, 你会得到一个文件在何处写及为什么失败的明确信息.
14. 更改应用创建的文件权限在 linux环境中, 权限问题可能会浪费你很多时间. 从今往后, 无论何时, 当你创建一些文件后, 确保使用chmod设置正确权限. 否则的话, 可能文件先是由"php"用户创建, 但你用其它的用户登录工作, 系统將会拒绝访问或打开文件, 你不得不奋力获取root权限, &更改文件的权限等等.
//&Read&and&write&for&owner,&read&for&everybody&else &
chmod("/somedir/somefile",&0644); &
//&Everything&for&owner,&read&and&execute&for&others &
chmod("/somedir/somefile",&0755);&
15. 不要依赖submit按钮值来检查表单提交行为
if($_POST['submit']&==&'Save') &
&&&&//Save&the&things &
上面大多数情况正确, 除了应用是多语言的. 'Save' 可能代表其它含义. 你怎么区分它们呢. 因此, 不要依赖于submit按钮的值.
if(&$_SERVER['REQUEST_METHOD']&==&'POST'&and&isset($_POST['submit'])&) &
&&&&//Save&the&things &
现在你从submit按钮值中解脱出来了.
16. 为函数内总具有相同值的变量定义成静态变量
//Delay&for&some&time &
function&delay() &
&&&&$sync_delay&=&get_option('sync_delay'); &
&&&&echo&"&br&/&Delaying&for&$sync_delay&seconds..."; &
&&&&sleep($sync_delay); &
&&&&echo&"Done&&br&/&"; &
用静态变量取代:
//Delay&for&some&time &
function&delay() &
&&&&static&$sync_delay&=& &
&&&&if($sync_delay&==&null) &
&&&&$sync_delay&=&get_option('sync_delay'); &
&&&&echo&"&br&/&Delaying&for&$sync_delay&seconds..."; &
&&&&sleep($sync_delay); &
&&&&echo&"Done&&br&/&"; &
17. 不要直接使用 $_SESSION 变量
$_SESSION['username']&=&$username; &
$username&=&$_SESSION['username'];&
这会导致某些问题. 如果在同个域名中运行了多个应用, session 变量可能会冲突. 两个不同的应用可能使用同一个session key. 例如, 一个前端门户, 和一个后台管理系统使用同一域名.从现在开始, 使用应用相关的key和一个包装函数:
define('APP_ID'&,&'abc_corp_ecommerce'); &
//Function&to&get&a&session&variable &
function&session_get($key) &
&&&&$k&=&APP_ID&.&'.'&.&$key; &
&&&&if(isset($_SESSION[$k])) &
&&&&&&&&return&$_SESSION[$k]; &
&&&&return& &
//Function&set&the&session&variable &
function&session_set($key&,&$value) &
&&&&$k&=&APP_ID&.&'.'&.&$key; &
&&&&$_SESSION[$k]&=&$value; &
&&&&return& &
18. 將工具函数封装到类中假如你在某文件中定义了很多工具函数:
function&utility_a() &
&&&&//This&function&does&a&utility&thing&like&string&processing &
function&utility_b() &
&&&&//This&function&does&nother&utility&thing&like&database&processing &
function&utility_c() &
&&&&//This&function&is&... &
这些函数的使用分散到应用各处. 你可能想將他们封装到某个类中:
class&Utility &
&&&&public&static&function&utility_a() &
&&&&public&static&function&utility_b() &
&&&&public&static&function&utility_c() &
//and&call&them&as& &
$a&=&Utility::utility_a(); &
$b&=&Utility::utility_b();&
显而易见的好处是, 如果php内建有同名的函数, 这样可以避免冲突.另一种看法是, 你可以在同个应用中为同个类维护多个版本, 而不导致冲突.&这是封装的基本好处, 无它.
19. Bunch of silly tips&&&使用echo取代print&&使用str_replace取代preg_replace, 除非你绝对需要&&不要使用 short tag&&简单字符串用单引号取代双引号&&head重定向后记得使用exit&&不要在循环中调用函数&&isset比strlen快&&始中如一的格式化代码&&不要删除循环或者if-else的括号不要这样写代码:
&span&style="color:#333333;font-family:''Helvetica,&Arial,&sans-serif'';"&if($a&==&true)&$a_count++;&/span&&
这绝对WASTE.写成:
&span&style="color:#333333;font-family:''Helvetica,&Arial,&sans-serif'';"&if($a&==&true) &
&&&&$a_count++; &
不要尝试省略一些语法来缩短代码. 而是让你的逻辑简短.&&使用有高亮语法显示的文本编辑器. 高亮语法能让你减少错误.
20. 使用array_map快速处理数组比如说你想 trim 数组中的所有元素. 新手可能会:
foreach($arr&as&$c&=&&$v) &
&&&&$arr[$c]&=&trim($v); &
但使用 array_map 更简单:
$arr&=&array_map('trim'&,&$arr);&
这会为$arr数组的每个元素都申请调用trim. 另一个类似的函数是 array_walk. 请查阅文档学习更多技巧.
21. 使用 php filter 验证数据你肯定曾使用过正则表达式验证 email , ip地址等. 是的,每个人都这么使用. 现在, 我们想做不同的尝试, 称为filter.php的filter扩展提供了简单的方式验证和检查输入.
22. 强制类型检查
$amount&=&intval(&$_GET['amount']&); &
$rate&=&(int)&$_GET['rate'];&
这是个好习惯.
23. 如果需要,使用profiler如xdebug如果你使用php开发大型的应用, php承担了很多运算量, 速度会是一个很重要的指标. 使用profile帮助优化代码. 可使用xdebug和webgrid.
24. 小心处理大数组对于大的数组和字符串, 必须小心处理. 常见错误是发生数组拷贝导致内存溢出,抛出Fat
$db_records_in_array_format;&//This&is&a&big&array&holding&1000&rows&from&a&table&each&having&20&columns&,&every&row&is&atleast&100&bytes&,&so&total&1000&*&20&*&100&=&2MB &
$cc&=&$db_records_in_array_format;&//2MB&more &
some_function($cc);&//Another&2MB&?&
&当导入或导出csv文件时, 常常会这么做.不要认为上面的代码会经常因内存限制导致脚本崩溃. 对于小的变量是没问题的, 但处理大数组的时候就必须避免.确保通过引用传递, 或存储在类变量中:
$a&=&get_large_array(); &
pass_to_function(&$a);&
这么做后,向函数传递变量引用(而不是拷贝数组). 查看.
&&&&function&first() &
&&&&&&&&$this-&a&=&get_large_array(); &
&&&&&&&&$this-&pass_to_function(); &
&&&&function&pass_to_function() &
&&&&&&&&//process&$this-&a &
尽快的 unset 它们, 让内存得以释放,减轻脚本负担.
25. &由始至终使用单一数据库连接确保你的脚本由始至终都使用单一的数据库连接. 在开始处正确的打开连接, 使用它直到结束, 最后关闭它. 不要像下面这样在函数中打开连接:
function&add_to_cart() &
&&&&$db&=&new&Database(); &
&&&&$db-&query("INSERT&INTO&cart&....."); &
function&empty_cart() &
&&&&$db&=&new&Database(); &
&&&&$db-&query("DELETE&FROM&cart&....."); &
使用多个连接是个糟糕的, 它们会拖慢应用, 因为创建连接需要时间和占用内存.特定情况使用单例模式, 如数据库连接.
26. 避免直接写SQL, 抽象之不厌其烦的写了太多如下的语句:
&span&style="color:#333333;font-family:''Helvetica,&Arial,&sans-serif'';"&$query&=&"INSERT&INTO&users(name&,&email&,&address&,&phone)&VALUES('$name'&,&'$email'&,&'$address'&,&'$phone')"; &
$db-&query($query);&//call&to&mysqli_query()&/span&&
这不是个建壮的方案. 它有些缺点:&&每次都手动转义值&&验证查询是否正确&&查询的错误会花很长时间识别(除非每次都用if-else检查)&&很难维护复杂的查询因此使用函数封装:
&span&style="color:#333333;font-family:''Helvetica,&Arial,&sans-serif'';"&function&insert_record($table_name&,&$data) &
&&&&foreach($data&as&$key&=&&$value) &
&&&&//mysqli_real_escape_string &
&&&&&&&&$data[$key]&=&$db-&mres($value); &
&&&&$fields&=&implode(','&,&array_keys($data)); &
&&&&$values&=&"'"&.&implode("','"&,&array_values($data))&.&"'"; &
&&&&//Final&query &
&&&&$query&=&"INSERT&INTO&{$table}($fields)&VALUES($values)"; &
&&&&return&$db-&query($query); &
$data&=&array('name'&=&&$name&,&'email'&=&&$email&&,&'address'&=&&$address&,&'phone'&=&&$phone); &
insert_record('users'&,&$data);&/span&&
看到了吗? 这样会更易读和扩展. record_data 函数小心的处理了转义.&最大的优点是数据被预处理为一个数组, 任何语法错误都会被捕获.该函数应该定义在某个database类中, 你可以像 $db-&insert_record这样调用.查看本文, 看看怎样让你处理数据库更容易.类似的也可以编写update,select,delete方法. 试试吧.
27. 將数据库生成的内容缓存到静态文件中如果所有的内容都是从数据库获取的, 它们应该被缓存. 一旦生成了, 就將它们保存在临时文件中. 下次请求该页面时, 可直接从缓存中取, 不用再查数据库.好处:&&节约php处理页面的时间, 执行更快&&更少的数据库查询意味着更少的mysql连接开销
28. 在数据库中保存sessio-base 标签非常有用. 假设你的应用分成几个子目录, 它们都要包括相同的导航菜单./store/home.php/store/products/ipad.php在首页中, 可以写:
&a&href="home.php"&Home&/a& &
&a&href="products/ipad.php"&Ipad&/a&&
但在你的ipad.php不得不写成:
&span&style="color:#333333;font-family:''Helvetica,&Arial,&sans-serif'';"&&a&href="../home.php"&Home&/a& &
&a&href="ipad.php"&Ipad&/a&&/span&&
因为目录不一样. 有这么多不同版本的导航菜单要维护, 很糟糕啊.&因此, 请使用base标签.
&span&style="color:#333333;font-family:''Helvetica,&Arial,&sans-serif'';"&&head& &
&base&href="/store/"& &
&a&href="home.php"&Home&/a& &
&a&href="products/ipad.php"&Ipad&/a& &
&/html&&/span&&
现在, 这段代码放在应用的各个目录文件中行为都一致.&
31. 永远不要將 error_reporting 设为 0关闭不相的错误报告.&E_FATAL 错误是很重要的.&
&span&style="color:#333333;font-family:'Helvetica,&Arial,&sans-serif';"&ini_set('display_errors',&1); &
error_reporting(~E_WARNING&&&~E_NOTICE&&&~E_STRICT);&/span&&
32. 注意平台体系结构integer在32位和64位体系结构中长度是不同的. 因此某些函数如&strtotime 的行为会不同.在64位的机器中, 你会看到如下的输出.
&span&style="color:#333333;font-family:''Helvetica,&Arial,&sans-serif'';"&$&php&-a &
Interactive&shell &
php&&&echo&strtotime("&00:00:00"); &
php&&&echo&strtotime(''); &
php&&&echo&strtotime(''); &
但在32位机器中, 它们將是bool(false). 查看, 了解更多.
33. 不要过分依赖 set_time_limit如果你想限制最小时间, 可以使用下面的脚本:
&span&style="color:#333333;font-family:''Helvetica,&Arial,&sans-serif'';"&set_time_limit(30); &
//Rest&of&the&code&/span&&
高枕无忧吗? &注意任何外部的执行, 如系统调用,socket操作, 数据库操作等, 就不在set_time_limits的控制之下.因此, 就算数据库花费了很多时间查询, 脚本也不会停止执行. 视情况而定.
34. 使用扩展库一些例子:&&mPDF -- 能通过html生成pdf文档&&PHPExcel -- 读写excel&&PhpMailer -- 轻松处理发送包含附近的邮件&&pChart -- 使用php生成报表使用开源库完成复杂任务, 如生成pdf,&ms-excel文件, 报表等.
35. 使用MVC框架是时候使用像&codeigniter 这样的MVC框架了. MVC框架并不强迫你写面向对象的代码. 它们仅將php代码与html分离.&&明确区分php和html代码. 在团队协作中有好处, 设计师和程序员可以同时工作.&&面向对象设计的函数能让你更容易维护&&内建函数完成了很多工作, 你不需要重复编写&&开发大的应用是必须的&&很多建议, 技巧和hack已被框架实现了
36. 时常看看 phpbench&
&提供了些php基本操作的基准测试结果, 它展示了一些徽小的语法变化是怎样导致巨大差异的.查看php站点的评论, 有问题到IRC提问, 时常阅读开源代码, 使用Linux开发.&英文:原文链接:
IBM的Web 应用程序开发人员PHP读物列表
PHP 是一个脚本语言,在最常见的情况下嵌在 HTML 文档中,在服务器上在输出发送到 Web 浏览器之前执行。也可以把它用在 Web 服务器环境之外,作为命令行工具来执行。
PHP 通常与其他开放源码软件安装在一起,构建 Web 应用程序,常见的平台组合用术语 &LAMP&(代表 Linux、Apache、MySQL 和 PHP)表示,不过也可以使用其他组件。例如,用 AIX 代替 Linux,或用 DB2代替 MySQL。
维基百科全书用代码示例提供了对 PHP 的概述,演示了基本的编程概念。
PHP 手册是 PHP 信息的主要来源。它包含常见问题(FAQ)列表、安装指南、语言参考和带有用户评论的全面的函数文档。
不用专门的工具就可以编写 PHP,不论是简单的文本编辑器还是全功能的集成开发环境(IDE)都可以。因为可以选择的有许多,所以以下提供一些最流行的编辑器的链接。
Zend Studio 是一个商业 IDE,来自构造 PHP 引擎的公司。这个编辑器提供了语言高亮显示、代码辅助,并支持调试、源代码控制、文档,以及在工具内部的数据库连接。
是个免费的开放源码软件框架,独立于平台,可以开发富客户机应用程序。 是个 Eclipse 插件,提供完整的 IDE 体验,包括解析器、调试器、代码格式化器、大纲视图以及模板。这篇文章提供了关于配置和安装带有 PHPeclipse 插件的 Eclipse 的说明。
jEdit 是一个免费软件,是一个用 Java? 编程语言编写的文本编辑器,所以可以在多个平台上运行,可以通过插件扩展。jEdit 支持 PHP 的语法高亮显示和附加特性,例如语言验证和代码导航,可以通过 PHP 插件 PHPParse 得到。
在创建或部署 PHP 应用程序时,必须有一个合适的环境运行它们。
Zend Core for IBM 是一个可以立即使用、易于安装、支持 PHP 的开发和生产环境。 提供了高级概述。 和
有助于迅速地设置和运行它。
像 XAMPP 这样来自 Apache Friends 的开放源码技术正在简化开放源码开发,使得在稳定的、标准化的环境中开发和分发应用程序更加容易。请学习如何在 Mandrake Linux V10.0 上安装、配置和备份 XAMPP,学习如何配置和管理 XAMPP,学习如何在 XAMPP 环境中安装自己的应用程序。
不论是在进行团队协作还是需要保留自己的文件版本,源代码控制都是需要的。
Jeff Knight 和 Andrew Yochum 演示了如何使用 Subversion 管理多个项目和开发人员,以及开发和生产环境。
PHP 是一种优秀的 Web 编程语言,在创建动态 Web 站点(例如博客站点)时可以使用它。这份教程解释了如何从头开始创建一个博客,其中使用文本文件保存数据。可以用 Subversion 把这个 Web 站点在远程系统上备份,从而在发生 Web 站点崩溃的时候保护数据。Subversion 正在日益流行,是备份站点的好选择。使用 Subversion,在服务器崩溃时,或者在讨厌上周的内容的时候,都可以把 Web 站点回退到较早的版本。
有了开发环境之后,可以学习 PHP 的核心功能并开始编写代码。
Zend 维护了一份 PHP 入门级介绍性教程的集合,针对 PHP 的新手。
这份教程研究了 LAMP Web 开发框架,并介绍了这个框架如何帮助构建解决问题的应用程序。这个教程首先研究 LAMP 架构,然后介绍基本的 PHP 概念。在有了 PHP 的扎实基础之后,教程解释了 MySQL 支持,介绍的重点是数据库的概念和如何从 PHP 访问 MySQL。所有这些技术都是在一个真实的客户管理系统的示例中讨论的。
这篇文章描述了 PHP V5 中的对象和类的基础知识,从非常基础的部分到继承,针对的是有经验的面向对象程序员和以前不了解对象的程序员。
这份教程是三部分系列的第 1 部分,这个系列通过构建一个文档

我要回帖

更多关于 硬盘启动时哒哒哒 的文章

 

随机推荐