分类 ‘PHP’ 归档文章

PHP开发人员必须知道的一些技巧

由 徐永久 发表于 2007年03月16日 20:22。

看完这个网站 http://www.cluesheet.com/ 的首页,觉得确实对我们的 PHP 开发人员很有裨益。因为有些术语的缘故不能全部翻译成英文。
安全方面:

* 不要为 SQL 语句使用 PDO 参数传值,以防止 SQL injection.
* 务必使用 htmlspecialchars/htmlentities 和/或者 strip_tags 转义 html 和JavaScript 来防止 XSS(交叉站点脚本) 攻击.
* 务必使用 sessions 和安全套接字来防止 session 被劫持,采用 md5 校验和来验证 session ids. 在 session 里存储一个特殊的令牌 md5(uniqueid(rand(),time)) 放到一个隐含的表单提交项里:eg. $_SESSION["token"]===$FORM["token"].
* 务必使用 escapeshellarg/escapeshellcmd 调用外部命令防止命令行注入
* 务必从进入的http头删除分行符以防止http头提早终止 Do remove linebreaks from incoming headers to prevent early header termination and injection. Fixed >PHP5.1
* 采用 md5 校验和来序列化参数值和 sessionid来验证一致性
* 使用 === 来验证输入值以保证类型一致
* 设置以下参数来提高安全性:
o ini_set(“display_errors”,false);
o ini_set(“log_errors”,true);
o ini_set(“error_log”,”path/to/php.log”);
o ini_set(“session.save_path”,”path/above/www”); or “mm” session module or store in a sqllite db
o php.ini expose_php=off
o php.ini register_globals=off
o Apache servertokens=prod
* 在任何用户特权提升的应用中,采用 session_regenerate
* 在商务交易中采用安全套接字

性能方面

