PHP编码标准
PHP标记的WordPress代码结构的一些部分在其风格上是不一致的。 WordPress正在努力通过帮助用户保持一致的风格逐渐改进,以便代码可以一目了然地变得干净,易于阅读。
在为WordPress编写PHP代码时,请注意以下几点:无论是核心编程代码,插件或主题。 这些指南在许多方面与Pear标准类似,但在一些关键方面有所不同。
PHP
单引号和双引号
酌情使用单引号和双引号。 如果您不评估字符串中的任何内容,请使用单引号。 你应该几乎不必在字符串中避免引号,因为你可以替代你的引用样式,像这样:
echo '<a href="/static/link" title="Yeah yeah!">Link name</a>';
echo "<a href='$link' title='$linktitle'>$linkname</a>";
进入属性的文本应该通过esc_attr()
运行,以便单引号或双引号不会结束属性值并使HTML无效并导致安全问题。 有关详细信息,请参阅食典中的数据验证。
缩进
您的缩进应始终反映逻辑结构。 使用真实的选项卡而不是空格,因为这允许客户端具有最大的灵活性。
异常:如果你有一个代码块,如果事情是对齐的,可以更容易读取,使用空格:
[tab]$foo = 'somevalue';
[tab]$foo2 = 'somevalue2';
[tab]$foo34 = 'somevalue3';
[tab]$foo5 = 'somevalue4';
对于关联数组,值应从新行开始。 注意最后一个数组项之后的逗号:建议这样做,因为它可以更容易地改变数组的顺序,并在添加新项时使更清晰的差异。
$my_array = array(
[tab]'foo' => 'somevalue',
[tab]'foo2' => 'somevalue2',
[tab]'foo3' => 'somevalue3',
[tab]'foo34' => 'somevalue3',
);
经验法则:应在起始处使用标签进行缩进,而中间线可用于对齐。
大括号风格
大括号应用于所有块中,如下所示:
if ( condition ) {
action1();
action2();
} elseif ( condition2 && condition3 ) {
action3();
action4();
} else {
defaultaction();
}
此外,如果你有一个很长的块,可以考虑它是否可以分成两个或更多个更短的块或者功能。 如果你认为这么长的一个块是不可避免的,那么请稍等一下,所以人们可以一眼就知道结束大括号是结束的 - 通常情况下这个逻辑块大约是35行,而不是直观的代码 明显可以注释。
大括号应始终使用,即使不需要使用:
if ( condition ) {
action0();
}
if ( condition ) {
action1();
} elseif ( condition2 ) {
action2a();
action2b();
}
foreach ( $items as $item ) {
process_item( $item );
}
请注意,使用大括号只意味着禁止使用单一语句的内联控制结构。 您可以自由地使用控制结构的替代语法(例如,if / endif,while / endwhile) - 特别是在HTML代码嵌入的模板中,例如:
<?php if ( have_posts() ) : ?>
<div class="hfeed">
<?php while ( have_posts() ) : the_post(); ?>
<article id="post-<?php the_ID() ?>" class="<?php post_class() ?>">
<!-- ... -->
</article>
<?php endwhile; ?>
</div>
<?php endif; ?>
使用 elseif
不是 else if
else if 不符合if | elseif 块的规范语法。 因此,使用elseif作为条件。
正则表达式
应该使用Perl兼容的正则表达式(PCRE,preg_函数)优于其POSIX对等体。 切勿使用/ e开关,请改用preg_replace_callback。
对于正则表达式,使用单引号的字符串是最方便的,因为与双引号字符串相反,它们只有两个元素:'和\。
简化PHP开始标签
重要提示:切勿使用简化的PHP开始标签。 始终使用完整的PHP标签。
正确:
<?php ... ?>
<?php echo $var; ?>
不正确:
<? ... ?>
<?= $var ?>
删除每行代码末尾的尾随空格
删除每行代码末尾的尾随空格。 在文件末尾省略关闭的PHP标签是首选。 如果您使用该标签,请确保删除尾随的空格。
空间使用
始终将空格放在逗号之后,并在逻辑,比较,字符串和赋值操作符的两边。
x == 23
foo && bar
! foo
array( 1, 2, 3 )
$baz . '-5'
$term .= 'X'
在if,elseif,foreach,for和switch块的开头和右括号的两侧放置空格。
foreach ( $foo as $bar ) { ...
定义一个函数时,可以这样做:
function my_function( $param1 = 'foo', $param2 = 'bar' ) { ...
调用函数时,请执行以下操作:
my_function( $param1, func_param( $param2 ) );
执行逻辑比较时,可以这样做:
if ( ! $foo ) { ...
当进行类型转换时,请执行以下操作:
foreach ( (array) $foo as $bar ) { ...
$foo = (boolean) $bar;
当引用数组项时,如果索引是一个变量,则只包括索引周围的空格,例如:
$x = $foo['bar']; // correct
$x = $foo[ 'bar' ]; // incorrect
$x = $foo[0]; // correct
$x = $foo[ 0 ]; // incorrect
$x = $foo[ $bar ]; // correct
$x = $foo[$bar]; // incorrect
格式化SQL语句
格式化SQL语句时,如果要保证SQL语句非常复杂,您可以将其分解成多行并缩进。 尽管如此,大多数的声明都是一致的。 始终将语句的SQL部分大写,如UPDATE或WHERE。
更新数据库的函数应该期望它们的参数在传递时缺少SQL斜杠转义。 应尽可能接近查询时间完成转义,最好使用$ wpdb-> prepare()
$ wpdb-> prepare()是一种处理SQL查询的转义,引用和int-cast的方法。 它使用sprintf()格式的一个子集。 示例:
$var = "dangerous'"; // raw data that may or may not need to be escaped
$id = some_foo_number(); // data we expect to be an integer, but we're not certain
$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_title = %s WHERE ID = %d", $var, $id ) );
%s 用于字符串占位符,%d用于整数占位符。 请注意,它们不是“引用”! $ wpdb-> prepare()将照顾转义和引用我们。 这样做的好处是我们不需要记住手动使用esc_sql(),而且很容易看到有没有被转义,因为查询发生时会发生。
有关详细信息,请参阅食典中的数据验证。
数据库查询
避免直接触碰数据库。 如果有一个定义的函数可以获取所需的数据,请使用它。 数据库抽象(使用函数而不是查询)有助于保持您的代码向前兼容,并且在结果缓存在内存中的情况下可以快很多倍。
如果您必须触摸数据库,请通过向wp-hackers邮件列表发送消息与某些开发人员联系。 他们可能想考虑为下一个WordPress版本创建一个功能来覆盖您想要的功能。
命名约定
在变量,动作和函数名中使用小写字母(绝对不是camelCase)。 通过下划线分隔单词。 不要不必要地缩写变量名称; 让代码明确和自我记录。
function some_name( $some_variable ) { [...] }
类名应使用以下划线分隔的大写字。 任何首字母缩略词都应该是大写的。
class Walker_Category extends Walker { [...] }
class WP_HTTP { [...] }
常量应该是大写的,用下划线分隔单词:
define( 'DOING_AJAX', true );
文件名使用小写。 连字符应该分开单词。
my-plugin-name.php
类文件名应基于具有类前缀的类名称,类名称中的下划线用连字符替换,例如WP_Error成为:
class-wp-error.php
此文件命名标准适用于具有类的所有当前和新文件。 有三个文件包含已被移植到BackPress的代码的一个例外:class.wp-dependencies.php,class.wp-scripts.php,class.wp-styles.php。 这些文件是前面加上类,一个点后面的单词类,而不是一个连字符。
包含wp-includes中的模板标签的文件应该将-template附加到名称的末尾,以使它们显而易见。
general-template.php
函数参数的默认值
在调用函数时,将字符串值设为true和false。
// 不正确
function eat( $what, $slowly = true ) {
...
}
eat( 'mushrooms' );
eat( 'mushrooms', true ); // what does true mean?
eat( 'dogfood', false ); // what does false mean? The opposite of true?
由于PHP不支持命名参数,因此标志的值是无意义的,每次遇到如上例所示的函数调用时,我们必须搜索函数定义。 通过使用描述性字符串值而不是布尔值,可以使代码更易读。
// Correct
function eat( $what, $speed = 'slowly' ) {
...
}
eat( 'mushrooms' );
eat( 'mushrooms', 'slowly' );
eat( 'dogfood', 'quickly' );
当需要更多的单词来描述函数参数时,$args数组可能是更好的模式。
// Even Better
function eat( $what, $args ) {
...
}
eat ( 'noodles', array( 'speed' => 'moderate' ) );
命名动态挂钩插值
应使用插值命名动态挂钩,而不是为了可读性和可发现性而连接。
动态挂钩是挂钩,包括其标签名称中的动态值,例如 {$new_status} _ {$post-> post_type}(publish_post)。
钩子标签中使用的变量应该包裹在花括号{和}中,完整的外部标签名称用双引号括起来。 这是为了确保PHP可以正确解析插入字符串中给定的变量的类型。
do_action( "{$new_status}_{$post->post_type}", $post->ID, $post );
在可能的情况下,标签名称中的动态值也应尽可能简洁明了。 $ user_id比$ this-> id更为自我记录。
三元运算符
三元运算符是好的,但是如果声明是真的,那么总是让它们进行测试,而不是假的。 否则,它只会变得混乱。 (一个例外是使用!empty(),因为这里的false的测试一般比较直观。)
例如:
// (if statement is true) ? (do this) : (else, do this);
$musictype = ( 'jazz' == $music ) ? 'cool' : 'blah';
// (if field is not empty ) ? (do this) : (else, do this);
条件
if ( true == $the_force ) {
$victorious = you_will( $be );
}
当进行涉及变量的逻辑比较时,始终将变量放在右侧,并将常量,文字或函数调用放在左侧。 如果双方都不是变量,则顺序并不重要。 (在计算机科学方面,比较中总是试图把左值的左值和右值放在左边。
在上面的例子中,如果你省略了一个等号(承认它,甚至发生在我们最经验的人),你会得到一个解析错误,因为你不能像一个常量那样分配。 如果声明是相反的($the_force = true),则赋值将完全有效,返回1,导致if语句评估为true,您可以追踪该错误一段时间。
有点奇怪,就是阅读。 习惯了,你会的。
这适用于==,!=,===和!==。 对于<,>,<=或> =的Yoda条件显然难以阅读,最好避免。
聪明的代码
一般来说,可读性比聪明或简洁更重要。
isset( $var ) || $var = some_function();
虽然上面的这一行很聪明,但如果你不熟悉它需要一些时间。 所以,只是写这样:
if ( ! isset( $var ) ) {
$var = some_function();
}
###错误控制运算符 @
如PHP文档中所述:
PHP支持一个错误控制运算符:at符号(@)。 在PHP中添加表达式时,可能会忽略该表达式生成的任何错误消息。
虽然这个操作系统确实存在于Core中,但它通常被懒惰地使用,而不是进行适当的错误检查。 它的用法非常不鼓励,即使PHP文档也说明:
警告:目前,“@”错误控制运算符前缀甚至可以关闭将终止脚本执行的关键错误的错误报告。 除此之外,这意味着如果您使用“@”来抑制特定功能的错误,或者它不可用或已输入错误,那么脚本就会在那里死亡,没有指示为什么。
extract()是一个可怕的函数,使代码更难调试,更难理解。 我们应该阻止它的使用和删除我们的所有用途。