Skip to content

Laravel - FAQ

Laravel 6.0 升级到 6.x 记录

composer 2.0

composer 2.0 版本和 laravel 6.0 版本不兼容

这个是 laravel 6.0 lts 版本的问题, 由于更改了加载方式, 这个方式在 6.0 版本中没有被修复导致的问题,
可以查看 : composer/composer/issues/9340

对于 laravel 版本的支持程度可以查看

这里的解决问题的办法是强制使用 composer 1.x 版本

$ composer self-update --1

相关组件

为了使用 composer 2.x, 我把 laravel 6.0 升级到 6.x , 因为 laravel 自 6.18 之后才支持 composer 2, 同时升级的组件还有

json
{
    ...
    "require": {
        tucker-eric/eloquentfilter: "~2"
        =>
        "3"
    },
    "require-dev": {
        "itsgoingd/clockwork": "~4.0"
        =>
        "~5.0"
        "barryvdh/laravel-ide-helper": "~2.7"
        =>
        "~2.*"
        "doctrine/dbal": "^2.5"
        =>
        "^3"
    }
    ...
}

Method Monolog\Logger::addDebug() does not exist

重新命名一下之前的 ide-helper.php 重新发布一下配置

$ php artisan vendor:publish --provider="Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider" --tag=config

移除 Log 部分

diff
'magic' => [
-   'Log' => [
-     'debug'     => 'Monolog\\Logger::addDebug',
-     'info'      => 'Monolog\\Logger::addInfo',
-     'notice'    => 'Monolog\\Logger::addNotice',
-     'warning'   => 'Monolog\\Logger::addWarning',
-     'error'     => 'Monolog\\Logger::addError',
-     'critical'  => 'Monolog\\Logger::addCritical',
-     'alert'     => 'Monolog\\Logger::addAlert',
-     'emergency' => 'Monolog\\Logger::addEmergency',
-  ],
],

Laravel 5.5 升级到 6.0 记录

1. 可以选择缓存使用 phpredis/predis

phpredis : 指的是使用 pecl 安装的 php 扩展 redis

predis : 指的是 github 上的 predis/predis 的包

Laravel 推荐使用 phpredis 来代替 predis 。原因是 predis 包很长时间没有更新

所以要记得先安装 phpredis , 然后在 config/app.php 中去掉 Redis 别名

Mac 安装

# 这里需要将当前版本设置为主版本才可以, 如果不是主版本则安装会太费劲
$ brew link --force php@{version}
$ pecl install igbinary
$ pecl install redis
$ brew services restart php@7.2

其他平台

应该是直接安装即可(未测试)

项目中在考虑兼容的情况下, 使用 predis, 暂时不启用 phpredis.

2. Unable to create configured logger. Using emergency logger

在 5.6 之后已经将配置文件独立 config/logging.php, 将这个文件放置到指定目录, 然后 app.php
移除日志的配置 Logging Configuration

3. Call to undefined method Illuminate\Events\Dispatcher::fire()

