本人第一个laravel项目~

基本流程如下:

  • 编写前端(用作测试)
  • 创建并model,migration,seeder类
  • 编写路由
  • 编写控制器
  • 编写详细逻辑
  • 部署到服务器(本篇不讲)
  • 上传项目到GitHub
    那么我们现在就开始吧

编写前端

实际中请求后端需要设置跨域和CSRF验证.但由于我还不会(我是群里最弱的玩家.jpg),可以先进行如下设置跳过验证:
打开app/Http/Middleware/VerifyCsrfToken.php,其中的$except数组中储存的是可以跳过验证的url
我们可以在其中直接填上'*'让所有请求跳过验证

    protected $except = [
        '*'
    ];

前端使用了一些laravel自带的样式,引了react的外链,使用fetch异步请求后端.前后端交互一般都是使用json形式的post请求.
由于需要加载react的外链,使用时需要联网
没什么好说的,毕竟我的作业主要是后端部分,就直接贴代码了吧
注意文件名一定要是*.blade.php,放到resource/views下或其次级目录下

下面这份代码我自己是保存为baoming.blade.php,放到了resource/views/baoming目录下
后端响应的信息都显示在控制台(懒得写更多样式了)

@extends('layouts.app')
@section('content')
<meta name="csrf-token" content="{{ csrf_token() }}">
<div style="margin-left:35%;width: 25%">
    <form action="javascript:judge();" id="baoming" >
        <div class="form-group">
            <label class="col-md-4 control-label"><span style="color:red">*</span>姓名</label>
            <input class="form-control" name="name" />
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label"><span style="color:red">*</span>性别</label><br/>
            <input type="radio" name="sex" value="male" checked />男
            <input type="radio" name="sex" value="female" style="margin-left:50px" />女
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label"><span style="color:red">*</span>电话号码</label>
            <input class="form-control" name="phone"/>
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label"><span style="color:red">*</span>邮箱</label>
            <input class="form-control" name="email" />
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label"><span style="color:red">*</span>学号</label>
            <input class="form-control" name="xuehao" />
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label"><span style="color:red">*</span>学院</label>
            <input class="form-control" name="college" />
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label"><span style="color:red">*</span>专业</label>
            <input class="form-control" name="major" />
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label">&nbsp备注</label>
            <input class="form-control" name="beizhu" />
        </div>
        <div style="text-align:center;">
            <button type="submit" class="btn btn-primary">
                                    提交
            </button>
        </div>
    </form>
    <div style="text-align:center;">
        <button type="submit" class="btn btn-primary" onclick="showTable();" >
            获取整个表
        </button>
    </div>
</div>
@endsection
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
<script type="text/babel">
    function judge(){
        let Form = document.getElementById("baoming");
        let form_data = {};
        let inputs = Form.getElementsByTagName('input');
        for(let i = 0;i < inputs.length; ++i){
            form_data[inputs[i].name] = inputs[i].value;
        }
            fetch('baoming',{
                method:     'POST',
                headers: {
                            "Content-Type": "text/json"
                },
                body:       JSON.stringify(form_data),
            }).then(function(res){
                if(res.status != 200){
                    console.log("Error, status: " + res.status);
                    return;
                }else{
                    console.log("Success, status: " + res.status);
                    return res;
                }
            }).then(function(res){
                console.log(res.json());
            }).catch(function(err){
                console.log("Fetch error: " + err);
            })
    }

    function showTable() {
        fetch('baoming/show',{
            method:     'POST',
        }).then(function(res){
            if(res.status != 200){
                console.log("Error, status: " + res.status);
                return;
            }else{
                console.log("Success, status: " + res.status);
                return res;
            }
        }).then(function(res){
            console.log(res.json());
        }).catch(function(err){
            console.log("Fetch error: " + err);
        })
    }

</script>

创建并使用Model和Migration类

在项目目录的命令行窗口下,依次输入以下指令

# php artisan make:model Baoming
# php artisan make:migration create_baomings_table

然后找到database/migrations目录下你刚刚创建的名字中含有create_baomings_table.php的文件
在其中的up方法内填入以下内容来创建指定格式的数据表
extra:由于Model类默认的数据表为派生的Model类名+s,所以创建的数据表名为baomings

        Schema::create('baomings', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('sex');
            $table->string('phone');
            $table->string('email');
            $table->string('xuehao');
            $table->string('college');
            $table->string('major');
            $table->string('beizhu')->nullable();
            $table->timestamps();
        });

