2010-03-12 15 views
18

Próbowałem pobierania wyników kwerendy MySQL przy użyciu mysql_fetch_row() i mysql_result() i wartości numeryczne są zwracane jako ciągi.Uzyskaj wyniki zapytań MySQL jako ich rodzime typy danych?

Czy istnieje sposób na pobranie danych jako typ danych przechowywany w tabeli?

Aplikacja będzie wysyłać zapytania do wielu różnych zapytań, więc nie będę w stanie odrzucić wartości jako zamierzonego typu danych na zasadzie 1 na 1.

Odpowiedz

14

Nie sądzę pobierania danych w swoich rodzimych typów danych (czyli nic innego, że struny) można zrobić w PHP 5.2 ...

w PHP 5.3, staje się możliwe, jeśli dobrze pamiętam, kiedy używasz nowego sterownika (nowy jak w PHP> = 5.3) mysqlnd (MySQL Native Driver).

Po przeszukiwaniem moich zakładek znalazłem ten artykuł o mysqlnd: PDO_MYSQLND: The new features of PDO_MYSQL in PHP 5.3

mówi to (cytat):

zalety korzystania mysqlnd dla PDO

mysqlnd zwraca rodzimy typy danych, gdy za pomocą instrukcji przetworzonych po stronie serwera, , na przykład zwracana jest kolumna INT jako zmienna całkowita e nie jako ciąg znaków . Oznacza to wewnętrznie mniej konwersji danych.

Ale to tylko PHP 5.3 (o ile twoja wersja PHP 5.3 jest skompilowany z mysqlnd (a nie starego libmysql)) i wydaje się, że tylko w przypadku sprawozdania przygotowanego :-(

który nie dość pomocy, w sytuacji, myślę ...


A oto jeszcze jeden, wciąż o nowe funkcje mysqlnd, które mówi o tym, że nie tylko sporządzanych sprawozdań. PHP: New network traffic, CPU and memory savings with mysqlnd

Nie jestem pewien, czy został on scalony z oficjalnym sterownikiem mysqlnd, najlepiej jednak spróbować; ale to nadal PHP> = 5,3 tylko, tak ...


Innym rozwiązaniem byłoby mieć na PHP-boku, jakieś odwzorowanie systemem (jak ORM) do konwersji wyników pochodzących z DB typów danych PHP ...

i tak, to jest źle, jeśli chcesz używać operatorów jak === i !==, które są wrażliwe na rodzaj ...

+0

Thanks Pascal MARTIN! Prowadziłem go przez kilka godzin i nie znalazłem niczego, co mógłbym wykorzystać. Jestem względnie nowy w PHP, ale wydaje mi się, że będę potrzebować pomocy z PDO, jeśli chcę mieć natywne wsparcie. Niestety, mój host działa 5.2.something ... Również trudne jest to, że próbuję utworzyć plik wejściowy raportu XML, który zawiera różne informacje o zapytaniu. Skrypt PHP odczytuje żądany plik xml i wysyła kwerendy do bazy danych, więc naprawdę nigdy nie dowiem się, jakie dane są wyszukiwane i jak powinny zostać zwrócone. Czas na kreatywność, jak sądzę :) –

+1

PDO czy nie PDO nie powinno niczego zmieniać, w tym przypadku: ważne są sterowniki używane pod * * (tj. Libmysql vs mysqlnd) * - i nie jestem nawet pewien, że mysqlnd w PHP 5.3.2 zwraca typ natywny dla standardowych zapytań ;;; w każdym razie, w PHP 5.2 jedynym rozwiązaniem będzie warstwa mapująca, która w razie potrzeby wykona konwersję ... –

+0

Należy pamiętać, że trzeba będzie [wyłączyć przygotowaną emulację instrukcji] (http: // /stackoverflow.com/a/15592818/441684) jeśli korzystasz z PDO. –

3

i zostały wdrożone to sposób ręczny. Nie jest tak źle, tylko kilka linijek.

Zgodnie z sugestią, wywołaj funkcję mysqli_fetch_fields() dla zasobu wynikowego z zapytania.

Następnie z odwzorowania liczb typu pola PHP na typy danych MySQL (patrz pracowity tutaj http://www.php.net/manual/en/mysqli-result.fetch-field-direct.php) możesz konwertować swoje wartości z szerokiego zakresu typów baz danych zwracanych jako ciągi przez MySQLi, do odpowiedniego typu w PHP.

Ile spowolnienia nie jestem pewien.

+0

to jest dokładnie to, czego potrzebowałem. Dzięki! – jbrahy

1

napisałem funkcję circuvent to (w przypadku ChNP):

/** 
* Converts columns from strings to types according to 
* PDOStatement::columnMeta 
* 
* @param PDOStatement $st 
* @param array $assoc returned by PDOStatement::fetch with PDO::FETCH_ASSOC 
* @return copy of $assoc with matching type fields 
*/ 
function convertTypes(PDOStatement $statement, $assoc) 
{ 
    for ($i = 0; $columnMeta = $statement->getColumnMeta($i); $i++) 
    { 
     $type = $columnMeta['native_type']; 

     switch($type) 
     { 
      case 'DECIMAL': 
      case 'TINY': 
      case 'SHORT': 
      case 'LONG': 
      case 'LONGLONG': 
      case 'INT24': 
       $assoc[$columnMeta['name']] = (int) $assoc[$columnMeta['name']]; 
       break; 
      case 'DATETIME': 
      case 'DATE': 
      case 'TIMESTAMP': 
       $assoc[$columnMeta['name']] = strtotime($assoc[$columnMeta['name']]); 
       break; 
      // default: keep as string 
     } 
    } 

    return $assoc; 
} 

Oczywiście lista typu nie są kompletne, a konwersja jest uproszczony, ale mogą być przydatne do początku.

3

spróbować tego, czy używając mysqli zamiast PDO

$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1); 
+0

To zrobiło to za mnie. Dziękuję Ci! – Victor

-1

Oprócz Pascal MARTIN odpowiedź, jeśli używasz MySQLi powinny również działać. Spróbuj tego:

<?php 
$mysqli = new mysqli("example.com", "user", "password", "database"); 
if ($mysqli->connect_errno) { 
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error; 
} 

if (!$mysqli->query("DROP TABLE IF EXISTS test") || 
    !$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))") || 
    !$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')")) { 
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error; 
} 

$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1"); 
$stmt->execute(); 
$res = $stmt->get_result(); 
$row = $res->fetch_assoc(); 

printf("id = %s (%s)\n", $row['id'], gettype($row['id'])); 
printf("label = %s (%s)\n", $row['label'], gettype($row['label'])); 
?> 

Powyższy przykład wyświetli:

id = 1 (integer) 
label = a (string) 

Można uzyskać więcej informacji tutaj: https://dev.mysql.com/doc/apis-php/en/apis-php-mysqli.quickstart.prepared-statements.html

Nadzieja to pomaga