在 (5.8 升级指南)( https://laravel.com/docs/5.8/upgrade ) 指出,

Likelihood Of Impact: Low

deprecated and removed
Events The fire Method

使用 dispatch 方法替代 You should use the dispatch method instead.

4. Class 'Illuminate\Support\Facades\Input' not found

使用 Request 替代 Input

Input no longer exists. Either use the Request facade or alias that instead of Input .

5. str_contains 等 helper 函数

这些函数均需要替换成静态函数方法 Str::contains

下面是 辅助函数列表

5.1 辅助函数列表

Laravel 使用

Laravel 错误 Class log does not exist ...

Fatal error: Uncaught exception 'ReflectionException' with message 'Class log does not exist' in
/Users/freek/dev/laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:776

出现这种问题的原因是不能够加载 log 方法. 原因是在加载的时候会加载 config 文件的数据, 而 config 文件中的配置是批量加载的, 所以在自己加载的时候 config
文件的写法不支持自定义的函数变量/ 常量/ 自定义方法.

所以从配置文件入手, 删除未加载的配置文件, 删除未导入包的配置文件.

这种问题一般出现在 复制项目, 并且删除了包的情况下.

控制器数值类不能使用 int 类型

Argument 1 passed to Poppy\Sms\Http\Request\Backend\SmsController::destroy() must be of the type int or null, string given, called in
/Users/duoli/Documents/workbench/dl.poppy/dev-v4/vendor/laravel/framework/src/Illuminate/Routing/Controller.php on line 54

需要对控制器进行如下调整

diff
- public function destroy(int $id = null)
+ public function destroy(string $id = null)
{
...
}

Laravel 5.3+ 控制器里如何获取登录用户

原文地址: Laravel 5.3+ 控制器里如何获取登录用户

应该不少同学都遇到这个问题了:5.3 起,由于框架运行流程的修改,你无法在控制器的构造函数里获取登录用户,那么我们怎么办呢?以下是几个方法:

  • 不再从构造函数取用户

我们可以从 request 中获取登录用户: request()->user()

  • 或者在控制器方法里我们使用 Auth::user()

除了上面的折中的办法,我们一定要在构造函数搞定的话那么请看这里:

protected $user;
public function __construct()
{
    $this->middleware(function ($request, $next) {
        $this->user = $request->user();
        return $next($request);
    });
}

这样你就可以在其它方法里使用 $this->user 来访问当前登录用户了。

FYI: [5.3] Controller closure middleware

使用 Faker 获取假数据

Laravel 源码中是在 DatabaseServiceProvider 中注册的国际化支持。

// vendor/laravel/framework/src/Illuminate/Database/DatabaseServiceProvider.php
protected function registerEloquentFactory()
{
    $this->app->singleton(FakerGenerator::class, function ($app) {
        return FakerFactory::create($app['config']->get('app.faker_locale', 'en_US'));
    });
    $this->app->singleton(EloquentFactory::class, function ($app) {
        return EloquentFactory::construct(
            $app->make(FakerGenerator::class), $this->app->databasePath('factories')
        );
    });
}
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.15 — cli) by Justin Hileman
>>> app(\\Faker\\Generator::class)->phoneNumber
=> "13977433809"

php图片写法在 laravel 框架中显示乱码

问题 : 使用laravel 框架直接在php中输出图片是不显示的.

php
Route::get('png', function () {
    $im = @imagecreate(200, 50) or die("创建图像资源失败");
    imagecolorallocate($im, 255, 255, 255);
    $text_color = imagecolorallocate($im, 0, 0, 255);
    imagestring($im, 5, 0, 0, "Hello world!", $text_color);
    imagepng($im);
    imagedestroy($im);
});

显示内容如下:

这里的头信息是:

$ curl -I https://i.wulicode.com/php/image/png
HTTP/1.1 200 OK
Server: nginx/1.23.2
Content-Type: text/html; charset=UTF-8

这里返回的类型是 text/html 类型, 所以输出错误, 这里需要继续修改头信息, 于是更改为如下的代码

php
Route::get('png', function () {
    ob_start();
    $im = @imagecreate(200, 50) or die("创建图像资源失败");
    imagecolorallocate($im, 255, 255, 255);
    $text_color = imagecolorallocate($im, 0, 0, 255);
    imagestring($im, 5, 0, 0, "Hello world!", $text_color);
    imagepng($im);
    imagedestroy($im);
    $content = ob_get_clean();
    return response($content, 200, [
        'Content-Type' => 'image/png',
    ]);
});

这里在某些情况下可以展示, 内容为:

但是有些框架也不行, 如下展示

在不可以的框架中, 由于考虑可能是 缓存/缓冲区 的问题, 输出下 ob_get_status() 结果发现是有内容的

Array
(
    [name] => default output handler
    [type] => 0
    [flags] => 112
    [level] => 0
    [chunk_size] => 4096
    [buffer_size] => 8192
    [buffer_used] => 1
)

所以我们需要清除缓冲区内容, 然后重新生成并且输出, 也就是输出的时候是保证不要输出任何内容/ 包含空行, 当然出现这个问题的原因可能是编码的时候是 utf-8
但是存在 bom 头导致的信息.

最终源码解决如下:

php
Route::get('png', function () {
    if (ob_get_status()) {
        ob_end_clean();
    }
    ob_start();
    $im = @imagecreate(200, 50) or die("创建图像资源失败");
    imagecolorallocate($im, 255, 255, 255);
    $text_color = imagecolorallocate($im, 0, 0, 255);
    imagestring($im, 5, 0, 0, "Hello world!", $text_color);
    imagepng($im);
    imagedestroy($im);
    $content = ob_get_clean();
    return response($content, 200, [
        'Content-Type' => 'image/png',
    ]);
});

如此, 问题解决

参考


说明

创建时间: 2023-12-10 10:06:00 , 最后编辑于 2023-12-17 09:22:00