完成后保存退出,在项目目录命令行下使用以下命令来启用镜像

artisan migrate

在mysql命令行下使用desc baomings可以看到刚刚创建的表的结构

mysql> desc baomings;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255)     | NO   |     | NULL    |                |
| sex        | varchar(255)     | NO   |     | NULL    |                |
| phone      | varchar(255)     | NO   |     | NULL    |                |
| email      | varchar(255)     | NO   |     | NULL    |                |
| xuehao     | varchar(255)     | NO   |     | NULL    |                |
| college    | varchar(255)     | NO   |     | NULL    |                |
| major      | varchar(255)     | NO   |     | NULL    |                |
| beizhu     | varchar(255)     | YES  |     | NULL    |                |
| created_at | timestamp        | YES  |     | NULL    |                |
| updated_at | timestamp        | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
11 rows in set (0.00 sec)

即以int型数字id排序,后面跟上8个字符串,其中beizhu可以为空,再后面跟上时间戳
id和时间戳会在插入数据时自动生成

如果你想插入一些假数据用作测试,可以使用seeder:
在命令行下输入

 php artisan make:seeder BaomingSeeder

然后在database/seeds目录下的BaomingSeeder中的run函数中填入插入数据逻辑

        $selectSex = function($n){
            return ($n % 2 ? 'male' : 'female');
        };
        $writeBeizhu = function($n){
            if($n < 5){
                return 'WD牛逼啊!'.$n;
            }else{
                return null;
            }
        };

         for($i = 0; $i < 10; ++$i){
             \App\Baoming::create([
                 'name'      =>  'TestName'.$i,
                 'sex'       =>  $selectSex($i),
                 'phone'     =>  '123456'.$i,
                 'email'     =>  'TestEmail'.$i.'@email.com',
                 'xuehao'    =>  '2017000'.$i,
                 'college'   =>  'WD第'.$i.'牛逼学院',
                 'major'     =>  'WD第'.$i.'牛逼专业',
                 'beizhu'    =>  $writeBeizhu($i),
             ]);
         }

完成后保存,在同一目录下的DataBaseSeeder.phprun方法中注册播种机

public function run()
    {
        $this->call(BaomingSeeder::class);
    }

完成后回到项目目录,在命令行中运行以下命令来启用播种机

artisan db:seed

运行完成后可以在数据库中查看刚才生成的假数据

编写路由

首先打开routes/web.php
这里我使用的是资源路由.资源路由自带了一些各种方式的http请求的操作处理,可以避免我们编写重复的路由
资源路由的写法如下:

Route::resource('baoming', 'BaomingController');

资源路由中自带的各种操作处理如下:

photos替换为你在资源路由中写入的第一个参数,这里是baoming
第一行是http请求方法,第二行是对应的URL路径,第三行是控制器中对应的方法

不过我需要两个不同的POST请求操作,然而资源路由只自带了一个POST请求的操作,所以还要在下面添加一个post路由.
所以我们填写的路由就变为了:

Route::resource('baoming', 'BaomingController');
Route::post('baoming/show', 'BaomingController@showTable');

编写控制器

首先使用以下命令来创建一个控制器

artisan make:controller BaomingController

生成的控制器在app/Http/Controllers
接下来要编写控制器逻辑
考虑待会要实现三个功能:
1.显示前端页面,由GET方法请求
2.接收前端发送的用户填好的表单,由POST方法请求
3.用户点击按钮后返回数据表中的所有数据,个人使用POST方法请求,GET也可

所以我们需要编写三个方法待路由调用,顺便待会编写详细逻辑时还需要引用自定义的BaomingAPI类,需要用绝对命名空间引用它
写好的整个控制器文件如下

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
//注意这里引用了BaomingAPI
use App\BaomingAPI\BaomingAPI;

class BaomingController extends Controller
{
    //显示前端页面
    public function index(){
        return view('baoming/home');
    }
    //增改数据 
    public function store(Request $request){
        $bm = new BaomingAPI();
        //如果前端发送的是一个post表单,使用$request->all()会得到一个键值对数组
         return response($bm->handle($request->all()));
    }
    //返回所有数据
    public function showTable(Request $request){
        $bm = new BaomingAPI();
        return response($bm->showTable());
    }
}

