Laravel 杂记

安装

先检查下PHP的扩展有没有开全:

  1. openssl
  2. fileinfo

## 两种安装方式:


首先确定安装了php 和 composer。安装的时候注意下使用的PHP版本。如果版本太小可能安装不成功。

第一种方式:


新建项目并安装:
d:\a> composer create-project --prefer-dist laravel/laravel blog
在a目录下新建blog目录,并安装laravel框架。

第二种方式:


1.新建目录,进入目录后在命令行下执行:
d:> cd c:\a
d:\a> composer require laravel/installer -- 只安装laravel的new模块命令

2.使用new命令新建项目:
d:\a> vendor\bin\laravel.bat new blog -- 新建目录为blog的项目,建立目录框架
d:\a> vendor\bin\laravel.bat new -- 当前目录做为项目,建立目录框架(建议使用这种方式,因为每个项目使用的Laravel框架的版本可能不同)

3.安装框架:
d:\a> composer require laravel/laravel -- 安装laravel的完整框架

## 框架安装完后的配置:

安装完后复制环境文件:
.env.example 复制为 .env
.evn文件中除了APP和LOG开头的变量全部删除。使用config目录中的php文件进行配置。

创建应用程序key,运行:
d:\a> php artisan key:generate


最后运行laravel自带的开发时的web服务器,可以看到框架的默认页
d:\a> php artisan serve
d:\a> php artisan serve --port=9867  # 指定端口启动

.env参数

APP_ENV
开发: local
测试: testing
预上线: staging
正式环境: production

引入自定义包

"repositories": {
	"packagist": {
	    "type": "composer",
	    "url": "https://mirrors.aliyun.com/composer/"
	}
	"包名":{
	    "type": "vcs",
	    "url": "https://gitee.com/txFramework/xxx.git"
	}
}

Illuminate\Support\Facades\Http

post表单

Http::withHeaders($headers)
        ->contentType($this->contentType)
        ->post($url, $data);

post原始字符串

 Http::withHeaders($headers)
        ->contentType($this->contentType)
        ->send($this->method, $url, ['body'=>$data]);

postJson

Http::withHeaders($headers)
        ->asJson()
        ->contentType($this->contentType) // asJson方法会设置为contentType=application/json造成签名失败,重新设置下contentType
        ->post($url, $data);

参考:PHP Guzzle HTTP 请求库使用方法快速入门 - 可以替代 WP HTTP API 使用 _WordPress智库 

文件上传请求

use Illuminate\Support\Facades\Http;
use GuzzleHttp\Client;

$url = 'http://localhost:9999/a.php';
$filename = 'D:\tmp\2.jpg';

方式一:
// 使用门面
$response = Http::attach('upfile', fopen($filename, 'r'), '5.jpg')->post($url, ['foo'=>'bar']);
return $response->body();

方式二:
$response = Http::asMultipart()->post($url, [
            [
                'name'=>'file_name',
                'filename'=>'4.jpg',
                'contents'=>fopen($filename, 'r')
            ],
            [
                'name'=>'link',
                'contents'=>'aaaaaaaaa'
            ]
        ]);
return $response->body();

方式三:
$client = new Client();
$response = $client->request('POST', $url, [
            'multipart' => [
                [
                    'name' => 'file_name',
                    'filename'=>$filename,
                    'contents' => fopen($filename, 'r')
                ],
                [
                    'name' => 'id_link',
                    'contents' => 'aaa'
                ],
            ]
        ]);

return $response->getBody();

SSL 证书问题:

SSL certificate problem: unable to get local issuer certificate

2种处理方法

1。如果内容不敏感,一个快捷的方法是使用curl_exec()之前跳过ssl检查项。

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

// use Illuminate\Support\Facades\Http;
$response = Http::withoutVerifying()->withHeaders(['Referer' => $referer])->get($url);

2。下载证书

地址:https://curl.se/ca/cacert.pem

配置php.ini,搜索‘curl.cainfo’,修改如下:

curl.cainfo = "D:\phpstudy\Extensions\php\php7.3.4nts\cacert.pem"

 重启服务。

Illuminate\Http\Request

上传文件

$file = $request->file('file');
$filename = $file->getClientOriginalName();
$mimeType = $file->getMimeType();
$realPath = $file->getRealPath();

获取请求原始内容

$content = $request->getContent();

获取全部json

$data = $request->json()->all();

修改视图加载路径:

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\View;
use Illuminate\View\FileViewFinder;

View::addExtension('html','blade');
$finder = new FileViewFinder(App::make ('files'), [public_path()]);
View::setFinder($finder);
return view('page.a.index');

快速复制一条记录:

$resource = Resource::find($id)->replicate();
$resource->name .= ' copy';
$resource->state = '';
$resource->current_page = 0;
$resource->save();

