PHP 程式設計/編碼規範
使用一個製表符縮排(不要使用空格!好的 IDE 可以將製表符轉換為偽空格 - 2、4 等)。如果你使用 Emacs 編輯程式碼,你應該將 indent-tabs-mode 設定為 nil。建議你在大約 75-85 個字元處換行。關於換行最佳方式沒有標準規則;請使用你的判斷。這適用於所有檔案型別:PHP、HTML、CSS、JavaScript 等。
縮排規則應該應用於將由其他人編輯的原始檔。生成 HTML 程式碼的視覺效果不應該在編寫生成 HTML 程式碼時考慮。
截至 2006 年 9 月,我們文件上的 DocType 將為 XHTML 1.0 Transitional。因此,應始終使用符合 XHTML 1.0 標準的相容 HTML。例外情況應僅是例外情況。可以在 DevGuru 上找到 XHTML 元素的良好參考。
此外,為了確保 Internet Explorer 6 正確執行盒子模型,我們必須在所有頁面上使用以下 DocType。只應使用此文件型別。在其之前不應放置任何其他資訊。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
儘可能使用標準 HTML 元素。應始終避免使用 "Div Soup"。"Div Soup" 指的是在不需要的情況下使用 div(或 span)的 HTML。例如,如果你需要使一個詞加粗,不要使用<span>標籤並應用樣式。相反,使用<strong>標籤。
表格僅應在需要將資料以列形式顯示時使用。永遠不要使用單格表格。
一個常見的例外是需要使用<div>標籤代替<p>標籤,當標籤的內容將是其他塊級元素(如<ul>.
<div class="article">
<h4>this is the headline</h4>
<p>This is the body with an <strong>important word</strong>.</p>
<small>Posted 2 days ago</small>
</div>
應避免使用內聯樣式!
CSS 檔案中的樣式應儘可能具體。應該始終嘗試避免使用裸類名。如果你正在為包含一個容器的物件設定樣式,你的樣式應該引用容器以及正在設定樣式的元素。CSS 中的樣式越冗長,你就越不可能意外地搞亂其他頁面上的其他元素。
為元素設定樣式的最有效方法是為容器內的該型別元素設定樣式。如果只有一個元素需要以特殊方式設定樣式,則應為其分配一個 ID 並使用該 ID 設定樣式,最好是使用一個容器。
以下是我們側邊欄中的一些 HTML 程式碼
<div id="sidebar">
<ul class="blue" id="categories">
<label><a href="/categories/">Categories</a></label>
<li class="current"><a href="/categories/Computer/39.html">Computer</a></li>
<li><a href="/categories/Electronics/142.html">Electronics</a></li>
<li><a href="/categories/Gaming-Toys/186.html">Gaming & Toys</a></li>
<li><a href="/categories/Office-Supplies/182.html">Office & Supplies</a></li>
<li><a href="/categories/DVDs-Music-Books/178.html">DVDs, Music, Books</a></li>
<li><a href="/categories/Clothing-Accessories/202.html">Clothing & Accessories</a></li>
<li><a href="/categories/Home-Garden/196.html">Home & Garden</a></li>
<li><a href="/categories/Everything-Else/231.html">Everything Else</a></li>
<li><a href="/categories/Store-Events/40.html">Store Events</a></li>
<li><a href="http://dealnews.com/coupons/">Coupons</a></li>
<li><a href="http://dealnews.com/deals/The-new-dealnews-Gift-Finder-sort-by-price-/101164.html">Gift Ideas</a></li>
</ul>
<ul class="gray">
<label>Stores</label>
<li><a href="/online-stores/Amazon-com/313/">Amazon.com</a></li>
<li><a href="/online-stores/Buy-com/233/">Buy.com</a></li>
<li><a href="/online-stores/Circuit-City-com/296/">CircuitCity.com</a></li>
<li><a href="/online-stores/Dell-Home/638/">Dell Home</a></li>
<li><a href="/online-stores/Best-Buy-com/560/">BestBuy.com</a></li>
<li><a href="/online-stores/Comp-USA-com/595/">CompUSA.com</a></li>
<li><a href="/online-stores/Dell-Small-Business/604/">Dell Small Business</a></li>
<li><a href="/online-stores/Newegg-com/504/">Newegg.com</a></li>
<li><a href="/online-stores/Meritline/303/">Meritline</a></li>
</ul>
</div>
以下是如何為這些元素設定樣式的一小部分。
#sidebar ul {
list-style: none;
margin: 0 0 15px 0;
padding: 0 0 4px 0;
}
#sidebar ul label {
color: White;
display: block;
font-weight: bold;
font-size: 100%;
margin: 0 0 4px 0;
padding: 6px 8px 4px 10px;
}
#sidebar ul label a, #sidebar ul label a:visited {
color: White;
text-decoration: none;
display: block;
}
#sidebar ul li {
font-size: 95%;
margin: 0 0 4px 0;
padding: 2px 8px 2px 12px;
}
#sidebar ul li a {
display: block;
color: Black;
text-decoration: none;
}
#sidebar ul.gray {
background: #DDDDE2 url('http://images.dealnews.com/dealnews/backgrounds/sidebar/footer_light_gray.png') no-repeat 0 100%;
}
#sidebar ul.gray label {
color: White;
background: #75758A url('http://images.dealnews.com/dealnews/backgrounds/sidebar/header_dark_gray.png') no-repeat 0 0;
}
#sidebar ul.blue {
background: #EBEBFA url('http://images.dealnews.com/dealnews/backgrounds/sidebar/footer_light_blue.png') no-repeat 0 100%;
}
#sidebar ul.blue label {
color: White;
background: #2E2E6B url('http://images.dealnews.com/dealnews/backgrounds/sidebar/header_dark_blue.png') no-repeat 0 0;
}
#sidebar #categories li.current {
color: #FF9A00;
font-weight: bold;
}
這種冗長確保不會意外地為其他元素設定樣式。
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('display_startup_errors', true);
require_once('functions/base_url.php');
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
// database connect file check
!file_exists('functions/Connect_db.php') ? header('Location: ' . $base_url . 'functions/databaseSettings.php') : '';
require_once('functions/Connect_db.php');
require_once('functions/SqlQuery.php');
require_once('functions/CheckerFn.php');
require_once('currencyAndIcons.php');
require_once('SendMail.php');
class Action
{
public $db;
public $checker;
public $theDay;
public function __construct()
{
$this->db = new SqlQuery;
$this->theDay = date('Y-m-d');
$this->checker = new CheckerFn;
}
// company settings manage add, update
public function manageSettings()
{
$logo = '';
$companyName = $this->checker->c_valid($_POST['companyName']);
$userCurrency = $this->checker->c_valid($_POST['userCurrency']);
$smtpHost = $this->checker->c_valid($_POST['smtpHost']);
$smtpPort = $this->checker->c_valid($_POST['smtpPort']);
$smtpAuth = $this->checker->c_valid($_POST['smtpAuth']);
$contactEmail = $this->checker->c_valid($_POST['contactEmail']);
$emailPassword = $this->checker->c_valid($_POST['emailPassword']);
$startingDate = $this->checker->c_valid($_POST['startingDate']);
if (!empty($_FILES['logo']['name'])) {
$logo_array = $_FILES['logo'];
$name = explode('.', $logo_array['name']);
$logo = md5(rand() . time()) . '.' . end($name);
} else {
$logo = $this->checker->c_valid($_POST['preLogo']);
}
$data = [
'companyName' => $companyName,
'companyLogo' => $logo,
'userCurrency' => $userCurrency,
'smtpHost' => $smtpHost,
'smtpPort' => $smtpPort,
'smtpAuth' => $smtpAuth,
'contactEmail' => $contactEmail,
'emailPassword' => $emailPassword,
'startingDate' => $startingDate
];
// check smtp connection
$smtpCheck = fsockopen($smtpHost, $smtpPort, $errno, $errstr, 6);
if (is_bool($smtpCheck) && $smtpCheck === false) {
$_SESSION['smtpInvalid'] = $data;
return $this->checker->redirect('settings');
}
if (isset($_SESSION['atFirstSettings'])) {
$insertSuccess = $this->db->insertAction('company_settings', $data);
if (isset($insertSuccess)) {
unset($_SESSION['atFirstSettings']);
move_uploaded_file($logo_array['tmp_name'], 'img/' . $logo);
return $this->checker->redirect('registerPartner');
}
} elseif (isset($_POST['settingsEdit'])) {
$id = $this->checker->c_valid($_POST['settingsEdit']);
$success = $this->db->updateAction('company_settings', $data, ['id' => $id]);
if (isset($success)) {
if ($logo !== $_POST['preLogo']) {
$_SESSION['logo'] = $logo;
unlink('img/' . $_POST['preLogo']);
move_uploaded_file($logo_array['tmp_name'], 'img/' . $logo);
}
$_SESSION['settingsUpdated'] = 1;
$_SESSION['currency'] = currency_symbol($userCurrency);
return $this->checker->redirect('manageSettings');
}
}
}
// user account recovery method if user forgot user account informetion
public function getAccount($getBy)
{
// user account information get by email
$getAccount;
if ($getBy === '010') {
$email = $this->checker->c_valid($_POST['email']);
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailExist = $this->db->get_row("fms_admin", ['email' => $email]);
if (isset($emailExist) && $emailExist) {
$getAccount = $emailExist;
} else {
$_SESSION['doesNotExist_e'] = $email;
return $this->checker->redirect('forgotPassword');
}
} else {
$_SESSION['invalidEmail'] = $email;
return $this->checker->redirect('forgotPassword');
}
}
// to get user account information by user full name & birthday
if ($getBy === '101') {
$fullName = $this->checker->c_valid($_POST['fn']) . ' ' . $this->checker->c_valid($_POST['ln']);
$birthday = $this->checker->c_valid($_POST['birthday']);
$userExist = $this->db->get_row('fms_admin', ['fullName' => $fullName, 'birthday' => $birthday]);
if (isset($userExist)) {
$userExist = $getAccount;
} else {
$_SESSION['actionfaild'] = 1;
return $this->checker->redirect('forgotPassword');
}
}
// check user is exists
if (isset($getAccount)) {
$email = $getAccount['email'];
$userName = $getAccount['userName'];
$fullName = $getAccount['fullName'];
$sec = json_decode($getAccount['userInfo_sc']); // secure informetion container
$password = md5(sha1($userName . rand()));
$sec_one = md5(sha1($password . rand()));
$sec_two = md5(sha1($sec_one . rand()));
$setLink = $this->checker->base_url() . 'resetPassword.php?' . $userName . '=' . $password . '&' . $sec_one . '=' . $sec_two;
$getEmail = $this->db->get_row("company_settings");
$accountInf = [$sec->userName_sc, $sec->password_sc];
// this is mail data to send a mail
$emailData = ['getEmail' => $getEmail, 'toMail' => $email, 'fullName' => $fullName, 'link' => $setLink, 'accountInf' => $accountInf];
// mail sender class
$emailClass = new SendMail;
$sendResult = $emailClass->send_mail($emailData);
// check, mail send is success
if (isset($sendResult) && intval($sendResult) === 1) {
$sec = $this->checker->secureInfoProcess($sec);
$id = $getAccount['id'];
array_push($sec, [$sec_one, $sec_two]);
$upd = ['userInfo_sc' => json_encode($sec)];
$edit = $this->db->updateAction('fms_admin', $upd, ['id' => $id]);
if (isset($edit)) {
$_SESSION['emailSend'] = $email;
return $this->checker->redirect('login');
} else {
$_SESSION['actionfaild'] = 3;
return $this->checker->redirect('forgotPassword');
}
} else {
$_SESSION['actionfaild'] = 2;
return $this->checker->redirect('forgotPassword');
}
}
}
// user account reset
public function resetPassword($updateUser = null)
{
if (isset($_SESSION['userInformetion'])) {
$info = $_SESSION['userInformetion'];
$ridirectLink = $_SESSION['ridirect_l'];
$protocol = isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : 'http';
$ridirectLink = $protocol . '://' . $_SERVER['HTTP_HOST'] . $ridirectLink;
if (empty($_POST['passworda']) || empty($_POST['passwordr'])) {
$_SESSION['emptyField'] = 1;
return header('Location: ' . $ridirectLink);
} else {
if ($_POST['passworda'] === $_POST['passwordr']) {
$pas = $this->checker->c_valid($_POST['passworda']);
$secure = json_decode($info['userInfo_sc']);
$secure_od = $secure;
$secure = $secure->oldPassword_sc;
if (empty($secure)) {
$password = $pas;
} else {
if (in_array($pas, $secure) || $pas === $secure_od->password_sc) {
$_SESSION['old_p'] = 1;
return header('Location: ' . $ridirectLink);
} else {
$password = $pas;
}
}
if (isset($password)) {
$getEmail = $this->db->get_row("company_settings");
$email = !isset($updateUser) ? $info['email'] : $this->checker->c_valid($_POST['email']);
$newPassword = $password;
$fullName = !isset($updateUser) ? $info['fullName'] : $this->checker->c_valid($_POST['fn']) . ' ' . $this->checker->c_valid($_POST['ln']);
$userName = !isset($updateUser) ? $secure_od->userName_sc : $updateUser;
$accountInf = [$userName, $newPassword];
$emailData = ['getEmail' => $getEmail, 'toMail' => $email, 'fullName' => $fullName, 'accountInf' => $accountInf];
// mail sender class
$emailClass = new SendMail;
$sendResult = $emailClass->send_mail($emailData);
if (isset($sendResult) && intval($sendResult) === 1) {
$password = password_hash($password, PASSWORD_BCRYPT, ["cost" => 12]);
$password_sc = $newPassword;
$oldPassword_sc = $secure_od->oldPassword_sc;
array_push($oldPassword_sc, $secure_od->password_sc);
$new_userInfo_sc = ['userName_sc' => $userName, 'password_sc' => $password_sc, 'oldPassword_sc' => $oldPassword_sc];
$upd = ['password' => $password, 'userInfo_sc' => json_encode($new_userInfo_sc)];
unset($_SESSION['ridirect_l']);
unset($_SESSION['userInformetion']);
if (isset($updateUser)) {
return $upd;
} else {
$passwordUpdate = $this->db->updateAction('fms_admin', $upd, ['id' => $info['id']]);
if (isset($passwordUpdate)) {
$_SESSION['resetSuccess'] = $email;
return $this->checker->redirect('login');
}
}
}
}
} else {
$_SESSION['doesNot_m'] = 1;
return header('Location: ' . $ridirectLink);
}
}
}
}
// create user account
public function createUserNamePassword($securAction = null)
{
if (isset($securAction) && $securAction === 8994723402 && !empty($_POST)) {
$info = $_SESSION['userinfo'];
$userName = $this->checker->c_valid($_POST['userName']);
$password = $this->checker->c_valid($_POST['password']);
$userInfo_sc = json_encode(array('userName_sc' => $userName, 'password_sc' => $password, 'oldPassword_sc' => []));
if (ctype_alnum($userName)) {
$email = $info['email'];
$fullName = $info['fullName'];
$accountInf = [$userName, $password];
$getEmail = $this->db->get_row("company_settings");
$emailData = ['getEmail' => $getEmail, 'toMail' => $email, 'fullName' => $fullName, 'accountInf' => $accountInf];
// mail sender class
$emailClass = new SendMail;
$sendResult = $emailClass->send_mail($emailData);
if (isset($sendResult) && intval($sendResult) === 1) {
$userName = md5(sha1($userName));
$password = password_hash($password, PASSWORD_BCRYPT, ["cost" => 12]);
$upData = [
'userName' => $userName,
'password' => $password,
'userInfo_sc' => $userInfo_sc
];
$success = $this->db->updateAction('fms_admin', $upData, ['id' => $info['id']]);
if (isset($success)) {
unset($_SESSION['userinfo']);
$_SESSION['a_create_success'] = $email;
return $this->checker->redirect('login');
} else {
return $this->checker->redirect('setUserNamePassword');
}
}
}
}
}
// user informetion add or eidt manager
function manageUsers()
{
if (isset($_SESSION['ridirect_l'])) {
$ridirectLink = $_SESSION['ridirect_l'];
$protocol = isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : 'http';
$ridirectLink = $protocol . '://' . $_SERVER['HTTP_HOST'] . $ridirectLink;
}
if (isset($_POST['fn']) && filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
$fullName = $this->checker->c_valid($_POST['fn']) . ' ' . $this->checker->c_valid($_POST['ln']);
$currency = isset($_POST['currency']) ? $_POST['currency'] : '';
$percentage = $this->checker->c_valid($_POST['percentage']);
$birthday = $this->checker->c_valid($_POST['birthday']);
$email = $this->checker->c_valid($_POST['email']);
$gender = $this->checker->c_valid($_POST['gender']);
$userRoll = $this->checker->c_valid($_POST['userRoll']);
$file_name = '';
if (!empty($_FILES['img']['name'])) {
$photo_array = $_FILES['img'];
$name = explode('.', $photo_array['name']);
$file_name = md5(rand() . time()) . '.' . end($name);
}
if (isset($_POST['register']) || isset($_POST['atFirstRegisterUser'])) {
$userName = md5(sha1($email . rand()));
$password = md5(sha1($email . rand() . $fullName));
$setLink = $this->checker->base_url() . 'setUserNamePassword.php?' . $userName . '=' . $password;
$getEmail = $this->db->get_row("company_settings");
$emailData = ['getEmail' => $getEmail, 'toMail' => $email, 'fullName' => $fullName, 'link' => $setLink];
$emailClass = new SendMail;
$sendResult = $emailClass->send_mail($emailData);
if (isset($sendResult) && intval($sendResult) === 1) {
$insertD = ['fullName' => $fullName, 'email' => $email, 'userName' => $userName, 'password' => $password, 'userInfo_sc' => '', 'percentage' => $percentage, 'photo' => $file_name, 'birthday' => $birthday, 'gender' => $gender, 'userRoll' => $userRoll, 'a_date' => $this->theDay, 'u_date' => ''];
$insertSuccess = $this->db->insertAction('fms_admin', $insertD);
if (isset($insertSuccess)) {
$_SESSION['install'] = 1;
$_SESSION['registerSuccess'] = $email;
move_uploaded_file($photo_array['tmp_name'], 'uploadFiles/userPhoto/' . $file_name);
$page = isset($_POST['register']) ? 'userRegistration' : 'login';
return $this->checker->redirect($page);
} else {
$_SESSION['sorry'] = 'action failde';
return $this->checker->redirect('userRegistration');
}
} else {
$exists_p = $this->db->get("fms_admin");
if (isset($exists_p)) {
return $this->checker->redirect('userRegistration');
}
return $this->checker->redirect('registerPartner');
}
}
if (isset($_POST['editUserInfo'])) {
$preEdit = $_SESSION['userInformetion'];
$upFile = empty($_FILES['img']['name']) ? $preEdit['photo'] : $file_name;
$upd = ['fullName' => $fullName, 'email' => $email, 'percentage' => $percentage, 'photo' => $upFile, 'birthday' => $birthday, 'gender' => $gender, 'userRoll' => $userRoll, 'u_date' => $this->theDay];
if (isset($_POST['passworda']) && !password_verify($_POST['passworda'], $preEdit['password'])) {
$userName = $this->checker->c_valid($_POST['userName']);
$updatePass = $this->resetPassword($userName);
if (is_array($updatePass) && !empty($updatePass)) {
$resetSuccess = 1;
$upd['userName'] = md5(sha1($userName));
$upd['password'] = $updatePass['password'];
$upd['userInfo_sc'] = $updatePass['userInfo_sc'];
} else {
return header('Location: ' . $ridirectLink);
}
} elseif (isset($_POST['userName'])) {
$userName = $this->checker->c_valid($_POST['userName']);
$upd['userName'] = md5(sha1($userName));
}
$id = $preEdit['id'];
$edit = $this->db->updateAction('fms_admin', $upd, ['id' => $id]);
if (isset($edit)) {
$_SESSION['editSuccess'] = 1;
isset($resetSuccess) ? $_SESSION['resetSuccess'] = $email : false;
$user = $this->db->get_row('fms_admin', ['id' => $id]);
unset($user['password']);
unset($user['userName']);
unset($user['userInfo_sc']);
$_SESSION['userinfo']['id'] === $id ? $_SESSION['userinfo'] = $user : false;
if ($upFile === $file_name) {
move_uploaded_file($photo_array['tmp_name'], 'uploadFiles/userPhoto/' . $upFile);
unlink('uploadFiles/userPhoto/' . $preEdit['photo']);
}
return $this->checker->redirect('users');
} else {
$_SESSION['editfaild'] = 1;
}
}
} else {
$_SESSION['invalidEmail'] = $_POST['email'];
if (isset($_POST['editUserInfo'])) {
return header('Location: ' . $ridirectLink);
} else {
return $this->checker->redirect('userRegistration');
}
}
}
// add user Earns
public function cashInsert()
{
$source = $this->checker->c_valid($_POST['source']);
$amount = $this->checker->c_valid($_POST['amount']);
if (ctype_digit($amount)) {
$id = $_SESSION['userinfo']['id'];
$insertData = ['id' => $id, 'earnSource' => $source, 'amount' => $amount, 'currency' => '', 'ba_date' => $this->theDay, 'bu_date' => ''];
$result = $this->db->insertAction('fms_bank', $insertData);
if (isset($result)) {
$_SESSION['success_ms'] = 1;
return $this->checker->redirect('bankCash');
}
} else {
$_SESSION['invalidAmount'] = $amount;
return $this->checker->redirect('bankCash');
}
}
// edit user Earns
public function cashUpdate()
{
$source = $this->checker->c_valid($_POST['source']);
$bankId = $this->checker->c_valid($_POST['updateId']);
$amount = $this->checker->c_valid($_POST['amount']);
if (!empty($bankId)) {
$up_data = ['earnSource' => $source, 'amount' => $amount, 'bu_date' => $this->theDay];
$result = $this->db->updateAction('fms_bank', $up_data, ['bankId' => $bankId]);
if (isset($result)) {
$_SESSION['info_message'] = 1;
return $this->checker->redirect('cashDetails');
}
}
}
// Expense maange add or eidt
public function manageExpense()
{
$amount = $this->checker->c_valid($_POST['amount']);
if (isset($_SESSION['costInsert'])) {
$memoData = [];
$memoName = $_FILES['memo']['name'];
$tmpName = $_FILES['memo']['tmp_name'];
for ($i = 0; $i < count($memoName); $i++) {
$memoName[$i];
$tmpName[$i];
if (!empty($memoName[$i])) {
$name = explode('.', $memoName[$i]);
$fileName = md5(rand() . $name[0] . time()) . '.' . end($name);
$memoData[] = $fileName;
move_uploaded_file($tmpName[$i], 'uploadFiles/memo/' . $fileName);
} else {
$memoData[] = '';
}
}
$id = $_SESSION['userinfo']['id'];
$costDetails = json_encode(['c_productName' => $_POST['costCn'], 'c_amount' => $_POST['costCa'], 'c_memo' => $memoData]);
$insertData = ['id' => $id, 'cst_amount' => $amount, 'cst_currency' => '', 'cost_details' => $costDetails, 'cst_a_date' => $this->theDay, 'cst_u_date' => ''];
$result = $this->db->insertAction('fms_cost', $insertData);
if (isset($result)) {
$_SESSION['info_message'] = 'submited';
return $this->checker->redirect('costManage');
}
}
if (isset($_SESSION['costEdit'])) {
$memoData = [];
$upId = $_SESSION['costEdit'];
$memoName = $_FILES['memo']['name'];
$tmpName = $_FILES['memo']['tmp_name'];
$preEdit = $this->db->get_row('fms_cost', ['cst_id' => $upId]);
$oldMemo = json_decode($preEdit['cost_details']);
$upc_memo = isset($oldMemo->c_memo) ? $oldMemo->c_memo : [];
for ($i = 0; $i < count($memoName); $i++) {
$memoName[$i];
$tmpName[$i];
if (!empty($memoName[$i])) {
$name = explode('.', $memoName[$i]);
$fileName = md5(rand() . $name[0] . time()) . '.' . end($name);
$memoData[] = $fileName;
isset($upc_memo[$i]) ? unlink('uploadFiles/memo/' . $upc_memo[$i]) : false;
move_uploaded_file($tmpName[$i], 'uploadFiles/memo/' . $fileName);
} else {
$memoData[] = isset($upc_memo[$i]) ? $upc_memo[$i] : '';
}
}
$costDetails = json_encode(['c_productName' => $_POST['costCn'], 'c_amount' => $_POST['costCa'], 'c_memo' => $memoData]);
$upData = ['id' => $preEdit['id'], 'cst_amount' => $amount, 'cost_details' => $costDetails, 'cst_u_date' => $this->theDay];
$updateSuccess = $this->db->updateAction('fms_cost', $upData, ['cst_id' => $upId]);
if (isset($updateSuccess)) {
unset($_SESSION['costEdit']);
if ($upFile === $cst_memo) {
move_uploaded_file($photo_array['tmp_name'], 'uploadFiles/memo/' . $upFile);
!empty($preEdit['cst_memo']) ? unlink('uploadFiles/memo/' . $preEdit['cst_memo']) : false;
}
$_SESSION['info_message'] = ' update ' . $cst_memo_up;
return $this->checker->redirect('userCostDetails');
}
}
}
}
$action = new Action;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_SESSION['atFirstSettings'])) {
return $action->manageSettings(0000010113112);
} elseif (isset($_SESSION['registerPartner'])) {
unset($_SESSION['registerPartner']);
return $action->manageUsers();
} elseif (isset($_SESSION['userinfo'])) {
$userInfo = $_SESSION['userinfo'];
if (isset($_SESSION['createUserNamePassword'])) {
unset($_SESSION['createUserNamePassword']);
return $action->createUserNamePassword(0103010113112);
}
if (isset($_POST['getBy']) && !empty($_POST['getBy'])) {
$getBy = $action->checker->c_valid($_POST['getBy']);
if ($getBy === '101' || $getBy === '010') {
return $action->getAccount($getBy);
}
}
if (isset($_SESSION['resetAccount404'])) {
return $action->resetAccount(0103010112);
}
if (isset($_SESSION['csrf']) && $_SESSION['csrf'] === $_POST['cc']) {
unset($_SESSION['csrf']);
return $action->resetPassword();
}
// sec_a = secure action
if (isset($_SESSION['sec_a'], $_POST['sec_a']) && $_SESSION['sec_a'] === $_POST['sec_a']) {
if ($_POST['settingsEdit']) {
return $action->manageSettings(0000010113112);
}
if (isset($_POST['updateEmail'])) {
return $action->updateEmail();
}
if (isset($_SESSION['bank'])) {
unset($_SESSION['bank']);
if (isset($_SESSION['cashInsert'])) {
unset($_SESSION['cashInsert']);
return $action->cashInsert();
}
if (isset($_SESSION['cashUpdate'])) {
unset($_SESSION['cashUpdate']);
return $action->cashUpdate();
}
}
if (isset($_SESSION['userAction'])) {
unset($_SESSION['userAction']);
return $action->manageUsers();
}
if (isset($_SESSION['costAction'])) {
unset($_SESSION['costAction']);
return $action->manageExpense();
}
}
return $action->checker->redirect('404');
} else {
return $action->checker->redirect('login');
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_SESSION['userinfo']) && isset($_SESSION['sec_a']) && isset($_GET) && !empty($_GET)) {
$userInfo = $_SESSION['userinfo'];
$valueId = array_values($_GET);
$keysId = array_keys($_GET);
// to delete Earn row
if (isset($_SESSION['bank']) && $_SESSION['sec_a'] === $valueId[1]) {
$id = $action->checker->makeId($valueId[0]);
$pre_delete = $action->db->get_row('fms_bank', ['bankId' => $id]);
$delete = $action->db->deleteAction('fms_bank', ['bankId' => $id]);
if (isset($delete)) {
$currency = $pre_delete["currency"] === 'bdt' ? 'Tk' : '$';
$_SESSION['info_message'] = [($pre_delete["bankId"]), ($pre_delete["amount"] . $currency)];
return $action->checker->redirect('cashDetails');
}
}
// to delete user
if (isset($_SESSION['user']) && $_SESSION['sec_a'] === $keysId[0]) {
$id = $action->checker->makeId($valueId[0]); // make user id
$user = $action->db->get_row('fms_admin', ['id' => $id]); // user information
$deleteSucccess = $action->db->deleteAction('fms_admin', ['id' => $id]);
if (isset($deleteSucccess)) {
unlink('uploadFiles/userPhoto/' . $user['photo']);
if ($userInfo['id'] === $id) {
return $action->checker->redirect('login');
} else {
$_SESSION['deleteSucccess'] = $user['fullName'];
return $action->checker->redirect('users');
}
}
}
return $action->checker->redirect('404');
} else {
return $action->checker->redirect('404');
}
雖然我們的伺服器目前啟用了 register_globals,但 PHP 6 將刪除此選項。因此,在新程式碼中,你應該始終使用超級全域性變數 $_GET、$_POST 和 $_COOKIE。$_REQUEST 僅應在確定變數可以使用多種方法提供時使用。
不會使用 Smarty 等 "模板系統"。PHP 本身就是一種模板語言。應盡力將程式碼排列為將邏輯放在檔案頂部,並將輸出放在檔案底部。有時這需要迴圈相同的資訊兩次。但是,這將使程式碼更易於維護。
<?php
$sql = "select * from publications";
$PHEWSDB->query($sql);
while($rec = $PHEWSDB->fetch_array()){
$publications[] = $rec;
}
?>
<ul>
<label>Publications</label>
<?php foreach($publications as $pub) { ?>
<li><?=$pub["name"]?></li>
<?php } ?>
</ul>
這些包括if, for, while, switch等。
if (condition1 || condition2) {
action1;
} elseif (condition3 && (condition4 || condition5)) {
action2;
} else {
defaultaction;
}
控制語句應該在控制關鍵字和左括號之間有一個空格,以將它們與函式呼叫區分開來。
強烈建議你始終使用花括號,即使在它們在技術上可選的情況下也是如此。使用它們可以提高可讀性,並減少在新增新行時引入邏輯錯誤的可能性。
switch (condition) {
case 1:
action1;
break;
case 2:
action2;
break;
default:
defaultaction;
break;
}
函式應該在函式名稱、左括號和第一個引數之間沒有空格;逗號和每個引數之間有空格,最後一個引數、右括號和分號之間沒有空格。
$var = foo($bar, $baz, $quux);
如上所示,在用於將函式的返回值分配給變數的等號兩側應該有一個空格。在相關分配塊的情況下,可以插入更多空格以提高可讀性。
$short = foo($bar); $long_variable = foo($baz);
函式定義
[edit | edit source]函式宣告類似於函式呼叫,左括號與函式宣告位於同一行。
function foo_func($arg1, $arg2 = '') {
if (condition) {
statement;
}
return $val;
}
帶預設值的實參放在實參列表的最後。如果適用,請始終嘗試從函式返回有意義的值。
function connect(&$dsn, $persistent = false) {
if (is_array($dsn)) {
$dsninfo = &$dsn;
} else {
$dsninfo = DB::parseDSN($dsn);
}
if (!$dsninfo || !$dsninfo['phptype']) {
return $this->raiseError();
}
return true;
}
Comments
[edit | edit source]必須提供完整的內聯文件註釋塊(docblocks)。請閱讀示例檔案和頭註釋塊部分,瞭解為 PHP 編寫 docblocks 的具體方法。更多資訊可以在phpDocumentor網站上找到。
強烈建議使用非文件註釋。一個經驗法則是,如果你檢視一段程式碼並認為“哇,我不想嘗試描述它”,那麼你需要在忘記它如何工作之前對其進行註釋。
C 樣式註釋(/* */)和標準 C++ 註釋(//)都可以。使用 Perl/shell 樣式註釋(#)強烈不鼓勵。
Including Code
[edit | edit source]在任何無條件包含類檔案的地方,使用require_once. 在任何有條件包含類檔案的地方,使用include_once. 這兩種方法都將確保類檔案只被包含一次。它們共享相同的檔案列表,因此您無需擔心混合它們 - 透過require_once包含的檔案不會被include_once.
PHP Code Tags
[edit | edit source]始終使用<?php ?>來分隔 PHP 程式碼,而不是<? ?>簡寫。這是在不同作業系統和伺服器設定上包含 PHP 程式碼的最便攜方式。
Header Comment Blocks
[edit | edit source]所有原始碼檔案都應在每個檔案的頂部包含一個“頁面級”docblock,以及在每個類或函式上方立即包含一個“類級”docblock。
<?php
/**
* Short description for file
*
* Long description for file (if any)...
*
* @category CategoryName
* @package PackageName
* @author Original Author <author@example.com>
* @author Another Author <another@example.com>
* @copyright 1997-2005 The PHP Group
* @license https://php.net.tw/license/3_0.txt PHP License 3.0
* @version CVS: $Id:$
* @link http://pear.php.net/package/PackageName
* @see NetOther, Net_Sample::Net_Sample()
* @since File available since Release 1.2.0
* @deprecated File deprecated in Release 2.0.0
*/
/*
* Place includes, constant defines and $_GLOBAL settings here.
* Make sure they have appropriate docblocks to avoid phpDocumentor
* construing they are documented by the page-level docblock.
*/
/**
* Short description for class
*
* Long description for class (if any)...
*
* @category CategoryName
* @package PackageName
* @author Original Author <author@example.com>
* @author Another Author <another@example.com>
* @copyright 1997-2005 The PHP Group
* @license https://php.net.tw/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/PackageName
* @see NetOther, Net_Sample::Net_Sample()
* @since Class available since Release 1.2.0
* @deprecated Class deprecated in Release 2.0.0
*/
class foo
{
}
?>
Required Tags That Have Variable Content
[edit | edit source]Short Descriptions
[edit | edit source]所有 docblocks 必須提供簡短描述。它們應該是一句話,而不是專案的名稱。請閱讀編碼標準的示例檔案,瞭解如何編寫良好的描述。
@author
[edit | edit source]沒有硬性規定來確定何時將新的程式碼貢獻者新增到給定原始檔的作者列表中。一般來說,他們的更改應該屬於“實質性”類別(意味著大約 10% 到 20% 的程式碼更改)。可以對重寫函式或貢獻新邏輯進行例外處理。
簡單的程式碼重組或錯誤修復不會為作者列表中新增新的人員提供理由。
@since
[edit | edit source]在包首次釋出後新增檔案或類時,此標記是必需的。不要在初始釋出中使用它。
@deprecated
[edit | edit source]當檔案或類不再使用但出於向後相容性而保留時,此標記是必需的。
Order and Spacing
[edit | edit source]為了方便原始碼的長期可讀性,文字和標記必須符合上述示例中提供的順序和間距。此標準是從 JavaDoc 標準中採用的。
Example URLs
[edit | edit source]根據RFC 2606,對於所有示例 URL 和電子郵件地址,使用 example.com、example.org 和 example.net。
Naming Conventions
[edit | edit source]Classes
[edit | edit source]類應該被賦予描述性的名稱。儘可能避免使用縮寫。類名應該始終以大寫字母開頭,並使用混合大小寫來分隔單詞。
一些好的類名示例是
Log NetFinger HTMLUploadError
Functions, Methods and Variable Names
[edit | edit source]函式、方法和變數名應該使用 Unix C 樣式命名。如果適用,函式應該以包或庫名稱作為字首,以避免名稱衝突。名稱應該全部小寫,每個新“單詞”用下劃線(_)分隔。一些例子
connect() get_data() build_some_widget() $i $count $temp_array
私有類成員(指僅在宣告它們的同一類中使用的類成員)前面有一個下劃線。例如
_sort() _init_tree() $this->_status
Constants and Global Variables
[edit | edit source]常量和全域性變數應該始終為全大寫,用下劃線分隔單詞。常量名稱以它們所用類的/包的大寫名稱為字首。例如,名為DB的包使用的常量以DB_.
開頭。注意:true、false 和 null 常量除外,它們始終為小寫。
File Formats
[edit | edit source]所有指令碼必須
- 以 ASCII 文字形式儲存
- 使用 ISO-8859-1 字元編碼
- 以 Unix 格式,這意味著
- 行只能以換行符(LF)結尾。換行符表示為序號 10、八進位制 012 和十六進位制 0A。不要使用像 Macintosh 電腦那樣的回車符(CR)或像 Windows 電腦那樣的回車符/換行符組合(CRLF)。
- 建議檔案中的最後一個字元為換行符。這意味著,當游標位於檔案的末尾時,它應該位於文字的最後一行下方。某些實用程式,例如 diff,如果檔案中的最後一個字元不是換行符,則會抱怨。
示例中的每個文件塊都包含許多關於編寫文件塊註釋的細節。遵循這些說明很重要,原因有兩個。首先,當文件塊易於閱讀時,使用者和開發人員可以快速瞭解您的程式碼的功能。
請注意垂直和水平間距。它們是標準的一部分。
<?php
/**
* Short description for file
*
* Long description for file (if any)...
*
* @category CategoryName
* @package PackageName
* @author Original Author <author@example.com>
* @author Another Author <another@example.com>
* @copyright 1997-2005 The PHP Group
* @license https://php.net.tw/license/3_0.txt PHP License 3.0
* @version CVS: $Id:$
* @link http://pear.php.net/package/PackageName
* @see NetOther, Net_Sample::Net_Sample()
* @since File available since Release 1.2.0
* @deprecated File deprecated in Release 2.0.0
*/
/**
* This is a "Docblock Comment," also known as a "docblock." The class'
* docblock, below, contains a complete description of how to write these.
*/
require_once 'PEAR.php';
/**
* Methods return this if they succeed
*/
define('NET_SAMPLE_OK', 1);
/**
* The number of objects created
* @global int $GLOBALS['NET_SAMPLE_COUNT']
*/
$GLOBALS['NET_SAMPLE_COUNT'] = 0;
/**
* An example of how to write code to PEAR's standards
*
* Docblock comments start with "/**" at the top. Notice how the "/"
* lines up with the normal indenting and the asterisks on subsequent rows
* are in line with the first asterisk. The last line of comment text
* should be immediately followed on the next line by the closing asterisk
* and slash and then the item you are commenting on should be on the next
* line below that. Don't add extra lines. Please put a blank line
* between paragraphs as well as between the end of the description and
* the start of the @tags. Wrap comments before 80 columns in order to
* ease readability for a wide variety of users.
*
* Docblocks can only be used for programming constructs that allow them
* (classes, properties, methods, defines, includes, globals). See the
* phpDocumentor documentation for more information.
* http://phpdoc.org/docs/HTMLSmartyConverter/default/phpDocumentor/tutorial_phpDocumentor.howto.pkg.html
*
* The Javadoc Style Guide is an excellent resource for figuring out
* how to say what needs to be said in docblock comments. Much of what is
* written here is a summary of what is found there, though there are some
* cases where what's said here overrides what is said there.
* http://java.sun.com/j2se/javadoc/writingdoccomments/index.html#styleguide
*
* The first line of any docblock is the summary. Make them one short
* sentence, without a period at the end. Summaries for classes, properties
* and constants should omit the subject and simply state the object,
* because they are describing things rather than actions or behaviors.
*
* Below are the tags commonly used for classes. @category through @access
* are required. The remainder should only be used when necessary.
* Please use them in the order they appear here. phpDocumentor has
* several other tags available, feel free to use them.
*
* @category CategoryName
* @package PackageName
* @author Original Author <author@example.com>
* @author Another Author <another@example.com>
* @copyright 1997-2005 The PHP Group
* @license https://php.net.tw/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/PackageName
* @see NetOther, Net_Sample::Net_Sample()
* @since Class available since Release 1.2.0
* @deprecated Class deprecated in Release 2.0.0
*/
class Net_Sample
{
/**
* The status of foo's universe
*
* Potential values are 'good', 'fair', 'poor' and 'unknown'.
*
* @var string
*/
var $foo = 'unknown';
/**
* The status of life
*
* Note that names of private properties or methods must be
* preceeded by an underscore.
*
* @var bool
* @access private
*/
var $_good = true;
/**
* Registers the status of foo's universe
*
* Summaries for methods should use 3rd person declarative rather
* than 2nd person imperative, beginning with a verb phrase.
*
* Summaries should add description beyond the method's name. The
* best method names are "self-documenting", meaning they tell you
* basically what the method does. If the summary merely repeats
* the method name in sentence form, it is not providing more
* information.
*
* Summary Examples:
* + Sets the label (preferred)
* + Set the label (avoid)
* + This method sets the label (avoid)
*
* Below are the tags commonly used for methods. A @param tag is
* required for each parameter the method has. The @return and
* @access tags are mandatory. The @throws tag is required if the
* method uses exceptions. @static is required if the method can
* be called statically. The remainder should only be used when
* necessary. Please use them in the order they appear here.
* phpDocumentor has several other tags available, feel free to use
* them.
*
* The @param tag contains the data type, then the parameter's
* name, followed by a description. By convention, the first noun in
* the description is the data type of the parameter. Articles like
* "a", "an", and "the" can precede the noun. The descriptions
* should start with a phrase. If further description is necessary,
* follow with sentences. Having two spaces between the name and the
* description aids readability.
*
* When writing a phrase, do not capitalize and do not end with a
* period:
* + the string to be tested
*
* When writing a phrase followed by a sentence, do not capitalize the
* phrase, but end it with a period to distinguish it from the start
* of the next sentence:
* + the string to be tested. Must use UTF-8 encoding.
*
* Return tags should contain the data type then a description of
* the data returned. The data type can be any of PHP's data types
* (int, float, bool, string, array, object, resource, mixed)
* and should contain the type primarily returned. For example, if
* a method returns an object when things work correctly but false
* when an error happens, say 'object' rather than 'mixed.' Use
* 'void' if nothing is returned.
*
* Here's an example of how to format examples:
* <sample>
* require_once 'Net/Sample.php';
*
* $s = new Net_Sample();
* if (PEAR::isError($s)) {
* echo $s->getMessage() . "\n";
* }
* </sample>
*
* @param string $arg1 the string to quote
* @param int $arg2 an integer of how many problems happened.
* Indent to the description's starting point
* for long ones.
*
* @return int the integer of the set mode used. FALSE if foo
* foo could not be set.
* @throws exceptionclass [description]
*
* @access public
* @static
* @see Net_Sample::$foo, Net_Other::someMethod()
* @since Method available since Release 1.2.0
* @deprecated Method deprecated in Release 2.0.0
*/
function set_foo($arg1, $arg2 = 0) {
/*
* This is a "Block Comment." The format is the same as
* Docblock Comments except there is only one asterisk at the
* top. phpDocumentor doesn't parse these.
*/
if ($arg1 == 'good' || $arg1 == 'fair') {
$this->foo = $arg1;
return 1;
} else if ($arg1 == 'poor' && $arg2 > 1) {
$this->foo = 'poor';
return 2;
} else {
return false;
}
}
}
?>