zachleigh/yarak

Laravel 启发的 Phalcon 开发工具。数据库迁移、模型工厂和数据库种子。

安装量: 3,783

依赖者: 0

建议者: 0

安全性: 0

星级: 28

关注者: 7

分支: 11

开放性问题: 1

类型:项目

v1.2.0 2018-01-17 13:06 UTC

This package is auto-updated.

Last update: 2024-09-22 17:11:51 UTC


README

Latest Stable Version License Build Status Quality Score StyleCI

yarak - (猎鹰术) 猎鹰的最佳健康状态

Laravel 启发的 Phalcon 开发工具

  • 可逐步回滚、重置数据库和刷新数据库的数据库迁移。
  • 模型工厂,用于轻松创建测试数据。
  • 使用单个命令填充数据库的数据库种子。
  • 在几分钟内创建自定义命令,以简化并个性化您的流程。

内容

发行说明

从 1.1.* 迁移到 1.2.*

核心命令包装器已提取为单独的包(zachleigh/artisanize)。尽可能保持 Yarak 类不变,以最小化更新问题。但是,在安装新版本后,某些接口类型声明可能需要更新。

安装

要求

此包假设您拥有以下内容

  • Phalcon >= 3.0
  • PHP >= 5.6.5

通过 composer 安装

composer require zachleigh/yarak

注册服务

use Yarak\Kernel;

$di->setShared('yarak',function () {
    return new Kernel();
});

Yarak 需要以下配置值在此结构中

'database' => [
    'adapter'     => '',
    'host'        => '',
    'username'    => '',
    'password'    => '',
    'dbname'      => '',
    'charset'     => '',
],
'application' => [
    'appDir'         => APP_PATH.'/',
    'commandsDir'    => APP_PATH.'/console/commands',
    'consoleDir'     => APP_PATH.'/console/',
    'databaseDir'    => APP_PATH.'/database/',
    'migrationsDir'  => APP_PATH.'/database/migrations/',
    'modelsDir'      => APP_PATH.'/models/',
],
'namespaces' => [
    'root' => '',
],

Yarak 使用您的应用程序配置,如果您的配置已经是这种结构,只需添加必要的值。如果您的配置策略与此不同,您有几种选择。首先,您可以创建特定的 Yarak 配置键,并在其中设置所有值

'yarak' => [
    'database' => [
        'adapter'     => '',
        'host'        => '',
        'username'    => '',
        'password'    => '',
        'dbname'      => '',
        'charset'     => '',
    ],
    'application' => [
        'appDir'         => APP_PATH.'/',
        'commandsDir'    => APP_PATH.'/console/commands',
        'consoleDir'     => APP_PATH.'/console/',
        'databaseDir'    => APP_PATH.'/database/',
        'migrationsDir'  => APP_PATH.'/database/migrations/',
        'modelsDir'      => APP_PATH.'/models/',
    ],
    'namespaces' => [
        'root' => '',
    ],
]

然后,在注册服务时传递配置路径

$di->setShared('yarak',function () {
    return new Kernel('yarak');
});

如果配置路径有多级,请使用点表示法

'services' => [
    'yarak' => [
        'database' => [
            'adapter'     => '',
            'host'        => '',
            'username'    => '',
            'password'    => '',
            'dbname'      => '',
            'charset'     => '',
        ],
        'application' => [
            'appDir'         => APP_PATH.'/',
            'commandsDir'    => APP_PATH.'/console/commands',
            'consoleDir'     => APP_PATH.'/console/',
            'databaseDir'    => APP_PATH.'/database/',
            'migrationsDir'  => APP_PATH.'/database/migrations/',
            'modelsDir'      => APP_PATH.'/models/',
        ],
        'namespaces' => [
            'root' => '',
        ],
    ]
]
$di->setShared('yarak',function () {
    return new Kernel('services.yarak');
});

如果您希望在注册 Yarak 时添加配置值,请作为数组传递,Yarak 将将其合并到现有的配置中

$di->setShared('yarak',function () {
    return new Kernel([
        'namespaces' => [
            'root' => '',
        ],
    ]);
});

