PHP 规范 - Symfony 代码规范
注:规范主要来源于 Symfony Coding Standards ,示例由本人添加,如有错误地方还请多指正。
Symfony 的编码规范是建立在 PSR-1
, PSR-2
and PSR-4
的基础上的。
工具
使用 php-cs-fixer
工具来自动检查编码规范
$ cd your-project/
$ php php-cs-fixer.phar fix -v
结构
每个逗号分隔符之后添加一个空格
$arr = [1, 2, 3];
所有的二元运算符左右都添加一个空格,.
运算符除外
$sum = $a + $b;
$name = $firstName.$lastName;
一元运算符紧跟关联的变量,不需要添加空格
if( !$name )
始终使用全等,除非你需要进行一些类型转换(type juggling)
if($rst === true)
使用 ==
, !=
,===
,和 !==
等判断时,需要将不变的量放在左边,避免意外情况出现
if(10 === $number)
多行数组的最后一项始终添加括号
$arr = [
[1,2],
[1,2],
];
代码块中除了 return
语句之外还包含其他代码,那么 return
语句之前保留一个空行
// 添加空行
function sum($a, $b)
{
$sum = $a + $b;
return $sum;
}
// 只有 return 语句,无需添加空行
function sum($a, $b)
{
return $a + $b;
}
虽然 return;
与 return null
在语法上没有什么区别。但是在使用上要根据具体的场景来:如果函数不需要返回值,则使用 return;
如果需要返回值但是返回值为 null
,就使用 return null
。
function foo() : void
{
return;
}
控制语句不能省略花括号
if($a === 1){
return true;
}
一个文件中只包括一个类。除非是那些不需要在外部实例化的私有的帮助类。
将类的继承和实现的接口声明都写在同一行。
class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
属性要在方法之前声明
class Foo
{
private $bar;
public function foo()
{
}
}
方法默认按照可访问性从高到低排列。除此之外,构造函数 __construct
、测试方法 setUp()
、 tearDown()
始终放在最前面,以提高可读性
public foo() {}
protected bar() {}
private barz() {}
无论方法中包括多少个参数,都应当在同一行声明
public function __construct($command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
{
}
类的实例化始终使用括号
$foo = new Foo();
异常和错误消息字符串必须使用 sprintf
来进行拼接;
throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
当错误类型为 E_USER_DEPRECATED
时,需要添加 @
@trigger_error("foo", E_USER_DEPRECATED);
数组访问器之间不要存在空格
$arr[0][1];
引用的类如果不属于全局命名空间,则每个类都需要使用 use
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
注释文档中 @param
或 @return
如果包括 null
类型,要将 null
放在最后面
/**
* @param int|null
* @return string|null
*/
命名约定
使用驼峰法 (camelCase) 命名变量、方法或函数
$acceptableContentTypes
hasSession();
使用蛇形 (snake_case) 命名法来命名配置参数以及 Twig
模板变量
framework.csrf_protection
http_status_code
为所有的类添加命名空间,类名始终使用大写驼峰 (UpperCamelCase)
<?php
namespace App;
class FooBar {
}
抽象类添加 abstract
前缀,除了 PHPUnit 的 TestCase 抽象类。
abstract class Helper
{
}
接口添加 Interface
后缀
interface ExceptionInterface
{
}
Trait 添加 Trait
后缀
trait FooTrait
{
}
异常添加 Exception
后缀
class CommandNotFoundException
{
}
使用大写驼峰命名 PHP 文件,小写蛇形命名模板引擎或 web 资源文件
FooBar.php
section_layout.html.twig
index.scss
文档注释或者类型转换中,使用 bool
而不是 boolean
或 Boolean
,使用 int
而不是 integer
,使用 float
而不是 double
或 real
(int) $a;
(bool) $a;
(float) $a;
服务
这部分主要是介绍 symfony
框架的 services
使用规范
- 服务的名称使用类的完全限定名,如
App\EventSubscriber\UserSubscriber
; - 存在多个同名服务时,主要的服务使用完全限定名,其他服务使用小写下划线命名。也可以用
.
符号进行分组,例如something.service_name
,fos_user.something.service_name
; - 参数名使用小写,环境变量名使用
%env(VARIABLE_NAME)%
- 公共的服务添加类关联,例如关联
Symfony\Component\Something\ClassName
为something.service_name
文档
为所有的类、方法以及函数添加 PHPDoc
注释。
根据类型来进行分组,不同类型之间空一行
/**
* @FooBar(1)
* @FooBar(2)
*
* @var int
*/
private $var;
无返回值时,省略 @return
注释
/**
* Configures the current command.
*/
protected function configure()
{
}
不要使用 @package
和 @subpackage
标记。
块注释时即使只有一个标签,也不要写在同一行,比如 /** {@inheritdoc} */
/**
* @inheritdoc
*/
function testInheritDocValid1($test)
{
}
当添加一个新的类或者大量改动一个已存在类时,也许要添加一个 @author
标记来留下个人的联系方式。
/**
* @author Jérôme Tamarelle <jerome@tamarelle.net>
*/
示例
官方给的示例
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Acme;
/**
* Coding standards demonstration.
*/
class FooBar
{
const SOME_CONST = 42;
/**
* @var string
*/
private $fooBar;
/**
* @param string $dummy Some argument description
*/
public function __construct($dummy)
{
$this->fooBar = $this->transformText($dummy);
}
/**
* @return string
*
* @deprecated
*/
public function someDeprecatedMethod()
{
@trigger_error(sprintf('The %s() method is deprecated since vendor-name/package-name 2.8 and will be removed in 3.0. Use Acme\Baz::someMethod() instead.', __METHOD__), E_USER_DEPRECATED);
return Baz::someMethod();
}
/**
* Transforms the input given as first argument.
*
* @param bool|string $dummy Some argument description
* @param array $options An options collection to be used within the transformation
*
* @return string|null The transformed input
*
* @throws \RuntimeException When an invalid option is provided
*/
private function transformText($dummy, array $options = [])
{
$defaultOptions = [
'some_default' => 'values',
'another_default' => 'more values',
];
foreach ($options as $option) {
if (!in_array($option, $defaultOptions)) {
throw new \RuntimeException(sprintf('Unrecognized option "%s"', $option));
}
}
$mergedOptions = array_merge(
$defaultOptions,
$options
);
if (true === $dummy) {
return null;
}
if ('string' === $dummy) {
if ('values' === $mergedOptions['some_default']) {
return substr($dummy, 0, 5);
}
return ucwords($dummy);
}
}
/**
* Performs some basic check for a given value.
*
* @param mixed $value Some value to check against
* @param bool $theSwitch Some switch to control the method's flow
*
* @return bool|void The resultant check if $theSwitch isn't false, void otherwise
*/
private function reverseBoolean($value = null, $theSwitch = false)
{
if (!$theSwitch) {
return;
}
return !$value;
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: