15

我正在尝试 Kohana,我正在尝试使用 ORM + PDO + MySQL 数据库,但我似乎在 google 或 SO 中找不到答案。

我启用了数据库和 ORM 模块,并且在 modules/database/config/database.php 中将 PDO 设置为默认值

我有一个简单的控制器和一个简单的模型:

模型应用程序/类/模型/blogpost.php:

<?php
class Model_Blogpost extends ORM {
    protected $_table_name  = 'blog_post'; 
}

控制器:在 application/classes/controller/welcome.php

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Welcome extends Controller {

  public function action_index() {

    $Blog_Post = ORM::factory('blogpost');    // ==> ERROR HERE

    $Blog_Post->name = 'test1';
    $Blog_Post->description = 'this is a quick test';
    $Blog_Post->content = 'The content goes here....';
    $Blog_Post->save();

    $id = $Blog_Post->id;

    $Blog_Post = ORM::factory('blogpost', $id);
    $view->Blog_Post = $Blog_Post;

    $this->response->body($view);
  }
} // End Welcome

尝试运行测试时出现以下错误:

Kohana_Exception [ 0 ]:Kohana_Database_PDO 不支持数据库方法 list_columns

我在 google 和 Stack Overflow 中进行了搜索,我的印象是 ORM 可能不适用于 PDO,这是正确的吗?还是我错过了什么?

谢谢你。

4

3 回答 3

19

list_columns用于 ORM 在未指定时获取表中的所有列。为了解决这个问题,您可以在_table_columns受保护的属性中指定表列:

class Model_Blogpost extends ORM {
  protected $_table_name  = 'blog_post';
  protected $_table_columns = array(
    'column1' => NULL,
    'column2' => NULL,
    // ...
    'columnx' => NULL,
  ); 
}

这将确保list_columns不调用。缺点是您必须跟踪对表所做的每一次更改。好处是不会调用额外的SHOW FULL COLUMNS查询,这意味着性能的小幅提升。

另一种方法是覆盖该list_columns方法并提供您自己的列出列的方法。

于 2011-09-06T08:26:42.787 回答
3

在这里。有时 Kohana 的文档可能会令人困惑——不要害怕!源代码虽然听起来很吓人,但却充满了注释,实际上是一个非常好的文档。

于 2011-09-06T04:00:14.933 回答
2

我刚刚找到了最新的 Kohana 3.3,这里有一个链接可以帮助了解为什么 ORM 不支持 PDO:http: //dev.kohanaframework.org/issues/3412 即,

没有不可知的方式来实现列表表和列。

所以,嗯,我花了一点时间尝试支持它,因为描述每张桌子听起来像是很多工作,尽管这个答案很受欢迎!

因此,在您的 MODPATH 或 APPPATH 中(取决于您加载数据库内容的位置)在 %above%/classes/Database/PDO/MySQL.php 处创建一个新文件

<?php defined('SYSPATH') or die('No direct script access.');

class Database_PDO_MySQL extends Database_PDO {
    public function list_columns($table, $like = NULL, $add_prefix = TRUE)
    {
            // Quote the table name
            $table = ($add_prefix === TRUE) ? $this->quote_table($table) : $table;

            if (is_string($like))
            {
                    // Search for column names
                    $result = $this->query(Database::SELECT, 'SHOW FULL COLUMNS FROM '.$table.' LIKE '.$this->quote($like), FALSE);
            }
            else
            {
                    // Find all column names
                    $result = $this->query(Database::SELECT, 'SHOW FULL COLUMNS FROM '.$table, FALSE);
            }

            $count = 0;
            $columns = array();
            foreach ($result as $row)
            {
                    list($type, $length) = $this->_parse_type($row['Type']);

                    $column = $this->datatype($type);

                    $column['column_name']      = $row['Field'];
                    $column['column_default']   = $row['Default'];
                    $column['data_type']        = $type;
                    $column['is_nullable']      = ($row['Null'] == 'YES');
                    $column['ordinal_position'] = ++$count;

                    switch ($type) //was $column['type']
                    {
                            case 'float':
                                    if (isset($length))
                                    {
                                            list($column['numeric_precision'], $column['numeric_scale']) = explode(',', $length);
                                    }
                            break;
                            case 'int':
                                    if (isset($length))
                                    {
                                            // MySQL attribute
                                            $column['display'] = $length;
                                    }
                            break;
                           case 'string':
                                    switch ($column['data_type'])
                                    {
                                            case 'binary':
                                            case 'varbinary':
                                                    $column['character_maximum_length'] = $length;
                                            break;
                                            case 'char':
                                            case 'varchar':
                                                    $column['character_maximum_length'] = $length;
                                            case 'text':
                                            case 'tinytext':
                                            case 'mediumtext':
                                            case 'longtext':
                                                    $column['collation_name'] = $row['Collation'];
                                            break;
                                            case 'enum':
                                            case 'set':
                                                    $column['collation_name'] = $row['Collation'];
                                                    $column['options'] = explode('\',\'', substr($length, 1, -1));
                                            break;
                                    }
                            break;
                    }

                    // MySQL attributes
                    $column['comment']      = $row['Comment'];
                    $column['extra']        = $row['Extra'];
                    $column['key']          = $row['Key'];
                    $column['privileges']   = $row['Privileges'];

                    $columns[$row['Field']] = $column;
            }

            return $columns;
    }
}

这到底是什么,是我复制 %MODPATH%/database/classes/Kohana/databases/MySQL.php list_column 并做一个调整($type 而不是 $column['type']),它似乎有点工作到目前为止我已经测试过了。

其次,您需要使用新的驱动程序。这是通过将您的 %path%/database/config/database.php 'type' 字段从 PDO 更改为 PDO_MySQL 来完成的。

如果不清楚,或者您发现问题,请告诉我。

于 2013-10-04T10:53:11.230 回答