1、
$A="Hello "; functionprint_A() { $A = "phpmysql !!"; global $A; global 全局變量 函數是獨立的模塊 $A外界定義的 echo $A; } echo $A; //Hello print_A(); //Hello 在你將$A定義為全局變量的時候,并未修改$A的值
2、
$email = ‘langwan@thizlinux.com.cn’; $str = ___strstr_($email,‘@’); $info = __explode__(‘.’,$str); ___print_r_($info); 輸出結果為: Array ([0] => @thizlinux [1]=>com[2]=>cn) 輸出結果是一個數組
3、定義一個404跳轉
header("Http/1.1 404 Not Found");
5、不用PHP函數實現字符串反轉
Notice: Uninitialized string offset: 7 in D:\wamp\www\phpTest\test.php on line 7 //數組越界的問題 $str = 'abcdefg'; $len = strlen($str); $return = ''; for($i=$len-1;$i>=0;$i--){ $return.=$str{$i}; } echo $return;
6、寫出五種獲取.jpg或者jpg的的方法
$dir = 'Uploads/img.upload.jpg'; substr($str,-3); //echo substr($dir,strrpos($dir,'.')); //echo strrchr($dir,'.'); //$arr = explode('.',$dir); //print_r(array_pop($arr)); //$p = pathinfo($dir); //print_r($p); //print_r($p['extension']); //$new_str = strrev($dir); //echo $new_str."\n"; //$a = strrev(substr($new_str,0,strpos($new_str,'.'))); //echo $a;
7、請寫一個函數,實現以下功能: 字符串“open_door” 轉換成 “OpenDoor”、”make_by_id” 轉換成 ”MakeById”
function o($str){ $arr = explode('_',$str); $str = ''; foreach($arr as $v){ $str.=ucfirst($v); } return $str; } echo o('make_by_id');
方法2:
function ucfirstTest($str){ return ucfirst($str); } function test($str){ $arr = explode('_',$str); $new_arr = array_map('ucfirstTest',$arr); $str = implode('',$new_arr); return $str; } $str = 'open_str'; echo test($str);
8、用PHP打印出前一天的時間格式是2006-5-10 22:21:21(2分)
echo date('Y-m-d H:i:s',strtotime('-1 days')); 9、mb_substr($str,1,10,'utf-8'); 10、修改session的生存時間 session_set_cookie_params
11、strpos====這里要注意的就是strpos返回的是0,因為他在第0,所以要用===判斷
$str = 'https://www.baidu.com'; $str1 = 'https://'; print_r(strpos($str,$str1)); if(strpos($str,$str1) !== false){ }
12、下面輸出是什么,主要考的就是運算符的優先級和++ --的問題
$x = 5; echo $x; 5 echo "<br />"; echo $x+++$x++; 5+6 = 11 echo "<br />"; echo $x; 11 echo "<br />"; echo $x---$x--; 7-6 = 1 echo "<br />"; echo $x; 5
13、array_merge合并的時候,傳入的都是數組,如果一個不是數組就會返回null
14、$x = true and false; var_dump($x); true
15、PHP的可變變量:$a = c; $$a = 10; $c = 10;
<form action="test.php" method="post"> <input type="text" name="a" id=""/> <input type="text" name="b" id=""/> <input type="submit" value="aa"/> </form> foreach($_POST as $k=>$v){ ${$k} = $v; } echo 'a'.isset($a)?$a:''.PHP_EOL; echo 'b'.isset($b)?$b:''.PHP_EOL;
16、什么是自連接:無限分類就是自己鏈接自己查詢
17、html動態生成的節點加點擊事件
$(".h3").on("click","h3",{foo:"文本:"},function(event){ alert(event.data.foo+this.textContent); });
18、$url = 'http://www.test.com.cn/abc/de/fg.php?id=1'; 獲取php或者.php
$b = parse_url($url); //php解析url地址,parse_str是解析字符串parse_str($str,$out) echo "<pre>"; /**array(4) { ["scheme"]=> string(4) "http" ["host"]=> string(15) "www.test.com.cn" ["path"]=> string(14) "/abc/de/fg.php" ["query"]=> string(4) "id=1" } */ $arr = $b['path']; ///abc/de/fg.php echo substr($arr,strpos($arr,'.')); $new_arr = explode('.',$arr); echo end($new_arr); 高效 $arr = parse_url('http://www.sina.com.cn/abc/de/fg.php?id=1'); $result=pathinfo(arr['path']);var_dump($arr); array(4) { ["dirname"]=> string(7) "/abc/de" ["basename"]=> string(6) "fg.php" ["extension"]=> string(3) "php" ["filename"]=> string(2) "fg" } var_dump($result['extension']);
19、mkdir和is_dir的使用
$dir = './liuzhu/test/'; if(is_dir($dir)){ //如果存在就返回true file_put_contents($dir.'1.txt',$url); }else{ //如果不存在就創建,true的這個參數是可以循環創建 if(mkdir($dir,0777,true)){ file_put_contents($dir.'1.txt',$url); }; }
20、定義一個字符串,然后獲取第一個字符
$str = 'abcdef'; $one = $str[1] || $str{1} 這兩種方式
21、下面輸出no
$v = 1; $m = 2; $l = 3; if( $l > $m > $v){ echo "yes"; }else{ echo "no"; }
首先$l>$m返回的是一個true 然后true>1 就返回了null
22、獲取圖片的信息
getimagesize () 獲取圖片的尺寸 Imagesx () 獲取圖片的寬度 Imagesy () 獲取圖片的高度 23、$_SERVER; $host = $_SERVER['HTTP_HOST']; //localhost $self = $_SERVER['PHP_SELF']; ///phpTest/test.php echo $host.$self; //localhost/phpTest/test.php echo $_SERVER['REMOTE_ADDR']; //客戶端ip地址 echo $_SERVER['SERVER_ADDR']; //服務端ip地址 echo $_SERVER['REQUEST_URI']; ///phpTest/test.php
24、php.ini 中safe mod關閉 影響哪些函數和參數,至少寫6個?
move_uploaded_file() exec() system() passthru() popen() fopen() mkdir() rmdir() rename() unlink() copy() chgrp() chown() chmod() touch() symlink() link() parse_ini_file() set_time_limit() max_execution_time mail()
25、isset() 、empty()與is_null的區別
1、當變量未定義時,is_null() 和“參數本身”是不允許作為參數判斷的,會報Notice警告錯誤;
2、empty , isset首先都會檢查變量是否存在,然后對變量值進行檢測。而is_null 和 “參數本身”只是直接檢查變量值,是否為null,因此如果變量未定義就會出現錯誤!
3、isset():僅當null和未定義,返回false;
4、empty():""、0、"0"、NULL、FALSE、array(),未定義,均返回true;
5、is_null():僅判斷是否為null,未定義報警告;
6、變量本身作為參數,與empty()一致,但接受未定義變量時,報警告;
26、http_build_query()
$arr = [ 'title'=>'nihao', 'content'=>'world' ]; $str = http_build_query($arr); var_dump($str);
27、curl file_get_contents() socket三種方式實現提交數據
28、var_dump(((bool)'all')+1); 2 true=1 1+1=2
29、如果你一個整型integer超出了范圍,那么就會被轉成float
30、如果你定義的了一個數組,那么當你unset這個數組的時候,你又定義了一個$a[5] 那么這個鍵應該是從5開始
31、如何保證你的api接口的安全性
32、這個地方考察是先用后加的問題
$a = 3; $b = 5; if($a == 3 || $b == 7){ echo $a++; echo $b++; } echo $a.' '.$b; 3 5 4 6
33、count除去數組和實例化對象 其他的count()都是1 null是0
①技術更新較快:根據市場的需求,不斷迭代更新.
②技術涉及面廣:除了 PHP,還會用到 Python,GO 等其他的一些語言;數據庫中 MySQL,nosql 是最頻繁使用的(當然也有的公司會用 oracle,但是 PHP 一般都是以 MySQL 為主),服務器端使用 Linux(少部分公司會用到 Unix),還經常涉及到服務器安全、系統安全等安全方面的技術.
③分布式:從前的單一的機器上運行,現在是分散到不同機器上,最后將數據集中匯總。集中式向分布式進行發展是由需求來推動.
④高并發、集群(高可用集群)、負載均衡:由并發問題采用集群進行處理,其中,集群會涉及服務器的主從以及分布問題,使用負載均衡。(權重高低)高可用是對用戶而言,用戶的服務不中斷(系統升級,服務不中斷,公司電商系統的部分更新等)。
⑤海量數據:每年商家的各類活動(雙 11,雙 12 等等)訂單量、瀏覽數、商品量、活動相關數據都將會超級大超級多(一般隨同高并發出現).
⑥業務復雜:電商業務并不簡單:并不是商品展示出來后,簡單地加入購物車后購買就完成了。除此以外后臺業務邏輯也是相當復雜,比如優惠(包郵、滿減),秒殺,搶購等.
⑦系統安全:系統上線必須通過系統安全部門審核通過,安全性問題正逐步地被放到臺面上,而且很多企業對這塊相當重視.
本商城系統是一個綜合性的 B2C 平臺,類似京東商城、天貓商城.
用戶:
商家:
以上是大部分常用模塊,如有其它模塊自行補充。根據上圖的體系架構,一層層的進行歸納記憶,從項目——模塊——功能一點點的往深入熟悉記憶,并且加以理解.
產品經理:1 人,確定需求以及給出產品原型圖。
項目經理:1 人,項目管理。
UI 設計 :1 人, 制作項目原型效果圖。
前端團隊:1 人,根據產品經理給出的原型制作靜態頁面。
后端團隊:3 人,實現產品功能。
運維 :1 人 ,負責公司運維項目的系統。
測試團隊:2 人,測試所有的功能。(小公司不會有測試)
(上述是以團隊為單位,有的公司技術部不止一個團隊,還有運維、UI、交互設計師等等,視情況而定)
前端:HTML CSS JS/JQ(Bootstrap、node.js、angluar.js 等可以了解下) AJAX
PHP:PHP+MySQL session 和 cookie Nosql(redis memcache mongdb) 接口技術 緩存技術 優化技術等等
服務器方面:Linux Nginx
開發環境:WAMP 或者是 LAMP 比較常見,除此以外還有 LNMP 等
(簡歷中或者是面試中盡量不要提及版本號,如果要寫則需要把版本號對齊,否則不要寫版本號)
我們公司之前主要以實體店為主,進行批發與零售,業務也相對比較傳統。為了適應市場需求,增強公司競爭力,提升業務績效,另一方面,也為基于互聯網的商務模式創新奠定基礎。所以開始 xxx 商城建設項目,其中包含商品管理、訂單管理、類目管理、客戶管理、合作商管理、客服管理、購物平臺、內容管理等,很大程度上分擔了人工的壓力,對提高客戶服務效率和客戶滿意度能夠起到較好的作用。(先大體的描述下項目,然后能夠挑一兩個自己最為熟悉的模塊進行敘述)
框架方面:從大處進行描述,比如本項目是屬于電商項目,采用的是 TP 框架,運用php+MySQL+Apache 進行開發。因為 TP 框架是開源的、輕量級的,所以用起來更加方便快捷,從效率和成本方面來講都是性價比比較高的,所以那時候團隊決定用這個框架進行開發。然后再從框架的一些優點特性進行說明下,讓面試官覺得你對這個框架很了解技術:描述技術時首先用從自己比較熟悉的模塊入手(比如說注冊驗證時會用到的 JS 技術、正則匹配、ajax 無刷新驗證等等),然后由此慢慢的向其他方面的技術進行拓展,在說具體技術的時候如果能說到目前比較新或者是比較有難度的技術,能夠讓面 試官眼前一亮,這樣能為自己的面試增加不少分。
①最為明顯的一點,在傳統的架構中,如果某個功能需要進行維護,那么我們必須停掉整個服務,這對于公司的運營會造成損失。分布式系統在核心功能模塊使用單獨服務器,維護部分模塊不影響用戶的其他操作。
②在海量數據處理方面,傳統架構顯得比較乏力;分布式系統架構采用服務器集群,使用負載均衡,海量數據處理游刃有余!
③在性能(檢索)以及維護方面,分布式系統架構也有較為明顯的優勢。
? 商品模塊:其中包括商品管理,類型管理,屬性管理,欄目管理等等
? 訂單模塊:其中包括下單,退單,庫存,收貨人信息等
? 會員模塊:會員注冊,會員信息管理,會員等級管理,會員權限等
? 購物車模塊:購物車數據存儲,增刪改查購物車商品,清空購物車等
? 提交訂單頁面:提交用戶的訂單信息, 處理并發問題。
? 個人中心:包括用戶的登錄,個人信息的管理,收貨地址的管理,用戶所下的訂單的管理
? 支付模塊:支付方式管理(在線支付、貨到付款)等
在項目中主要負責相關功能的開發,主要有:
1) 后臺管理系統:主要實現商品管理、商品規格參數管理、訂單管理、會員管理等、CMS(內容管理系統)等,并且提供了跨域支持;
2) 前臺系統:主要是面向用戶訪問,使用 js、ajax 進行前后臺數據交互(一般是用 json 格式數據返回)
3) 會員登錄:提供和用戶信息相關的接口,比如說用戶注冊、查詢等接口(登錄時需要進行多重驗證,特別注意安全方面)
4) 訂單功能:主要是提供和訂單相關的業務接口,在訂單系統了做了嚴格的數據校驗以及高并發寫的支持(這里可以說使用隊列實現),并且使用了定時器實現對下單的時間控制,比如說關閉超時未付款的訂單;
5) 搜索功能:主要是提供商品的搜索,可以采用 Sphinx 全文搜索,當然也有其他的搜索方式;
6) 會員系統:主要是維護用戶的信息,已購買訂單、優惠券、系統消息、修改密碼、綁定手機等功能;
7) 緩存:主要是用 Redis 實現,并且對 Redis 做了集群來保證 Redis 服務的高可用(緩存方面除了 redis 外還有 memcached)
8) 支付系統:主要是負責訂單的支付、對賬等功能,主要是對接了支付寶的接口;
(根據個人的實際情況選擇最為熟悉的模塊,進行敘述)
商品類型管理
包含功能:添加商品類型、顯示商品類型列表、修改商品類別、刪除商品類型
描述舉例:
1、添加商品類型:在后臺模塊新建一個商品類型的控制器(TypeController),并添加add 方法, 同時建立好對應的靜態頁。新建一個對應的商品類型表,在表里添加數據驗證。在商品類型控制器中的 add 方法中完成商品類型的添加。(其中關鍵點是 create 驗證和防止非法字段提交)
2、商品類型列表:在商品類型控制器中添加一個 lst 方法,取出商品類型數據,并在對應的靜態頁中完成數據遍歷,就能在頁面中得出相應的商品類型列表
屬性管理
包含功能:添加屬性、顯示屬性列表、根據商品類型搜索屬性、修改屬性、刪除屬性
描述舉例:
前提條件:建立一個屬性表將各字段全部預先設置好,才可以進行一下操作
1、添加屬性:在后臺模塊新建一個 AttributeController 的控制器,并添加 add 方法,并建立好對應的靜態頁面,修改頁面里的表單。然后新建一個 attribute 表對應的模型文件,進行數據驗證(驗證規則可以查手冊),在方法中完成屬性添加的代碼。在屬性控制器中寫入 lst 方法,并且完成對應靜態頁,把取出的數據遍歷到對應的靜態頁
2、根據商品類型搜索屬性:(給 select 添加 change 事件,完成提交表單, 表單提交到當前頁面。)首先在方法中將商品顯示出來,并將商品數據完成遍歷,給顯示商品 類型的 select 添加 change 事件,完成表單提交,其中會引用 JQ 添加 change 事件,當觸發change 事件后,顯示出當前顯示的商品類型。在商品類型列表,添加“屬性列表“的 連接,在添加完成屬性后,跳轉到屬性列表,直接顯示所 屬當前商品類型的屬性,最后實現分頁.
商品欄目管理
包含功能:創建欄目、欄目的增刪改查 (注:商品類型和商品欄目的區別,類型是大類,欄目是小類)
描述舉例:
前提條件:要創建一個欄目表,以便進行下面的功能開發
1、添加欄目:在 admin 模塊里面新建一個 category 的控制器,添加 add 方法,并完成對應頁面設計。在頁面上設計好表單,在添加欄目時將已經添加的欄目顯示出來(新建一個商品欄目模型,在里面定義好方法,用于取出欄目的數據,并且已經格式化好的),然后在 add 方法里將數據取出來,并且進行遍歷,在此方法中完成欄目的添加
2、欄目列表:在 category 的控制器里添加 lst 方法,并且完成對應頁面的設計,在頁面中遍歷欄目數據,將其遍歷顯示到頁面中
3、刪除欄目:(注:在刪除欄目時,如果有子欄目則不能刪除)在欄目列表中添加刪除欄目的鏈接(用 U 函數自動生成路徑),在相應的 category 控制器里,寫上 del 方法,接受傳遞過來的 id,實例化自定義模型,利用 sql 拼接進行查詢,找出對應的欄目記錄,將其刪除
商品管理
包含功能:商品的增刪改查,在線編輯器,屬性選項卡,屬性的增刪改查,商品相冊選項卡,添加相冊,文件上傳,相冊上傳等
描述舉例:
前提條件:要將商品表創建好,具體字段根據需求開設計
1、添加商品:在后臺模塊(admin 模塊)里新建一個 Goods 控制器,寫入 add 方法,同時完成相應的頁面設計,在 add 方法對應的頁面中對表單行進相應的修改(具體的頁面要求感覺需求來修改)。在 add 方法中完成商品的添加功能代碼,例如生成唯一的商品 id號、添加商品的時間等(利用前綴+時間+唯一碼=唯一 id)
2、圖片上傳:可以利用 TP 已經定義好的鉤子函數,來 完成圖片文件的上傳,返回保存圖片的路徑。鉤子函數在模型里面會自動調用, 比如:入庫之前:_before_insert() 和入庫之后:_after_insert() 會被模型里面的 add 方法,自動調用。只需要在上傳之前,把圖片的路徑、上傳單個文件的最大值、允許上傳格式限制好
3、縮略圖:在圖片上傳的基礎上利用 new \Think\Image()按照原生圖片的比例生成一個縮略像素*縮略像素的縮略圖,每個縮略圖都會生成一個唯一的 id 名,并且保存到預設好的路徑文件夾中(這里要注意的是生成多張縮略圖的時候,必須先生成大圖,再生成小圖),圖片生成后將路徑入庫。
4、顯示屬性選項卡:(選項卡的顯示重點是給標簽設置一個 onclick 事件函數)要在選項卡中顯示商品類型,在 goods 控制器里面的 add 方法中取出商品類型數據,然后在相應的頁面商品屬性選項卡位置遍歷商品類型數據,分別顯示出來
5、完成商品屬性的添加:前提將商品屬性表設計好,然后根據實際的靜態頁面進行表單的修改,修改指定表單的域名(即標簽中的 name),修改完成后在 Goods 模型里定義一個鉤子_after_insert,在該方法中完成屬性數據的入庫,由此屬性的添加完成.
權限管理
包含功能:管理員登錄,權限管理(權限管理控制),角色管理,管理員管理
權限管理簡述:權限管理是根據不同等級,不同管理員的情況下,授予不同的權限,各自操作各自授權。授權方式大體分為兩種:一種是直接給管理員授權權限,適合于管理員比較少,權限數量也比較少的情況下;第二種是 RBAC 基于角色的訪問控制。
在建表方面,采用五張表,其中有三張主表,權限表、角色表、管理員表,兩張從表,角色與權限的中間表、管理員與角色的中間表。
角色表與權限表的關系:一個角色可以有多個權限,一個權限可以屬于多個角色,權限表與角色表是多對多的關系,要體現這種關系,要使用角色與權限的中間表;管理員表與角色表的關系:一個管理員可以屬于多個角色,一個角色可以包含多個管理員,角色表與管理員表是多對多的關系,要體現這種關系,要使用管理員與角色的中間表。
五張表關系圖如下:
描述舉例:
1、權限管理:在項目中權限管理就是按鈕,通過按鈕給對應的管理員或者是角色分配權限。在后臺模塊新建一個權限的控制器,并寫入 add 方法,完成對應的頁面設計,修改好頁面上的表單,完善頁面。新建一個權限模型,并且在模型中添加數據驗證,設置好驗證規則(具體代碼參考項目中的),在模型中完成權限添加。在父級權限完成后,繼續添加子級權限:在模型里面定義一個方法,用于取出權限,并格式化好權限數據,然后在添加權限控制器里面,取出權限數據,并進行遍歷,將遍歷出來的子級權限顯示在頁面中
2、角色管理:角色管理中包含對角色的增刪改查,授權等等。添加角色首先要在在后臺模塊新建一個 RoleController 的控制器,寫入添加 add 方法,完成對應的靜態頁面,取出權限數據,并修改對應的表單。在后臺模塊里面,添加一個 RoleModel 模型,寫入添加數據驗證。接下來就是數據入庫,在入庫時要注意的是該表單提交的數據,是入庫兩張的表,一個是角色表,一個是角色與權限的中間表,其中角色與權限的中間表的數據,是使用鉤子函數_after_insert()來完成。
3、角色刪除:如果角色里面有管理員,則不能刪除,在刪除角色的同時,要刪除角色與權限的中間表里面的對應的數據。首先在角色列表中添加刪除的鏈接(用 U 函數自動生成路徑),然后在角色控制器中添加刪除 del 方法,用于刪除角色,其次在角色模型中添加鉤子函數_after_delete()用來刪除角色與權限中間表對應的角色數據,刪除完成
4、管理員管理:在添加管理員時,要分配管理員所屬角色,并且將管理員各個數據根據要求設定好格式。創建管理員控制器,添加 add 方法,取出角色數據,并完成頁面設計將數據顯示到頁面上。在管理員模型中添加數據驗證,使用靜態方法來完成驗證,
使用模型添加數據,接受明文密碼,然后用雙重 md5 進行加密,這個過程的代碼可以直接寫到鉤子函數里。使用鉤子函數添加管理員與角色中間表的數據,在管理員的模型里面,添加_after_insert()鉤子函數
5、管理員列表:在管理員的控制器里面添加 lst 方法,用于取出管理員數據,并完成對應的靜態頁面,要注意:顯示管理員的同時,要顯示出所屬角色的名稱,因此要連表查詢(管理員表 管理員角色表 角色表)
然后在對應的界面中進行管理員數據遍歷并且顯示到頁面上。
6、刪除管理員:要操作的表是:it_admin 和 it_admin_role,在刪除 it_admin_role表里面數據時,則可以使用鉤子函數_after_delete(),鉤子函數是 TP 框架里面提供的,
主要有:_before_insert()、_after_insert()、_before_update()、_after_update(),_before_delete(),_after_delete()(該系列函數是在模型里面定義,會被自動調用。)
注意:超級管理員不能被刪除(擁有最高權限)
郵件發送驗證管理
包含功能:(原理要理解、)注冊、登錄、發送、密碼找回等
描述舉例:
1、原理:
郵件的 SMTP(Simple Mail Transfer Protocol):即簡單郵件傳輸協議,它是一組用于由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。SMTP 協議屬于TCP/IP 協議族,它幫助每臺計算機在發送或中轉信件時找到下一個目的地。通過 SMTP協議所指定的服務器,就可以把 E-mail 寄到收信人的服務器上了,整個過程只要幾分鐘。SMTP 服務器則是遵循 SMTP 協議的發送郵件服務器,用來發送或中轉發出的電子郵件。
2、用戶注冊:創建用戶表,將所需字段設置好(在設置字段的時候可以預留一些字段以便后面拓展使用)。在前臺模塊中新建一個 user 控制器,添加 register 方法,并且完成對應靜態頁。在 user 模型中添加數據驗證,返回數據.
在控制器中完成注冊后,發送郵件:
郵件發送后,由用戶進行激活認證,因此在控制器中新建 active 方法。方法中首先要接受數據(key 值,用戶郵件數據),然后判斷鏈接是否合法,根據傳遞的 email 查找出 vaildate字段內容和 key 值進行匹配。如果匹配成功那么,就讓用戶進行激活,激活的同時將 active的初始狀態更改為 1,則功能完結
3、密碼找回功能:實現方式,根據用戶名->查找出注冊時設置的問題->輸入問題的答案->如果答案正確->發送一封郵件,根據該郵件里面的鏈接去完成密碼的修改。首先在頁面上將密碼找回的鏈接設置好,在 user 控制器里添加 findpwd1 方法(用于找回密碼的第一個方法),該方法顯示出找回密碼輸入用戶的一個界面,同時應該完成對應頁面的編寫。再在 user 控制器中添加 findpwd2 方法,根據用戶名查找出注冊時設置的問題,讓用戶輸入問題的答案。第三是在user 控制器中寫入 findpwd3 方法,用于問題答案的匹配并發送郵件,通過郵件的鏈接來完成密碼的修改。最后在 user 控制器中添加一個 update 方法,用于完成密碼的修改
購物車管理
包含功能:提交商品到購物車、顯示購物車列表、刪除購物車里商品、修改購物車、
清空購物車等等
1、 購物車的實現方式:① 可以把購物車的數據,給存儲到 session 里面,一旦關閉瀏覽器,則商品數據就丟失;②可以把購物車的數據,給存儲到 cookie 里面,可以長久的保存購物車里面的數據;③可以把購物車的數據,給存儲到數據庫里面,可以長久的保存購物車里面的數據;④可以把購物車的數據,給存儲到緩存里(memcache,redis),也可以長久的保存購物車的數據。
注:Session 可能會引起并發問題,如果腳本很短,這通常沒有問題。但如果腳本運行時間比較長,那就可能會產生問題。在現代 Web 應用程序開發中,有一個非常常見的情況,就是使用 AJAX 技術在同一個頁面內發送多個請求獲取數據。如果這些請求都需要使用Session,那么第一個請求到達服務器后會取得 Session 鎖,其它請求就必須等待,所有請求將串行處理,即使它們彼此之間并沒有依賴關系。這將大大增加頁面的響應時間。有一個方法可以避免這個問題,就是在使用完 Session 以后立即調用 session_write_close()方法關閉 Session。這樣 Session 鎖就會釋放,即使當前腳本還在等在處理。需要注意的是,調用該方法后,當前腳本就不能進一步操作 Session 了
2、實例:京東購物車的設置,如果用戶已經登錄,則把購物車數據保存到數據庫里面,如果沒有登錄,則把購物車的數據給保存到 cookie 里面,當登錄時,要判斷 cookie是否有購物車的數據,如果有,則把 cookie 里面的數據給移動到數據庫里面。
3、提交商品到購物車:在前臺模塊里新建一個 CartController 控制器,添加 addCart方法
4、購物車列表:在購物車模型里添加 cartList 方法,用于顯示列表。如果用戶已經登錄,則直接從購物車數據庫里面取出數據,如果用戶沒有登錄,則直接從 cookie里面獲取數據。最后在購物車控制器里面的 cartList 的方法中,并取出購物車數據,并在對應的靜態頁面里完成遍歷,顯示出來
5、cookie 移到 DB 中:用戶登錄后,要判斷 cookie 里面是否有購物車數據,如果有,則就移動到數據庫,在購物車模型里面定義一個方法 cookie2db
登錄成功后調用 cookie2db 方法即可
訂單管理
描述舉例:
1、建立訂單控制器,添加 flow 方法,完成對應的靜態頁面。在 order 控制器里面添加一個 done 方法,用來完成下訂單功能:首先接受傳遞過來的訂單信息數據,判斷購物車里面是否有商品,防止出現能夠直接訪問該方法的情況,如果沒有商品則提示無法下單,接著判斷用戶是否已經登陸,如果沒有登錄把當前訪問的地址存儲到 session里,跳轉登錄頁面,完成登錄后再跳轉回來,再判斷是否填寫收貨人的信息,同理,如果沒有填寫則跳轉填寫頁面。下單時會自動算出訂單總額,生成唯一的訂單號,并且從session 中取出用戶 id,獲取收貨人信息。隨后將訂單信息和訂單商品信息入庫結算完成后,清空購物車,訂單完成
2、下訂單注意事項:
①在下訂單之前要判斷庫存是否充足:判斷商品屬性 id 是否有值,如果有說明該商品有屬性,直接從 product 表里進行判斷,如果沒有屬性則直接從goods 表里判斷庫存
②下完訂單后要減掉庫存:在入庫 it_order_goods 表時,要完成減掉庫存
③ 高并發下訂單問題:使用文件鎖,對文件鎖定后,不是操作文件,是鎖定文件后,執行下訂單, 查看庫存之前,就要加鎖,一直到購買完成(另外 redis 消息隊列)
④添加事務:防止某些操作只完成一半
網上支付管理
支付過程主要是調用第三方支付接口
網上支付流程:
商城與銀行對接方案:
1、直接與銀行對接
優點:
因為直接與銀行進行財務結算,交易資金結算比較安全。適合資金流量比較大的企業,這種方案適合于,每月結算金額百萬以上的企業。
缺點:
開發工作量比較大,而且銀行會不定期升級交易系統,隨著銀行系統的升級,企業也也需要做相應的改動,所以維護工作量也是比較大的,而且企業每年還需要向銀行交納一定數量的接口使用費用。
2、通過中間公司間接與銀行對接
優點:
開發工作量較少,銀行升級系統,不需要企業做相應的修改,除非中間企業的接入規范發生了改變,相對前一種接入方案,這種方案的維護工作量比較少的。因為只與一家企業對接,所以接入費用相對比較低。這種方案適合于:每月結算資金在幾十萬以下的中小企業。
缺點:
因為是與中間企業進行資金結算,目前所有中間企業都是私企,資金安全是個大問題
①確認服務器硬件是否足夠支持當前的流量
②優化數據庫訪問
③禁止外部的盜鏈
④控制大文件的下載
⑤使用不同主機分流主要流量、集群
⑥使用流量分析統計軟件
MyISAM、InnoDB
構成上,MyISAM 的表在磁盤中有三個文件組成,分別是表定義文件(.frm)、數據文件(.MYD)、索引文件(.MYI),而 InnoDB 的表由表定義文件(.frm)、表空間數據和日志文件組成。
安全方面,MyISAM 強調的是性能,其查詢效率較高,但不支持事務和外鍵等安全性方面的功能,而 InnoDB 支持事務和外鍵等高級功能,查詢效率稍低。
對鎖的支持,MyISAM 支持表鎖,而 InnoDB 支持行鎖。
1)盡量選擇較小的列
2)將 where 中用的比較頻繁的字段建立索引
3)select 子句中避免使用‘*’
4)避免在索引列上使用計算、not in 和<>等操作
5)當只需要一行數據的時候使用 limit 1
6)保證單表數據不超過 200W,適時分割表。針對查詢較慢的語句,可以使用 explain 來分析該語句具體的執行情況。
就是把一個動態的頁面(操作數據庫的 php 頁面)變成一個靜態頁面,后續用戶直接訪問靜態頁面。
頁面靜態化技術分為兩種:真靜態和偽靜態。
真靜態:把一個動態的頁面,實實在在的轉成一個靜態的頁面,即.html 文件
偽靜態:所謂偽靜態是從 url 地址上看是一個靜態頁面,但是實際上還是對應一個動態頁面
①防止 Sql 注入,對特殊字符進行轉義、過濾或者使用預編譯的 sql 語句綁定變量。最小權限原則,特別是不要用 root 賬戶,為不同的類型的動作或者組建使用不同的賬戶。
②當 sql 運行出錯時,不要把數據庫返回的錯誤信息全部顯示給用戶,以防止泄露服務器和數據庫相關信息
③XSS 攻擊
④暴力破解
Memcache 是把所有的數據保存在內存中,采用 hash 表的方式,把每條數據有 key 和 value組成,每個 key 獨一無二的,當要訪問的某個值的時候先按照找到值,然后在返回結果,Memcache采用 LRU 算法來逐漸把過期的數據清除掉
$(selector).hide() 隱藏被選元素
$(selector).show() 顯示被選元素
$(selector).toggle() 切換(在隱藏與顯示之間)被選元素
$(selector).slideDown() 向下滑動(顯示)被選元素
$(selector).slideUp() 向上滑動(隱藏)被選元素
$(selector).slideToggle() 對被選元素切換向上滑動和向下
$(selector).fadeIn() 淡入被選元素$(selector).fadeOut() 淡出被選元素
$(selector).fadeTo() 把被選元素淡出為給定的不透明度
$(selector).animate() 對被選元素執行自定義動畫
二次開發,簡單的說就是在現有的軟件上進行定制修改,功能的擴展,然后達到自己想要的功能,一般來說都不會改變原有系統的內核。dede 二次開發就是以 dede 織夢系統為基礎進行的二次開發。
弊端:
1)插件限制太多;
2)修改源文件對升級有影響。
兩種,分別是 RDB 和 AOF 快照;
Redis 的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此 Redis 適合的場景主要局限在較小數據量的高性能操作和運算上
前后操作人員錄入數據保持一致,開啟驗證功能,由于通訊故障造成的前臺數據積壓,維護時及時備份
讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從數據庫處理 SELECT 查詢操作。數據庫復制被用來把事務性操作導致的變更同步到集群中的從數據庫。
至少兩臺數據庫服務器,可以分別設置主服務器和從服務器,對主服務器的任何操作都會同步到從服務器上
原理:mysql 中有一種日志,叫做 bin 日志(二進制日志),會記錄下所有修改過數據庫的 sql 語句。主從復制的原理實際是多臺服務器都開啟 bin 日志,然后主服務器會把執行過的sql 語句記錄到 bin 日志中,之后把這個 bin 日志發給從服務器,在從服務器再把 bin 日志中記錄的 sql 語句同樣的執行一遍。這樣從服務器上的數據就和主服務器相同了。
需要對服務器的架構分層,重新布局,負載均衡,集群策略。
負載均衡器(硬件和軟件)
硬件:F5-Bigip:立竿見影,價格昂貴,網游公司或大網站用的比較多
軟件:lvs(linux virtual server 虛擬服務,集成到內核中),nginx(可以做 web 服務器,也可以做負載均衡使用)
負載均衡策略:
(1)輪詢技術:把客戶端的請求輪流分發給服務器。
(2)最少連接;負載均衡把請求給最空閑的服務器
(3)ip 哈希:同一地址的客戶端,始終請求同一臺服務器。
Ajax,Ajax 的跨域請求常用的有兩種方式:
1)使用中間層過渡的方式:
中間過渡,很明顯,就是在 AJAX 與不同域的服務器進行通訊的中間加一層過渡,這一層過渡可以是 PHP 、JSP、c++等任何具備網絡通訊功能的語言,由中間層向不同域的服務器進行讀取數據的操作。拿 PHP 做 一個例子,如果需要對不同域的某一個 php 進行通訊,現在客戶端的xmlhttprequest 先 query 本域的一個 PHP,然后由本域的這個 PHP 去和不同域的 PHP 進行通訊,然后由本域的 PHP 輸出 response;
2)使用標簽
這個方法是利用標簽中的 src 來 query 一個 PHP 獲得 response,因為標簽 的 src 屬性不存在跨域的問題。
Ajax 是一種在頁面沒有刷新的情況下,通過客戶端(瀏覽器)與服務器交互的一種技術。
Ajax 語言的載體是 javascript,最大特點:頁面不刷新完成請求。
open 方法:如 xhr.open(‘get’,’demo.php’,true)open 方法,第三個參數表示是異步請求,默認 true 表示異步請求處理
簡單、直觀、強悍的前端開發框架,讓 Web 開發更快速、簡單
優勢:入門簡單,支持響應式,優先支持移動設備
200(成功):服務器已成功處理了請求。通常,這表示服務器提供了請求的網頁
201(已創建):請求成功并且服務器創建了新的資源
202(已接受):服務器已接受請求,但尚未處理
203(非授權信息):服務器已成功處理了請求,但返回的信息可能來自另一來源
204(無內容):服務器成功處理了請求,但沒有返回任何內容
205(重置內容):服務器成功處理了請求,但沒有返回任何內容
206 (部分內容):服務器成功處理了部分 GET 請求
404(未找到):服務器找不到請求的網頁
500(服務器內部錯誤):服務器遇到錯誤,無法完成請求