基於laravel框架構建最小內容管理系統

校園失物招領平臺開發

——基於laravel框架構建最小內容管理系統



摘要

針對目前大學校園人口密度大、人羣活動頻繁、師生學習生活等物品容易遺失的基本現狀,在分析傳統失物招領過程當中的工做效率低下、找回率低、保密性差、管理分散等問題和不足的基礎上,提出了WEB模式的失物招領信息管理平臺。該平臺主要經過失物信息發佈和失物領取功能,較好的解決了傳統失物招領管理過程當中的信息孤島的缺陷,提升了失物招領的工做效率,減小了師生的直接經濟損失,方便了廣大師生的平常生活。 本系統採用了LAMP(ubuntu+Apache+MySQL+php)做爲開發環境,後端php框架使用了目前流行的laravel框架,徹底遵循MVC的設計模式。選用國產開源的響應式HTML5開發框架AmazeUI做爲前端視圖框架,能夠很好地適應移動端頁面佈局。javascript

關鍵詞:校園;失物招領;信息發佈;內容管理系統;php;laravel;MySQL;AmazeUIphp


目錄

1、引言

1.課題研究背景及意義css

2.系統可行性分析html

2、系統需求分析

1.業務流程分析前端

2.用戶體驗分析java

3、系統模塊設計

1.功能模塊mysql

2.用戶界面jquery

4、核心功能的技術實現

1.開發環境linux

2.技術框架laravel

3.數據庫設計

4.MVC設計模式

5.核心代碼實現

6.測試及操做說明

5、總結

6、參考文獻


引言

1. 課題研究背景及意義

大學生因爲攜帶的東西較多,活動多,並且常常來往於不一樣的地 方,所以很容易發生物品丟失的狀況,而目前咱們學校又缺少一套行之有效的能夠幫助學生尋找失物的系統。考慮到大學生廣泛上網,並且校園網絡覆蓋率高, 那麼就經過網絡這一便捷高效的方式來實現一個失物招領系統,優化失物招領業務,使得失物招領管理清晰化、透明化,便於操做,易於管理。經過本系統,拾主能夠經過這個平臺發佈最新的招領啓事以通知大 家,而失主能夠經過這個平臺尋找和聯繫拾主。而且只要是網站的註冊用戶,就能夠發佈管理文章、留言,這樣不只財產上的損失避 免了,還增強了人與人之間的交流。因此說開發這個失物招領平臺,定會大大便利校園內廣大師生的生活,沒必要再爲丟失尋找物品這類雜事煩擾,真正地讓技術服務於生活。

2.系統可行性分析

  • 技術可行性

    利用穩定的ubuntu linux做爲服務器環境,Apache處理客戶端與服務端的通訊,MySQL數據庫存放用戶信息和發佈的文章、留言,php做爲後端語言,實現動態頁面處理,再加上簡潔優雅的響應式前端開發框架,能夠開發出符合要求的管理系統。

  • 經濟可行性

    網站平臺的開發及後期的運營維護所需的人力物力不多,而且能夠部署在學校的服務器上,由網絡服務中心的工做人員統一管理。

  • 社會可行性

    在校園裏,咱們常常見到這樣一幕,一位同窗在熱水房門口一遍一遍尋找,而後口裏說着,怎麼又不見了呢?,一邊不甘心的再找一遍。又或許是這麼一幕,「尋物啓事——宿舍號,丟失物品,最後再詛咒一下那些撿拾物品不還的人。」現有失物招領處工做繁瑣且效率低,所以開發失物招領管理系統是很是必要的。


系統需求分析

一、業務流程

業務流程分析能夠幫助開發者瞭解該業務處理過程,發現和處理系統調查工做中的錯誤和疏漏。業務流程分析是經過業務流程圖來進行,即用一些規定的符號及連線來表示某個具體業務處理過程。

本系統具體的業務流程以下圖所示:

二、用戶體驗分析

