欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PHP良好编码方式与技巧注意事项

程序员文章站 2022-03-20 11:13:49
...

PHP编码习惯

PHP的命名

function extName($fileName){
$dotPos = strrpos($fileName, '.');
$extName = substr($fileName, $dotPos + 1 );
return $extName;
}

命名的注意事项:

  • 命名要有实际含义
  • 命名风格保持一致
  • 不用拼音命名
  • 不用语言关键字

适当的使用注释

终极要求:代码就是注释

  • 好的代码应该是自描述的
  • 难以理解的地方加上注释
  • 函数的功能加上注释说明
  • 类的功能和使用方法加注释

多备份重要的代码

  • 代码不能只有一份
  • 启用编辑器的自动备份
  • 用代码管理工具备份

坚持字符编码统一

PHP文件编码 == 模版编码 == 数据库编码

使用之前,变量要初始化

function getInfo($arrId){
$ids = implode(',', $arrId);
$query = mysql_query("select * from test where id in ($ids)");
while($info = mysql_fetch_array($query)){
$info['name'] = trim($info['name']);
$info['addr'] = trim($info['addr']);
$list[] = $info;
}
return $list;
}
function getInfo($arrId){
$list = array();
$ids = implode(',', $arrId);
$query = mysql_query("select * from test where id in ($ids)");
while($info = mysql_fetch_array($query)){
$info['name'] = trim($info['name']);
$info['addr'] = trim($info['addr']);
$list[] = $info;
}
return $list;
}

使用一个未定义的变量, 比使用一个定义好的变量要慢8倍以上!
可以相像, PHP引擎会首先按照正常的逻辑来获取这个变量, 然而这个变量不存在, 所以
PHP引擎需要抛出一个NOTICE, 并且进入一段使用未定义变量时应该走的逻辑, 然后返回
一个新的变量.
另外, 阅读代码的角度讲, 当你使用一个未定义的变量时, 会让阅读你代码的人困惑:”这
个变量在那里初始化的, 和之前的代码有关系么? 和include进来的文件有关系么?”

使用 NULL === 来代替 is_null

is_null和 NULL === 完全是一样的效果, 但是却节省了一次函数调用.

尽量使用 === 尽量不用 ==

PHP有俩组相等比较运算符 === /!==== /!= , == /!= 会有隐式类型转换,=== /!== 会严格比较俩个操作时是否类型相同并且值相等.

避免在for循环中计算

for($i=0; $i<strlen($str); $i++) {
}

会导致每次循环都调用strlen, 改为

$j=strlen($str);
for ($i=0; $i<$j; $i++) {
}

strtr替代str_replace

$subject = 'hello, world';
echo strtr($subject, array('hello'=>'world', 'world'=>'hello'));
echo str_replace(['hello'=>'world'], ['world'=>'hello'],$subject);

strtr函数的效率是str_replace的四倍

优先使用单引号

$row[‘id’] 的效率是 $row[id]7

header头的编码

header("Content-type: text/html;charset=utf-8");

php结束标记不要写

纯 PHP 代码,最好在文件末尾删除 PHP 结束标记

测试环境开启所有错误

error_reporting(7)
  • 1:E_ERROR
  • 2:E_WARNING
  • 4:E_PARSE
    但切记,上线之后要关闭我们的报错,将我们的错误代码写入到错误日志中,方便查错

屏蔽错误非常低效

养成不用 @ 的好习惯

$handle = @file('a.txt');

用FALSE表示错误, 用NULL表示不存在

对于操作类的函数, 失败返回FALSE, 表示”操作失败了”, 而对于查询类的函数,
如果找不到想要的值, 则应该返回NULL, 表示”找不到”.

优先使用PHP内置函数

正则耗时, 尽量避免, 而采用直接的字符串处理函数代替, 如:

filter_var('[email protected]', FILTER_VALIDATE_EMAIL);

有用的PHP内置函数

usort — 使用用户自定义的比较函数对数组中的值进行排序
rawurlencode — 按照 RFC 1738URL 进行编码
parse_url — 解析 URL,返回其组成部分
http_build_query — 生成 URL-encode 之后的请求字符串
exif_imagetype — 判断一个图像的类型
uniqid — 生成一个唯一ID
get_browser — 获取浏览器具有的功能
str_word_count — 返回字符串中单词的使用情况

我们php手册中常见的字符串函数和数组函数,也需要熟悉,优先使用

防御式编程思想

不要相信外部的一切输入! 所有的输入都要检查!

<?php
$username = htmlspecialchars($_GET['username']);

使用PDO操作MySQL

# 写法一
$sql = "select * from chapter where id=:id";
// 预处理 SQL 语句
$res = $db->prepare($sql);
// 执行 SQL
if ($res->execute([":id" => 1])) {
// 获取一行结果集
$row = $res->fetch();
print_r($row);
}
# 写法二
$sql = "select * from chapter where id=? and status=?";
// 预处理 SQL 语句
$res = $db->prepare($sql);
// 执行一条预处理语句
if ($res->execute([2, 1])) {
// 获取一行结果集
$row = $res->fetch();
print_r($row);
}

