PHP编程
编码标准与格式化说明
缩进和行长
使用一个制表符(Tab)进行缩进(不要使用空格!好的IDE可以将制表符转换为伪空格,例如2个、4个空格等)。如果你使用Emacs编辑代码,应将 indent-tabs-mode
设置为 nil
。建议将行宽限制在75-85个字符之间。对于如何拆分一行没有标准规则,应该根据实际情况做出判断。这个规则适用于所有文件类型:PHP、HTML、CSS、JavaScript等。
缩进规则应适用于可能被他人编辑的源文件。在编写生成HTML的代码时,不应考虑HTML输出的视觉效果。
HTML标准
验证
自2006年9月起,我们的文档的DocType将使用XHTML 1.0 Transitional。因此,应该始终使用符合XHTML 1.0标准的HTML。只有在特殊情况下才应有例外。关于XHTML元素的良好参考可以在DevGuru网站找到。
此外,为了确保Internet Explorer 6正确处理盒模型,我们必须在所有页面中使用以下DocType。仅应使用此DocType,不能在其前面添加其他信息。
示例 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
)标签。例如,如果你想要加粗一个词语,不应使用<span>
标签并应用样式,而应使用<strong>
标签。
表格应仅在需要以列形式显示数据时使用。单个单元格的表格不应使用。
常见的例外情况是当标签内容是其他块级元素(如<ul>
)时,可以使用<div>
标签替代<p>
标签。
示例 HTML
<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示例:
示例文章 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>
And here is a small bit of how we style those elements.
#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;
}
This verbosity ensures that other elements are not accidentally styled.
<?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');
}
PHP 语法
请求变量
尽管我们的服务器当前启用了 register_globals
,但 PHP 6 将移除此选项。因此,在新代码中,应该始终使用超全局变量 $_GET
、$_POST
和 $_COOKIE
。只有在确认变量可能通过多种方法提供时,才应使用 $_REQUEST
。
PHP 与 HTML
将不使用诸如 Smarty 之类的“模板系统”。PHP 本身即为一种模板语言。在编写代码时,应该尽量将逻辑放在文件的顶部,输出放在文件的底部。有时这需要对相同的信息进行两次循环。然而,这样的做法会使代码更加可维护。
示例 PHP/HTML 混合代码
<?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 语句
if (condition1 || condition2) {
action1;
} elseif (condition3 && (condition4 || condition5)) {
action2;
} else {
defaultaction;
}
控制语句中的控制关键字与左括号之间应有一个空格,以便与函数调用区分开。
强烈建议在所有情况下都使用花括号,即使在技术上它们是可选的。使用花括号有助于提高可读性,并减少在添加新行时引入逻辑错误的可能性。
示例 switch 语句
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);
函数定义
函数声明
函数声明与函数调用类似,函数的开始花括号应该与函数声明位于同一行。
示例函数定义
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;
}
注释
必须提供完整的内联文档注释块(docblocks)。请阅读 示例文件和头部注释块 部分,了解如何为 PHP 编写 docblocks。更多信息可参见 phpDocumentor 网站。
鼓励使用非文档注释。经验法则是,如果你查看一段代码并觉得“哇,我不想描述它”,那么你需要在忘记如何工作的之前对其进行注释。
C 风格的注释(/* */
)和标准 C++ 注释(//
)都可以使用。不建议使用 Perl / shell 风格的注释(#
)。
包含代码
在无条件包含类文件的地方,使用 require_once
。在有条件包含类文件的地方,使用 include_once
。这两者确保类文件只被包含一次。它们共享相同的文件列表,因此你不需要担心混用——一个使用 require_once
包含的文件不会再次被 include_once
包含。
PHP 代码标签
始终使用 <?php ?>
来标识 PHP 代码,而不是 <? ?>
简写。这是最便于在不同操作系统和服务器设置中使用 PHP 代码的方式。
头部注释块
所有源代码文件必须在每个文件的顶部包含一个“页面级” docblock,并且在每个类或函数上方必须有一个“类级” docblock。
示例 docblocks
<?php
/**
* 文件的简短描述
*
* 文件的详细描述(如果有的话)...
*
* @category CategoryName
* @package PackageName
* @author Original Author <author@example.com>
* @author Another Author <another@example.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/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 文件自 Release 1.2.0 以来可用
* @deprecated 文件在 Release 2.0.0 中弃用
*/
/*
* 在这里放置包含、常量定义和 $_GLOBAL 设置。
* 确保它们有适当的 docblocks,以避免 phpDocumentor
* 将它们视为由页面级 docblock 文档化。
*/
/**
* 类的简短描述
*
* 类的详细描述(如果有的话)...
*
* @category CategoryName
* @package PackageName
* @author Original Author <author@example.com>
* @author Another Author <another@example.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/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 类自 Release 1.2.0 以来可用
* @deprecated 类在 Release 2.0.0 中弃用
*/
class foo
{
}
?>
必需的变量内容标签
简短描述 所有的 docblock 都必须提供简短的描述。描述应该是一个简短的句子,而不是项目名称。请阅读编码标准的示例文件,了解如何写出良好的描述。
@author 没有硬性规则来确定何时将新的代码贡献者添加到给定源文件的作者列表中。一般来说,作者的更改应该属于“实质性”类别(意味着大约 10% 到 20% 的代码更改)。对于重写函数或贡献新逻辑的情况,可以做出例外。
简单的代码重构或 bug 修复不会为添加新的作者提供充分的理由。
@since 当文件或类在包的初始版本后被添加时,必须使用此标签。在初始发布中不要使用此标签。
@deprecated 当文件或类不再使用但出于向后兼容性原因保留时,必须使用此标签。
顺序和间距
为了便于长期可读性,文本和标签必须遵循上述示例中的顺序和间距。此标准借鉴了 JavaDoc 标准。
示例 URL
根据 RFC 2606,所有示例 URL 和电子邮件地址应使用 example.com
、example.org
和 example.net
。
命名约定
类 类应使用具有描述性的名称,尽量避免使用缩写。类名应始终以大写字母开头,并使用混合大小写来分隔单词。
优秀的类名示例:
- Log
- NetFinger
- HTMLUploadError
函数、方法和变量名 函数、方法和变量名应使用 Unix C 风格。如果适用,函数应以包或库名称作为前缀,以避免命名冲突。名称应全部小写,每个新单词由下划线(_
)分隔。
示例:
- connect()
- get_data()
- build_some_widget()
私有类成员 私有类成员(即只允许在同一个类中使用的类成员)前应加一个下划线。例如:
_sort()
_init_tree()
$this->_status
常量和全局变量 常量和全局变量应始终全部大写,用下划线分隔单词。常量名应以所使用的类/包的大写名称为前缀。例如,名为 DB
的包使用的常量应以 DB_
开头。
注意: true
、false
和 null
常量不受全大写规则的限制,必须始终小写。
文件格式
所有脚本必须:
- 存储为 ASCII 文本
- 使用 ISO-8859-1 字符编码
- 使用 Unix 格式,即:
- 行必须仅以换行符(LF)结束。换行符表示为 10(十进制)、012(八进制)和 0A(十六进制)。不要使用回车符(CR),如 Macintosh 系统所用,或回车符/换行符组合(CRLF),如 Windows 系统所用。
- 建议文件的最后一个字符是换行符。即当光标位于文件的最末端时,应该在文本的最后一行下方一行。某些工具(如
diff
)会在文件的最后一个字符不是换行符时发出警告。
示例文件
每个 docblock 示例中包含了写 docblock 注释的许多细节。遵循这些说明非常重要,原因有二。首先,当 docblocks 易于阅读时,用户和开发人员可以快速了解你的代码是做什么的。
请注意垂直和水平的间距,它们是标准的一部分。
<?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 http://www.php.net/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 http://www.php.net/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;
}
}
}
?>