最后,您可以在注册服务时传递所有配置值。将 'false' 作为 Kernel 构造函数的第二个参数传递以关闭配置合并。

$di->setShared('yarak',function () {
    return new Kernel([
        'database' => [
            'adapter'     => '',
            'host'        => '',
            'username'    => '',
            'password'    => '',
            'dbname'      => '',
            'charset'     => '',
        ],
        'application' => [
            'appDir'         => APP_PATH.'/',
            'commandsDir'    => APP_PATH.'/console/commands',
            'consoleDir'     => APP_PATH.'/console/',
            'databaseDir'    => APP_PATH.'/database/',
            'migrationsDir'  => APP_PATH.'/database/migrations/',
            'modelsDir'      => APP_PATH.'/models/',
        ],
        'namespaces' => [
            'root' => '',
        ],
    ], false);
});

创建 yarak 文件

在项目根目录中创建一个名为 yarak 的文件。此文件需要执行以下操作

  • 自动加载所有项目文件和供应商目录文件
  • 加载项目服务
  • 从服务容器中解析 Yarak 内核,并对其调用 handle 方法

示例

#!/usr/bin/env php
<?php

use Phalcon\Di\FactoryDefault;

error_reporting(E_ALL);

define('BASE_PATH', __DIR__);
define('APP_PATH', BASE_PATH . '/app');

/*
|--------------------------------------------------------------------------
| Autoload The Application
|--------------------------------------------------------------------------
|
| In order to work properly, Yarak will need both your project files and the
| vendor folder to be autoloaded.
|
*/
include APP_PATH . '/config/loader.php';

/*
|--------------------------------------------------------------------------
| Register The App Services
|--------------------------------------------------------------------------
|
| We need to register the app services in order to spin up Yarak. Be sure you
| have registered Yarak in the services file.
|
*/
$di = new FactoryDefault();

include APP_PATH . '/config/services.php';

/*
|--------------------------------------------------------------------------
| Handle The Incoming Commands
|--------------------------------------------------------------------------
|
| We'll get the Yarak kernel from the dependency injector and defer to it for 
| command handling.
|
*/
$kernel = $di->getYarak();

$kernel->handle();

上述示例包含在项目 yarak/src/yarak_example 中。请使用以下命令将其复制到您的项目中,从项目根目录执行

cp vendor/zachleigh/yarak/src/yarak_example yarak

一旦 yarak 文件存在,使其可执行

chomd +x yarak

将数据库目录添加到 composer 自动加载器

由于迁移不符合psr-4命名约定,请使用类映射加载它们。

"autoload": {
    "classmap": [
        "relative/path/to/database/directory"
    ]
}

您可能需要清除composer的autoload缓存,以便更改生效。

composer dumpautoload

在控制台中测试以确保它正在正常工作。

php yarak

顶部

数据库

Yarak为用户提供了几种有用的数据库功能,使开发更加容易。

生成数据库目录和文件

所有数据库和迁移功能都需要一个标准化的文件层次结构。要生成此层次结构,请使用db:generate命令。

php yarak db:generate

这将创建一个位于Yarak配置中设置的路径的数据库目录。数据库目录将包含迁移、种子和工厂目录以及一些帮助您开始的文件占位符。

模型工厂

模型工厂提供了一个简单的方法来使用Faker库创建测试数据。

定义工厂

模型工厂位于/database/factories目录中。此目录和占位符工厂文件可以通过使用php yarak db:generate命令创建。

要定义一个工厂,请使用名为$factory的变量的define方法。该方法具有以下方法签名:

public function define($class, callable $attributes, $name = 'default')

第一个参数是类的全名/命名空间。第二个参数是一个返回数组的回调。此数组必须包含创建模型所需的数据。第三个可选参数是工厂的名称。设置名称允许您为单个模型定义多个工厂。

要创建一个简单的用户模型工厂

use App\Models\Users;

$factory->define(Users::class, function (Faker\Generator $faker) {
    return [
        'username' => $faker->userName,
        'email' => $faker->unique()->safeEmail,
        'password' => 'password',
    ];
});

要创建一个命名的用户模型工厂

use App\Models\Users;

