校園失物招領平臺開發(fā)
——基于laravel框架構建最小內(nèi)容管理系統(tǒng)
摘要
?
針對目前大學校園人口密度大泳挥、人群活動頻繁沽瘦、師生學習生活等物品容易遺失的基本現(xiàn)狀柬甥,在分析傳統(tǒng)失物招領過程中的工作效率低下、找回率低其垄、保密性差苛蒲、管理分散等問題和不足的基礎上,提出了WEB模式的失物招領信息管理平臺绿满。該平臺主要通過失物信息發(fā)布和失物領取功能臂外,較好的解決了傳統(tǒng)失物招領管理過程中的信息孤島的缺陷,提高了失物招領的工作效率喇颁,減少了師生的直接經(jīng)濟損失漏健,方便了廣大師生的日常生活。 本系統(tǒng)采用了LAMP(ubuntu+Apache+MySQL+php)作為開發(fā)環(huán)境橘霎,后端php框架使用了目前流行的laravel框架蔫浆,完全遵循MVC的設計模式。選用國產(chǎn)開源的響應式HTML5開發(fā)框架AmazeUI作為前端視圖框架姐叁,可以很好地適應移動端頁面布局忆某。
關鍵詞:校園;失物招領禀晓;信息發(fā)布;內(nèi)容管理系統(tǒng)挠唆;php;laravel嘱吗;MySQL玄组;AmazeUI
?
?
目錄
一、引言
1.課題研究背景及意義
2.系統(tǒng)可行性分析
二谒麦、系統(tǒng)需求分析
1.業(yè)務流程分析
2.用戶體驗分析
三俄讹、系統(tǒng)模塊設計
1.功能模塊
2.用戶界面
四、核心功能的技術實現(xiàn)
1.開發(fā)環(huán)境
2.技術框架
3.數(shù)據(jù)庫設計
4.MVC設計模式
5.核心代碼實現(xiàn)
6.測試及操作說明
五绕德、總結
六颅悉、參考文獻
引言
1. 課題研究背景及意義
大學生由于攜帶的東西較多,活動多迁匠,而且經(jīng)常來往于不同的地 方,因此很容易發(fā)生物品丟失的情況驹溃,而目前我們學校又缺乏一套行之有效的可以幫助學生尋找失物的系統(tǒng)城丧。考慮到大學生普遍上網(wǎng)豌鹤,而且校園網(wǎng)絡覆蓋率高亡哄, 那么就通過網(wǎng)絡這一便捷高效的方式來實現(xiàn)一個失物招領系統(tǒng),優(yōu)化失物招領業(yè)務布疙,使得失物招領管理清晰化蚊惯、透明化,便于操作灵临,易于管理截型。通過本系統(tǒng),拾主可以通過這個平臺發(fā)布最新的招領啟事以通知大 家儒溉,而失主可以通過這個平臺尋找和聯(lián)系拾主宦焦。并且只要是網(wǎng)站的注冊用戶,就可以發(fā)布管理文章顿涣、留言波闹,這樣不僅財產(chǎn)上的損失避 免了,還加強了人與人之間的交流涛碑。所以說開發(fā)這個失物招領平臺精堕,定會大大便利校園內(nèi)廣大師生的生活,不必再為丟失尋找物品這類瑣事煩擾蒲障,真正地讓技術服務于生活歹篓。
?
2.系統(tǒng)可行性分析
-
技術可行性
利用穩(wěn)定的ubuntu linux作為服務器環(huán)境瘫证,Apache處理客戶端與服務端的通信,MySQL數(shù)據(jù)庫存放用戶信息和發(fā)布的文章滋捶、留言痛悯,php作為后端語言,實現(xiàn)動態(tài)頁面處理重窟,再加上簡潔優(yōu)雅的響應式前端開發(fā)框架载萌,可以開發(fā)出符合要求的管理系統(tǒng)。
-
經(jīng)濟可行性
網(wǎng)站平臺的開發(fā)及后期的運營維護所需的人力物力很少巡扇,并且可以部署在學校的服務器上扭仁,由網(wǎng)絡服務中心的工作人員統(tǒng)一管理。
-
社會可行性
在校園里厅翔,我們經(jīng)常見到這樣一幕乖坠,一位同學在熱水房門口一遍一遍尋找,然后口里說著刀闷,怎么又不見了呢熊泵?,一邊不甘心的再找一遍甸昏。又或許是這么一幕顽分,“尋物啟事——宿舍號,丟失物品施蜜,最后再詛咒一下那些撿拾物品不還的人卒蘸。”現(xiàn)有失物招領處工作繁瑣且效率低翻默,因此開發(fā)失物招領管理系統(tǒng)是非常必要的缸沃。
系統(tǒng)需求分析
1、業(yè)務流程
業(yè)務流程分析可以幫助開發(fā)者了解該業(yè)務處理過程修械,發(fā)現(xiàn)和處理系統(tǒng)調(diào)查工作中的錯誤和疏漏趾牧。業(yè)務流程分析是通過業(yè)務流程圖來進行,即用一些規(guī)定的符號及連線來表示某個具體業(yè)務處理過程肯污。
本系統(tǒng)具體的業(yè)務流程如下圖所示:
2武氓、用戶體驗分析
用戶體驗是現(xiàn)今產(chǎn)品開發(fā)過程中非常重視的一個方面,我們開發(fā)出一款產(chǎn)品或者提供一項服務仇箱,其最終面向的是不重視或不在乎技術層面的廣大用戶县恕,因此在界面友好性、直觀性剂桥、易于操作性方面必須加以考慮忠烛。本失物招領系統(tǒng)按照下述原則進行:
- 實用性:系統(tǒng)以用戶需求為目標,以方便用戶使用為原則权逗,充分考慮實際操作的各項細節(jié)美尸,使得普通用戶在打開頁面的第一眼即能對操作流程有清晰的理解冤议。真正構建起一個為師生服務的平臺,為用戶的在線失物招領查詢發(fā)布提供方便师坎。
- 高安全性:在設計中恕酸,將充分考慮網(wǎng)絡軟、硬件方面的各種安全措施胯陋,保障用戶數(shù)據(jù)信息安全蕊温。比如用戶存放在數(shù)據(jù)庫的賬號密碼采用php的哈希加密,即使數(shù)據(jù)庫泄露遏乔,看到的也將是一堆亂碼义矛。
- 可維護性:網(wǎng)站的設計要求方便維護,文件目錄及代碼結構清晰盟萨。
- 可擴展性:網(wǎng)站的設計以方便未來的擴展和系統(tǒng)擴充為目標凉翻,系統(tǒng)要求能夠方便升級,方便添加功能模塊捻激。
系統(tǒng)模塊設計
1.功能模塊
本管理系統(tǒng)主要能夠實現(xiàn)用戶注冊制轰、用戶(管理員)登錄、首頁展示胞谭、失物招領的文章發(fā)布垃杖、留言板、后臺管理韭赘, 以及標簽管理等幾大模塊的功能:
- 用戶注冊:本功能主要是實現(xiàn)對用戶信息的注冊管理
- 用戶(管理員)登錄:本功能主要實現(xiàn)用戶(管理員)登錄的功能
- 首頁模塊:本模塊主要是對失物招領文章的展示功能、添加功能势就、查看詳情功能及各模塊入口
- 留言板模塊:主要是實現(xiàn)用戶(管理員)留言功能泉瞻,以供用戶反饋
- 后臺管理:用戶信息管理、失物招領文章管理苞冯、留言板留言管理袖牙、管理員信息管理、標簽管理
本系統(tǒng)主要功能結構如下圖所示:
?
2舅锄、用戶界面
- 注冊頁面:本界面主要采集注冊用戶的信息鞭达,然后存入系統(tǒng)數(shù)據(jù)庫
- 登錄頁面:本頁面根據(jù)登錄用戶的信息和類型進行驗證登錄
- 首頁:本頁面展示用戶所發(fā)布的失物招領的文章,以及文章的標簽
- 留言板頁面:本頁面顯示歷史留言和添加留言的版塊
- 用戶信息頁面:本頁面顯示當前登錄的用戶的信息及發(fā)布的文章管理
- 管理頁面:本頁面是管理員對本網(wǎng)站各個版塊進行管理的可視化操作頁面
核心功能的技術實現(xiàn)
1皇忿、開發(fā)環(huán)境
網(wǎng)站的本地開發(fā)環(huán)境使用lamp(即Linux+Apache+MySQL+PHP)畴蹭。lamp是一組常用來搭建動態(tài)網(wǎng)站或者服務器的開源軟件,本身都是各自獨立的程序鳍烁,但是因為常被放在一起使用叨襟,擁有了越來越高的兼容度,共同組成了一個強大的Web應用程序平臺幔荒。lamp的所有開發(fā)工具都是開源軟件糊闽,隨著開源潮流的蓬勃發(fā)展梳玫,可以預見lamp會是未來web開發(fā)的主流,并且由于其零成本右犹、學習資料多提澎,自然成為我的首選開發(fā)環(huán)境。
2念链、技術框架
后端的php框架選用了國外流行的開源框架——laravel盼忌,也是號稱“最簡潔、優(yōu)雅的php web開發(fā)框架”钓账,基于此可以快速碴犬、高效地構建一個web APP,Laravel的目標是給開發(fā)者創(chuàng)造一個愉快的開發(fā)過程梆暮,并且不犧牲應用的功能性服协。剛開始學習php開發(fā)沒多久,對php的一些框架了解甚少啦粹,在csdn上看到一篇文章《php開發(fā)框架流行度排名:laravel居首》偿荷,才知道有l(wèi)aravel這么一個框架,并且其文件目錄唠椭、代碼結構清晰跳纳,基于MVC的設計模式,對初學者較友好贪嫂,故選用了此框架寺庄,本篇課程設計很大程度上也算是我對laravel框架的學習實踐吧。php的應用框架眾多力崇,如國產(chǎn)的thinkPHP框架在國內(nèi)也使用者甚廣斗塘,前期曾嘗試使用thinkPHP來開發(fā),其結構代碼簡單直接亮靴,易于上手馍盟,但在代碼規(guī)范性方面毀譽參半,不適合初學者養(yǎng)成良好的編碼習慣茧吊,故棄之贞岭。
下面就對laravel框架體系結構作簡要介紹。
Laravel被稱為“全棿曛叮”式框架瞄桨,因為它能夠處理從網(wǎng)絡服務到數(shù)據(jù)庫管理、HTML生成的一切事情讶踪,垂直集成的web開發(fā)環(huán)境給開發(fā)者提供了更好的體驗讲婚。開發(fā)人員可以通過命令行工具,生成和管理Laravel項目環(huán)境。 Laravel帶有一個名為Artisan的優(yōu)秀的命令行工具俊柔,可以用它來生成框架代碼和數(shù)據(jù)庫架構筹麸,Artisan能夠處理從數(shù)據(jù)庫架構遷移到資源和配置管理的一切事情活合。
laravel項目使用composer來創(chuàng)建(Composer是PHP中用來管理依賴(dependency)關系的工具。你可以在自己的項目中聲明所依賴的外部工具庫(libraries)物赶,Composer會幫你安裝這些依賴的庫文件)白指。在linux終端中執(zhí)行:
$ composer create-project laravel/laravel --prefer-dist web 5.1
就會在/home目錄下創(chuàng)建一個名為web的項目文件夾,指定的laravel版本為5.1 酵紫。其目錄結構如下圖所示:
下面是各個文件夾和文件的基本介紹:
頂級文件夾 | 作用 |
---|---|
app | 包含了站點的controller(控制器)告嘲,models(模型),views(視圖)和assets(資源)奖地。這些事網(wǎng)站運行的主要代碼橄唬,你將會花費大部分的時間在這些上面。 |
bootstrap | 用來存放系統(tǒng)啟動時需要的文件参歹,這些文件會被如index.php這樣的文件調(diào)用仰楚。 |
這個文件夾是外界唯一可以看到的,是必須指向你web服務器的目錄犬庇。它含有l(wèi)aravel框架核心的引導文件index.php僧界,這個目錄也可以用來存放任何可以公開的靜態(tài)資源,如css臭挽,JavaScript捂襟,images等。 | |
vendor | 用來存放所有的第三方代碼欢峰,在一個典型的laravel應用程序葬荷,這包括larceny源代碼及其相關,并含有額外的預包裝功能的插件纽帖。 |
如上所述宠漩,/app是其核心部分,/app文件夾的詳細信息如下:
?
下面是詳細介紹:
文件及文件夾 | 作用 |
---|---|
/app/config/ | 配置應用程序的運行時規(guī)則抛计、 數(shù)據(jù)庫哄孤、 session等等照筑。包含大量的用來更改框架的各個方面的配置文件吹截。大部分的配置文件中返回的選項關聯(lián)PHP數(shù)組。 |
/app/config/app.php | 各種應用程序級設置凝危,即時區(qū)波俄、 區(qū)域設置(語言環(huán)境)、 調(diào)試模式和獨特的加密密鑰蛾默。 |
/app/config/auth.php | 控制在應用程序中如何進行身份驗證懦铺,即身份驗證驅動程序。 |
/app/config/cache.php | 如果應用程序利用緩存來加快響應時間支鸡,要在此配置該功能冬念。 |
/app/config/compile.php | 在此處可以指定一些額外類趁窃,去包含由‘a(chǎn)rtisan optimize’命令聲稱的編譯文件。這些應該是被包括在基本上每個請求到應用程序中的類急前。 |
/app/config/database.php | 包含數(shù)據(jù)庫的相關配置信息醒陆,即默認數(shù)據(jù)庫引擎和連接信息。 |
/app/config/mail.php | 為電子郵件發(fā)件引擎的配置文件裆针,即 SMTP 服務器刨摩。 |
/app/config/session.php | 控制Laravel怎樣管理用戶sessions,即session driver, session lifetime。 |
/app/config/view.php | 模板系統(tǒng)的雜項配置世吨。 |
/app/controllers | 包含用于提供基本的邏輯澡刹、 數(shù)據(jù)模型交互以及加載應用程序的視圖文件的控制器類。 |
/app/database/migrations/ | 包含一些 PHP 類耘婚,允許 Laravel更新當前數(shù)據(jù)庫的架構并同時保持所有版本的數(shù)據(jù)庫的同步罢浇。遷移文件是使用Artisan工具生成的。 |
/app/database/seeds/ | 包含允許Artisan工具用關系數(shù)據(jù)來填充數(shù)據(jù)庫表的 PHP 文件边篮。 |
/app/lang/ | PHP 文件己莺,其中包含使應用程序易于本地化的字符串的數(shù)組。默認情況下目錄包含英語語言的分頁和表單驗證的語言行戈轿。 |
/app/models/ | 模型是代表應用程序的信息(數(shù)據(jù))和操作數(shù)據(jù)的規(guī)則的一些類凌受。在大多數(shù)情況下,數(shù)據(jù)庫中的每個表將對應應用中的一個模型思杯。應用程序業(yè)務邏輯的大部分將集中在模型中胜蛉。 |
/app/start/ | 包含與Artisan工具以及全球和本地上下文相關的自定義設置。 |
/app/storage/ | 該目錄存儲Laravel各種服務的臨時文件色乾,如session, cache, compiled view templates誊册。這個目錄在web服務器上必須是可以寫入的。該目錄由Laravel維護暖璧,我們可以不關心案怯。 |
/app/tests/ | 該文件夾給你提供了一個方便的位置,用來做單元測試澎办。如果你使用PHPUnit嘲碱,你可以使用Artisan工具一次執(zhí)行所有的測試。 |
/app/views/ | 該文件夾包含了控制器或者路由使用的HTML模版局蚀。請注意麦锯,這個文件夾下你只能放置模版文件。其他的靜態(tài)資源文件如css, javascript和images文件應該放在/public文件夾下琅绅。 |
/app/filters.php | 此文件包含各種應用程序和路由篩選方法扶欣,用來改變您的應用程序的結果。Laravel 具有訪問控制和 XSS 保護的一些預定義篩選器。 |
/app/routes.php | 這是您的應用程序的路由文件料祠,其中包含路由規(guī)則骆捧,告訴 Laravel 如何將傳入的請求連接到路由處理的閉包函數(shù)、 控制器和操作髓绽。該文件還包含幾個事件聲明凑懂,包括錯誤頁的,可以用于定義視圖的composers梧宫。 |
3接谨、模型-視圖-控制器(MVC)
/app文件夾下有三個子目錄:models/,views/和controllers/。這說明laravel遵循MVC架構模式塘匣。這就是強制將輸入到展示邏輯關系的“業(yè)務邏輯”與圖形用戶界面(GUI)分開脓豪。就laravel web應用而言,業(yè)務邏輯通常由像用戶忌卤,文章這樣的數(shù)據(jù)模型組成扫夜。GUI只是瀏覽器中的網(wǎng)頁而已。MVC設計模式在web開發(fā)領域中很流行驰徊。
MVC模式包括三個組件:
- 模型(model)
- 視圖(view)
- 控制器(controller)
一個典型的laravel應用程序包含上面提到的MVC組件笤闯,如下圖:
laravel的響應流程
當與Laravel交互時,瀏覽器發(fā)送一個請求棍厂,web服務器接收到請求并且傳給Laravel路由引擎颗味。Laravel路由接收到請求,然后重定向給基于路由的URL模式的合適的控制器類方法牺弹。然后控制器類接管浦马。在某種情況下,控制器會立即呈現(xiàn)出一個視圖张漂,它是一個被轉換成HTML并送回瀏覽器的模版晶默。更常見的動態(tài)網(wǎng)站,控制器與模型交互航攒,這是一個PHP對象磺陡,它表示應用程序(如用戶、博客文章)中的一個元素漠畜,并負責與數(shù)據(jù)庫進行通信的币他。調(diào)用模型后,控制器則呈現(xiàn)最終視圖( HTML盆驹,CSS和圖像)圆丹,并返回完整的網(wǎng)頁到用戶的瀏覽器滩愁。Laravel促進了這樣的概念——模型躯喇、視圖和控制器,應通過存儲這些元素在不同的目錄中的單獨的代碼文件中來保持相當?shù)莫毩⑿浴_@就是Laravel目錄結構發(fā)揮了作用廉丽。
? ——laravel文檔
4倦微、數(shù)據(jù)庫設計
使用phpmyadmin來對MySQL數(shù)據(jù)庫進行可視化操作,在MySQL中先創(chuàng)建名為web的數(shù)據(jù)庫正压,然后配置laravel的數(shù)據(jù)庫配置文件/config/database.php如下:
'mysql' => [
? 'driver' => 'mysql',
? 'host' => env('DB_HOST', 'localhost'),
? 'database' => env('DB_DATABASE', 'web'),
? 'username' => env('DB_USERNAME', 'root'),
? 'password' => env('DB_PASSWORD', 'sheng'),
? 'charset' => 'utf8',
? 'collation' => 'utf8_unicode_ci',
? 'prefix' => '',
? 'strict' => false,
],
MySQL數(shù)據(jù)庫中存在的表如下圖所示:
?
部分表的說明:
articles:存放用戶發(fā)布的失物招領文章
article_tag:發(fā)布的文章的標簽
migrations:php做遷移數(shù)據(jù)時產(chǎn)生欣福,與核心功能無關
tags:用戶標簽
users:存放用戶賬戶信息
5、核心代碼實現(xiàn)
web程序的代碼一般都較多焦履,如果把所有的代碼均放到論文里拓劝,事無巨細,一一說明嘉裤,是不現(xiàn)實的郑临,故只會選擇核心的業(yè)務邏輯部分代碼,配以必要的解釋屑宠。在前端方面厢洞,使用了AmazeUI響應式開發(fā)框架和jQuery的JavaScript庫,與流行的bootstrap類似典奉,故對前端的div躺翻,css等樣式也不做過多說明。
著重解釋的主要包括以下內(nèi)容:
- 路由管理
- 用戶管理卫玖,如用戶注冊公你、修改信息、鎖定用戶等
- 文章管理假瞬,如發(fā)表文章省店、修改文章等
- 標簽管理,文章會有一到多個標簽
- 數(shù)據(jù)庫管理笨触,如遷移懦傍、填充數(shù)據(jù)等
- Web表單驗證
- Blade模版引擎
- 分頁處理
- 安全處理
laravel使用blade模板引擎,故視圖文件均須以xxx.blade.php方式命名芦劣,web/resources/views/文件夾下的目錄結構如圖所示:
?
網(wǎng)站入口文件首先會加載的視圖文件是layouts/defalut.blade.php:
<!DOCTYPE html>
<html>
<head lang="zh"><meta charset="UTF-8"/> <title>校園失物招領平臺</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="format-detection" content="telephone=no"/> <meta name="renderer" content="webkit"/> <meta http-equiv="Cache-Control" content="no-siteapp"/> <link rel="alternate icon" type="image/x-icon" href="{{ asset('img/favicon.ico') }}"/> <link rel="stylesheet" /> <link rel="stylesheet" href="{{asset('css/custom.css')}}"> <script src="http://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<header class="am-topbar am-topbar-fixed-top"><div class="am-container"> <h1 class="am-topbar-brand"> <a href="/">校園失物招領平臺</a> </h1> @include('layouts.nav') </div>
</header>
@yield('main')
@include('layouts.footer')
<script src="http://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
<script src="http://cdn.amazeui.org/amazeui/2.7.2/js/amazeui.min.js"></script>
</body>
</html>
其中amazeui前端框架文件以及jQuery文件均是存放在cdn網(wǎng)絡上粗俱,無需在本地加載,精簡了網(wǎng)站文件夾的結構虚吟。
- asset('img/favicon.ico') 會生成 http://localhost:8000/img/favicon.ico
- asset('css/custom.css') 會生成 <link media="all" type="text/css"rel="stylesheet" href="http://localhost:8000/css/custom.css">寸认,其中的 img 和 css 文件夾是放在 public 目錄下的,public 目錄是項目的資源文件夾
- @include('layouts.nav') 會包含 app/views/layouts/nav.blade.php 文件
- @yield('main') 用于模版繼承
大部分的視圖文件都會繼承default.blade.php的模板框架串慰,例如index.blade.php:
@extends('layouts.default')
@section('main')
<div class="am-g am-g-fixed"> <div class="am-u-md-8"> <!-- 循環(huán)輸出文章 --> @foreach ($articles as $article) <article class="blog-main"> <h3 class="am-article-title blog-title"> <a href="{{ URL::route('article.show', $article->id) }}">{{{ $article->title }}}</a> </h3> <h4 class="am-article-meta blog-meta"> 由 <a href="{{ URL::to('user/' . $article->user->id . '/articles') }}">{{{ $article->user->nickname }}}</a> 發(fā)布于 {{ $article->created_at->format('Y/m/d H:i') }} 標簽: <!-- 輸出標簽 --> @foreach ($article->tags as $tag) <a href="{{ URL::to('tag/' . $tag->id . '/articles') }}">{{ $tag->name }}</a> @endforeach </h4> <div class="am-g"> <div class="am-u-sm-12"> @if ($article->summary) <p>{!! $article->summary !!}</p> @endif <hr class="am-article-divider"/> </div> </div> </article> @endforeach </div>
?
- @extends('layouts.default') 會繼承 app/views/layouts/default.blade.php 文件
- @yield('main')對應 @section('main') 并填充為其中的內(nèi)容
用戶登錄表單(在login.blade.php文件中)如下:
<form action="login" method="post" accept-charset="utf-8" class="am-form"> <!-- 添加 token 值 --> <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>"> <label for="email">郵箱: <input type="email" name="email" value="{{Input::old('email')}}" placeholder=""> </label> <br> <label for="password">密碼: <input type="password" name="password" value="" placeholder=""> </label> <br> <label for="remember_me"> <input id="remember_me" name="remember_me" type="checkbox" value="1"> 記住我 </label> <br> <div class="am-cf"> <input type="submit" name="submit" value="登錄" class="am-btn am-btn-primary am-btn-sm am-fl"> </div> </form>
laravel及大多數(shù)php框架使用路由(route)來生成URL偏塞,處理http請求,用戶登錄數(shù)據(jù)的驗證也是放在了路由文件里(web/app/route.php):
//post登陸數(shù)據(jù)
Route::post('login', function(){ //數(shù)據(jù)驗證規(guī)則 $rules = array( 'email' => 'required|email', 'password' => 'required|min:6', 'remember_me' => 'boolean', ); $validator = Validator::make(Request::all(), $rules); //驗證通過 if ($validator->passes()) { if (Auth::attempt([ 'email' => Request::input('email'), 'password' => Request::input('password'), 'block' => 0], (boolean) Request::input('remember_me'))) { return Redirect::to('home'); } //賬號或密碼錯誤 else { return Redirect::to('login')->withInput()->with('message', array('type' => 'danger', 'content' => 'E-mail or password error')); } } //數(shù)據(jù)格式錯誤 else { return Redirect::to('login')->withInput()->withErrors($validator); } });
//訪問主頁
Route::get('home', ['middleware' => 'auth', function()
{
return view('home');
}]);
注冊操作路由:
Route::post('register', function()
{
$rules = ['email' => 'required|email|unique:users,email', 'nickname' => 'required|min:4|unique:users,nickname', 'password' => 'required|min:6|confirmed',
];
$validator = Validator::make(Request::all(), $rules);
if ($validator->passes())
{$user = new App\User(); $user->email = Request::input('email'); $user->nickname = Request::input('nickname'); $user->password = Hash::make(Request::input('password')); if ($user->save()) { return Redirect::to('login')->with('message', array('type' => 'success', 'content' => 'Register successfully, please login')); } else { return Redirect::to('register')->withInput()->with('message', array('type' => 'danger', 'content' => 'Register failed')); }
} else {
return Redirect::to('register')->withInput()->withErrors($validator);
}
});
上面表單驗證規(guī)則的unique:users,email能確保 users 表中的 email 字段是唯一的,例如當輸入已存在的 email 時邦鲫,會出現(xiàn)錯誤提示:
?
若注冊成功就會跳轉到登錄頁面灸叼,并給出成功的提示:
?
用戶發(fā)布失物招領啟事神汹,即文章發(fā)布模塊,在數(shù)據(jù)庫中對應三張表:articles 古今、 tags 以及 article_tag屁魏,每篇文章會有一到多個標簽,每個標簽會有一到多篇文章捉腥。模型文件/app/Article.php和Tag.php氓拼、User.php的核心代碼如下:
User.php:
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{use Authenticatable, CanResetPassword;
/** * The database table used by the model. * * @var string */ protected $table = 'users'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['name', 'email', 'password']; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = ['password', 'remember_token']; //模型關聯(lián) public function articles() { return $this->hasMany('App\Article'); }
}
?
一個用戶會有多篇文章。
?
Article.php:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; //使用軟刪除 traitclass Article extends Model
{use SoftDeletes;
protected $fillable = ['title', 'content'];
public function tags() { return $this->belongsToMany('App\Tag'); } public function user() { return $this->belongsTo('App\User'); }
}
一篇文章會有多個標簽并屬于一個用戶抵碟。
Tag.php:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;class Tag extends Model
{use SoftDeletes;
protected $fillable = ['name'];
public function articles() { return $this->belongsToMany('App\Article'); }
}
一個標簽會有多篇文章桃漾。
此文章編輯器使用了markdown編輯器,markdown簡潔優(yōu)雅的排版格式可以使文章樣式更美觀(可能也需要一定的學習成本)
向數(shù)據(jù)庫中添加文章拟逮,要用到MVC中的control了./web/app/http/Controllers/ArticleController.php的核心代碼如下:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests; use App\Http\Controllers\Controller; use Markdown; use Validator; use App\Article; use Auth; use App\Tag; use Redirect; class ArticleController extends Controller ****** ****** //保存文章 public function store(Request $request) { $rules = [ 'title' => 'required|max:100', 'content' => 'required', 'tags' => ['required', 'regex:/^\w+$|^(\w+,)+\w+$/'], ]; //數(shù)據(jù)校驗 $validator = Validator::make($request->all(), $rules); if ($validator->passes()) { $article = Article::create($request->only('title', 'content')); $article->user_id = Auth::id(); $resolved_content = Markdown::parse($request->input('content')); $article->resolved_content = $resolved_content; $tags = explode(',', $request->input('tags')); //添加 summary if (str_contains($resolved_content, '<p>')) { $start = strpos($resolved_content, '<p>'); $length = strpos($resolved_content, '</p>') - $start - 4; $article->summary = substr($resolved_content, $start + 3, $length); } else if (str_contains($resolved_content, '</h')) { $start = strpos($resolved_content, '<h>'); $length = strpos($resolved_content, '</h>') - $start - 4; $article->summary = substr($resolved_content, $start + 4, $length); } $article->save(); //處理標簽 foreach ($tags as $tagName) { $tag = Tag::whereName($tagName)->first(); if (!$tag) { $tag = Tag::create(array('name' => $tagName)); } $tag->count++; $article->tags()->save($tag); } return Redirect::route('article.show', $article->id); } else { return Redirect::route('article.create')->withInput()->withErrors($validator); } } //展示文章詳情 public function show($id) { return view('articles.show')->with('article', Article::find($id)); }
上面代碼實現(xiàn)了保存文章和顯示文章的業(yè)務邏輯呈队,保存文章時驗證 tags 用了 regex 正則表達式來驗證標簽是否用逗號分隔。
用戶修改已經(jīng)發(fā)布的文章的核心代碼如下:
?
@extends('layouts.default')
@section('main')
<div class="am-g am-g-fixed">
<div class="am-u-sm-12">
<h1>Edit Article</h1>
<hr/>
@if ($errors->has())
<div class="am-alert am-alert-danger" data-am-alert>
<p>{{ $errors->first() }}</p>
</div>
@endif
<form action="{{ URL::route('article.update',$article->id)}}" method="post" accept-charset="utf-8" class="am-form">
<input type="hidden" name="_token" id="token" value="<?php echo csrf_token(); ?>">
<div class="am-form-group">
<label for="title">Title:</label>
<input type="text" name="title" id="title" value="{{ $article->title}}" placeholder="">
</div>
<div class="am-form-group">
<label for="content">Content:</label>
<textarea name="content" id="content" rows="20" >{{ $article->content }}</textarea>
<p class="am-form-help">
<button id="preview" type="button" class="am-btn am-btn-xs am-btn-primary">
<span class="am-icon-eye"></span> Preview
</button>
</p>
</div>
<div class="am-form-group">
<label for="tags">Tags:
<input type="text" name="tags" value="{{ $article->tags }}" placeholder="">
</label>
<p class="am-form-help">Separate multiple tags with a comma ","</p>
</div>
<p><button type="submit" class="am-btn am-btn-success">
<span class="am-icon-pencil"></span> Modify</button>
</p>
</form>
</div>
</div>
<div class="am-popup" id="preview-popup">
<div class="am-popup-inner">
<div class="am-popup-hd">
<h4 class="am-popup-title"></h4>
<span data-am-modal-close
class="am-close">×</span>
</div>
<div class="am-popup-bd">
</div>
</div>
</div>
<script>
$(function() {
$('#preview').on('click', function() {
$('.am-popup-title').text($('#title').val());
$.post('preview', {'content': $('#content').val(),'_token':$('#token').val()}, function(data, status) {
$('.am-popup-bd').html(data);
});
$('#preview-popup').modal();
});
});
</script>
@endsection
標簽是為了給用戶發(fā)布的文章分類唱歧,便于查找相關信息宪摧,其核心代碼實現(xiàn)為:
@extends('layouts.default')
@section('main')
<div class="am-g am-g-fixed blog-g-fixed">
<div class="am-u-sm-12"><table class="am-table am-table-hover am-table-striped "> <thead> <tr> <th>TagName</th> <th>ArticleCount</th> <th>CreateDateTime</th> <th>Managment</th> </tr> </thead> <tbody> @foreach ($tags as $tag) <tr> <td>{{{ $tag->name }}}</td> <td>{{ $tag->count }}</td> <td>{{ $tag->created_at->format('Y-m-d H:i') }}</td> <td> <a href="{{ URL::to('tag/'. $tag->id . '/edit') }}" class="am-btn am-btn-xs am-btn-primary"><span class="am-icon-pencil"></span> Edit</a> <form action="{{ URL::to('tag/'.$tag->id.'/delete')}}" method="get" accept-charset="utf-8" style="display: inline;"> <button type="button" class="am-btn am-btn-xs am-btn-danger" id="delete{{ $tag->id }}"> <span class="am-icon-remove"></span> Delete </button> </form> </td> </tr> @endforeach </tbody> </table>
</div>
</div>
<div class="am-modal am-modal-confirm" tabindex="-1" id="my-confirm">
<div class="am-modal-dialog"><div class="am-modal-bd"> </div> <div class="am-modal-footer"> <span class="am-modal-btn" data-am-modal-cancel>No</span> <span class="am-modal-btn" data-am-modal-confirm>Yes</span> </div>
</div>
</div>
<script>
$(function() {$('[id^=delete]').on('click', function() { $('.am-modal-bd').text('Sure you want to delete it?'); $('#my-confirm').modal({ relatedTarget: this, onConfirm: function(options) { $(this.relatedTarget).parent().submit(); }, onCancel: function() { } }); });
});
</script>
@endsection
錯誤處理:
如果用戶訪問的URL不存在或者服務器存在錯誤時,我們不希望返回一個默認的錯誤頁面颅崩,而想返回一個友好提示的頁面几于,在 Laravel 中可以很輕松地實現(xiàn),Laravel有很簡單的錯誤和日志處理沿后,當服務器端存在錯誤時沿彭,app\Exceptions\Handler.php 里默認有一個報告所有異常的程序:
/**
* Report or log an exception. * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * * @param \Exception $e * @return void */
public function report(Exception $e)
{return parent::report($e);
}
當訪問的URL不存在時,服務器會拋出一個 404 錯誤尖滚,laravel 對 HTTP 異常有特別的處理方式:
@extends('layouts.default')
@section('main')
<h1 style="text-align:center;">啊哦喉刘,你訪問的頁面不存在!</h1> <h2 style="text-align:center;">返回 <a href="/">首頁</a></h2>
@endsection
現(xiàn)在當你訪問的 URL 不存在時,laravel 會自動到模板目錄去尋找狀態(tài)碼為 404 的錯誤模板頁面 404.blade.php
6、測試及操作說明
主頁展示:
整體頁面做的比較簡潔,因為我側重在功能實現(xiàn)耕渴,故對界面設計方面沒有花太多時間雾叭。
用戶登錄:
這里的登錄注冊使用了laravel框架的regex正則表達式匹配豺谈。
登錄之后,會出現(xiàn)文章管理界面:
這里隨便添加了一些測試數(shù)據(jù)。
刪除文章:
點擊刪除文章會調(diào)用一段js代碼,實現(xiàn)模態(tài)彈出框蛛蒙。
發(fā)布文章:
這個編輯器使用了markdown語法來編輯文字,可能對于普通用戶來說有比較高的門檻渤愁,本想用富文本編輯器的牵祟,但是由于時間較為緊張,而markdown插件易于使用抖格,故在beta版本中以此來暫時代替诺苹。
點擊預覽:
這里也調(diào)用了js解析markdown咕晋,生成html。
發(fā)布之后:
這樣一個簡單的失物招領啟事發(fā)布管理系統(tǒng)就完成了筝尾,測試各功能正常。
總結
通過開發(fā)這個校園失物招領平臺办桨,其實就完成了一個最小內(nèi)容管理系統(tǒng)筹淫,一個完整的內(nèi)容管理系統(tǒng)包括這幾個核心的模塊:
- 用戶管理
- 文章管理
- 權限管理
- 標簽管理
90%的網(wǎng)站功能開發(fā)都可以歸納為CRUD(即增刪改查)操作,可能對于一個這樣功能簡單的管理系統(tǒng)來說呢撞,沒有必要去使用重型的laravel框架损姜,看起來有點過度設計了,但是我作為一個php初學者來說殊霞,也是想通過這個機會來學習一下這個優(yōu)秀的框架摧阅,學習框架的過程也加深了對php語言的理解,對于以后開發(fā)更大型的網(wǎng)站能夠積累一點相關經(jīng)驗绷蹲。
這個系統(tǒng)目前還存在很多問題棒卷,比如界面不太符合失物招領的常規(guī)設計,有很多當初的設想也沒能實現(xiàn)祝钢,markdown的編輯器不可能用在面向普通用戶的網(wǎng)頁中比规,入口首頁和留言板功能由于時間關系沒能加上,頗為遺憾拦英。我希望以后能有時間去逐步地完善它蜒什,改造為我的個人博客,或者以此為基礎疤估,實現(xiàn)我一直以來的一個想法——搭建一個學生門戶網(wǎng)站灾常,當然這個工程量就非常大了。
回顧一下這整個的學習開發(fā)過程铃拇,深感不易钞瀑。從最基本的前端html+css+js學起,到php的基本語法慷荔,再到laravel框架的學習仔戈,期間查閱了大量的資料,觀看了100+小時的在線mooc視頻拧廊,才完成了這份課程設計监徘。感謝那些技術博客博主的無私分享,前人的經(jīng)驗與見解避免后人少走了多少彎路吧碾,也由此深感開源分享精神之重要凰盔,正是開源運動才使得現(xiàn)今的互聯(lián)網(wǎng)行業(yè)獲得如此蓬勃的發(fā)展。所以我想在以后的學習過程中倦春,也應當時時勿忘總結個人的經(jīng)驗户敬,并且要分享出來落剪,讓自己的彎路成為別人的橋梁。
也感謝我的小伙伴們的鼓勵和付出尿庐,正是一個團隊的合作才使得這份作品能夠如期完成忠怖。
參考文獻
- 《php與MySQL web程序設計》
- 《html+css+js 網(wǎng)頁設計》
- 《laravel 5.1 官方文檔》
- 眾多博客及慕課網(wǎng)、網(wǎng)易云課堂相關教程