用戶體驗是現今產品開發過程當中很是重視的一個方面,咱們開發出一款產品或者提供一項服務,其最終面向的是不重視或不在意技術層面的廣大用戶,所以在界面友好性、直觀性、易於操做性方面必須加以考慮。本失物招領系統按照下述原則進行:

  • 實用性:系統以用戶需求爲目標,以方便用戶使用爲原則,充分考慮實際操做的各項細節,使得普通用戶在打開頁面的第一眼即能對操做流程有清晰的理解。真正構建起一個爲師生服務的平臺,爲用戶的在線失物招領查詢發佈提供方便。
  • 高安全性:在設計中,將充分考慮網絡軟、硬件方面的各類安全措施,保障用戶數據信息安全。好比用戶存放在數據庫的帳號密碼採用php的哈希加密,即便數據庫泄露,看到的也將是一堆亂碼。
  • 可維護性:網站的設計要求方便維護,文件目錄及代碼結構清晰。
  • 可擴展性:網站的設計以方便將來的擴展和系統擴充爲目標,系統要求可以方便升級,方便添加功能模塊。

系統模塊設計

1.功能模塊

本管理系統主要可以實現用戶註冊、用戶(管理員)登陸、首頁展現、失物招領的文章發佈、留言板、後臺管理, 以及標籤管理等幾大模塊的功能:

  • 用戶註冊:本功能主要是實現對用戶信息的註冊管理
  • 用戶(管理員)登陸:本功能主要實現用戶(管理員)登陸的功能
  • 首頁模塊:本模塊主要是對失物招領文章的展現功能、添加功能、查看詳情功能及各模塊入口
  • 留言板模塊:主要是實現用戶(管理員)留言功能,以供用戶反饋
  • 後臺管理:用戶信息管理、失物招領文章管理、留言板留言管理、管理員信息管理、標籤管理

本系統主要功能結構以下圖所示:

二、用戶界面

  • 註冊頁面:本界面主要採集註冊用戶的信息,而後存入系統數據庫
  • 登陸頁面:本頁面根據登陸用戶的信息和類型進行驗證登陸
  • 首頁:本頁面展現用戶所發佈的失物招領的文章,以及文章的標籤
  • 留言板頁面:本頁面顯示歷史留言和添加留言的版塊
  • 用戶信息頁面:本頁面顯示當前登陸的用戶的信息及發佈的文章管理
  • 管理頁面:本頁面是管理員對本網站各個版塊進行管理的可視化操做頁面

核心功能的技術實現

一、開發環境

網站的本地開發環境使用lamp(即Linux+Apache+MySQL+PHP)。lamp是一組經常使用來搭建動態網站或者服務器的開源軟件,自己都是各自獨立的程序,可是由於常被放在一塊兒使用,擁有了愈來愈高的兼容度,共同組成了一個強大的Web應用程序平臺。lamp的全部開發工具都是開源軟件,隨着開源潮流的蓬勃發展,能夠預見lamp會是將來web開發的主流,而且因爲其零成本、學習資料多,天然成爲個人首選開發環境。

二、技術框架

後端的php框架選用了國外流行的開源框架——laravel,也是號稱「最簡潔、優雅的php web開發框架」,基於此能夠快速、高效地構建一個web APP,Laravel的目標是給開發者創造一個愉快的開發過程,而且不犧牲應用的功能性。剛開始學習php開發沒多久,對php的一些框架了解甚少,在csdn上看到一篇文章《php開發框架流行度排名:laravel居首》,才知道有laravel這麼一個框架,而且其文件目錄、代碼結構清晰,基於MVC的設計模式,對初學者較友好,故選用了此框架,本篇課程設計很大程度上也算是我對laravel框架的學習實踐吧。php的應用框架衆多,如國產的thinkPHP框架在國內也使用者甚廣,前期曾嘗試使用thinkPHP來開發,其結構代碼簡單直接,易於上手,但在代碼規範性方面譭譽參半,不適合初學者養成良好的編碼習慣,故棄之。

