2013-08-05 14 views
6

ho questa query in CodeIgniter:CodeIgniter restituisce tutti i campi come stringhe

$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(); 

Quando ho var_dump di fila, ottengo questo:

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

id e group_id sono entrambi integer s in PostgreSQL, ma $query->result() li restituisce come stringhe. Come posso dire a CodeIgniter di restituire i campi usando i tipi di dati corretti (text s come stringhe, integer s come numeri interi, timestamp s come DateTime oggetti, ecc ...)?

Sto usando CodeIgniter 2.1.4 su PHP 5.3.15.

+1

-1: questo è il comportamento previsto. Qual è l'errore ** ** causato da questa forma di dati restituiti? –

+2

@ tereško che non è un valido motivo per un downvote, per l'amor di dio! Se non altro, è PHP che sta di nuovo. –

+0

@rightfold Hai avuto qualche soluzione. Si prega di aggiornare come risposta .. affrontare gli stessi problemi –

risposta

-2

Se si desidera ottenere questa query come oggetto,

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

Nel file vista

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

PS: PHP dà sempre uscita come "String". Se si desidera eseguire il cast in qualsiasi tipo di dati, stringa da esempio a intero, utilizzare il valore (int) $

+0

I _fields_ restituiti sono ancora stringhe in PHP. – rightfold

+1

Cosa vuoi dire che è tornato come stringhe?Tutto l'output sql in php verrà esportato stringa, verrà recuperato da db e ti darà risultato come stringa. Se vuoi fare una matematica. calcoli, o qualcos'altro che puoi usare (int) $ row-> nome_oggetto, ma nell'associazione dati php non è necessario. –

+0

PostgreSQL restituisce risultati digitati che non sono sempre stringhe. Inoltre, altre interfacce di database, come HDBC in Haskell e psycopg2 in Python, restituiscono i campi con i tipi corretti. – rightfold

0

La mia lettura della documentazione CodeIgnitor (vedi http://ellislab.com/codeigniter/user-guide/database/fields.html) è che ci si vuole collegare attraverso i dati di campo e poi fare la propria scelta su ciò che fare con i dati.

La mia ipotesi è che per fare ciò senza problemi probabilmente vorrebbe sottoclassi il proprio database e/o classi di query, in modo che si possa fare fare loro quello che vuoi.

Questo non mi sembra una piccola quantità di lavoro, anche se potrebbe non essere troppo brutto per iniziare.

1

PDO restituisce valori con i tipi di dati corretti. Usalo al posto della libreria di database di CodeIgniter.

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(); 
-3

prova questo, è utile per me.

$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 
2

Questo ha funzionato per me. È necessario scorrere il set di dati convertendo le variabili dell'array se si desidera il cast arbitrario.Aggiungere questa funzione al controller:

<?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; 
} 

utilizzarlo come:

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

Si potrebbe desiderare di modificarlo per supportare i parametri, ma questa è l'idea fondamentalmente: $query->field_data() ti dà i metadati per i campi del set di dati . Con ciò è possibile "correggere" i valori restituiti da $query->result_array() utilizzando la funzione settype.

Ricordare che può essere un sovraccarico in base alla dimensione del set di dati e che è necessario eseguirlo solo quando il reso è arbitrario. Se conosci i tipi in anticipo, è meglio lanciarli di conseguenza.

Ho provato PDO e restituisce anche tutti i valori come stringa.

Consulta anche:

0

Ho faticato un po 'di tempo con questo. E non sono riuscito a trovare una soluzione funzionante che non fosse troppo hacky. Questo è quello che mi è venuto in mente. Funziona all'interno di tutti i controller, ma può essere esteso a qualsiasi classe CI in modo simile.

  1. Change application/config/database.php usare DOP:

    $db['default'] = array(
        'dsn' => 'mysql:host=localhost;dbname={{my_db}};charset=utf8;', 
        'username' => 'my_db_user', 
        'password' => '123', 
        'database' => 'my_db', 
        'dbdriver' => 'pdo', 
        ... 
    ); 
    
  2. Crea classe mio_controllore di estendere CI_Controller application/core/MY_Controller.php:

    class MY_Controller extends CI_Controller { 
        public function __construct() { 
         parent::__construct(); 
         $this->db->conn_id->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
        } 
    } 
    
  3. Utilizzo della classe estesa nei controller. Modificare questa in tutti i controller (Esempio di controllo degli utenti):

Modifica questo:

classe Utenti estende CI _controller {

in questo ->

Utenti classe estende MY _Controller {

Ora dovresti avere tutti i dati restituiti dal DB con tipi corretti.

Problemi correlati