1. 创建问题的Migration
php artisan make:migration create_questions_table --create=questions
出现错误
[ErrorException]
include(/Users/junchow/Code/laravel/vendor/composer/../../database/migrations/2017_06_22_150313_create_questions_table.php): failed to open stream: No such file or directory
解决方案
composer update
composer dumpautoload
database/migrations/2017_03_02_065319_create_questions_table.php
注意:创建表时表名使用复数形式
2. 创建表结构与操作
increments('id');
$table->timestamps();
// 自定义字段
$table->string('title',64)->comment('问题标题');//标题非空可重复
$table->text('desc')->nullable()->comment('问题描述');//描述为空
$table->unsignedInteger('user_id')->comment('用户编号');
$table->tinyInteger('status')->default(0)->comment('审核状态');
//外键
$table->foreign('user_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('questions');
}
}
# 版本2
Schema::create('questions', function (Blueprint $table) {
$table->increments('id');
$table->string('title',128)->default('')->comment('标题');
$table->text('description')->nullable()->comment('描述');
$table->unsignedInteger('user_id')->default('0')->comment('评论人');
$table->foreign('user_id')->references('id')->on('users');
$table->unsignedInteger('admin_id')->default('0')->comment('审核人');
$table->unsignedInteger('status')->default('0')->comment('审核状态');
$table->timestamps();
});
创建表结构
php artisan migrate --pretend
php artisan migrate:rollback
php artisan migrate
3. 创建问题模型
php artisan make:model Model\Question
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class Question extends Model
{
//
}
4.问题API的实现
在路由文件中为对公共方法进行抽取
/*获取URL地址参数*/
function rq($key=null, $default=null){
if(!$key){
return Request::all();
}
return Request::get($key,$default);
}
/*实例化问题对象*/
function questionInstance(){
return new App\Model\Question;
}
版本2
# 路由文件 route.php 或 web.php 中提取公共方法
use Illuminate\Support\Facades\Request;
/*Common API Function*/
function rq($key=null, $default=null){
return $key ? Request::get($key,$default) : Request::all();
}
//获取 question 模型实例
function question(){
return new Question();
}
接口返回值约定:err为错误状态,err=1表示出错,err=0表示正确。
4.1 增加问题API
建立路由
Route::any('/api/question/add',function(){
return questionInstance()->add();
});
实现方法
/*添加问题API*/
public function add()
{
//判断用户是否登录
if(!userInstance()->isLogin()){
return ['err'=>1, 'msg'=>'请先登录'];
}
//判断必填字段
if(!rq('title')){
return ['err'=>1, 'msg'=>'请填写标题'];
}
//判断可选字段
if(!rq('desc')){
$this->desc = rq('desc');
}
$this->user_id = session('user.id');
$this->title = rq('title');
return $this->save() ? ['err'=>0, 'id'=>$this->id] : ['err'=>1,'msg'=>'添加失败'];
}
接口实现 v2
//API 添加问题
public function add()
{
//判断用户是否登录
if(!user()->islogin()){
return ['err'=>1, 'msg'=>'尚未登录'];
}
$this->user_id = session('user_id');
//判断标题是否传入(必选)
if(!rq('title')){
return ['err'=>1, 'msg'=>'标题不存在'];
}
$this->title = rq('title');
//判断描述是否传入(可选)
if(rq('description')){
$this->description = rq('description');
}
return $this->save() ? ['err'=>0, 'msg'=>'添加成功','id'=>$this->id] : ['err'=>1,'添加失败'];
}
遗留问题
接口中字段的验证,需使用 validator 完善。
4.2 修改问题API
建立路由
Route::any('/api/question/edit',function(){
return questionInstance()->edit();
});
实现方法
/*修改问题API*/
public function edit()
{
//判断用户是否登录
if(!userInstance()->isLogin()){
return ['err'=>1, 'msg'=>'请先登录'];
}
//判断必填字段
if(!rq('id')){
return ['err'=>1, 'msg'=>'参数错误'];
}
//获取记录
$question = $this->find(rq('id'));
//若数据库不存在问题记录
if(!$question){
return ['err'=>1, 'msg'=>'暂无数据'];
}
//问题仅限创建者可修改
if($question->user_id != session('user.id')){
return ['err'=>1, 'msg'=>'权限不足'];
}
//获取用户修改的数据
if(rq('title')){
$question->title = rq('title');
}
if(rq('desc')){
$question->desc = rq('desc');
}
return $question->save() ? ['err'=>0] : ['err'=>1,'msg'=>'修改失败'];
}
实现版本2
// API 编辑问题
public function edit()
{
//判断用户是否登录
if(!user()->islogin()){
return ['err'=>1, 'msg'=>'尚未登录'];
}
//判断问题编号
if(!rq('id')){
return ['err'=>1,'msg'=>'参数错误'];
}
//仅发布人可修改
$question = $this->find(rq('id'));
if(!$question){
return ['err'=>1,'msg'=>'问题不存在'];
}
//仅发布人可修改
if($question['user_id'] != session('user_id')){
return ['err'=>1, 'msg'=>'仅发布人可编辑'];
}
//获取更新字段
if(rq('title')){
$question->title = rq('title');
}
if(rq('description')){
$question->description = rq('description');
}
//数据库更新
return $question->save()?['err'=>0,'msg'=>'编辑成功']:['err'=>1,'编辑失败'];
}
4.3 查看问题API
建立路由
Route::any('/api/question/read',function(){
return questionInstance()->read();
});
实现方法
/*查看问题API*/
public function read()
{
if(rq('id')){
$data = $this->find(rq('id'),['id','title','desc']);
return ['err'=>0, 'data'=>$data];
}
//默认分页查询
$limit = rq('limit')?:15;//每页显示条数
$skip = (rq('page')?:0)*$limit;//页码从0开始
$data = $this->orderBy('created_at')->limit($limit)->skip($skip)->get(['id','title','desc'])->keyBy('id');
return ['err'=>0, 'data'=>$data];
}
实现版本2
//API 查看问题
public function read()
{
//指定ID查询
if(rq('id')){
return ['err'=>0,'data'=>$this->find(rq('id'))];
}
//默认查看多条
$limit = rq('limit') ? : 3;// 每页条数
$skip = (rq('page')?rq('page')-1:0) * $limit;// 页码求位移
$field = ['id','title','description','created_at'];
$data = $this->orderBy('created_at')->limit($limit)->skip($skip)->get($field)->keyBy('id');
//返回 collection 数据
return $data ? ['err'=>0, 'data'=>$data] : ['err'=>1,'暂无数据'];
}
4.4 删除问题API
建立路由
Route::any('/api/question/remove',function(){
return questionInstance()->remove();
});
实现方法
/*删除问题API*/
public function remove()
{
//判断用户是否登录
if(!userInstance()->isLogin()){
return ['err'=>1, 'msg'=>'请先登录'];
}
//判断必填字段
if(!rq('id')){
return ['err'=>1, 'msg'=>'参数错误'];
}
//判断问题是否存在
$question = $this->find(rq('id'));
if(!$question){
return ['err'=>1, 'msg'=>'暂无数据'];
}
//仅有问题所有者才有权限删除
if($question->user_id != session('user.id')){
return ['err'=>1, 'msg'=>'权限不足'];
}
//删除记录
return $question->delete() ? ['err'=>0] : ['err'=>1,'msg'=>'删除失败'];
}
实现版本2
//API 删除问题
public function del()
{
//判断用户是否登录
if(!user()->islogin()){
return ['err'=>1, 'msg'=>'尚未登录'];
}
//判断问题编号是否存在
if(!rq('id')){
return ['err'=>1, 'msg'=>'参数错误'];
}
//判断问题是否存在
$question = $this->find(rq('id'));
if(!$question){
return ['err'=>1, 'msg'=>'数据不存在'];
}
//发布者可删除,审核人可删除(未实现)
if(session('user_id') != $question['user_id']){
return ['err'=>1, 'msg'=>'权限不足'];
}
//返回数据
return $question->delete() ? ['err'=>0,'msg'=>'删除成功'] : ['err'=>1,'msg'=>'删除失败'];
}