下面就對laravel框架體系結構做簡要介紹。

Laravel被稱爲「全棧」式框架,由於它可以處理從網絡服務到數據庫管理、HTML生成的一切事情,垂直集成的web開發環境給開發者提供了更好的體驗。開發人員能夠經過命令行工具,生成和管理Laravel項目環境。 Laravel帶有一個名爲Artisan的優秀的命令行工具,能夠用它來生成框架代碼和數據庫架構,Artisan可以處理從數據庫架構遷移到資源和配置管理的一切事情。

laravel項目使用composer來建立(Composer是PHP中用來管理依賴(dependency)關係的工具。你能夠在本身的項目中聲明所依賴的外部工具庫(libraries),Composer會幫你安裝這些依賴的庫文件)。在linux終端中執行:

$ composer create-project laravel/laravel --prefer-dist web 5.1

就會在/home目錄下建立一個名爲web的項目文件夾,指定的laravel版本爲5.1 。其目錄結構以下圖所示:

下面是各個文件夾和文件的基本介紹:

頂級文件夾 做用
app 包含了站點的controller(控制器),models(模型),views(視圖)和assets(資源)。這些事網站運行的主要代碼,你將會花費大部分的時間在這些上面。
bootstrap 用來存放系統啓動時須要的文件,這些文件會被如index.php這樣的文件調用。
這個文件夾是外界惟一能夠看到的,是必須指向你web服務器的目錄。它含有laravel框架核心的引導文件index.php,這個目錄也能夠用來存聽任何能夠公開的靜態資源,如css,JavaScript,images等。
vendor 用來存放全部的第三方代碼,在一個典型的laravel應用程序,這包括larceny源代碼及其相關,並含有額外的預包裝功能的插件。

如上所述,/app是其核心部分,/app文件夾的詳細信息以下:

下面是詳細介紹:

文件及文件夾 做用
/app/config/ 配置應用程序的運行時規則、 數據庫、 session等等。包含大量的用來更改框架的各個方面的配置文件。大部分的配置文件中返回的選項關聯PHP數組。
/app/config/app.php 各類應用程序級設置,即時區、 區域設置(語言環境)、 調試模式和獨特的加密密鑰。
/app/config/auth.php 控制在應用程序中如何進行身份驗證,即身份驗證驅動程序。
/app/config/cache.php 若是應用程序利用緩存來加快響應時間,要在此配置該功能。
/app/config/compile.php 在此處能夠指定一些額外類,去包含由‘artisan optimize’命令聲稱的編譯文件。這些應該是被包括在基本上每一個請求到應用程序中的類。
/app/config/database.php 包含數據庫的相關配置信息,即默認數據庫引擎和鏈接信息。
/app/config/mail.php 爲電子郵件發件引擎的配置文件,即 SMTP 服務器。
/app/config/session.php 控制Laravel怎樣管理用戶sessions,即session driver, session lifetime。
/app/config/view.php 模板系統的雜項配置。
/app/controllers 包含用於提供基本的邏輯、 數據模型交互以及加載應用程序的視圖文件的控制器類。
/app/database/migrations/ 包含一些 PHP 類,容許 Laravel更新當前數據庫的架構並同時保持全部版本的數據庫的同步。遷移文件是使用Artisan工具生成的。
/app/database/seeds/ 包含容許Artisan工具用關係數據來填充數據庫表的 PHP 文件。
/app/lang/ PHP 文件,其中包含使應用程序易於本地化的字符串的數組。默認狀況下目錄包含英語語言的分頁和表單驗證的語言行。
/app/models/ 模型是表明應用程序的信息(數據)和操做數據的規則的一些類。在大多數狀況下,數據庫中的每一個表將對應應用中的一個模型。應用程序業務邏輯的大部分將集中在模型中。
/app/start/ 包含與Artisan工具以及全球和本地上下文相關的自定義設置。
/app/storage/ 該目錄存儲Laravel各類服務的臨時文件,如session, cache, compiled view templates。這個目錄在web服務器上必須是能夠寫入的。該目錄由Laravel維護,咱們能夠不關心。
/app/tests/ 該文件夾給你提供了一個方便的位置,用來作單元測試。若是你使用PHPUnit,你可使用Artisan工具一次執行全部的測試。
/app/views/ 該文件夾包含了控制器或者路由使用的HTML模版。請注意,這個文件夾下你只能放置模版文件。其餘的靜態資源文件如css, javascript和images文件應該放在/public文件夾下。
/app/filters.php 此文件包含各類應用程序和路由篩選方法,用來改變您的應用程序的結果。Laravel 具備訪問控制和 XSS 保護的一些預約義篩選器。
/app/routes.php 這是您的應用程序的路由文件,其中包含路由規則,告訴 Laravel 如何將傳入的請求鏈接到路由處理的閉包函數、 控制器和操做。該文件還包含幾個事件聲明,包括錯誤頁的,能夠用於定義視圖的composers。