编写详细逻辑

laravel会自动加载app目录下的所有类,所以自定义类一般放在这个目录下的合适位置,并使用从这个目录开始的绝对命名空间
现在我们就在app目录下创建一个名为BaomingAPI的目录,接着在里面创建一个名为BaomingAPI.php的php文件
并在里面先填上它的命名空间:

<?php namespace App\BaomingAPI;

然后待会需要使用DB类来进行数据库操作,先绝对命名空间引用它吧

use Illuminate\Support\Facades\DB;

然后是创建一个BaomingAPI类,使得控制器调用方便

class BaomingAPI{};

然后我们就可以在这个类里愉快地填上详细逻辑啦

首先考虑一下我们需要什么:
1.两个接口,其中一个用于增改数据,其中一个用于返回整个数据表
2.判断表单是否合法,虽然主要是在前端判断,但是后端也要判断一下防止恶意请求
3.进行数据库操作来实现增改数据
4.一个用于返回各种信息(报错,是否成功等)的键值对数组

在实现的过程中再增加一些细节,最终我们就可以写出如下代码啦~(以下为整个BaomingAPI.php文件)

<?php namespace App\BaomingAPI;
use Illuminate\Support\Facades\DB;
class BaomingAPI{

    private $table = 'baomings';        //数据表名
    private $return_arr = array();     //要返回的键值对数组(最后要转换成json对象再返回)
    private $receive_arr;               //得到的json转换成的键值对数组
    private $should_have =   [          //判断数据是否合法时使用,'beizhu'并非必须项所以在此没有
                'name', 'sex', 'phone', 'email', 'xuehao' , 'college', 'major'
                ];

    private function judge(){
        //判断
        foreach ($this->should_have as $key){
            if(!isset($this->receive_arr[$key])){
                $this->return_arr = array_merge($this->return_arr, ['code' => '-1','message' => $key.'_not_set']);
                return false;
            }else if(mb_strlen($this->receive_arr[$key]) > 30){
                $this->return_arr = array_merge($this->return_arr, ['code' => '-2','message' => $key.'too_long']);
                return false;
            }
        }

        if(isset($this->receive_arr['beizhu'])){
            if(mb_strlen($this->receive_arr['beizhu']) > 256){
                $this->return_arr = array_merge($this->return_arr, ['code' => '-2','message' => 'beizhu_too_long']);
                return false;
            }
        }
        return true;
    }

    private function write(){
        try {
            $name = DB::table($this->table)->where('name','=',$this->receive_arr['name'])->first();
            if($name != null){
                DB::table($this->table)->where('name','=',$this->receive_arr['name'])->update([
                    'sex'       => $this->receive_arr["sex"],
                    'phone'     => $this->receive_arr["phone"],
                    'email'     => $this->receive_arr["email"],
                    'xuehao'    => $this->receive_arr["xuehao"],
                    'college'   => $this->receive_arr["college"],
                    'major'     => $this->receive_arr["major"],
                    'beizhu'    => $this->receive_arr["beizhu"],
                ]);
                return;
            }

            $phone = DB::table($this->table)->where('phone','=',$this->receive_arr['phone'])->first();
            if($phone != null){
                DB::table($this->table)->where('phone','=',$this->receive_arr['phone'])->update([
                    'name'      => $this->receive_arr['name'],
                    'sex'       => $this->receive_arr["sex"],
                    'email'     => $this->receive_arr["email"],
                    'xuehao'    => $this->receive_arr["xuehao"],
                    'college'   => $this->receive_arr["college"],
                    'major'     => $this->receive_arr["major"],
                    'beizhu'    => $this->receive_arr["beizhu"],
                ]);
                return;
            }

            DB::table($this->table)->insert([
                'name'      => $this->receive_arr['name'],
                'sex'       => $this->receive_arr["sex"],
                'phone'     => $this->receive_arr["phone"],
                'email'     => $this->receive_arr["email"],
                'xuehao'    => $this->receive_arr["xuehao"],
                'college'   => $this->receive_arr["college"],
                'major'     => $this->receive_arr["major"],
                'beizhu'    => $this->receive_arr["beizhu"],
            ]);

        }catch(Exception $e){
            $this->return_arr = array_merge($this->return_arr,
                ['code' => '-3', 'message' => '写入数据库失败'.$e->getMessage()]);
        }
    }