admin_toastr('复制成功', 'success');

Laravel 解决接口数据带T Z格式问题 

model中增加方法:

protected function serializeDate(DateTimeInterface $date)
{
    return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
}

参考:Laravel 解决接口数据带T Z格式问题 - 非你网

 数据库结构

依赖包:composer require doctrine/dbal
参考:https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/schema-manager.html#schema-manager

$databases = DB::connection()->getDoctrineSchemaManager()->listDatabases();
$tables = DB::connection()->getDoctrineSchemaManager()->listTableNames();
$tables = DB::connection()->getDoctrineSchemaManager()->listTables();

问题:
Unknown database type enum requested, Doctrine\DBAL\Platforms\MySQL57Platform may not support it.
解决:
DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');

查询

        $query = Order::where('orders.id', '>', 0);

		$query1 = Status::where('current', 1)->groupBy('statusable_id')->select(['statusable_id']);

		// 子查询
		$query->leftjoinSub($query1, 's', 's.statusable_id', 'orders.id');

		// morpMany加条件
		$orders = $query->get()->each(function($value, $key){
			$value->load(['status'=>function($query){
				$query->where('current', 1);
			}]);
		});
		
		dd($orders->toArray());

添加数据库自动更新时间字段

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddTime extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('file', function (Blueprint $table) {
            $table->timestamp('created_at')->useCurrent();
            $table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('file', function (Blueprint $table) {
            $table->dropTimestamps();
        });
    }
}

在Provider中注册全局中间件

public function register()
    {
        $kernel = $this->app[\Illuminate\Contracts\Http\Kernel::class];
        $kernel->pushMiddleware(OperationLog::class);
    }

 参考:https://segmentfault.com/q/1010000020301323

路由参数

echo Route::currentRouteName(); // room.index
echo Route::currentRouteAction(); // Http\Controllers\RoomController@index

以编程方式执行命令行

Artisan::call('iseed', ['tables'=>$table, '--force'=>true]);

或传整个命令字符串

Artisan::call('mail:send 1 --queue=default');

参考:
https://learnku.com/docs/laravel/8.5/artisan/10381#programmatically-executing-commands

Laravel-admin 初始安装的文件

