Получите MySQL Query Results как их собственный тип данных? - PullRequest
18 голосов
/ 12 марта 2010

Я попытался извлечь результаты запроса MySQL, используя mysql_fetch_row() и mysql_result(), а числовые значения возвращаются в виде строк.

Есть ли способ извлечь данные в виде их типа данных, хранящихся в таблице?

Приложение будет запрашивать множество различных запросов, поэтому я не смогу привести значения в качестве предполагаемого типа данных 1 к 1.

Ответы [ 5 ]

16 голосов
/ 12 марта 2010

Я не думаю, что получение данных в их собственных типах данных (т. Е. Что-либо, кроме строк) может быть сделано в PHP 5.2 ...

В PHP 5.3 это становится возможным, если я правильно помню, когда вы используете новый (новый, как в PHP> = 5.3) mysqlnd (собственный драйвер MySQL) драйвер .

После того, как я покопался в моих закладках, я нашел эту статью о mysqlnd: PDO_MYSQLND: The new features of PDO_MYSQL in PHP 5.3

Это говорит это (цитата):

Преимущества использования mysqlnd для PDO

mysqlnd возвращает собственные типы данных, когда используя подготовленные операторы на стороне сервера, например, столбец INT возвращается как целочисленная переменная, а не как строка. Это означает, что меньше данных внутренние преобразования.

Но это только PHP 5.3 (при условии, что ваша версия PHP 5.3 скомпилирована с помощью mysqlnd (, а не старого libmysql) ) и, похоже, имеет место только для подготовленных операторов: - (

Что не совсем помогает, в вашей ситуации, я думаю ...


А вот еще один, все еще о новых функциях mysqlnd, который говорит об этом не только для подготовленных операторов: PHP: новый сетевой трафик, экономия ресурсов процессора и памяти с помощью mysqlnd .

Не уверен, что это было объединено с официальным драйвером mysqlnd - лучший способ - попробовать; но все равно это будет только PHP> = 5.3 ...


Другим решением было бы иметь на стороне PHP какую-то систему отображения (например, ORM) для преобразования результатов, поступающих из БД, в типы данных PHP ...

И да, это плохо, если вы хотите использовать такие операторы, как === и !==, которые чувствительны к типу ...

6 голосов
/ 04 августа 2015

попробуйте, если используете mysqli вместо PDO

$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
3 голосов
/ 08 августа 2011

Я реализовал это вручную. Это на самом деле не так уж и плохо, всего несколько строк.

Как и предполагалось, вызовите mysqli_fetch_fields () для ресурса, полученного в результате вашего запроса.

Затем из преобразования чисел типов полей PHP в типы данных MySQL (см. Трудолюбивую работу здесь http://www.php.net/manual/en/mysqli-result.fetch-field-direct.php), вы можете преобразовать ваши значения из широкого диапазона типов баз данных, возвращаемых MySQLi в виде строк, в соответствующий тип в PHP.

Сколько замедления, я не уверен.

1 голос
/ 31 марта 2012

Я написал функцию для обхода этого (для PDO):

/**
 * 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;
}

Конечно, список типов не завершен, и преобразование упрощено, но может быть полезно для запуска.

0 голосов
/ 06 октября 2016

В дополнение к ответу Паскаля МАРТИНА, если вы используете MySQLi, также должно работать. Попробуйте это:

<?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']));
?>

Приведенный выше пример выдаст:

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

Вы можете получить больше информации здесь: https://dev.mysql.com/doc/apis-php/en/apis-php-mysqli.quickstart.prepared-statements.html

Надеюсь, это поможет

...