在 Laravel 中运行 composer install 命令后将数据存储在数据库中?

Store data in database after run composer install command in Laravel?

提问人:Viraj Madhushan 提问时间:11/12/2023 最后编辑:Viraj Madhushan 更新时间:11/13/2023 访问量:79

问:

我正在处理 Laravel 10 项目,我想在运行 composer install <package_name>时向数据库添加一些数据。为此,我创建了一个自定义 PHP 文件,并在 composer.json 文件中调用该 postPackageInstall 函数。

在这里,我如何将其添加到我的composer.json文件中

    {
    
    <-- OTHER COMPOSER JSON DATA -->

    "scripts": {
        "post-package-install": [
            "Widgets\\PackageInstaller::postPackageInstall"
        ]
      },
    <-- OTHER COMPOSER JSON DATA -->
    }

这是我的自定义PHP文件的样子。

<?php

namespace Widgets;

use Composer\Installer\PackageEvent;
use Composer\Script\Event;
use Illuminate\Support\Facades\DB;

class PackageInstaller
{
    protected static $packageName = "";

    public static function postPackageInstall(PackageEvent $event)
    {
        // Get installing package
        $operation = $event->getOperation();

        $package = method_exists($operation, 'getPackage')
            ? $operation->getPackage()
            : $operation->getInitialPackage();

        DB::table('widgets')->insert(['name' => $package->getName()]);
    }
}

在这里,我的想法是在运行 composer install 命令后获取包名称并将该名称存储在数据库中。但问题是,它会抛出一个错误

In Facade.php line 350:           
  A facade root has not been set.

我假设这是因为 Laravel 在这个阶段还没有满载。此外,我尝试在 post-package-install 脚本中运行 Artisan 命令。数据库查询在命令中起作用,但我无法像脚本一样在命令中获取包名称。

有没有其他方法可以实现此目的或解决这些问题?

php laravel 数据库 编写器-php

评论

0赞 Adi 11/12/2023
您是否尝试过使用和创建这种结构,然后在 composer.json 中的脚本下添加 Artisan Run 命令?make:command
0赞 Viraj Madhushan 11/12/2023
我尝试了 making 命令,并且能够将数据添加到数据库中。但是我无法在命令处理程序函数中获取包名称。PackageEvent 在命令文件中不起作用。

答:

1赞 Kolyunya 11/13/2023 #1
  1. 使用数据库逻辑创建自定义工匠命令。
  2. 允许通过 CLI 参数向其传递数据。
  3. 更新以通过 exec() 运行命令。postPackageInstall()

评论

0赞 Viraj Madhushan 11/13/2023
我尝试了这个方法,但exec()不起作用
0赞 Kolyunya 11/14/2023
@VirajMadhushan错误是什么?
0赞 Viraj Madhushan 11/14/2023
未返回任何错误。似乎exec()不起作用,或者代码没有达到这一点。不确定确切的原因。
0赞 Viraj Madhushan 11/13/2023 #2

我是这么想的。由于 Laravel 在包卸载后阶段没有完全加载,因此我使用行 PHP 数据库查询来存储数据。

public static function postPackageInstall(PackageEvent $event)
    {
        // Get installing package
        $operation = $event->getOperation();
        $package = method_exists($operation, 'getPackage')
            ? $operation->getPackage()
            : $operation->getInitialPackage();

        // Extract package name
        $packageName = $package->getName();

        // Perform database operation
        $pdo = new \PDO('mysql:host=127.0.0.1;dbname=my_database', 'username', 'password');
        $stmt = $pdo->prepare('INSERT INTO widgets (name) VALUES (:name)');
        $stmt->bindParam(':name', $packageName);
        $stmt->execute();
    }

这种方法不干净。但它确实可以在 Laravel 的“post-package-uninstall”脚本中工作。

评论

0赞 The Alpha 11/13/2023
您可以在引导应用程序后使用 Laravel 的外观。看看我的答案。DB
1赞 The Alpha 11/13/2023 #3

你可以试试这个(使用 Laravel 门面):DB

namespace Widgets;

require __DIR__.'/../vendor/autoload.php';

use Composer\Installer\PackageEvent;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Support\Facades\DB;

class PackageInstaller
{
    protected static $packageName = "";

    public static function postPackageInstall(PackageEvent $event)
    {
        $app = require_once __DIR__.'/../bootstrap/app.php';

        $app->make(Kernel::class)->bootstrap();
    
        $operation = $event->getOperation();

        $package = method_exists($operation, 'getPackage')
            ? $operation->getPackage()
            : $operation->getInitialPackage();

        DB::table('widgets')->insert(
            ['name' => $package->getName()]
        );
    }
}