php artisan admin:install
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (39.43ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (32.03ms)
Migrating: 2016_01_04_173148_create_admin_tables
Migrated:  2016_01_04_173148_create_admin_tables (236.58ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (19.11ms)
Database seeding completed successfully.
Admin directory was created: \app\Admin
HomeController file was created: \app\Admin/Controllers/HomeController.php
AuthController file was created: \app\Admin/Controllers/AuthController.php
ExampleController file was created: \app\Admin/Controllers/ExampleController.php
Bootstrap file was created: \app\Admin/bootstrap.php
Routes file was created: \app\Admin/routes.php

Laravel-admin 配置

.env文件
ADMIN_ROUTE_PREFIX=blog # 修改访问路径由/admin改为/blog

Laravel-admin表单保存前的操作 $form->saveing

$form->text('title', '标题');
$form->text('test', '测试');
$form->file('upfile', '上传文件')->rules('required');
$form->ignore(['test', 'upfile']); // 忽略掉不保存的字段

$form->saving(function (Form $form) {
    $file = request('upfile'); // 获取被忽略掉的字段
    $filename = $file->getClientOriginalName();
    $extension = $file->getClientOriginalExtension();
    $realpath = $file->getRealPath();
    $dst_path = storage_path('app/upload/'.$extension.'/'.date('Ymd').'/');
    $newname = md5($filename.time().rand(1, 1000)).'.'.$extension;
    $realname = $file->move($dst_path, $newname);

    // 添加整理过的字段
    $form->model()->filename = $filename;
    $form->model()->realname = $realname;
    $form->model()->filetype = $extension;
    $form->title = 'new title'; // form中的字段只能通过这种方式改,model方式无效

    if ($form->isCreating()) { // 判断正在创建
        $form->model()->param = '{}';
    }

    if ($form->isEditing()) { // 判断正在修改
        $form->model()->param = '{"a":"a1"}';
    }

    // 报错,阻止表单保存
    $error = new MessageBag([
	'title'   => 'title...',
	'message' => 'message....',
    ]);

    return back()->with(compact('error'));

    // 成功,阻止表单保存
    $success = new MessageBag([
        'title'   => 'title...',
        'message' => 'message....',
    ]);

    return back()->with(compact('success'));
});

$form->saved(function (Form $form) {
    $newId = $form->model()->id;

    // 保存完毕提示
    $success = new MessageBag([
	'title'   => 'title...',
	'message' => 'message....',
    ]);

    return back()->with(compact('success'));
});

laravel-admin 给action传递自定义参数 

use Encore\Admin\Actions\RowAction;

class MyAction extends HandleRowAction
{
    public $name = '名称';

    // 修改按钮样式
    public function getElementClass()
    {
        return 'btn btn-warning '.parent::getElementClass();
    }

    // 增加额外的参数
    public function parameters()
    {
        return ['key'=>$this->row->getAttribute('key')];
    }

    public function handle($request)
    {
        $key = $request->post('key'); // 额外传递的参数
        return $this->response()->success('成功')->refresh();
    }

    public function dialog()
    {
        $this->confirm('确定?');
    }
}

Laravel-admin 模型打印SQL

$grid->model()->getQueryBuilder()->getQuery()->dump();
$grid->model()->getQueryBuilder()->getQuery()->dd();

给URL添加参数(页码),替换掉参数原值

{{request()->fullUrlWithQuery(['page'=>1])}}

.env文件中使用JSON

# .env 配置
JSON_TEST='{"a":1, "b":2, "c":"c3"}'

<?php
$data = json_decode(env('JSON_TEST'), true);
var_dump($data);

模型(Model)主键使用字符串类型

class User extends Model
{
    protected $primaryKey = 'key'; // 字符串类型字段
    public $incrementing = false;

}

模型取关联表的字段值

class User extends Model
{
    use SoftDeletes;


    public function userType()
    {
        return $this->hasOne(UserType::class, 'id', 'user_type_id');
    }
}

// 使用
$user = User::find(1);
$typeName = $user->userType->title;

关联关系

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Order extends Model
{
    use HasFactory;
    use SoftDeletes;

    public function status()
    {
        /**
         * @param  string  $related 子表名
         * @param  string  $name 子表用于关联的字段的前缀($type和$id变量的前缀,单独指定$type、$id的值时$name不起作用)
         * @param  string|null  $type 子表的类型字段名
         * @param  string|null  $id 子表的对应主表的ID字段名
         * @param  string|null  $localKey 主表ID字段名
         */
        return $this->morphMany(Status::class, 'statusable', 'statusable_type', 'statusable_id', 'id');
    }

    public function user()
    {
        return $this->hasOne(User::class, 'id', 'user_id');
    }
}

class Status extends Model
{
    use HasFactory;
	use SoftDeletes;
	
	protected $table = 'status';

	public function user(){
		return $this->hasOne(User::class, 'id', 'user_id');
	}
}

class User extends Authenticatable
{
    use HasFactory, Notifiable;
}

// 查询
private function whereHasTest(){
	$query = Order::whereHas((new Status)->getTable(), function($query){
		$query->where('current', 1) // 主表 exists(子表)
		->whereHas('user', function($query){
			$query->where('id', '>', 0); // 子表exists(子子表)
		});
	});

	// $query = Order::with(['status'=>function($query){
	//     $query->where('current', 1); // 子表in(主表IDs)
	// }]);

	$items = $query->get();

	foreach($items as $item){
		print_r($item->toArray());
		foreach ($item->status as $state) {
			print_r($state->toArray());
			print_r($state->user->toArray());
		}
	}
}

查询条件

$query->whereRaw('FIND_IN_SET("1",type)');

跨域包

Fruitcake\Cors

配置文件:config/cors

supports_credentials = true // 要求验证

参考:laravel fruitcake/laravel-cors 实现前后端分离 api 跨域 – 翻了车的老司机

内置服务器

php artisan serve

Laravel 队列使用

添加redis依赖
composer require predis/predis

修改.env文件
QUEUE_CONNECTION=redis # 默认值是sync(调用job时会立即执行)
REDIS_CLIENT=predis # 指定使用predis,如果不添加这行会去换phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

创建job
php artisan make:job TestQueue

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class JobTest implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $id; // 消息参数

    /**
     * 创建job对象,参数会被存入队列
     *
     * @return void
     */
    public function __construct($id)
    {
        $this->id = $id;
        Log::debug('入队时间: '.date('Y-m-d H:i:s'));
    }

    /**
     * job被执行时调用的方法
     *
     * @return void
     */
    public function handle()
    {
        Log::debug('执行时间: '.date('Y-m-d H:i:s'));
        echo 'queue --> '.$this->id, PHP_EOL;
        Log::debug('ID: '.$this->id);
    }
}

创建一个Command往队列中添加Job
php artisan make:command TestQueue

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Jobs\JobTest;

class TestQueue extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:TestQueue';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '测试队列的运行';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        JobTest::dispatch(1)->delay(3); // 队列延时3秒执行
        echo 'TestQueue...';
    }
}

把command添加到\app\Console\Kernel.php
<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        \App\Console\Commands\TestQueue::class
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')->hourly();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

执行命令监听队列
php artisan queue:listen

执行命令添加队列,并查看监听队列
php artisan command:TestQueue

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值