提高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生成报表

使用MVC框架

时常看看 phpbench

posted @ 2012-04-12 11:44  NiuWeb  阅读(215)  评论(0)    收藏  举报