$factory->define(Users::class, function (Faker\Generator $faker) {
    return [
        'username' => 'myUsername',
        'email' => 'myEmail',
        'password' => 'myPassword',
    ];
}, 'myUser');

负责创建模型实例的ModelFactory类扩展了Phalcon\Mvc\User\Component,并可以访问DI和任何已注册的服务。要访问ModelFactory类,请在$attributes闭包中使用$factory变量。

use App\Models\Users;

$factory->define(Users::class, function (Faker\Generator $faker) use ($factory) {
    return [
        'username' => $faker->userName,
        'email' => $faker->unique()->safeEmail,
        'password' => $factory->security->hash('password'),
    ];
});

使用工厂助手

Yarak附带一个全局的factory辅助函数,使创建模型实例变得简单。工厂函数返回一个ModelFactoryBuilder实例,可以用来制作或创建模型。在返回的类上调用make简单创建模型类,但不会将数据持久化到数据库中。调用create创建类并将其持久化到数据库中。

创建用户模型实例,但不持久化它

use App\Models\Users;

$user = factory(Users::class)->make();

创建用户模型并将其持久化

use App\Models\Users;

$user = factory(Users::class)->create();

创建多个模型实例

如果您需要模型类的多个实例,请将整数作为factory的第二个参数传递。

use App\Models\Users;

// Make three users
$users = factory(Users::class, 3)->make();

// Create three users
$users = factory(Users::class, 3)->create();

当创建多个模型时,将返回一个模型数组。

覆盖默认属性

要覆盖工厂定义中设置的默认属性,请将覆盖的数组传递给makecreate

use App\Models\Users;

// Make a user with username 'bobsmith' and email 'bobsmith@example.com'
$user = factory(Users::class)->make([
    'username' => 'bobsmith',
    'email'    => 'bobsmith@example.com'
]);

// Create a user with username 'bobsmith' and email 'bobsmith@example.com'
$user = factory(Users::class)->create([
    'username' => 'bobsmith',
    'email'    => 'bobsmith@example.com'
]);

使用命名工厂

要使用名称工厂,请将名称作为factory函数的第二个参数传递。

use App\Models\Users;

// Make a user using the factory named 'myUser'
factory(Users::class, 'myUser')->make()

// Create a user using the factory named 'myUser'
factory(Users::class, 'myUser')->create()

要创建多个名称工厂的实例,请将所需的实例数作为第三个参数传递。

use App\Models\Users;

// Make three users using the factory named 'myUser'
$users = factory(Users::class, 'myUser', 3)->make();

// Create three users using the factory named 'myUser'
$users = factory(Users::class, 'myUser', 3)->creates();

模型关系

当创建需要建立模型关系的模型实例时,您有几个选项。

首先,您可以手动创建相关模型。在这个例子中,我们有帖子(Posts)和用户(Users),它们有一个一对多的关系:一个帖子只能属于一个用户,但一个用户可以有多个帖子。帖子表中包含一个users_id列,它引用用户表中的id列。帖子表迁移

$connection->createTable(
    'posts',
    null,
    [
        'columns' => [
            new Column('id', [
                'type'          => Column::TYPE_INTEGER,
                'size'          => 10,
                'unsigned'      => true,
                'notNull'       => true,
                'autoIncrement' => true,
            ]),
            new Column('title', [
                'type'    => Column::TYPE_VARCHAR,
                'size'    => 200,
                'notNull' => true,
            ]),
            new Column('body', [
                'type'    => Column::TYPE_TEXT,
                'notNull' => true,
            ]),
            new Column('users_id', [
                'type'     => Column::TYPE_INTEGER,
                'size'     => 10,
                'unsigned' => true,
                'notNull'  => true,
            ]),
            new Column('created_at', [
                'type'    => Column::TYPE_TIMESTAMP,
                'notNull' => true,
                'default' => 'CURRENT_TIMESTAMP',
            ]),
        ],
        'indexes' => [
            new Index('PRIMARY', ['id'], 'PRIMARY')
        ],
        'references' => [
            new Reference(
                'user_idfk',
                [
                    'referencedTable'   => 'users',
                    'columns'           => ['users_id'],
                    'referencedColumns' => ['id'],
                ]
            ),
        ],
    ]
);

