注:規範主要來源於 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 協議》,轉載必須註明作者和本文連結