三、模型-視圖-控制器(MVC)

/app文件夾下有三個子目錄:models/,views/和controllers/。這說明laravel遵循MVC架構模式。這就是強制將輸入到展現邏輯關係的「業務邏輯」與圖形用戶界面(GUI)分開。就laravel web應用而言,業務邏輯一般由像用戶,文章這樣的數據模型組成。GUI只是瀏覽器中的網頁而已。MVC設計模式在web開發領域中很流行。

MVC模式包括三個組件:

  • 模型(model)
  • 視圖(view)
  • 控制器(controller)

一個典型的laravel應用程序包含上面提到的MVC組件,以下圖:


laravel的響應流程

當與Laravel交互時,瀏覽器發送一個請求,web服務器接收到請求而且傳給Laravel路由引擎。Laravel路由接收到請求,而後重定向給基於路由的URL模式的合適的控制器類方法。而後控制器類接管。在某種狀況下,控制器會當即呈現出一個視圖,它是一個被轉換成HTML並送回瀏覽器的模版。更常見的動態網站,控制器與模型交互,這是一個PHP對象,它表示應用程序(如用戶、博客文章)中的一個元素,並負責與數據庫進行通訊的。調用模型後,控制器則呈現最終視圖( HTML,CSS和圖像),並返回完整的網頁到用戶的瀏覽器。Laravel促進了這樣的概念——模型、視圖和控制器,應經過存儲這些元素在不一樣的目錄中的單獨的代碼文件中來保持至關的獨立性。這就是Laravel目錄結構發揮了做用。

​ ——laravel文檔

四、數據庫設計

使用phpmyadmin來對MySQL數據庫進行可視化操做,在MySQL中先建立名爲web的數據庫,而後配置laravel的數據庫配置文件/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數據庫中存在的表以下圖所示:

部分表的說明:

articles:存放用戶發佈的失物招領文章

article_tag:發佈的文章的標籤

migrations:php作遷移數據時產生,與核心功能無關

tags:用戶標籤

users:存放用戶帳戶信息

五、核心代碼實現

web程序的代碼通常都較多,若是把全部的代碼均放到論文裏,事無鉅細,一一說明,是不現實的,故只會選擇核心的業務邏輯部分代碼,配以必要的解釋。在前端方面,使用了AmazeUI響應式開發框架和jQuery的JavaScript庫,與流行的bootstrap相似,故對前端的div,css等樣式也不作過多說明。

着重解釋的主要包括如下內容:

  • 路由管理
  • 用戶管理,如用戶註冊、修改信息、鎖定用戶等
  • 文章管理,如發表文章、修改文章等
  • 標籤管理,文章會有一到多個標籤
  • 數據庫管理,如遷移、填充數據等
  • Web表單驗證
  • Blade模版引擎
  • 分頁處理
  • 安全處理