首先,我们需要为用户和帖子创建工厂

use App\Models\Posts;
use App\Models\Users;

$factory->define(Users::class, function (Faker\Generator $faker) use ($factory) {
    return [
        'username' => $faker->userName,
        'email'    => $faker->unique()->safeEmail,
        'password' => $factory->security->hash('password'),
    ];
});

$factory->define(Posts::class, function (Faker\Generator $faker) {
    return [
        'title' => $faker->unique()->sentence(4, true),
        'body'  => $faker->paragraph(4, true),
    ];
});

要创建三个用户,每个用户有一个帖子,我们可以简单地遍历新创建的用户并为每个用户创建一个帖子,发送用户ID作为属性覆盖

use App\Models\Posts;
use App\Models\Users;

$users = factory(Users::class, 3)->create();

foreach ($users as $user) {
    factory(Posts::class)->create([
        'users_id' => $user->id
    ]);
}

对于多个帖子,只需将所需的数量作为工厂辅助函数的第二个变量传递即可

use App\Models\Posts;
use App\Models\Users;

$users = factory(Users::class, 3)->create();

foreach ($users as $user) {
    factory(Posts::class, 3)->create([
        'users_id' => $user->id
    ]);
}

另一种创建关系的方法是在工厂定义中使用返回关系的闭包

use App\Models\Posts;
use App\Models\Users;

$factory->define(Users::class, function (Faker\Generator $faker) use ($factory) {
    return [
        'username' => $faker->userName,
        'email'    => $faker->unique()->safeEmail,
        'password' => $factory->security->hash('password'),
    ];
});

$factory->define(Posts::class, function (Faker\Generator $faker) {
    return [
        'title'    => $faker->unique()->sentence(4, true),
        'body'     => $faker->paragraph(4, true),
        'users_id' => function () {
            return factory(Users::class)->create()->id;
        }
    ];
}, 'withUser');

在这里,我们在工厂内部使用工厂为每个新创建的帖子创建一个新用户。我们还将工厂命名为'withUser'以方便使用。要创建由20个用户创建的20个帖子,我们可以这样做

use App\Models\Posts;

factory(Posts::class, 'withUser', 20)->create();

数据库种子

数据库初始化功能可以让您在几秒钟内将测试数据填充到数据库中。

创建数据库种子

要创建一个空的数据库初始化文件,使用make:seeder命令

php yarak make:seeder SeederName

这将在/database/seeds目录下生成一个空的初始化文件。建议为每个数据库表创建单独的初始化文件。

编写数据库种子

所有数据库初始化文件都必须有一个run方法,其中定义了数据库初始化逻辑。在run方法中,进行必要的操作以填充数据库表。使用模型工厂可以简化此过程。一个用户表的示例初始化文件可能如下所示

use App\Models\Users;
use Yarak\DB\Seeders\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(Users::class, 5)->create();
    }
}

运行此初始化文件将在数据库中创建五个用户。

父级初始化类有一个call方法,该方法将调用其他初始化文件中的run方法。这允许您创建多个初始化文件,然后创建一个主数据库初始化文件,以填充整个数据库。我们已经有了一个UsersTableSeeder,现在让我们创建一个PostsTableSeeder

use App\Models\Posts;
use App\Models\Users;
use Yarak\DB\Seeders\Seeder;

class PostsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $allUsers = Users::find();

        foreach ($allUsers as $user) {
            factory(Posts::class, 5)->create(['users_id' => $user->getId()]);
        }
    }
}

这将为我们的每个用户创建5篇帖子。然后我们可以将我们的两个初始化文件合并到一个主数据库初始化文件中

use Yarak\DB\Seeders\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UsersTableSeeder::class);
        $this->call(PostsTableSeeder::class);
    }
}

这将按列表顺序运行每个初始化文件。首先,我们将使用UsersTableSeeder创建五个用户,然后对于这些用户中的每一个,我们将使用PostsTableSeeder创建五个帖子。

使用数据库种子

要运行数据库初始化文件,使用db:seed命令

php yarak db:seed SeederName

默认的初始化文件名为'DatabaseSeeder'。