* Do use single quotes over double quotes.
* Do use switch over lots of if statements
* Do avoid testing loop conditionals with function tests every iteration eg. for($i=0;i<=count($x);$i++){...
* Do use foreach for looping collections/arrays.
o PHP4 items are byval
o >PHP5 items are byref
* Do consider using the Singleton Method when creating complex PHP classes.
* Do use POST over GET for all values that will wind up in the database for TCP/IP packet performance reasons.
* Do use ctype_alnum,ctype_alpha and ctype_digit over regular expression to test form value types for performance reasons.
* Do use full file paths in production environment over basename/fileexists/open_basedir to avoid performance hits for the filesystem having to hunt through the file path. Once determined, serialize and/or cache path values in a $_SETTINGS array. $_SETTINGS["cwd"]=cwd(./);
* Do use require/include over require_once/include_once to ensure proper opcode caching.
* Do use tmpfile or tempnam for creating temp files/filenames
* Do use a proxy to access web services (XML or JSOM) on foreign domains using XMLHTTP to avoid cross-domain errors. eg. foo.com<-->XMLHTTP<-->bar.com
* Do use error_reporting (E_ALL); during debug.
* Do set Apache allowoverride to “none” to improve Apache performance in accessing files/directories.
* Do use a fast fileserver for serving static content (thttpd). static.mydomain.com, dynamic.mydomain.com
* Do serialize application settings like paths into an associative array and cache or serialize that array after first execution.
* Do use PHP output control buffering for page caching of heavilty accessed pages
* Do use PDO prepare over native db prepare for statements. mysql_attr_direct_query=>1
* Do NOT use SQL wildcard select. eg. SELECT *
* Do use database logic (queries, joins, views, procedures) over loopy PHP.
* Do use shortcut syntax for SQL insers if not using PDO parameters parameters. eg. INSERT INTO MYTABLE (FIELD1,FIELD2) VALUES ((“x”,”y”),(“p”,”q”));

工具方面

* microtime() – Return current Unix timestamp with microseconds to mark performance.
* ab Apache Bench server benchmarking tool.(-n 1000, -c 500)
* Zend Performance Suite
* Callgrind/KCachegrind profiling tool.
* http_load multiprocessing http test client.
* xdebug helps you debugging your script by providing a lot of valuable debug information.
* PHP Security Scanner
* PECL APC opcode caching module.
o pecl install APC
o php.ini APC.STAT=0
o APC_STORE($_SETTINGS)

新技术/技巧

* Service Data Objects -SDOs enable PHP applications to work with data from different sources (like a database query, an XML file, and a spreadsheet) using a single interface.
* JavaScript Object Notation – JSON is a lightweight computer data interchange format you can use instead of XML in AJAX apps.
* PHP5.1.3 to be released within the week.
* PHP6 will implement numerous changes.
* DB2 Viper implements extensive XML support.

其他有用的人物/博客

* Chris ShiflettPHP Security Consortium and PHP security guru
* John Coggeshall
* Ilia Alshanetsky: PDO Lecture, Security Lecture
* Marcus Boerger
* Derick Rethans: eZ Components – RAD for PHP
* Rasmus Lerdorf
* Christian Wenz: The Return of Javascript: AJAX , New (and old) Trends in Web Hacking, The ABCs of Web Services
* Andrei Zmievski: PHP 6 and Unicode
* Paul Reinheimer: Simple Web Services: REST
* Sara Golemon: Embedding and Extending PHP
* Davey Shafik: Future Deployment of PHP Applications, Migrating to PHP 5.1
* Marcus Baker: Is Agile Right for You? , The OO Sound Barrier: Leveraging OOP
* Lukas Smith: Beyond SQL
* Johannes Schlueter:
* Grant Hutchison: XML to the Max – DB2 Viper with PHP
* Caroline Maynard: PHP Service Data Objects
* Andi Gutmans
* Jason Sweat
* Joe Stagner
* Hartmut Holzgraefe
* Tony Cairns: i5/OS Zend Core Roadmap
* Marco Tabini

用 PHP 致”富”

由 徐永久 发表于 2007年03月16日 20:48。

这里的 富 , Rich 其实是指 胖客户, 在 n-Tier 结构的时代,瘦客户成为时尚,在 Web 2.0 时代我们更崇尚 Rich Client,体现更加丰富,更加个性化的服务器内容。

http://talks.php.net/show/oscon06/3

这个 Slide 的前几页讲述了 PHP 性能提升的经过,十分值得一读。
(more…)

PHP trobleshooting 技巧

由 徐永久 发表于 2007年01月13日 11:41。

对 PHP 程序的 trobleshooting 其实是很简单的,只要打开 php.ini 里面 所有的 debug 选项,然后重新启动 Apache 即可。
打开 /usr/local/lib/php.ini 后, 设置:

error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
error_log = /var/logs/php.err

这样就可以调试出一些奇怪的 PHP 问题了。

例如, session 路径设置错误,没有写权限,会导致登陆界面提交用户名和口令后回到原来的登陆界面。需要设置 php.ini 中 session.save_path 为正确的路径(Apache 的用户能写入)。

快速安装 Pear

由 徐永久 发表于 2006年06月14日 15:17。

Pear 是 PHP 的类库集合,用 tarbal 安装 php 后不一定安装 pear ,这里介绍一个简单快速的办法安装 pear。

lynx -source http://pear.php.net/go-pear | php -q

安装完毕后用 pear -V 命令显示:

PEAR Version: 1.4.9
PHP Version: 4.4.2
Zend Engine Version: 1.3.0
Running on: SunOS hostname 5.10 Generic i86pc


pear install –alldeps channel://pear.php.net/Image_Graph-0.7.2

这样的格式可以安装所需要的包了。

快速安装 Pear

由 徐永久 发表于 2006年06月14日 15:17。

Pear 是 PHP 的类库集合,用 tarbal 安装 php 后不一定安装 pear ,这里介绍一个简单快速的办法安装 pear。

lynx -source http://pear.php.net/go-pear | php -q

安装完毕后用 pear -V 命令显示:

PEAR Version: 1.4.9
PHP Version: 4.4.2
Zend Engine Version: 1.3.0
Running on: SunOS hostname 5.10 Generic i86pc


pear install –alldeps channel://pear.php.net/Image_Graph-0.7.2

这样的格式可以安装所需要的包了。

为 Mambo 开放源码内容管理系统添加“轻松背单词”功能

由 徐永久 发表于 2005年11月10日 03:18。

Mambo 是不错的开源内容管理系统(CMS) , 拿来主义就是采用 Mambo 架构的。 为了实现某些论坛上的背单词功能,笔者对 Mambo 作了一定的 Hack,过程如下。

(more…)

Mambo 站点使用 FeedCreator class v1.7.2 存在缓冲编码问题

由 徐永久 发表于 2005年09月25日 16:30。

RSS 技术和 Firefox 下的 livebookmark 是目前内容聚合的亮点。? 我的某网站采用了开放源码的 Mambo 来架构。
但是其 RSS 输出存在问题, 不仅其中的日期时区被固定在 +0100 ,而且还有严重的编码问题。

本文没有提出系统修改的解决方案。 仅仅在解决编码问题上做出一些小的 Hack 。

在 /includes/feedcreator.class.php 这段主要代码中:
(more…)

一个把 pLog 博客数据移植到 Mambo 的脚本

由 徐永久 发表于 2005年03月24日 13:34。

做知识管理,仅仅有博客是不能实现一个知识门户的功能的。因此需要一个功能较强,定制灵活的 CMS 系统。 Mambo 确实是一款不错的内容管理软件。虽然我较早时发布过一个 java.freelamp.com 的网站,也采用 Mambo ,那个时候也是整合了一下,后来由于没有时间写内容,所以关闭了该站。 今天有心把 pLog 转化到 Mambo ,所以写了个PHP脚本把 pLog 的数据迁移到 Mambo 上。

迁移之前,需要根据博客中不同的类别归类到几个 section 中,然后手工在 Mambo 后台建立 section 并根据博客中这些分类的名字分别建立分类到对应的 section 中。这部分工作由于 category 和 section 之间的关系必须人工确定所以只能手动完成。接下来就可以运行下面的程序,把博客中的数据导入到 Mambo 了。
(more…)

安装另外一个 PHP 缓冲加速器

由 徐永久 发表于 2003年07月05日 03:38。

PHP 加速的工具有很多,原理也都类似。但是以 Zend 的产品为最好。
网络上介绍 PHP 性能优化的文章中谈到了 Turck MMCache 这个产品。

http://www.turcksoft.com/en/e_mmc.htm#download

(more…)

SOAP Google API for PHP 发布

由 徐永久 发表于 2002年04月17日 15:08。

SOAP_Google 类让 PHP 开发者和 Google 的WebService 交互,并利用 Google 巨大的搜索数据库技术。

SOAP_Google.php

//
// +———————————————————————-+
// | PHP Interface to the Google API |
// +———————————————————————-+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +———————————————————————-+
// | Author: Sebastian Bergmann |
// +———————————————————————-+
//

require_once ‘SOAP/Client.php’;

/**
* PHP Interface to the Google API
*
* @author Sebastian Bergmann
* @access public
*/
class SOAP_Google {
/**
* @var string
* @access private
*/
var $_licenseKey = ”;

/**
* @var object
* @access private
*/
var $_soapClient = NULL;

/**
* Constructor.
*
* @param string
* @access public
*/
function SOAP_Google($licenseKey) {
$this->_licenseKey = $licenseKey;

$this->_soapClient = new SOAP_Client(
‘http://api.google.com/search/beta2′
);
}

/**
* Retrieves a page by URL from the Google Cache.
*
* @param string
* @return mixed
* @access public
*/
function getCachedPage($url) {
$result = $this->_performAPICall(
‘doGetCachedPage’,

array(
‘key’ => $this->_licenseKey,
‘url’ => $url
)
);

if ($result) {
$result = base64_decode($result);
}

return $result;
}

/**
* Retrieves a spelling suggestion for a phrase.
*
* @param string
* @return mixed
* @access public
*/
function getSpellingSuggestion($phrase) {
return $this->_performAPICall(
‘doSpellingSuggestion’,

array(
‘key’ => $this->_licenseKey,
‘phrase’ => $phrase
)
);
}

/**
* Performs a web search.
*
* @param array
* @return mixed
* @access public
*/
function search($parameters = array()) {
if (!isset($parameters['query'])) {
return false;
}

return $this->_performAPICall(
‘doGoogleSearch’,

array(
‘key’ => $this->_licenseKey,
‘q’ => $parameters['query'],
‘start’ => isset($parameters['start']) ? $parameters['start'] : 0,
‘maxResults’ => isset($parameters['maxResults']) ? $parameters['maxResults'] : 10,
‘filter’ => isset($parameters['filter']) ? $parameters['filter'] : false,
‘restrict’ => isset($parameters['restrict']) ? $parameters['restrict'] : ”,
‘safeSearch’ => isset($parameters['safeSearch']) ? $parameters['safeSearch'] : false,
‘lr’ => isset($parameters['lr']) ? $parameters['lr'] : ”,
‘ie’ => isset($parameters['ie']) ? $parameters['ie'] : ”,
‘oe’ => isset($parameters['oe']) ? $parameters['oe'] : ”
)
);
}

/**
* @param string
* @param array
* @return mixed
* @access private
*/
function _performAPICall($apiCall, $parameters) {
$result = $this->_soapClient->call(
$apiCall,
$parameters,
‘urn:GoogleSearch’
);

if (!PEAR::isError($result)) {
return $result;
} else {
return false;
}
}
}
?>

程序示范:

require_once ‘SOAP_Google.php’;

$google = new SOAP_Google(‘your license key’);

$result = $google->search(
array(
‘query’ => ‘sebastian bergmann’
)
);

if (false !== $result) {
print_r($result);
} else {
echo ‘Query failed.’;
}
?>