laravel使用blade模板引擎,故視圖文件均須以xxx.blade.php方式命名,web/resources/views/文件夾下的目錄結構如圖所示:

網站入口文件首先會加載的視圖文件是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" href="http://cdn.amazeui.org/amazeui/2.7.1/css/amazeui.min.css"/> <link rel="stylesheet" href="{{asset('css/custom.css')}}"> <script src="//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="//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網絡上,無需在本地加載,精簡了網站文件夾的結構。

  • 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"> <!-- 循環輸出文章 --> @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> 發佈於 {{ $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') 並填充爲其中的內容

用戶登陸表單(在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及大多數php框架使用路由(route)來生成URL,處理http請求,用戶登陸數據的驗證也是放在了路由文件裏(web/app/route.php):

//post登錄數據
Route::post('login', function()

``` { //數據驗證規則 $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')); } } //數據格式錯誤 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); ```

}
});

上面表單驗證規則的unique:users,email能確保 users 表中的 email 字段是惟一的,例如當輸入已存在的 email 時,會出現錯誤提示:

若註冊成功就會跳轉到登陸頁面,並給出成功的提示:

用戶發佈失物招領啓事,即文章發佈模塊,在數據庫中對應三張表: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']; //模型關聯 public function articles() { return $this->hasMany('App\Article'); } ```

}

一個用戶會有多篇文章。

Article.php:

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; //使用軟刪除 trait

class 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簡潔優雅的排版格式可使文章樣式更美觀(可能也須要必定的學習成本)

向數據庫中添加文章,要用到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+$/'], ]; //數據校驗 $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)); } ```

上面代碼實現了保存文章和顯示文章的業務邏輯,保存文章時驗證 tags 用了 regex 正則表達式來驗證標籤是否用逗號分隔。

用戶修改已經發布的文章的核心代碼以下:

@extends('layouts.default')

@section('main')
<div class="am-g am-g-fixed">
<div class="am-u-sm-12">

&lt;h1&gt;Edit Article&lt;/h1&gt;
  &lt;hr/&gt;
@if ($errors-&gt;has())
&lt;div class="am-alert am-alert-danger" data-am-alert&gt;
  &lt;p&gt;{{ $errors-&gt;first() }}&lt;/p&gt;
&lt;/div&gt;
@endif


<form action="{{ URL::route('article.update',$article->id)}}" method="post" accept-charset="utf-8" class="am-form">

&lt;input type="hidden" name="_token" id="token" value="&lt;?php echo csrf_token(); ?&gt;"&gt;
  &lt;div class="am-form-group"&gt;
    &lt;label for="title"&gt;Title:&lt;/label&gt;
    &lt;input type="text" name="title" id="title" value="{{ $article-&gt;title}}" placeholder=""&gt;
  &lt;/div&gt;
  &lt;div class="am-form-group"&gt;
    &lt;label for="content"&gt;Content:&lt;/label&gt;
    &lt;textarea name="content" id="content" rows="20" &gt;{{ $article-&gt;content }}&lt;/textarea&gt;
    &lt;p class="am-form-help"&gt;
      &lt;button id="preview" type="button" class="am-btn am-btn-xs am-btn-primary"&gt;
      &lt;span class="am-icon-eye"&gt;&lt;/span&gt; Preview
      &lt;/button&gt;
    &lt;/p&gt;
  &lt;/div&gt;
  &lt;div class="am-form-group"&gt;
    &lt;label for="tags"&gt;Tags:
        &lt;input type="text" name="tags" value="{{ $article-&gt;tags }}" placeholder=""&gt;
    &lt;/label&gt;
    &lt;p class="am-form-help"&gt;Separate multiple tags with a comma ","&lt;/p&gt;
  &lt;/div&gt;
  &lt;p&gt;&lt;button type="submit" class="am-btn am-btn-success"&gt;
    &lt;span class="am-icon-pencil"&gt;&lt;/span&gt; Modify&lt;/button&gt;
  &lt;/p&gt;