您还可以使用--seed标志与migrate:refresh命令一起使用

php yarak migrate:refresh --seed --class=SeederName

刷新数据库将删除数据库中的所有数据。此命令将删除所有表,重新运行所有迁移,然后使用给定的初始化类名称填充数据库。初始化类名称的默认值是'DatabaseSeeder'。

顶部

迁移

Yarak迁移提供了一个简单、干净的方式来管理您的数据库。

生成迁移

所有迁移都存储在databaseDir/migrations中。当注册Yarak服务时可以设置databaseDir路径。

要生成迁移,使用make:migration命令

php yarak make:migration migration_name --create=table_name

迁移名称必须是小写蛇形命名法,将用于创建迁移文件名和类名。例如

php yarak make:migration create_users_table

使用名称create_users_table将生成一个名为CreateUsersTable的迁移类。迁移文件名使用时间戳和给定名称生成。在这个例子中,生成的文件名可能看起来像这样:2017_03_04_055719_create_users_table.php。

如果您正在创建一个新的表,使用--create标志加上数据库表名称将创建一个包含一些额外模板代码的迁移文件以节省时间。

php yarak make:migration create_users_table --create=users

编写迁移

Yarak使用Phalcon的数据库抽象层与数据库进行交互。本指南将仅涵盖最常用的操作。有关更多信息,请参阅API文档。因为Phalcon的官方迁移也使用数据库抽象层,所以Phalcon迁移文档也可能很有用。

创建表

要创建一个表,使用$connection变量的createTable方法。

public createTable (mixed $tableName, mixed $schemaName, array $definition)

要创建一个简单的用户表,您的up方法可能如下所示

use Phalcon\Db\Index;
use Phalcon\Db\Column;

//

public function up(Pdo $connection)
{
    $connection->createTable(
        'users',
        null,
        [
            'columns' => [
                new Column('id', [
                    'type'          => Column::TYPE_INTEGER,
                    'size'          => 10,
                    'unsigned'      => true,
                    'notNull'       => true,
                    'autoIncrement' => true
                ]),
                new Column('username', [
                    'type'    => Column::TYPE_VARCHAR,
                    'size'    => 32,
                    'notNull' => true
                ]),
                new Column('password', [
                    'type'    => Column::TYPE_CHAR,
                    'size'    => 40,
                    'notNull' => true
                ]),
                new Column('email', [
                    'type'    => Column::TYPE_VARCHAR,
                    'size'    => 20,
                    'notNull' => true
                ]),
                new Column('created_at', [
                    'type'    => Column::TYPE_TIMESTAMP,
                    'notNull' => true,
                    'default' => 'CURRENT_TIMESTAMP'
                ])
            ],
            'indexes' => [
                new Index('PRIMARY', ['id'], 'PRIMARY'),
                new Index('users_username_unique', ['username'], 'UNIQUE'),
                new Index('users_email_unique', ['email'], 'UNIQUE')
            ]
        ]
    );
}

定义数组必须包含一个 columns 数组,还可以包含 indexesreferencesoptions 数组。要定义列,请使用 Phalcon 的 DB Column 类,对于索引使用 DB Index 类,对于外键使用 DB Reference 类

有关更多信息,请参阅官方文档

更新表

要修改列,请使用 $connection 变量的 modifyColumn 方法

public modifyColumn (mixed $tableName, mixed $schemaName, Phalcon\Db\ColumnInterface $column, [Phalcon\Db\ColumnInterface $currentColumn])

继续上面的示例,我们当前设置的电子邮件列大小为 20,这显然不够大。要修改这一点,我们可以创建一个新的迁移

php yarak make:migration increase_user_email_column_size

在创建的迁移的 up 方法中,我们可以编写以下内容

public function up(Pdo $connection)
{
    $connection->modifyColumn(
        'users',
        null,
        new Column(
            'email',
            [
                'type' => Column::TYPE_VARCHAR,
                'size' => 70,
            ]
        )
    );
}

请注意,当使用 Column 类时,type 是必需的。

要向表中添加额外的列,请使用 addColumn 方法