PHP的语法糖即语言结构

echo(), print(),die(),isset(),unset(),include(),include_once(),requ
ire(),require_once(),array(),list(),empty(),eval()

echo的逗号和点号

$foo = 'hello';
$bar = 'world';
echo $foo . $bar;
echo $foo , $bar;

逗号优于点号

脚本运行效率检测

microtime()对脚本的运行计时
参考文档:
https://www.php.net/manual/zh/function.error-reporting.php

判断字符串的长度

$str = 'hello';
if (strlen($str) === 5) echo 'do sth...';
if (!isset($str[5])) echo 'do sth..';

strlen()函数函数执行起来相当快,只返回在zval 结构中存储的已知字符串长
度。但是由于strlen()是函数,多多少少会有些慢,isset()是语法糖,因为函数的调用会在内存里开辟内存空间增加内存消耗

使用[]代替array()

$arr = array();
$arr = [];
$arr = array(1,2,3,4);
$arr = [1,2,3,4];

用 … 定义变长参数函数

function addAll(...$num){
    $sum = '';
    $sum = array_sum($num);
    return $sum;
}
addAll(1,2,3,4,5,6,7);

不用eval()

eval() 能够执行所有的php代码,非常的危险!慎用!

//执行当前文件程序所在目录
eval('echo `pwd`;');

解决方案:

  1. 编译php环境时去除eval()语法糖
  2. 使用Suhosin保护PHP应用系统

PHP代码的优化

if代码块的优化

<?php
if ( 1 == $orderState ) {
$status = 'success';
}else{
$status = 'error';
}
return $status;
#### 完全可以简化成如下代码
//1 先声明变量赋值,2 判断是否等于1,是则怎么样不是则怎么样
$orderState = 'error';
if ( 1 == $orderState ) {
$status = 'success';
}
return $status;

使用三元运算符来替换if

<?php
if ( !empty($_POST['action']) ) {
$action = $_POST['action'];
}else{
$action = 'default';
}
#### 完全可以简化成如下代码
$action = !empty($_POST['action']) ? $_POST['action'] : 'default'

中间结果赋值给变量

<?php
$str = 'this_is_test';
$res = implode('', array_map('ucfirst', explode('_', $str)));
#### 完全可以简化成如下代码
$str = 'this_is_test';
$words = explode('_', $str);
$uWords = array_map('ucfirst', $words);
$res = implode(' ', $uWords);

结果:
PHP良好编码方式与技巧注意事项

使用更加精悍短小的代码

  • 函数的最佳最大长度是 50-150行代码 ,更容易理解也方便修改
  • 函数参数 不超过7个
  • 只做一件事情的函数更易于复用

PHP的编码规范

https://github.com/PizzaLiu/PHP-FIG
1、psr-1编码规范(重要)
https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-1-basic-coding-standard-cn.md

  • PHP代码文件必须以 <?php 或 <?= 标签开始;
  • PHP代码文件必须以 不带BOM的 UTF-8 编码;
  • PHP代码中应该只定义类、函数、常量等声明,或其他会产生 从属效应 的操作(如:生成文件输出以及修改.ini配置文件等),二者只能选其一;
  • 命名空间以及类必须符合 PSR 的自动加载规范:PSR-4;
  • 类的命名必须遵循 StudlyCaps 大写开头的驼峰命名规范;
  • 类中的常量所有字母都必须大写,单词间用下划线分隔;
  • 方法名称必须符合 camelCase 式的小写开头驼峰命名规范。

2、psr-2编码规范(重要)
https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-2-coding-style-guide-cn.md

  • 代码必须遵循 PSR-1 中的编码规范 。
  • 代码必须使用4个空格符而不是 tab键 进行缩进。
  • 每行的字符数应该软性保持在80个之内, 理论上一定不可多于120个, 但一定不能有硬性限制。
  • 每个 namespace 命名空间声明语句和 use 声明语句块后面,必须插入一个空白行。
  • 类的开始花括号({)必须写在其声明后自成一行,结束花括号(})也必须写在其主体后自成一行。
  • 方法的开始花括号({)必须写在函数声明后自成一行,结束花括号(})也必须写在函数主体后自成一行。
  • 类的属性和方法必须添加访问修饰符(private、protected 以及 public), abstract 以及 final 必须声明在访问修饰符之前,而 static 必须声明在访问修饰符之后。
  • 控制结构的关键字后必须要有一个空格符,而调用方法或函数时则一定不能有。
  • 控制结构的开始花括号({)必须写在声明的同一行,而结束花括号(})必须写在主体后自成一行。
  • 控制结构的开始左括号后和结束右括号前,都一定不能有空格符。

以下例子程序简单地展示了以上大部分规范:

<?php
namespace Vendor\Package;

use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class Foo extends Bar implements FooInterface
{
    public function sampleFunction($a, $b = null)
    {
        if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }

    final public static function bar()
    {
        // method body
    }
}

3、psr-3编码规范-定义日志规范(重要)
https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-3-logger-interface-cn.md

4、psr-4命名空间编码规范(重要)
https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-4-autoloader-cn.md