CodeIgniter将所有字段作为字符串返回

时间:2013-08-05 22:11:17

标签: php codeigniter postgresql

我在CodeIgniter中有这个查询:

$query = $this->db->query("
      SELECT u.id
           , u.first_name, u.last_name
           , u.email_address
           , g.id AS group_id
           , g.name AS group_name
           , g.human_readable_name AS human_readable_group_name
        FROM users AS u
        JOIN groups AS g
          ON u.group_id = g.id
    ORDER BY u.last_name
");

return $query->result();

当我var_dump一行时,我明白了:

object(stdClass)#22 (4) {
  ["id"]=>
  string(2) "19"
  ["first_name"]=>
  string(9) "rightfold"
  // etc
}
PostgreSQL中的

idgroup_id都是integer,但$query->result()将它们作为字符串返回。如何告诉CodeIgniter使用正确的数据类型返回字段(text为字符串,integer为整数,timestampDateTime个对象等等?)?

我在PHP 5.3.15上使用CodeIgniter 2.1.4。

10 个答案:

答案 0 :(得分:4)

解决此问题的正确方法是在Codeigniter驱动程序中设置mysqli选项。 以下方法适用于使用mysqli作为数据库驱动程序的人。

方法1:
在php扩展中启用mysqlnd驱动程序。这将主要解决您的问题。如果没有,那么尝试方法2

方法2(可能不适用于所有系统):

  1. 从系统>打开mysqli_driver.php文件数据库>司机> mysqli_driver.php
  2. 将以下行添加到代码
  3. 代码:

    public function db_connect($persistent = FALSE)
        ...
        $this->_mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10); // already exits
        $this->_mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE,TRUE); // add this line
        ...
    

    代码更改后,您会得到如下所示的响应

    array (size=16)
        'auth_id' => int 1            
        'role' => string 'admin' (length=5)
        'permissions' => string 'all' (length=3)       
        'login_attempt' => int 0
        'active' => int 1        
        'mobile_verified' => int 1
    

答案 1 :(得分:2)

这对我有用。如果要进行任意转换,则需要迭代转换数组变量的数据集。将此功能添加到控制器:

<?php 
/**
 * Runs a query and returns an array of array, with correct types (as Code
 * Igniter returns everything as string) 
 * @param string $sql
 * @return array Array of array, 1st index is the row number, 2nd is column name
 */
public function queryWithProperTypes($sql) {

  $query = $this->db->query($sql);
  $fields = $query->field_data();
  $result = $query->result_array();

  foreach ($result as $r => $row) {
    $c = 0;
    foreach ($row as $header => $value) {

      // fix variables types according to what is expected from
      // the database, as CodeIgniter get all as string.

      // $c = column index (starting from 0)
      // $r = row index (starting from 0)
      // $header = column name
      // $result[$r][$header] = that's the value to fix. Must
      //                        reference like this because settype
      //                        uses a pointer as param

      $field = $fields[$c];

      switch ($field->type) {

        case MYSQLI_TYPE_LONGLONG: // 8 = bigint
        case MYSQLI_TYPE_LONG: // 3 = int
        case MYSQLI_TYPE_TINY: // 1 = tinyint
        case MYSQLI_TYPE_SHORT: // 2 = smallint
        case MYSQLI_TYPE_INT24: // 9 = mediumint
        case MYSQLI_TYPE_YEAR: // 13 = year
          settype($result[$r][$header], 'integer');
          break;

        case MYSQLI_TYPE_DECIMAL: // 0 = decimal
        case MYSQLI_TYPE_NEWDECIMAL: // 246 = decimal
        case MYSQLI_TYPE_FLOAT: // 4 = float
        case MYSQLI_TYPE_DOUBLE: // 5 = double
          settype($result[$r][$header], 'float');
          break;

        case MYSQLI_TYPE_BIT: // 16 = bit
          settype($result[$r][$header], 'boolean');
          break;

      }

      $c = $c + 1;
    }
  }

  return $result;
}

使用它像:

$sql = "SELECT * FROM whatever_table";
$result = $this->queryWithProperTypes($sql);
var_dump($result); // check that all types are correctly cast

您可能想要调整它以支持参数,但这基本上是这个想法:$query->field_data()为您提供数据集字段的元数据。有了它,您可以使用settype函数“修复”$query->result_array()返回的值。

请记住,根据数据集大小,它可能是一个非常大的开销,您应该只在返回任意时执行此操作。如果您事先知道这些类型,最好相应地进行投射。

我尝试了PDO,它还将所有值都返回为字符串。

另见:

答案 2 :(得分:1)