&lt;/form&gt;
&lt;/div&gt;

</div>

<div class="am-popup" id="preview-popup">
<div class="am-popup-inner">

&lt;div class="am-popup-hd"&gt;
  &lt;h4 class="am-popup-title"&gt;&lt;/h4&gt;
  &lt;span data-am-modal-close
        class="am-close"&gt;×&lt;/span&gt;
&lt;/div&gt;
&lt;div class="am-popup-bd"&gt;
&lt;/div&gt;
&lt;/div&gt;

</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

標籤是爲了給用戶發佈的文章分類,便於查找相關信息,其核心代碼實現爲:

@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 中能夠很輕鬆地實現,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

如今當你訪問的 URL 不存在時,laravel 會自動到模板目錄去尋找狀態碼爲 404 的錯誤模板頁面 404.blade.php

六、測試及操做說明

主頁展現:

總體頁面作的比較簡潔,由於我側重在功能實現,故對界面設計方面沒有花太多時間。

用戶登陸:

這裏的登陸註冊使用了laravel框架的regex正則表達式匹配。

登陸以後,會出現文章管理界面:

這裏隨便添加了一些測試數據。

刪除文章:


點擊刪除文章會調用一段js代碼,實現模態彈出框。

發佈文章:

這個編輯器使用了markdown語法來編輯文字,可能對於普通用戶來講有比較高的門檻,本想用富文本編輯器的,可是因爲時間較爲緊張,而markdown插件易於使用,故在beta版本中以此來暫時代替。

點擊預覽:

這裏也調用了js解析markdown,生成html。

發佈以後:

這樣一個簡單的失物招領啓事發布管理系統就完成了,測試各功能正常。

總結

經過開發這個校園失物招領平臺,其實就完成了一個最小內容管理系統,一個完整的內容管理系統包括這幾個核心的模塊:

  • 用戶管理
  • 文章管理
  • 權限管理
  • 標籤管理

90%的網站功能開發均可以概括爲CRUD(即增刪改查)操做,可能對於一個這樣功能簡單的管理系統來講,沒有必要去使用重型的laravel框架,看起來有點過分設計了,可是我做爲一個php初學者來講,也是想經過這個機會來學習一下這個優秀的框架,學習框架的過程也加深了對php語言的理解,對於之後開發更大型的網站可以積累一點相關經驗。

這個系統目前還存在不少問題,好比界面不太符合失物招領的常規設計,有不少當初的設想也沒能實現,markdown的編輯器不可能用在面向普通用戶的網頁中,入口首頁和留言板功能因爲時間關係沒能加上,頗爲遺憾。我但願之後能有時間去逐步地完善它,改造爲個人我的博客,或者以此爲基礎,實現我一直以來的一個想法——搭建一個學生門戶網站,固然這個工程量就很是大了。

回顧一下這整個的學習開發過程,深感不易。從最基本的前端html+css+js學起,到php的基本語法,再到laravel框架的學習,期間查閱了大量的資料,觀看了100+小時的在線mooc視頻,才完成了這份課程設計。感謝那些技術博客博主的無私分享,前人的經驗與看法避免後人少走了多少彎路,也由此深感開源分享精神之重要,正是開源運動才使得現今的互聯網行業得到如此蓬勃的發展。因此我想在之後的學習過程當中,也應當時時勿忘總結我的的經驗,而且要分享出來,讓本身的彎路成爲別人的橋樑。

也感謝個人小夥伴們的鼓勵和付出,正是一個團隊的合做才使得這份做品可以如期完成。

參考文獻

  1. 《php與MySQL web程序設計》
  2. 《html+css+js 網頁設計》
  3. 《laravel 5.1 官方文檔》
  4. 衆多博客及慕課網、網易雲課堂相關教程

原文地址:https://www.jianshu.com/p/d86135aee612

相關文章
相關標籤/搜索