我正在开发一个包,它创建了几个迁移,我想要种子。然后还有一些其他子包,也可以创建带种子的迁移。所以周围可能会有很多种子,我不想强迫用户向DatabaseSeeder添加数十行。
.apk
之类的内容可行,但这样用户无法使用相同的命令进行迁移和播种,因为php artisan db:seed --class="MyNamespace\\DatabaseSeeder"
不接受类选项。
基本上,我正在寻找与php artisan migrate --seed
类的loadMigrationsFrom()
类似的内容。
任何帮助都将不胜感激。
更新:我主要对Laravel 5.3的解决方案感兴趣,我会以某种方式找出向后兼容性
答案 0 :(得分:2)
无法找到以正确顺序加载的本机函数,包含文件并执行它们。方法很粗糙,但有效。 migrate:refresh --seed不适用于此方法,因为它假定在运行服务提供程序时存在表,但db:seed会这样做。
protected function registerSeedsFrom($path)
{
foreach (glob("$path/*.php") as $filename)
{
include $filename;
$classes = get_declared_classes();
$class = end($classes);
$command = Request::server('argv', null);
if (is_array($command)) {
$command = implode(' ', $command);
if ($command == "artisan db:seed") {
Artisan::call('db:seed', ['--class' => $class]);
}
}
}
}
在引导方法中使用自定义服务提供者/包:
if ($this->app->runningInConsole()) {
$this->registerMigrations();
$this->registerEloquentFactoriesFrom(__DIR__.'/../database/factories');
$this->registerSeedsFrom(__DIR__.'/../database/seeds');
}
答案 1 :(得分:0)
该功能适用于“ db:seed”命令和“ --seed”选项。
更多信息,请访问:https://github.com/wowcee/laravel-seeds-service-provider
<?php
namespace Core\Providers;
use Illuminate\Console\Events\CommandFinished;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\Console\Output\ConsoleOutput;
class SeedServiceProvider extends ServiceProvider
{
protected $seeds_path = '/../database/seeds';
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
if ($this->app->runningInConsole()) {
if ($this->isConsoleCommandContains([ 'db:seed', '--seed' ], [ '--class', 'help', '-h' ])) {
$this->addSeedsAfterConsoleCommandFinished();
}
}
}
/**
* Get a value that indicates whether the current command in console
* contains a string in the specified $fields.
*
* @param string|array $contain_options
* @param string|array $exclude_options
*
* @return bool
*/
protected function isConsoleCommandContains($contain_options, $exclude_options = null) : bool
{
$args = Request::server('argv', null);
if (is_array($args)) {
$command = implode(' ', $args);
if (str_contains($command, $contain_options) && ($exclude_options == null || !str_contains($command, $exclude_options))) {
return true;
}
}
return false;
}
/**
* Add seeds from the $seed_path after the current command in console finished.
*/
protected function addSeedsAfterConsoleCommandFinished()
{
Event::listen(CommandFinished::class, function(CommandFinished $event) {
// Accept command in console only,
// exclude all commands from Artisan::call() method.
if ($event->output instanceof ConsoleOutput) {
$this->addSeedsFrom(__DIR__ . $this->seeds_path);
}
});
}
/**
* Register seeds.
*
* @param string $seeds_path
* @return void
*/
protected function addSeedsFrom($seeds_path)
{
$file_names = glob( $seeds_path . '/*.php');
foreach ($file_names as $filename)
{
$classes = $this->getClassesFromFile($filename);
foreach ($classes as $class) {
Artisan::call('db:seed', [ '--class' => $class, '--force' => '' ]);
}
}
}
/**
* Get full class names declared in the specified file.
*
* @param string $filename
* @return array an array of class names.
*/
private function getClassesFromFile(string $filename) : array
{
// Get namespace of class (if vary)
$namespace = "";
$lines = file($filename);
$namespaceLines = preg_grep('/^namespace /', $lines);
if (is_array($namespaceLines)) {
$namespaceLine = array_shift($namespaceLines);
$match = array();
preg_match('/^namespace (.*);$/', $namespaceLine, $match);
$namespace = array_pop($match);
}
// Get name of all class has in the file.
$classes = array();
$php_code = file_get_contents($filename);
$tokens = token_get_all($php_code);
$count = count($tokens);
for ($i = 2; $i < $count; $i++) {
if ($tokens[$i - 2][0] == T_CLASS && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING) {
$class_name = $tokens[$i][1];
if ($namespace !== "") {
$classes[] = $namespace . "\\$class_name";
} else {
$classes[] = $class_name;
}
}
}
return $classes;
}
}
答案 2 :(得分:0)
php artisan db:seed --class="Package\Name\database\seeds\NameTableSeeder"