尝试获取列数据时,类返回整数而不是对象

时间:2014-02-16 18:22:20

标签: php mysql class pdo

刚进入OOP,并从mysql查询更改为PDO。我正在尝试创建一个类,它将返回表的列名和元数据。这样我就可以为我使用的所有表输出复制/粘贴数据。我已经使用了这样一个基于mysql扩展的工具,它已经很长时间了,并且它会发出诸如完整的SELECT / INSERT / UPDATE查询之类的变体。除此之外,我现在想要为存储过程添加DECLARE列表 - 因此获取类型和长度等元数据是必不可少的。在两个模式中有大约150个表,这种自动化是必不可少的。

由于对getColumnMeta可靠性的不确定性,我寻找代码并发现Sitepoint answer中看起来不错的东西。我试图将它包装在一个类中并模仿其原始上下文,但当我尝试回显或print_r响应时,我只是得到一个数字1。在尝试解决方案时,我也遇到了“非对象”错误消息。

这是主叫代码

$db_host="localhost";
$db_username='root';
$db_pass='';
$db_name='mydatabase';
try{
    $db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_username,$db_pass, array(PDO::ATTR_PERSISTENT=>false));
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}
catch(PDOException $e){echo "Error: ".$e->getMessage()."<br />"; die(); }
include 'ColMetaData.php';   //the file containing the class for getting a column listing for each table
$coldat= new supplyColumnMeta($db);
$tablemet=$coldat->getColumnMeta('groups');   // a manual insertion of a table name for testing
echo $tablemet;

这是包含在include文件中的类     class supplyColumnMeta {         public function __construct($ db){             $这 - &GT; DB = $分贝;

    }
    /**
        *    Automatically get column metadata
    */
    public function getColumnMeta($table)
    {$this->tableName=$table;
        // Clear any previous column/field info
        $this->_fields = array();
        $this->_fieldMeta = array();
        $this->_primaryKey = NULL;

        // Automatically retrieve column information if column info not specified
        if(count($this->_fields) == 0 || count($this->_fieldMeta) == 0)
        {
            // Fetch all columns and store in $this->fields
            $columns = $this->db->query("SHOW COLUMNS FROM " . $this->tableName, PDO::FETCH_ASSOC);
            foreach($columns as $key => $col)
            {
                // Insert into fields array
                $colname = $col['Field'];
                $this->_fields[$colname] = $col;
                if($col['Key'] == "PRI" && empty($this->_primaryKey)) {
                    $this->_primaryKey = $colname;
                }

                // Set field types
                $colType = $this->parseColumnType($col['Type']);
                $this->_fieldMeta[$colname] = $colType;
            }
        }
        return true;
    }
    protected function parseColumnType($colType)
    {
        $colInfo = array();
        $colParts = explode(" ", $colType);
        if($fparen = strpos($colParts[0], "("))
        {
            $colInfo['type'] = substr($colParts[0], 0, $fparen);
            $colInfo['pdoType'] = '';
            $colInfo['length']  = str_replace(")", "", substr($colParts[0], $fparen+1));
            $colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
        }
        else
        {
            $colInfo['type'] = $colParts[0];
        }   
        // PDO Bind types
        $pdoType = '';
        foreach($this->_pdoBindTypes as $pKey => $pType)
        {
            if(strpos(' '.strtolower($colInfo['type']).' ', $pKey)) {
                $colInfo['pdoType'] = $pType;
                break;
                } else {
                $colInfo['pdoType'] = PDO::PARAM_STR;
            }
        }       
        return $colInfo;
    }
    /**
        *    Will attempt to bind columns with datatypes based on parts of the column type name
        *    Any part of the name below will be picked up and converted unless otherwise sepcified
        *     Example: 'VARCHAR' columns have 'CHAR' in them, so 'char' => PDO::PARAM_STR will convert
        *    all columns of that type to be bound as PDO::PARAM_STR
        *    If there is no specification for a column type, column will be bound as PDO::PARAM_STR
    */
    protected $_pdoBindTypes = array(
    'char' => PDO::PARAM_STR,
    'int' => PDO::PARAM_INT,
    'bool' => PDO::PARAM_BOOL,
    'date' => PDO::PARAM_STR,
    'time' => PDO::PARAM_INT,
    'text' => PDO::PARAM_STR,
    'blob' => PDO::PARAM_LOB,
    'binary' => PDO::PARAM_LOB
    );  
}

1 个答案:

答案 0 :(得分:0)

问题在于:

public function getColumnMeta($table)
{
    $this->tableName=$table;
    // Clear any previous column/field info
    $this->_fields = array();
    $this->_fieldMeta = array();
    $this->_primaryKey = NULL;

    // Automatically retrieve column information if column info not specified
    if(count($this->_fields) == 0 || count($this->_fieldMeta) == 0)
    {
        // Fetch all columns and store in $this->fields
        $columns = $this->db->query("SHOW COLUMNS FROM " . $this->tableName, PDO::FETCH_ASSOC);
        foreach($columns as $key => $col)
        {
            // Insert into fields array
            $colname = $col['Field'];
            $this->_fields[$colname] = $col;
            if($col['Key'] == "PRI" && empty($this->_primaryKey)) {
                $this->_primaryKey = $colname;
            }

            // Set field types
            $colType = $this->parseColumnType($col['Type']);
            $this->_fieldMeta[$colname] = $colType;
        }
    }
    return true;//<<--- not returning an object/array!
}

您的getColumnMeta方法返回一个布尔值true。当然,此值的字符串表示形式为1.如果希望此方法返回所有元数据,请将return语句更改为:

    return array(
        'fields'  => $this->_fields,
        'meta'    => $this->_fieldMeta,
        'primary' => $this->_primaryKey
    );

您的代码也存在其他一些问题,但是因为这是而不是 codereview.stackexchange,我不打算详细介绍。不过我会这样说:请尽量遵循大多数主要参与者所遵循的编码标准:这些标准可以在这里找到:PHP-FIG

哦,如果您想显示元数据,请不要echo他们,而是var_dumpprint_r他们,你返回一个数组或一个对象 或者至少echo json_encode($instance->getColumnMeta($table));来获得返回值的正确字符串表示。