    private function returnJson(){
        return json_encode($this->return_arr);
    }

    /**
     * 增改数据
     * @return array(json)
     */
    public function handle($request){
        $this->receive_arr = $request;
        if($this->judge()){
            $this->write();
            if(!isset($this->return_arr['code'])){
                $this->return_arr = array_merge($this->return_arr,["code" => "0","message" => "ok"]);
            }
        }
        return $this->returnJson();
    }

    /**
     * 查询整个表
     * @return array(json)
     */
    public function showTable(){
        $this->return_arr = DB::table($this->table)->get();
        return $this->returnJson($this->return_arr);
    }

};

然后就可以开启服务,访问域名/baoming看看效果啦

将项目上传到GitHub

安装git

首先安装好Git
然后在任意位置右键,选择Git Bash Here打开git命令行

设置账户

先使用以下两行命令设置好你的GitHub账户($不用打,下面都是)

$ git config --global user.name 'yourAccountName'
$ git config --global user.email 'your@email.com'

yourAccountName为你的账户名,your@email.com为你的私人邮箱(即可以用来登录的邮箱)

设置SSH密钥

首先使用以下两行命令来看你本机有没有设置ssh密钥

$ cd ~/.ssh
$ ls

如果出现了以下输出,则说明安装过了

id_rsa  id_rsa.pub  known_hosts

否则使用以下命令来创建(注意要改成你自己的邮箱)

$ ssh-keygen -t rsa -C "your@email.com"

然后再ls,看看有没有创建成功
id_rsa文件里的是你的私钥,id_rsa.pub里的是你的公钥,我们接下来需要将公钥上传给GitHub

那么就先来获取一下公钥,使用以下指令

$ cat id_rsa.pub

会获得一长串输出,类似如下(已打码处理

ssh-rsa AAAAB3NzaC1ycxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxEAW0rKrpHc35fSZNAuKkDLGT4F9JfkMeR2jJa4nV/sOYndVC0TNvaKsDB2V3ihGmsHrPeEb/L elatis@Dwdnba

把得到的所有输出先复制下来
然后在网页上登录你的GitHub,按如下操作



title是为了你自己区分,随意填

创建本地仓库

打开你的项目目录,先把里面的vendor文件夹移出去,因为这个文件夹里的都是项目依赖,可以通过composer install重新安装,不需要上传
然后在里面运行git bash

使用以下命令初始化

$ git init

添加项目下所有文件到本地仓库

$ git add .

创建并关联云端仓库

在GitHub中创建一个仓库(repository):

创建完成后进入仓库,可以看到箭头所指的url,将它复制下来

然后执行以下命令将本地仓库管理到云端仓库:

$ git remote add origin http://github.com/elatisy/mylaravel_-_-.git

注意后面的url要改成你自己的
如果出现错误:fatal: remote origin already exists,那么就先删除关联再重新关联:

$ git remote rm origin
$ git remote add origin http://github.com/elatisy/mylaravel_-_-.git

上传文件

首先输入本次提交说明,每次提交前都要输入,否则git不会开始准备提交暂存区中的已更改文件

$ git commit -m "layout"

其中layout可以替换成本次提交的说明内容

最后执行

$ git push origin master

即可将本地文件上传到云端仓库的master分支
如果出现failed to push som refs to…,可能是云端的文件和本地不同步,它不允许你直接覆盖
就先执行以下命令拉取云端文件

$ git pull origin master

然后再次上传

$ git push origin master

如果还是不行,就使用-f强行上传,当然首先你得先确认云端仓库上的文件你都不需要了

$ git push -f origin master

最后重新进入云端仓库,就可以看到你刚才上传的文件了

总结

本次虽然大致完成了布置的作业,但水平与一个良好的项目还相差甚远
对比学长做的项目可以看出我的架构能力还是不行

而且还有以下几点没有完成:
1.验证请求
2.进行csrf验证
3.设置好跨域

待周末试着完成一下以上三点

标签: none

添加新评论