Ag和Laravel开发仿知乎笔记-后端
来源:互联网 发布:淘宝怎么搜迷幻蘑菇 编辑:程序博客网 时间:2024/04/28 10:20
结构预览
难点:
Laravel表机制:保证结构复杂的数据的一致性,如何规划数据结构,如何封装为易用且运行稳定的API
使用composer安装laravel
php composer.phar create-project laravel/laravel project disable-tls(前提把composer.phar放在安装目录)
报错:
The openssl extension is required for SSL/TLS protection but is not available. If you can not enable the openssl extensi on, you can disable this error, at your own risk, by setting the 'disable-tls' option to true.
解决:php.ini中extension=php_openssl.dll打开
运行:
php artisan --version 查看版本F:\phpStudy\WWW\Larvael>php -S localhost:8000 -t project/public
配置国内全量镜像Packagist:composer.json
"repositories": { "packagist": { "type": "composer", "url": "https://packagist.phpcomposer.com" }}
小技巧(win):shift 点击鼠表邮件,cmd
Migration:数据库的版本控制
- . 解决团队合作下数据库结构不统一的问题
- SQL语句->PHP语句
create table users( id int(10) unsigned not null auto_increment, username varchar(12), password varchar(255) not null, primary key(id), UNIQUE KEY users_username_unique(username)) engine=innodb;
mysqldump -uroot -p *** > wangba.sql
创建Migration
up:
php artisan make:migration create_table_table1(生成在database)artisan是laravel里面的一个命令行工具
class CreateTableTable1 extends Migration{ /** * Run the migrations. * * @return void */ public function up() { // Schema::create('table',function(Blueprint $table){ $table->increments('id'); $table->string('name',12)->nullable()->unique(); $table->text('name')->nullable(); }); }
php artisan migrate
回滚(down):
public function down() { // Schema::drop('table1'); }
php artisan migrate:rollback
参数:–pretend,预先查看
开发user表:
php artisan make:migration create_table_users --create=users
public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('username')->unique(); $table->text('avatar_url')->nullable(); //默认代替 $table->string('email')->unique()->nullable(); $table->string('phone')->unique()->nullable(); // string or number 区号+,或者未来x $table->string('password',255); $table->text('intro')->nullable(); $table->timestamps(); }); }
php artisan migratephp artisan migrate:rollback(保证都能正确执行)php artisan migrate
注册API的实现
App->Http->routes.php(处理所有网络连接的设置)
如果是字符串,默认返回html/text
如果是数组,默认返回json
laravel 5.3之后就不存在route文件了。
而是改用routes文件夹中的web.php文件。routes->web.php
Route::any('api',function(){ return ['version' => '2.0'];});调用user模块Route::any('api/user',function(){ $user = new App\User; return $user->signup();});
php artisan make:model User 创建一个模板app->User.phpclass User extends Model{ // public function signup(){ return 'signup'; }}
注册API的实现
http://localhost:8000/public/index.php/api/user?username=%E7%8E%8B%E6%B7%B3%E9%BE%99&password=123
dd dorp and die 就是debug
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;use Request;class User extends Model{ // public function signup(){ // dd(Request::get('age')); dd(Request::has('age')); dd(Request::all());// return 'signup'; }}
加密密码:Hash::make(
登陆API的实现
登陆接口:
function user_ins(){ return new App\User;}Route::any('api/login',function(){ return user_ins()->login();});
登陆函数:
public function login(){ // 监测用户名和密码是否存在 // 接受Url参数 $has_username_and_password = $this->has_username_and_password(); if(!$has_username_and_password){ return ['status' => 0,'msg' => '用户名和密码皆不可为空']; }; $username = $has_username_and_password[0]; $password = $has_username_and_password[1]; // 监测用户是否存在 $user = $this->where('username',$username)->first(); if(!$user){ return ['status' => 0,'msg' => '用户不存在 ']; } // 监测密码是否正确 $hashed_possword =$user->password; if(!Hash::check($password,$hashed_possword)) return ['status' => 0,'msg' => '密码有误 ']; return 1; }
注意Laravel的php版本问题。For Laravel 5 you need:
The Laravel framework has a few system requirements:PHP >= 5.4 Mcrypt PHP Extension OpenSSL PHP Extension Mbstring PHPExtension Tokenizer PHP Extension
vendor/laravel/framework/src/Illuminate/Foundation/helpers.php on line 49(做其他项目时切换了下,没注意这个问题)
session:
session()->put('username',$user->username);session()->set('person.name.wangchunlong.age','20');//支持多级嵌套删除session:$_username = session()->pull('username'); //拿出来,剪切session()->forget('username');session()->put('username',null);session()->flush();
问题API的实现
Question Migration的建立(Up和Down)
php artisan make:migration create_table_questions --create=questions
突然写错了,发现删除后重新执行命令报错
[ErrorException] include(F:\phpStudy\WWW\Larvael\project\vendor\composer/../../database/migrations/2017_05_25_062526_create_table_questions.php): failed to open stream: No such file or directory
解决方法:
php artisan cache:clear 删除缓存文件(bootstrap文件夹)composer dump-autoload -ocomposer update 重新加载再生成包含在项目中的列表文件
public function up() { Schema::create('questions', function (Blueprint $table) { $table->increments('id'); $table->string('title',64); $table->text('desc')->nullable()->comment('description'); //description $table->unsignedInteger('user_id'); //无符号整形 $table->unsignedInteger('admin_id'); //防止误操作 $table->string('status')->default('ok'); //status,举报折叠问题 $table->timestamps(); $table->foreign('user_id')->references('id')->on('users'); }); }
php artisan migrate
报错,说users表已经创建,原来这个表之前就没有创建成功。
[Illuminate\Database\QueryException] SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_username_unique`(`username`))
经过查询,是数据库版本过低的原因造成的。
Laravel 5.4更改了默认数据库字符集,现在utf8mb4它包括支持存储emojis。这只会影响新的应用程序,只要你运行MySQL v5.7.7或更高版本,你就不需要做任何事情。
添加代码,限制索引长度:
迁移指南:
编辑AppServiceProvider.php文件,并在boot方法中设置一个默认的字符串长度:
use Illuminate\Support\Facades\Schema;public function boot(){ Schema::defaultStringLength(191);}
删表,重新执行,Good Job。
路由的建立和方法的建立
注意方法名不要和内置方法冲突
function question_ins(){ return new App\Question;}Route::any('api/question/add',function(){ return question_ins()->add();});
php artisan make:model Question
问题添加:
class Question extends Model{ // public function add(){ if(!user_ins()->is_logged_in()){ return ['status' => 0,'msg' => 'login required']; }; if(!rq('title')){ return ['status' => 0,'msg' => 'required title']; } if(rq('desc')) $this->desc = rq('desc'); $this->title = rq('title'); $this->user_id = session('user_id'); return $this->save() ? ['status' => 1,'id' => $this->id] : ['status' => 0,'msg' => 'db insert failed']; }}
小贴士:使用laravel validation可以验证长度,数据类型
自己看
问题更新:
//更新问题Route::any('api/question/refresh',function(){ return question_ins()->refresh();});
//更新问题API public function refresh(){ //检查用户是否登陆 if(!user_ins()->is_logged_in()){ return ['status' => 0,'msg' => 'login required']; } //检查传参中是否有ID if(!rq('id')) return ['status' => 0,'msg' => 'id is required']; //获取指定ID的model $question = $this->find(rq('id')); //返回主键对应的那一行 //用户不存在中断 if(!$question) return ['status' => 0,'msg' => 'user not exisits']; if($question->user_id != session('user_id')){ return ['status' => 0,'msg' => 'permission denied']; } //加判断的原因是有什么更新什么。 if(rq('title')) $question->title = rq('title'); if(rq('desc')) $question->desc = rq('desc'); return $question->save() ? ['status' => 1,] : ['status' => 0,'msg' => 'db refresh failed']; }
查看问题,删除问题(略)……….
回答API的实现
Answers Migration的建立(Up和Down)
php artisan make:migration create_table_answers --create=answers
public function up() { Schema::create('answers', function (Blueprint $table) { $table->increments('id'); $table->text('content'); $table->unsignedInteger('user_id'); $table->unsignedInteger('question_id'); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users'); $table->foreign('question_id')->references('id')->on('questions'); }); }
php artisan migrate --pretendphp artisan migratephp artisan make:model Answer
………
通用API的实现(跨表查询)
点赞和取消赞实现:
answer和user是多对多的关系
Answer模块和User模块下添加注册函数(指明两模块的关系):
public function users(){ return $this->belongsToMany('App\User'); }
public function answers(){ return $this->belongsToMany('App\Answer'); }
建立一个连接表,把answers表和users表通过一个轴表(中间表)连接起来
php artisan make:migration create_table_answer_user --create=answer_user(连接表例外,必须单数)
public function up() { Schema::create('answer_user', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('user_id'); //主键 $table->unsignedInteger('answer_id'); //主键 $table->unsignedSmallInteger('vote'); //赞同1,反对0 $table->timestamps(); $table->foreign('user_id')->references('users')->on('users'); $table->foreign('answer_id')->references('users')->on('answers'); }); }
user_id,answer_id,vote三者组合必须为1,所有需要限制一下(unique)。
$table->unique(['user_id','answer_id','vote']);
php artisan migrate添加php artisan migrate:rollbackphp artisan migrate
添加接口,写vote方法
public function vote(){ if(!user_ins()->is_logged_in()) return ['status' => 0,'msg' => 'logined required'];// answer_id是否存在,赞成还是反对 if(!rq('id') || !rq('vote')) return ['status' => 0,'msg' => 'id or vote is required']; //回答是否存在 $answer = $this->find(rq('id')); if(!$answer) return ['status' => 0,'msg' => 'answer not exists'];// 1赞同 2反对 $vote = rq('vote') <= 1 ? 1 : 2;// 在中间表查找是否有该键,检查用户是否在相同问题下投过票(如果投过票,则delete) $answer ->users() ->newPivotStatement() //进入user_answer连接表进行操作 ->where('user_id',session('user_id')) ->where('answer_id',rq('id')) ->delete();// 在连接表中添加数据 $answer->users()->attach(session('user_id'),['vote' => $vote]); return ['status' => 1]; }
时间线API实现
php artisan make:controller CommonController位置在Http->Controllers->Comm.....
接口
//时间线 @相当于分隔符Route::any('api/timeline','CommonController@timeline');
class CommonController extends Controller{ public function timeline(){ list($limit,$skip) = paginate(rq('page'),rq('limit')); $questions = question_ins() ->limit($limit) ->skip($skip) ->orderBy('created_at','desc') ->get(); $answers = answer_ins() ->limit($limit) ->skip($skip) ->orderBy('created_at','desc') ->get(); //合并两张表数据 $data = $questions->merge($answers);// 按照时间线来排序,把每一条数据存为item $data = $data->sortByDesc(function($item){ return $item->created_at; });// 只取值,不取键 $data = $data->values()->all(); return ['status' => 1, 'data' => $data]; }}
API设计指南
- 命名清晰,准确(功能+思想=名称)
- 第三方API最好有版本号,V0.1.1
- RESTful.http://www.ruanyifeng.com/blog/2014/05/restful_api.html(切末生搬硬套。设计理论,不是规范)
- Ag和Laravel开发仿知乎笔记-后端
- Ag和Laravel开发仿知乎笔记-前端
- Laravel 开发笔记
- Laravel 开发笔记
- Laravel 开发笔记
- 黑大助手后端和Android端开发笔记
- Java网站后端开发笔记
- ag
- ag
- CFM IEEE 802.1ag 笔记
- ThinkPHP开发笔记-前后端数据交互
- python后端开发视频教程学习笔记
- app后端开发三:laravel中使用百度的消息推送
- Laravel 5.2 作为APP后端开发修改系统错误成返回json
- 全栈开发:前后端分离配置篇(vue+webpack+mock+nginx+laravel)
- web前端和后端开发的区别
- 前端和后端分离开发思路
- Laravel发布和开发环境搭建
- java Spring中使用slf4j日志在控制台输出
- 2017计蒜之道程序设计大赛初赛第五场题解
- android studio 中去除应用标题栏
- 礼仪课程-湖南大学 袁涤非
- iOS 开发中遇到的问题
- Ag和Laravel开发仿知乎笔记-后端
- 操作系统原理读书笔记之死锁
- 树莓派USB声卡配置
- 类的无参
- Ubuntu16.04 OpenCV安装笔记
- 使用Mahout实现协同过滤
- 这些年一直记不住的 Java I/O
- 2017计蒜之道程序设计大赛初赛第六场题解
- BFS------迷宫