public addColumn (mixed $tableName, mixed $schemaName, Phalcon\Db\ColumnInterface $column)

所以,如果我们想向我们的用户表中添加一个 active 列,我们创建一个新的迁移

php yarak make:migration add_active_column_to_users_table

并且我们的迁移 up 方法可能看起来像这样

public function up(Pdo $connection)
{
    $connection->addColumn(
        'users',
        null,
        new Column(
            'active',
            [
                'type'    => Column::TYPE_CHAR,
                'size'    => 1,
                'notNull' => true,
            ]
        )
    );
}

官方文档 包含一些额外的示例和信息,可能有助于您。

Down 方法

为了使迁移回滚工作,迁移必须包含一个 down 方法,该方法将 up 方法中描述的过程反转。继续上面的示例,当创建用户表时,我们的 down 方法将使用 dropTable 方法

public function down(Pdo $connection)
{
    $connection->dropTable('users');
}

当修改电子邮件列时,我们可以简单地修改列,使其返回到之前的状态

public function down(Pdo $connection)
{
    $connection->modifyColumn(
        'users',
        null,
        new Column(
            'email',
            [
                'type' => Column::TYPE_VARCHAR,
                'size' => 20,
            ]
        )
    );
}

当添加 active 列时,使用 dropColumn 方法

public function down(Pdo $connection)
{
    $connection->dropColumn('users', null, 'active');
}

运行迁移

要运行所有挂起的迁移,只需使用 Yarak 的 migrate 命令

php yarak migrate

这将运行尚未运行的所有迁移。同时运行的迁移将在同一个 '批次' 中,并将一起回滚。

回滚迁移

❗在回滚之前,请注意,您回滚的表中的所有数据都将丢失。

要回滚最后一个批次的迁移,请调用 migrate:rollback

php yarak migrate:rollback

使用 migrate:rollback 并带有可选的 --steps 标志可以回滚多个批次。

php yarak migrate:rollback --steps=2

// with shortcut
php yarak migrate:rollback -s=2

这将回滚最后一个两个批次的迁移。

重置数据库

使用 migrate:reset 命令将回滚所有迁移。

❗重置数据库将删除数据库中的所有数据。

在进行操作之前,请确保备份了您希望保留的任何数据。

php yarak migrate:reset

刷新数据库

刷新数据库将回滚所有迁移,然后在一个单独的批次中重新运行它们。

❗刷新数据库将删除数据库中的所有数据。

在进行操作之前,请确保备份了您希望保留的任何数据。

php yarak migrate:refresh

在使用 migrate:refresh 命令时,您还可以使用 --seed 标志在数据库刷新后运行所有您的 数据库种子。有关更多信息,请参阅使用数据库种子

顶部

自定义命令

Yarak 还可以扩展并用作通用的命令行任务运行器。

生成控制台目录和文件

要生成控制台组件工作所需的所有目录和文件,请使用 console:generate 命令

php yarak console:generate

这将创建一个控制台目录、一个命令目录、一个示例命令和一个Kernel.php文件,您可以在其中注册自定义命令。如果设置了配置值namespaces => root,Yarak将使用文件路径信息和设置的根命名空间来自动生成命名空间。如果您使用的是非标准命名空间,请按照以下示例设置namespaces => console

生成自定义命令

在生成自定义命令之前,请确保在您的配置中包含consoleDir。如果自动生成的命名空间不正确,您还可以注册控制台命名空间。默认情况下,自定义命令将在名为commands的文件夹中位于定义的控制台目录内。您可以通过注册commandsDir来覆盖此设置。

'application' => [
    //
    'consoleDir' => APP_PATH.'/console/'
],
'namespaces' => [
    //
    'console' => 'App\Console'
],
});

别忘了用Phalcon加载器注册您的控制台命名空间。

一旦注册了consoleDir,就可以使用make:command命令生成自定义命令模板。

php yarak make:command CommandName

编写自定义命令

命令类有三个组件:签名、描述和handle方法。

namespace App\Console\Commands;

use Yarak\Console\Command;

class ExampleCommand extends Command
{
    /**
     * The command signature.
     *
     * @var string
     */
    protected $signature = 'namespace:name {argument} {--o|option=default}';

