提高PHP代码质量的36个技巧
摘选自伯乐在线
不要使用相对路径
define('ROOT' , pathinfo(__FILE__, PATHINFO_DIRNAME));
require_once(ROOT . 'http://www.cnblogs.com/lib/some_class.php');
不要直接使用 require, include, include_once, required_once
function load_class($class_name){
 $path = ROOT . '/lib/' . $class_name . '.php');
 if(file_exists($path)){
  require_once( $path );
 }
}
- define()
- define() 函数定义一个常量。
 常量类似变量,不同之处在于:
 - 在设定以后,常量的值无法更改
- 常量名不需要开头的美元符号 ($)
- 作用域不影响对常量的访问
- 常量值只能是字符串或数字
 摘选W3school 
- pathinfo()
- pathinfo() 函数以数组的形式返回文件路径的信息。
 文件路径的信息由三部分组成:
 - PATHINFO_DIRNAME - 只返回 dirname
- PATHINFO_BASENAME - 只返回 basename
- PATHINFO_EXTENSION - 只返回 extension
 摘选W3school 
为应用保留调试代码
define('ENVIRONMENT' , 'development');
if(! $db->query( $query ){
 if(ENVIRONMENT == 'development'){
  echo "$query failed";
 }else{
  echo "Database error. Please contact administrator";
 }
}
使用可跨平台的函数执行命令
function terminal($command){
 if(function_exists('system')){
  //system
  ob_start();
  system($command , $return_var);
  $output = ob_get_contents();
  ob_end_clean();
 }else if(function_exists('passthru')){
  //passthru
  ob_start();
  passthru($command , $return_var);
  $output = ob_get_contents();
  ob_end_clean();
 }else if(function_exists('exec')){
  //exec
  exec($command , $output , $return_var);
  $output = implode("\n" , $output);
 }else if(function_exists('shell_exec')){
  //shell_exec
  $output = shell_exec($command) ;
 }else{
  $output = 'Command execution not possible on this system';
  $return_var = 1;
 }
 return array('output' => $output , 'status' => $return_var);
}
terminal('ls');
灵活编写函数
function add_to_cart($item_id , $qty){
 if(!is_array($item_id)){
  $_SESSION['cart']['item_id'] = $qty;
 }else{
  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) );
有意忽略php关闭标签
避免出现“Headers already send error.”错误。
在某地方收集所有输入, 一次输出给浏览器
function print_header(){
 $o = "<div id='header'>Site Log and Login links</div>";
 return $o;
}
function print_footer(){
 $o = "
";
 return $o;
}
echo print_header();
for($i = 0 ; $i < 100; $i++){
 echo "I is : $i ';
}
echo print_footer();
逻辑/表现分离
如果输出非html内容,需要发送正确的mime类型头信息
$xml = '';
$xml = "0";
//Send xml data
header("content-type: text/xml");
echo $xml;
为mysql连接设置正确的字符编码
//Set the character set of the connection
if(!mysqli_set_charset ( $c , 'UTF8' )){
 die('mysqli_set_charset() failed');
}
使用 htmlentities 设置正确的编码选项
$value = htmlentities($this->value , ENT_QUOTES , CHARSET);
不要在应用中使用gzip压缩输出, 让apache处理
使用json_encode输出动态javascript内容
$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"]
- htmlentities()
- htmlentities() 函数把字符转换为 HTML 实体。 摘选W3school 
写文件前, 检查目录写权限
$contents = "All the content";
$dir = '/var/www/project';
$file_path = $dir . "/content.txt";
if(is_writable($dir)){
 file_put_contents($file_path , $contents);
}else{
 die("Directory $dir is not writable, or does not exist. Please check");
}
- is_writable()
- is_writable() 函数判断指定的文件是否可写。 摘选W3school 
更改应用创建的文件权限
chmod("/somedir/somefile", 0755);
不要依赖submit按钮值来检查表单提交行为
if( $_SERVER['REQUEST_METHOD'] == 'POST' and isset($_POST['submit']) ){
 //Save the things
}
为函数内总具有相同值的变量定义成静态变量
function delay(){
 static $sync_delay = null;
 if($sync_delay == null){
  $sync_delay = get_option('sync_delay');
 }
 echo "Delaying for $sync_delay seconds...";
 sleep($sync_delay);
 echo "Done ";
}
不要直接使用 $_SESSION 变量
define('APP_ID' , 'abc_corp_ecommerce');
function session_get($key){
 $k = APP_ID . '.' . $key;
 if(isset($_SESSION[$k])){
  return $_SESSION[$k];
 }
 return false;
}
function session_set($key , $value){
 $k = APP_ID . '.' . $key;
 $_SESSION[$k] = $value;
 return true;
}
避免相同域名下多项目之间的冲突。
將工具函数封装到类中
class Utility{
 public static function utility_a(){
 }
 public static function utility_b(){
 }
 public static function utility_c(){
 }
}
$a = Utility::utility_a();
$b = Utility::utility_b();
一些小建议
- 使用echo取代print
- 使用str_replace取代preg_replace, 除非你绝对需要
- 不要使用 short tag
- 简单字符串用单引号取代双引号
- head重定向后记得使用exit
- 不要在循环中调用函数
- isset比strlen快
- 始中如一的格式化代码
- 不要删除循环或者if-else的括号
- 使用有高亮语法显示的文本编辑器. 高亮语法能让你减少错误.
使用array_map快速处理数组
$arr = array_map('trim' , $arr);
使用 php filter 验证数据
php的filter扩展提供了简单的方式验证和检查输入.
强制类型检查
$amount = intval( $_GET['amount'] ); $rate = (int) $_GET['rate'];
如果需要,使用profiler如xdebug
小心处理大数组
传引用
$a = get_large_array(); pass_to_function(&$a);
存储在类变量中
class A{
 function first(){
  $this->a = get_large_array();
  $this->pass_to_function();
 }
 function pass_to_function(){
  //process $this->a
 }
}
由始至终使用单一数据库连接
避免直接写SQL, 抽象之
將数据库生成的内容缓存到静态文件中
在数据库中保存session
避免使用全局变量
在head中使用base标签
<html> <head> <base href="http://www.domain.com/store/"> </head> <body> <a href="home.php">Home</a> <a href="products/ipad.php">Ipad</a> </body> </html>
统一相对路径的起始位置。
永远不要將 error_reporting 设为 0
注意平台体系结构
integer在32位和64位体系结构中长度是不同的.
不要过分依赖 set_time_limit
任何外部的执行, 如系统调用,socket操作, 数据库操作等, 就不在set_time_limits的控制之下.<
使用扩展库
- mPDF — 能通过html生成pdf文档
- PHPExcel — 读写excel
- PhpMailer — 轻松处理发送包含附近的邮件
- pChart — 使用php生成报表
 
 
                
            
         
        