PDO返回具有正确数据类型的值。使用它而不是CodeIgniter的数据库库。

答案 3 :(得分:1)

我在这个问题上挣扎了很长时间。我无法找到一个不太苛刻的工作解决方案。这就是我提出的。在所有控制器内部工作,但可以以类似的方式扩展到任何CI类。

  1. 更改 application / config / database.php 以使用PDO:

        Bitmap myLogo = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background);
        Bitmap merge = mergeBitmaps(myLogo, bitmap);
    
        imageView.setImageBitmap(merge);
    
  2. 创建MY_Controller类以扩展CI_Controller application / core / MY_Controller.php

    using System;
    using System.Windows.Forms;
    
    namespace MsTscTest
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                axMsRdpClient2NotSafeForScripting1.Server = "127.0.0.1";
                axMsRdpClient2NotSafeForScripting1.Connect();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                axMsRdpClient2NotSafeForScripting1.Disconnect();
            }
        }
    }
    
  3. 在控制器中使用扩展类。在所有控制器(示例用户控制器)中更改此项:
  4. 改变这个:

    类用户扩展 CI _Controller {

    进入此 - &gt;

    类用户扩展 MY _Controller {

    现在您应该从DB返回所有正确类型的数据。

答案 4 :(得分:1)

如果您不想更改系统驱动程序,则可以更改application / Core / MY_Controller.php。

混合KalaivananFirze答案,但使用mysqli而不是PDO。

注意:小数仍然会在pdo和mysqli中转换为字符串,因此请使用Double。

创建/更改application / Core / MY_Controller.php如下:

class MY_Controller extends CI_Controller
{ 
    public function __construct()
    {
        parent::__construct();        
        $this->db->conn_id->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);
    }
}

答案 5 :(得分:0)

不,你不能用数据类型得到它。

这与codeignter无关。

MySQL将所有内容作为字符串返回,除了NULL。

1:PHP mysql_fetch_object, all properties are string?

2:Get MySQL Query Results as Their Native Data Type?

答案 6 :(得分:0)

我对CodeIgnitor文档的阅读(参见http://ellislab.com/codeigniter/user-guide/database/fields.html)是您想要遍历字段数据,然后自行决定如何处理数据。

我的猜测是,为了无缝地执行此操作,您可能希望将其数据库和/或查询类子类化,以便您可以使它们按照您的需要进行操作。

这不会让我感到轻微的工作,但开始时可能不会太糟糕。

答案 7 :(得分:0)

This is return sql object 

$query = $this->db->query("
      SELECT u.id
           , u.first_name, u.last_name
           , u.email_address
           , g.id AS group_id
           , g.name AS group_name
           , g.human_readable_name AS human_readable_group_name
        FROM users AS u
        JOIN groups AS g
          ON u.group_id = g.id
    ORDER BY u.last_name
");
return $query->result();

This query return multidimensional array as result
$query = $this->db->query("
      SELECT u.id
           , u.first_name, u.last_name
           , u.email_address
           , g.id AS group_id
           , g.name AS group_name
           , g.human_readable_name AS human_readable_group_name
        FROM users AS u
        JOIN groups AS g
          ON u.group_id = g.id
    ORDER BY u.last_name
");
return $query->result_array();

This query return single row as result
$query = $this->db->query("
      SELECT u.id
           , u.first_name, u.last_name
           , u.email_address
           , g.id AS group_id
           , g.name AS group_name
           , g.human_readable_name AS human_readable_group_name
        FROM users AS u
        JOIN groups AS g
          ON u.group_id = g.id
    ORDER BY u.last_name
");
return $query->row_array();

答案 8 :(得分:-2)

如果您想将此查询作为对象,

$query->row();
return $query;

在您的视图文件中

foreach($row as $query)
print $row->object_name;

PS:PHP总是将输出作为“字符串”。如果要将其转换为任何数据类型,例如字符串为整数,请使用(int)$ value

答案 9 :(得分:-3)

试试这个,对我有帮助。

$query = $this->db->query("
  SELECT u.id
       , u.first_name, u.last_name
       , u.email_address
       , g.id AS group_id
       , g.name AS group_name
       , g.human_readable_name AS human_readable_group_name
    FROM users AS u
    JOIN groups AS g
      ON u.group_id = g.id
ORDER BY u.last_name ");

 // use return $query->result_array();
 // use like this

  $data = $query->result_array();
  foreach ($data as $key => $value) {
      $data['group_id'] = intval($value['group_id']);
      $data['dateField'] = date_create($value['dateField']);
    }

   var_dump($data);
   //or return $data