    /**
     * The command description.
     *
     * @var string
     */
    protected $description = 'Command decription.';

    /**
     * Handle the command.
     */
    protected function handle()
    {
        // handle the command
    }
}

signature是您定义命令名称、参数和选项的地方。下面将详细介绍。 description是您可以设置描述消息的地方,当使用控制台时将显示该命令。当命令被触发时,将调用handle方法,您应该在其中编写命令的逻辑。将大部分逻辑提取到单独的服务类中可能很有用。

命令签名

命令签名以与在控制台中使用命令相同的方式编写,由三部分组成:命令名称、参数和选项。命令名称必须放在签名的开头,并且可以通过在命令名称前加上命名空间并加上冒号(:)来命名空间。

protected $signature = 'namespace:name';

参数和选项用大括号括起来,并跟在命令名称后面。选项以前面带有两个连字符('--')为前缀。

定义命令参数

标准参数由大括号括起来的参数名称组成

protected $signature = 'namespace:name {arg} {--option}'

如上例中的arg,参数名称用于通过argument方法访问参数值。

要使参数可选,在参数名称后附加一个问号('?')

protected $signature = 'namespace:name {arg?} {--option}'

要为参数提供一个默认值,用等号('=')将参数名称和默认值分开

protected $signature = 'namespace:name {arg=default} {--option}'

如果没有提供参数值,将使用默认值。

如果参数是数组形式,在参数名称后附加一个星号('*')

protected $signature = 'namespace:name {arg*} {--option}'

然后可以通过空格分隔来将参数传递给命令

php yarak namespace:name one two three

这将设置arg的值为['one', 'two', 'three']

参数数组也可以设置为可选

protected $signature = 'namespace:name {arg?*} {--option}'

在访问可选参数数组时,未传递的参数等于一个空数组。

提供参数描述通常很有帮助。为此,在参数定义后添加冒号(':'),然后附加描述

protected $signature = 'namespace:name {arg=default : Argument description} {--option}'
定义命令选项

标准选项由前缀为两个连字符('--')的大括号括起来的选项组成

protected $signature = 'namespace:name {argument} {--opt}'

选项名称opt用于通过option方法访问参数值。标准选项不取值,作为真/假标志:当调用命令时选项的存在将设置其值为true,如果不存在,则其值为false。

要定义一个具有所需值的选项,在选项名称后附加一个等号('=')

protected $signature = 'namespace:name {argument} {--opt=}'

要设置默认值,将其放置在等号之后

protected $signature = 'namespace:name {argument} {--opt=default}'

选项也可以有快捷方式,使其更容易记忆和使用。要设置快捷方式,将其添加到命令名称之前,并用管道('|')分隔

protected $signature = 'namespace:name {argument} {--o|opt}'

现在,可以使用标准方式调用选项

php yarak namespace:name argument --opt

或者使用快捷方式

php yarak namespace:name argument -o

选项也可以作为数组传递

protected $signature = 'namespace:name {argument} {--opt=*}'

在传递选项数组时,每个值必须以选项名称为前缀。

php yarak namespace:name argument --opt=one --opt=two --opt=three

opt的值将被设置为['one', 'two', 'three']

就像参数一样,选项描述最好是通过在选项名称定义后添加冒号(':')和描述来实现。

protected $signature = 'namespace:name {argument} {--o|opt : option description.}'

访问命令参数和选项

要在handle方法中访问参数,请使用argument方法。如果提供了参数名称,它将返回该参数的值;如果没有传递任何内容,它将返回所有参数的数组。

protected function handle()
{
    $arg = $this->argument('arg'); // passed value of arg

    $allArguments = $this->argument(); // array of all arguments
}

option方法的工作方式完全相同。

protected function handle()
{
    $opt = $this->option('opt'); // passed value of opt

    $allOptions = $this->option(); // array of all options
}

命令对象上还有hasArgumenthasOption方法。

protected function handle()
{
    $argExists = $this->hasArgument('exists');  // true

    $optExists = $this->hasOption('doesntExist');  // false
}

请求确认

可以使用confirm方法来请求用户进行简单的确认。

