2023-深入浅出Laravel框架


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

安装这边不记录了,自行官网下载和百度安装就好。

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的版本,否则就有一系列的错误~

  1. 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            # 安装项目模块, 忽略平台问题
  2. 设置应用密钥

    php artisan key:generate  

    结果: 设置成功后会在根目录的.env中有显示:APP_KEY的新值

  3. 配置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.控制器

  1. 创建基础的控制器

    app/Http/Controllers 控制器,逻辑控制,数据获取。
    1. 开启路由服务

      注意: 路由访问控制器时,应该打开app/Provides/RouteServiceProvider.php 中的路由服务

      protected $namespace = 'App\\Http\\Controllers';
    2. 创建基础控制器(可以复制, 但一定要注意默认的命名空间)

            php artisan make:controller UserController # 默认的控制器命名空间:
            
            namespace App\Http\Controllers;  // 默认是这个命名空间
      
      2. 创建完整的控制器
      
         ```php
         php artisan make:controller Admin\UserController --resource
  2. 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',
    ];

}
  1. 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,                           //引擎
    ],
  2. .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也有更简洁用注解去开发。

我们下期文章再见~


文章作者: 千羽
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 千羽 !
评论
  目录