Kohana 3.2 ORM 和 PDO

发布于 2024-12-02 20:26:22 字数 1233 浏览 0 评论 0原文

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

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

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

MODEL application/classes/model/blogpost.php:

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

CONTROLLER :在 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 ]: Database method list_columns is not support by Kohana_Database_PDO

我在google和Stack Overflow上进行了搜索,我的印象是ORM可能无法与PDO一起使用,这是正确的吗?或者我错过了什么?

谢谢。

I am giving Kohana a try and I was trying to use the ORM + PDO + MySQL database, and I don't seem to find an answer in google or SO.

I have both the database and ORM modules enabled, and I have set PDO as default in modules/database/config/database.php

I have a simple controller, and a simple model:

MODEL application/classes/model/blogpost.php:

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

CONTROLLER: in 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

I get the following error when I try to run the test:

Kohana_Exception [ 0 ]: Database method list_columns is not supported by Kohana_Database_PDO

I have done a search in google and Stack Overflow, and my impression is that ORM may not work with PDO, is this correct? or am I missing something?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷鸟归林 2024-12-09 20:26:22

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 方法并提供您自己的列出列的方法。

list_columns is used for ORM to get all the columns in a table when they are not specified. To get around this, you can specify the table columns in the _table_columns protected property:

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

This will ensure that list_columns is not called. The downside is that you will have to keep track of every change to the table you make. The upside is that an extra SHOW FULL COLUMNS query is not called, meaning a small performance boost.

Another way is to override the list_columns method and provide your own means of listing columns with it.

南冥有猫 2024-12-09 20:26:22

此处。有时 Kohana 的文档可能会令人困惑 - 别担心!源代码虽然听起来很可怕,但充满了注释,实际上是一个非常好的文档。

here. Sometimes Kohana's docs can be confusing - never fear! the source code, while it might sound scary, is FULL with comments and actually serves as a really good docs.

混浊又暗下来 2024-12-09 20:26:22

我刚刚获取了最新的 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 来完成的。

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

I just snagged the latest Kohana 3.3, and here's a link to help see why PDO isn't natively supported with ORM: http://dev.kohanaframework.org/issues/3412
Namely,

There is no agnostic way to implement listing tables and columns.

So, uh I took a moment to try to support it since describing every table sounded like a lot of work, though that answer is appreciated!

So, in your MODPATH or APPPATH (depending on where you load your database stuff) make a new file at %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;
    }
}

What this is really, is me copying the %MODPATH%/database/classes/Kohana/databases/MySQL.php list_column and doing one tweak ($type instead of $column['type']) and it appears to work the little bit I've tested so far.

SECOND, you need to use the new driver. This is done by changing your %path%/database/config/database.php 'type' field from PDO to PDO_MySQL.

Let me know if this isn't clear, or if you see issues.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文