if ($this->confirm('Do you wish to continue? ')) {
    //
}

提出问题

如果需要提示用户进行开放性提问,可以使用ask方法。第二个参数提供了一个默认的回退选项。

$name = $this->ask('What is your name?', 'Nobody');

请求密码

可以使用askPassword方法隐藏用户答案。

$password = $this->askPassword('Please type the password');

从列表中选择

choose方法只允许从预定义的选择列表中做出回答。

$car = $this->choose('What is your favourite car?', ['Ferrari', 'Lamborghini', 'Maserati'], 1);

自动完成

anticipate方法可以在用户开始输入时提供一些自动完成帮助。用户仍然可以选择任何答案,无论是否有自动完成提示。

$food = $this->anticipate('What is your favourite food?', ['Pizza', 'Pasta', 'Lasagna'], 'Mozzarella');

多选

当用户应该被允许选择多个答案时,choice方法允许用户从列表中选择它们。

$colors = $this->choice('What are your favourite colors (defaults to blue and red)?', ['Blue', 'Red', 'Green'], '0,1');

命令输出

每个命令都有一个存储在对象上的output变量,它包含几个帮助将输出写入控制台的方法。

write方法输出未格式化的纯文本,writeInfo输出绿色文本,writeError输出红色文本,而writeComment输出黄色文本。

protected function handle()
{
    $this->output->write('Message'); // plain text

    $this->output->writeInfo('Message');  // green text

    $this->output->writeError('Message');  // red text

    $this->output->writeComment('Message');  // yellow text
}

输出变量是Symfony输出类的一个简单包装。要访问此类,请使用getOutputInterface方法。

protected function handle()
{
    $output = $this->getOutputInterface(); // $output is instance of Symfony\Component\Console\Output\OutputInterface
}

请注意,Yarak命令类只是Symfony控制台组件的一个包装。所有Symfony命令功能都可在您的自定义命令对象上使用。有关更多详细信息,请参阅Symfony控制台组件文档

使用自定义命令

在使用您自定义的命令之前,您必须在命令Kernel的$commands数组中注册它。

use Yarak\Console\ConsoleKernel;
use App\Console\Commands\ExampleCommand;
use App\Comsone\Commands\YourCustomCommand;

class Kernel extends ConsoleKernel
{
    /**
     * Your custom Yarak commands.
     *
     * @var array
     */
    protected $commands = [
        ExampleCommand::class,
        YourCustomCommand::class
    ];
}

注册后,命令可以像使用其他Yarak命令一样使用。

php yarak namespace:name arg --opt

顶部

在代码中调用 Yarak

要从您的代码库中调用Yarak命令,请使用Yarak::call静态方法。

public static function call($command, array $arguments = [], \Phalcon\DiInterface $di = null)

例如,要调用migrate:rollback --steps=2

use Yarak\Yarak;

Yarak::call('migrate:rollback', [
    '--steps'    => 2,
]);

Yarak将使用默认DI来获取其设置。如果解析的默认DI不起作用,请将Phalcon\Di的实例作为call方法的第三个参数传递。

use Yarak\Yarak;

Yarak::call('migrate:rollback', [
    '--steps'    => 2,
], $di);

如果您正在运行PHP 5.6或更低版本,使用静态调用方法可能会导致以下错误消息

Cannot bind an instance to a static closure

为了避免此错误,将$di作为上面所示传递给Yarak::call的第三个变量。

顶部

开发

要将项目本地设置用于开发,请克隆存储库并从项目根目录运行composer install。创建必要的数据库,并在codeception.ymlapp/config/config.php中输入您的数据库配置详细信息。使用php vendor/codeception/codeception/codecept run运行完整的测试套件,或使用以下composer脚本

  • composer test:运行完整的测试套件
  • composer testf:仅运行功能测试
  • composer testu:仅运行单元测试

顶部

致谢和贡献

此项目在很大程度上受到了Laravel项目的启发。Yarak中的某些代码部分直接取自Laravel项目。向@taylorotwell和所有Laravel贡献者致以诚挚的感谢。

贡献总是受欢迎。Fork、改进并提交pull request。对于错误、改进想法或其他问题,请创建一个 问题