在CakePHP 3中动态添加现有表中的列

时间:2016-05-21 11:07:39

标签: php cakephp-3.0 database-migration phinx

我想在CakePHP 3中的现有表中添加列。

我的ContactsTable.php文件代码:

<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Migrations\AbstractMigration;

class ContactsTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('Timestamp');
        $table = $this->table('contacts');
        $table->addColumn('price', 'decimal')->update();

    }
}

我已经按照CakePHP 3文档中的描述进行了尝试,但是我收到了这个错误:

  

在非对象

上调用成员函数addColumn()

如何通过控制器即时添加列?

3 个答案:

答案 0 :(得分:6)

代码:

<?php

namespace App\Controller;

use Cake\Core\Configure;
use Cake\Network\Exception\NotFoundException;
use Cake\View\Exception\MissingTemplateException;
use Cake\ORM\TableRegistry;
use Cake\Database\Schema\Table;
use Cake\Datasource\ConnectionManager;
use \Migrations\AbstractMigration as AbstractMigration;
use \Phinx\Db\Adapter\MysqlAdapter as MysqlAdapter;

class PagesController extends AppController
{
    public function display()
    {
        $connectionArray = ConnectionManager::get('default')->config();
        $connectionArray['pass'] = $connectionArray['password'];
        $connectionArray['user'] = $connectionArray['username'];
        $connectionArray['name'] = $connectionArray['database'];

        $migrationObject = new AbstractMigration(mt_rand());
        $migrationObject->setAdapter(new MysqlAdapter($connectionArray));
        $tree = $migrationObject->table('tests');


        $tree->addColumn('something', 'text')
                        ->update();
    }
}

经过几个小时的黑客攻击后,终于找到了一种即时实现的方法。

测试默认cakephp 3(最新 - 截至今日 - 6月2日及#39; 16)

如果您使用的是其他数据库适配器,请将其从MysqlAdapter更改为该适配器。

  

用户注意:

     
      
  • 这是一个丑陋的黑客,只有在你不工作时才应该使用   每个迁移提交都需要对等参考的组织。

  •   
  • mt_rand()绝不能用作版本号黑客。

  •   
  • 通过控制器进行没有规范方式。必须始终通过迁移修改数据源中的更新 - 使用正确的结构。

  •   
  • 请参阅Running Migrations in a non-shell environment并尝试在/config/migrations下创建一个迁移日志,这些日志将更具规则性,并且您还可以查看同行的日志以供审核

  •   

答案 1 :(得分:2)

迁移插件也支持Running Migrations in a non-shell environment

  

自迁移插件的版本1.2发布以来,您可以使用新的Migrations类从非shell环境直接从应用程序运行迁移。如果您正在为CMS开发插件安装程序,这可能很方便。 Migrations类允许您从迁移shell运行以下命令:migraterollbackmarkMigratedstatusseed

     

这些命令中的每一个都有一个在Migrations类中定义的方法。

您可以准备一些自定义处理程序,它将接受来自用户端的列数据并运行迁移。在这种情况下,它可能是nametype输入的某种形式。在提交数据的表单后,将对DB进行迁移。

以下是使用方法:

use Migrations\Migrations;

$migrations = new Migrations();

// Will return an array of all migrations and their status
$status = $migrations->status();

// Will return true if success. If an error occurred, an exception will be thrown
$migrate = $migrations->migrate();

// Will return true if success. If an error occurred, an exception will be thrown
$rollback = $migrations->rollback();

// Will return true if success. If an error occurred, an exception will be thrown
$markMigrated = $migrations->markMigrated(20150804222900);

// Will return true if success. If an error occurred, an exception will be thrown
$seeded = $migrations->seed();

答案 2 :(得分:1)

如果你想在产品表中添加新列,例如'price',价格是'十进制',你应该去你的项目并在控制台中写这个:

bin/cake bake migration AddPriceToProducts price:decimal

您可以看到一个新文件,例如的配置/迁移/ 20160501190410_AddPriceToProducts.php

<?php
use Migrations\AbstractMigration;

class AddPriceToProducts extends AbstractMigration
{
    /**
     * Change Method.
     *
     * More information on this method is available here:
     * http://docs.phinx.org/en/latest/migrations.html#the-change-method
     * @return void
     */
    public function change()
    {
        $table = $this->table('products');
        $table->addColumn('price', 'decimal', [
            'default' => null,
            ...
            'null' => true,
        ]);
        $table->update();
    }
}

稍后只是启动迁移以将此列添加到数据库,在控制台中写入:

bin/cake migrations migrate