PHP代码_PHP整洁之道
摘录自 Robert C. Martin的Clean Code 书中的软件工程师的原则 ,适用于php。 这不是风格指南。 这是一个关于开发可读、可复用并且可重构的PHP软件指南。 并不是这里所有的原则都得遵循,甚至很少的能被普遍接受。 这些虽然只是指导,但是都是Clean Code作者多年总结出来的。
变量
Bad:
$ymdstr = $moment->format(‘y-m-d‘);
Good:
$currentDate = $moment->format(‘y-m-d‘);
Bad:
getUserInfo();
getClientData();
getCustomerRecord();
Good:
getUser();
Bad:
// What the heck is 86400 for?
addExpireAt(86400);
Good:
// Declare them as capitalized `const` globals.
interface DateGlobal {
const SECONDS_IN_A_DAY = 86400;
}
addExpireAt(DateGlobal::SECONDS_IN_A_DAY);
Bad:
$address = ‘One Infinite Loop, Cupertino 95014‘;
$cityZipCodeRegex = ‘/^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/‘;
preg_match($cityZipCodeRegex, $address, $matches);
saveCityZipCode($matches[1], $matches[2]);
Good:
$address = ‘One Infinite Loop, Cupertino 95014‘;
$cityZipCodeRegex = ‘/^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/‘;
preg_match($cityZipCodeRegex, $address, $matches);
list(, $city, $zipCode) = $matchers;
saveCityZipCode($city, $zipCode);
Bad:
$l = [‘Austin‘, ‘New York‘, ‘San Francisco‘];
foreach($i=0; $i<count($l); $i++) {
oStuff();
doSomeOtherStuff();
// ...
// ...
// ...
// 等等`$l` 又代表什么?
dispatch($l);
}
Good:
$locations = [‘Austin‘, ‘New York‘, ‘San Francisco‘];
foreach($i=0; $i<count($locations); $i++) {
$location = $locations[$i];
doStuff();
doSomeOtherStuff();
// ...
// ...
// ...
dispatch($location);
});
Bad:
$car = [
‘carMake‘ => ‘Honda‘,
‘carModel‘ => ‘Accord‘,
‘carColor‘ => ‘Blue‘,
];
function paintCar(&$car) {
$car[‘carColor‘] = ‘Red‘;
}
Good:
$car = [
‘make‘ => ‘Honda‘,
‘model‘ => ‘Accord‘,
‘color‘ => ‘Blue‘,
];
function paintCar(&$car) {
$car[‘color‘] = ‘Red‘;
}
Bad:
function createMicrobrewery($name = null) {
$breweryName = $name ?: ‘Hipster Brew Co.‘;
// ...
}
Good:
function createMicrobrewery($breweryName = ‘Hipster Brew Co.‘) {
// ...
}
函数
Bad:
function createMenu($title, $body, $buttonText, $cancellable) {
// ...
}
Good:
class menuConfig() {
public $title;
public $body;
public $buttonText;
public $cancellable = false;
}
$config = new MenuConfig();
$config->title = ‘Foo‘;
$config->body = ‘Bar‘;
$config->buttonText = ‘Baz‘;
$config->cancellable = true;
function createMenu(MenuConfig $config) {
// ...
}
Bad:
function emailClients($clients) {
foreach ($clients as $client) {
$clientRecord = $db->find($client);
if($clientRecord->isActive()) {
email($client);
}
}
}
Good:
function emailClients($clients) {
$activeClients = activeClients($clients);
array_walk($activeClients, ‘email‘);
}
function activeClients($clients) {
return array_filter($clients, ‘isClientActive‘);
}
function isClientActive($client) {
$clientRecord = $db->find($client);
return $clientRecord->isActive();
}
Bad:
function addToDate($date, $month) {
// ...
}
$date = new \DateTime();
// It‘s hard to to tell from the function name what is added
addToDate($date, 1);
Good:
function addMonthToDate($month, $date) {
// ...
}
$date = new \DateTime();
addMonthToDate(1, $date);
Bad:
function parseBetterJSAlternative($code) {
$regexes = [
// ...
];
$statements = split(‘ ‘, $code);
$tokens = [];
foreach($regexes as $regex) {
foreach($statements as $statement) {
// ...
}
}
$ast = [];
foreach($tokens as $token) {
// lex...
}
foreach($ast as $node) {
// parse...
}
}
Good:
function tokenize($code) {
$regexes = [
// ...
];
$statements = split(‘ ‘, $code);
$tokens = [];
foreach($regexes as $regex) {
foreach($statements as $statement) {
$tokens[] = /* ... */;
});
});
return tokens;
}
function lexer($tokens) {
$ast = [];
foreach($tokens as $token) {
$ast[] = /* ... */;
});
return ast;
}
function parseBetterJSAlternative($code) {
$tokens = tokenize($code);
$ast = lexer($tokens);
foreach($ast as $node) {
// parse...
});
}
Bad:
function showDeveloperList($developers) {
foreach($developers as $developer) {
$expectedSalary = $developer->calculateExpectedSalary();
$experience = $developer->getExperience();
$githubLink = $developer->getGithubLink();
$data = [
$expectedSalary,
$experience,
$githubLink
];
render($data);
}
}
function showManagerList($managers) {
foreach($managers as $manager) {
$expectedSalary = $manager->calculateExpectedSalary();
$experience = $manager->getExperience();
$githubLink = $manager->getGithubLink();
$data = [
$expectedSalary,
$experience,
$githubLink
];
render($data);
}
}
Good:
function showList($employees) {
foreach($employees as $employe) {
$expectedSalary = $employe->calculateExpectedSalary();
$experience = $employe->getExperience();
$githubLink = $employe->getGithubLink();
$data = [
$expectedSalary,
$experience,
$githubLink
];
render($data);
}
}
Bad:
$menuConfig = [
‘title‘ => null,
‘body‘ => ‘Bar‘,
‘buttonText‘ => null,
‘cancellable‘ => true,
];
function createMenu(&$config) {
$config[‘title‘] = $config[‘title‘] ?: ‘Foo‘;
$config[‘body‘] = $config[‘body‘] ?: ‘Bar‘;
$config[‘buttonText‘] = $config[‘buttonText‘] ?: ‘Baz‘;
$config[‘cancellable‘] = $config[‘cancellable‘] ?: true;
}
createMenu($menuConfig);
Good:
$menuConfig = [
‘title‘ => ‘Order‘,
// User did not include ‘body‘ key
‘buttonText‘ => ‘Send‘,
‘cancellable‘ => true,
];
function createMenu(&$config) {
$config = array_merge([
‘title‘ => ‘Foo‘,
‘body‘ => ‘Bar‘,
‘buttonText‘ => ‘Baz‘,
‘cancellable‘ => true,
], $config);
// config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
// ...
}
createMenu($menuConfig);
Bad:
function createFile(name, temp = false) {
if (temp) {
touch(‘./temp/‘.$name);
} else {
touch($name);
}
}
Good:
function createFile($name) {
touch(name);
}
function createTempFile($name) {
touch(‘./temp/‘.$name);
}
Bad:
// Global variable referenced by following function.
// If we had another function that used this name, now it‘d be an array and it could break it.
$name = ‘Ryan McDermott‘;
function splitIntoFirstAndLastName() {
$name = preg_split(‘/ /‘, $name);
}
splitIntoFirstAndLastName();
var_dump($name); // [‘Ryan‘, ‘McDermott‘];
Good:
$name = ‘Ryan McDermott‘;
function splitIntoFirstAndLastName($name) {
return preg_split(‘/ /‘, $name);
}
$name = ‘Ryan McDermott‘;
$newName = splitIntoFirstAndLastName(name);
var_export($name); // ‘Ryan McDermott‘;
var_export($newName); // [‘Ryan‘, ‘McDermott‘];
Bad:
function config() {
return [
‘foo‘: ‘bar‘,
]
};
Good:
class Configuration {
private static $instance;
private function __construct($configuration) {/* */}
public static function getInstance() {
if(self::$instance === null) {
self::$instance = new Configuration();
}
return self::$instance;
}
public function get($key) {/* */}
public function getAll() {/* */}
}
$singleton = Configuration::getInstance();
Bad:
if ($fsm->state === ‘fetching‘ && is_empty($listNode)) {
// ...
}
Good:
function shouldShowSpinner($fsm, $listNode) {
return $fsm->state === ‘fetching‘ && is_empty(listNode);
}
if (shouldShowSpinner($fsmInstance, $listNodeInstance)) {
// ...
}
Bad:
function isdomNodeNotPresent($node) {
// ...
}
if (!isDOMNodeNotPresent($node)) {
// ...
}
Good:
function isDOMNodePresent($node) {
// ...
}
if (isDOMNodePresent($node)) {
// ...
}
Bad:
class Airplane {
// ...
public function getCruisingAltitude() {
switch (this.type) {
case ‘777‘:
return $this->getMaxAltitude() - $this->getPassengerCount();
case ‘Air Force One‘:
return $this->getMaxAltitude();
case ‘Cessna‘:
return $this->getMaxAltitude() - $this->getFuelExpenditure();
}
}
}
Good:
class Airplane {
// ...
}
class Boeing777 extends Airplane {
// ...
public function getCruisingAltitude() {
return $this->getMaxAltitude() - $this->getPassengerCount();
}
}
class AirForceOne extends Airplane {
// ...
public function getCruisingAltitude() {
return $this->getMaxAltitude();
}
}
class Cessna extends Airplane {
// ...
public function getCruisingAltitude() {
return $this->getMaxAltitude() - $this->getFuelExpenditure();
}
}
Bad:
function travelToTexas($vehicle) {
if ($vehicle instanceof Bicycle) {
$vehicle->peddle($this->currentLocation, new Location(‘texas‘));
} else if ($vehicle instanceof Car) {
$vehicle->drive($this->currentLocation, new Location(‘texas‘));
}
}
Good:
function travelToTexas($vehicle) {
$vehicle->move($this->currentLocation, new Location(‘texas‘));
}
Bad:
function combine($val1, $val2) {
if (is_numeric($val1) && is_numeric(val2)) {
return val1 + val2;
}
throw new \Exception(‘Must be of type Number‘);
}
Good:
function combine(int $val1, int $val2) {
return $val1 + $val2;
}
Bad:
function oldRequestModule($url) {
// ...
}
function newRequestModule($url) {
// ...
}
$req = new newRequestModule();
inventoryTracker(‘apples‘, $req, ‘www.inventory-awesome.io‘);
Good:
function newRequestModule($url) {
// ...
}
$req = new newRequestModule();
inventoryTracker(‘apples‘, $req, ‘www.inventory-awesome.io‘);本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!