[TOC]
上一篇说到php被迫入门,引起了大部分人关注。好,今天我们来具体体验一下用php框架进行日常开发。
Laravel框架相当于Java的Spring,生态or文档 是很完善的。
之前写Java的mybatis各种sql的和字段的处理,试过php开发之后,确实很快啊。而且我也是从Java,golang裸转的php。这里不谈那种语言好坏之分。开发来说,拥抱技术,拥抱变化,公司用什么技术栈,你就用什么技术。熟练开发就好了。
这里记录一下php框架laravel进行保姆级开发。
1.环境配置
前提:lavarel框架要对应php的版本,否则就有可能报错误~
名称 | 版本号 |
---|---|
Laravel | 7.30.6 |
PHP | 7.4.13 |
Composer | 2.5.8 |
F:\GitHub--Gitee\2023\php\lavarel-learn>php artisan --version
Laravel Framework 7.30.6
F:\GitHub--Gitee\2023\php\lavarel-learn>php -v
PHP 7.4.13 (cli) (built: Nov 24 2020 12:43:30) ( NTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
F:\GitHub--Gitee\2023\php\lavarel-learn>composer --version
Composer version 2.5.8 2023-06-09 17:13:21
F:\GitHub--Gitee\2023\php\lavarel-learn>
安装这边不记录了,自行官网下载和百度安装就好。
Laravel 7 中文文档:https://learnku.com/docs/laravel/7.x/installation/7447
2.创建Laravel项目
## 通过 Laravel 安装器
composer global require laravel/installer
## 使用composer 创建一个为laravel-demo项目
composer create-project --prefer-dist laravel/laravel laravel-demo
## (进入项目后),安装依赖中的包(出现了vendor)
composer install --ignore-platform-reqs
## 启动 项目
php artisan serve # 默认8000端口
php artisan serve --port=8888 ## 或者是 指定端口号 --port=8888
到这一步就启动成功,可访问http://127.0.0.1:8000/ ,浏览器访问即可~
3.demo演示
在路由web.php下进行创建
Route::get('/home/index',function (){
echo "<h2>PHP是世界上最好的语言!!</h2>";
});
浏览器访问:http://127.0.0.1:8000/home/index
4.一些错误处理
lavarel框架要对应php的版本,否则就有一系列的错误~
composer无法安装依赖包
注意:如果出现composer update 无法更新包的情况, “Your requirements could not be resolved to an installable set of packages.” 这是composer版本引起的问题,然后安装成功后就会生成vendor 文件夹 ## 在项目下执行以下命令: composer update --ignore-platform-reqs # 更新Composer,(包的依赖)忽略平台问题 composer install --ignore-platform-reqs # 安装项目模块, 忽略平台问题
设置应用密钥
php artisan key:generate
结果: 设置成功后会在根目录的.env中有显示:APP_KEY的新值
配置mysql数据库
## 在.env文件修改数据库:账号密码
5.lavarel目录文件
app: 应用的核心代码
bootstrap: 少许文件,用于框擘的启动和自动载入百置
config: 应用的所有配活文件
database; 包含数规库迁移文件和境充文件
public: 应用的入口文件,前端资源文件:图片,js,cSs
resources: 视图文件资源
routes: 应用定ssss义的所有路由
storage: 编译后blade模板,session,文件缓存
tests: 自动化测试文件
vendor: 第三方类库,通过composer加载的依赖
6.路由
routes文件中定义路由规则 web.php
Route::get('/', function () {
return view('welcome');
});
Route::get('user/add', function () {
return view('user/add'); // 可以直接访问 resources中的views,
// 返回一个模板文件 html
});
Route::post('user/store',"UserController@store"); // 给这个Url绑定一个控制器
// 后台登录路由
Route::get('admin/login','Admin\LoginController@login',['middleware'=>'cors']);
## 分组路由
Route::group(['prefix' => 'auth','namespace'=>'Admin','middleware'=>'cors'], function(){
Route::post('login', 'AuthController@login');
Route::post('logout', 'AuthController@logout');
Route::post('refresh', 'AuthController@refresh');
Route::post('me', 'AuthController@me');
});
7.控制器
创建基础的控制器
app/Http/Controllers 控制器,逻辑控制,数据获取。
开启路由服务
注意: 路由访问控制器时,应该打开app/Provides/RouteServiceProvider.php 中的路由服务
protected $namespace = 'App\\Http\\Controllers';
创建基础控制器(可以复制, 但一定要注意默认的命名空间)
php artisan make:controller UserController # 默认的控制器命名空间: namespace App\Http\Controllers; // 默认是这个命名空间 2. 创建完整的控制器 ```php php artisan make:controller Admin\UserController --resource
php artisan route:list 查看路由
<?php
namespace App\Http\Controllers; // 引入控制器
use Illuminate\Http\Request; // 引入控制器
use App\Models\User; // 引入模型
class UserController extends Controller
{
// 添加方法
public function add(){
return view("");
}
// 存储方法
public function store(Request $request){
$input = $request->except("_token");
$input["password"] = md5($input["password"]); // md5 数据加密
"password"=>$input['password']]); // 按需求添加数据
$res = User::create($input); // 添加数据
// 1.如果添加成功,跳转到列表页, 否则 ,跳转回原页面
if($res){
return redirect("user/index"); // 跳转到目标页
}else{
return back();
}
}
public function index(){
....
}
}
// 用户模块相关路由
Route::resource(‘user’,’UserController’);
// admin/user 和POST 可以访问 UserController中的store方法
RouteServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* The path to the "home" route for your application.
* This is used by Laravel authentication to redirect users after login.
* @var string
/
public const HOME = '/home';
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* @var string|null
*/
protected $namespace = 'App\\Http\\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
/**
* Configure the rate limiters for the application.
*
* @return void
*/
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
});
}
}
8.Models 模型
app/Http/Models 模型,与数据库进行交互 User.php
php artisan make:model User # 命令行创建模型
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $table = 'blog_user'; // 1.用户模型关联表
protected $primaryKey = 'id'; //2. 关联表的主键
protected $fillable = [ // 3.允许被批量操作的字段, 相当于python的一个Meta中的序列器
'username',
'password',
];
public $timestamps = false; // 4.禁用时间戳
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
MySQL数据库连接
1.database.php数据库 在当前文件中配置mysql基本配置, config/database.php 'mysql' => [ 'driver' => 'mysql', //数据库的类型 'host' => env('DB_HOST', 'localhost'), //数据库的位置 'port' => env('DB_PORT', '3306'), //端口号 'database' => env('DB_DATABASE', 'laravel-test'), //数据库名 'username' => env('DB_USERNAME', 'root'), //用户名 'password' => env('DB_PASSWORD', '123456'), //密码 'charset' => 'gb2312', //字符集 'collation' => 'gb2312_chinese_ci', //排序方式 'prefix' => '', //前缀 'strict' => true, //Strict模式 'engine' => null, //引擎 ],
.env系统环境变量
.env是框架的环境变量,是为了让这个选项在不同环境下有不同的值。
.env文件在laravel根目录下。DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=laravel-test DB_USERNAME=root DB_PASSWORD=123456
如果是导入mysql文件,则不需要执行以下内容。
9.laravel进行增删改查
member表
CREATE TABLE `member` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`age` tinyint(4) NOT NULL,
`email` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
原生sql采取增删改查
9.1 新增
Route::get('/home/test/add', 'TestController@add');
public function add()
{
$db = DB::table('member');
$res = $db->insert([[
'name' => '千羽',
'age' => '18',
'email' => 'shaotongjie@qq.com'
], [
'name' => '千寻',
'age' => '12',
'email' => 'll@qq.com'
]]);
dd($res);
}
9.2 删除
Route::get('/home/test/del', 'TestController@del');
9.3 修改
Route::get('/home/test/update', 'TestController@update');
public function update()
{
$db = DB::table('member');
$res = $db->where('id','=','1')->update([
'name' => '邵桐杰'
]);
dd($res);
}
9.4 查询
Route::get('/home/test/select', 'TestController@select');
public function select()
{
$db = DB::table('member');
$res = $db->get();
dd($res);
}
注意 :
where 方法(and)之后继续调用 where 方法-> where() -> where()-> where()..->
where() -> orWhere() -> orWhere()…
这个语法是并且 (and) 关系语法这个语法是或者 (or) 关系语法
采取model进行sql增删改查(常用)
9.4 查询
laravel中对数据库开发模型非常重要。下面重点细讲解数据库models
下面演示一下开发中常用的编写sql语句
新建sql
CREATE TABLE `laravel_users` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '自动编号',
`username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` char(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`gender` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '男',
`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`price` decimal(8,2) unsigned NOT NULL DEFAULT '0.00',
`details` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`uid` smallint(6) DEFAULT NULL,
`status` tinyint(3) NOT NULL DEFAULT '0' COMMENT '状态',
`list` json DEFAULT NULL,
`created_at` datetime NOT NULL DEFAULT '1997-01-01 01:01:01' COMMENT '创建时间',
`updated_at` datetime NOT NULL DEFAULT '1997-01-01 01:01:01' COMMENT '修改时间',
`is_del` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
编写路由
// 查询user详情
$router->get('user/detail', 'UserController@detail');
新建UserController.php,
public function detail(Request $request)
{
$filter['id'] = $request->get('id');
$result = UserLogic::getInstance()->detail($filter);
return $this->respond($result, 0, '');
}
getInstance这里用到单例模式
/**
* @return static
*/
public static function getInstance()
{
$className = get_called_class();
$args = func_get_args();
//若$args中有resource类型的参数,则无法区分同一个类的不同实例
$key = md5($className . ':' . serialize($args));
if (!isset(self::$instances[$key])) {
//PHP_VERSION >= 5.6.0
self::$instances[$key] = new $className(...$args);
}
return self::$instances[$key];
}
新建UserModel.php
class UserModel extends Base
{
protected $table = 'laravel_users';
public $timestamps = false;
//分布式id改造
protected $distributed=true;
protected $distributedType=2;
protected $distributedTag="fs:f_common:laravel_users";
}
新建UserLogic.php
public function detail(array $where = [])
{
$result = ['detail' => []];
if(empty($where['id'])) {
return $result;
}
$where['is_del'] = 0;
$list = UserModel::query()->where($where)->first();
dd($list->toArray());
}
打开postman查询,进行dd调试
响应
{
"code": 0,
"msg": "",
"info": "",
"data": {
"id": 29,
"username": "千羽",
"password": "123",
"gender": "男",
"email": "qianyu@163.com",
"price": "100.00",
"details": "123",
"uid": 1008,
"status": 2,
"list": null,
"created_at": "2023-11-18 10:09:36",
"updated_at": "2023-11-18 01:01:01",
"is_del": 0
}
}
以上查询就开发完成了,下面进行一些调试处理
打印sql
$list = UserModel::query()->where($where)->first();
dd($list->toSql());
9.2 新增
UserController.php
public function save(Request $request)
{
date_default_timezone_set( 'Asia/Shanghai' );
$body = $request->json()->all();
$data = [];
if (isset($body['username'])) {
$data['username'] = $body['username'];
}
if (isset($body['id'])) {
$data['id'] = $body['id'];
}
if (!empty($body['password'])) {
$data['password'] = $body['password'];
}
if (isset($body['gender'])) {
$data['gender'] = $body['gender'];
}
if (isset($body['email'])) {
$data['email'] = $body['email'];
}
if (isset($body['price'])) {
$data['price'] = $body['price'];
}
if (isset($body['details'])) {
$data['details'] = $body['details'];
}
if (isset($body['status'])) {
$data['status'] = $body['status'];
}
if (isset($body['list'])) {
$data['list'] = $body['list'];
}
if (isset($body['updated_at'])) {
$data['updated_at'] = $body['updated_at'];
}
if (isset($body['created_at'])) {
$data['created_at'] = $body['created_at'];
}
$result = UserLogic::getInstance()->save($data);
return $this->respond($result, 0, '');
}
UserLogic.php
// 新增、更新
public function save(array $data = [], array $user = [])
{
$userMod = UserModel::getInstance();
$res = $userMod->insert($data);
if (empty($res)) {
$this->setErrorInfo(-1, 'insert fail');
return false;
}
return "插入成功";
}
9.3 修改
$res = $userMod->where($where)->update($data);
9.4 删除
$userMod->delete($data)
一般删除是采取软删除,不会把数据真正删除掉。
9.5 分页
$list = $userMod->where($where)
->forpage($page, $limit)
->orderby('create_at', 'desc')
->selectRaw("user.*")
->get();
9.6 联表
$builder = UserModel::query()->from('user AS u')->selectRaw('u.*');
$builderData = $builder->join('contract AS con', 'lg.con_id', '=', 'con.id', 'inner');
内连接,写法非常的简洁。
更高级的用法,更多内容建议看官方文档:https://learnku.com/docs/laravel/7.x/eloquent/7499
总结
laravel框架采取链式查询sql。我觉得重点也在sql编写。更多的sql链式编写查询官方文档,应该是很快可以上手的。
之后还有比laravel更高级的用法lumen框架,就类似Java的mybatis-plus与mybatis。
框架没有好坏之分,Java也有更简洁用注解去开发。
我们下期文章再见~