web-dev-qa-db-ja.com

MySQL整数フィールドは、PHPの文字列として返されます

MySQLデータベースにテーブルフィールドがあります。

userid INT(11)

だから私はこのクエリで私のページに呼び出しています:

"SELECT userid FROM DB WHERE name='john'"

次に、結果を処理するために:

$row=$result->fetch_assoc();

$id=$row['userid'];

今私がするなら:

echo gettype($id);

文字列を取得します。これは整数ではないでしょうか?

111
luca

PHPを使用してMySQLデータベースからデータを選択すると、データ型は常に文字列に変換されます。次のコードを使用して、整数に戻すことができます。

$id = (int) $row['userid'];

または、関数intval()を使用して:

$id = intval($row['userid']);
117
Michiel Pater

Phpにはmysqlnd(ネイティブドライバー)を使用します。

Ubuntuを使用している場合:

Sudo apt-get install php5-mysqlnd
Sudo service Apache2 restart

Centosを使用している場合:

Sudo yum install php-mysqlnd
Sudo service httpd restart

ネイティブドライバは整数型を適切に返します。

編集:

@Jeroenが指摘しているように、このメソッドはPDOですぐに使用できます。
@ LarsMoellekenが指摘したように、MYSQLI_OPT_INT_AND_FLOAT_NATIVEオプションもtrueに設定すると、このメソッドはmysqliで機能します。

例:

$mysqli = mysqli_init();
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);
69
advait

私の解決策は、クエリ結果$rsを渡し、キャストデータの連想配列を戻り値として取得することです。

function cast_query_results($rs) {
    $fields = mysqli_fetch_fields($rs);
    $data = array();
    $types = array();
    foreach($fields as $field) {
        switch($field->type) {
            case 3:
                $types[$field->name] = 'int';
                break;
            case 4:
                $types[$field->name] = 'float';
                break;
            default:
                $types[$field->name] = 'string';
                break;
        }
    }
    while($row=mysqli_fetch_assoc($rs)) array_Push($data,$row);
    for($i=0;$i<count($data);$i++) {
        foreach($types as $name => $type) {
            settype($data[$i][$name], $type);
        }
    }
    return $data;
}

使用例:

$dbconn = mysqli_connect('localhost','user','passwd','tablename');
$rs = mysqli_query($dbconn, "SELECT * FROM Matches");
$matches = cast_query_results($rs);
// $matches is now a assoc array of rows properly casted to ints/floats/strings
17
mastermind202

私が見つけた最も簡単な解決策:

Json_encodeに、数値のように見える値に実際の数値を使用させることができます。

json_encode($data, JSON_NUMERIC_CHECK) 

(PHP 5.3.3以降)。

または、IDをintにキャストすることもできます。

$row = $result->fetch_assoc();
$id = (int) $row['userid'];
15
Larney

いいえ。テーブルで定義されているデータ型に関係なく、PHPのMySQLドライバーは常に行の値を文字列として提供します。

IDをintにキャストする必要があります。

$row = $result->fetch_assoc();
$id = (int) $row['userid'];
13
BoltClock

Chadの答えは、特にクエリ結果がブラウザのjavascriptに渡される場合に気に入っています。 Javascriptは、数値のようなエンティティを数値としてきれいに処理しますが、数値のようなエンティティを文字列として処理するには追加の作業が必要です。つまり、parseIntまたはparseFloatを使用する必要があります。

私はこれをChadのソリューションに基づいて構築していますが、多くの場合、まさに必要なものであり、JavaScriptで簡単に処理できるようにJSONエンコード可能な構造を作成します。

while ($row = $result->fetch_assoc()) {
    // convert numeric looking things to numbers for javascript
    foreach ($row as &$val) {
        if (is_numeric($val))
            $val = $val + 0;
    }
}

数値文字列を0に追加すると、PHPの数値型が生成され、浮動小数点数が整数に切り捨てられないように型が正しく識別されます。

あなたはこれを行うことができます...

  1. mysql_fetch_field()
  2. mysqli_result :: fetch_field_direct または
  3. PDOStatement :: getColumnMeta()

...使用する拡張機能によって異なります。 mysql拡張機能は廃止されているため、最初のものは推奨されません。 3番目はまだ実験段階です。

これらのハイパーリンクのコメントは、タイプをデータベースの単純な古い文字列から元のタイプに設定する方法を説明するのに役立ちます。

一部のフレームワークもこれを抽象化します(CodeIgniterは $this->db->field_data() を提供します)。

また、結果の行をループして、それぞれに is_numeric() を使用するなど、推測を行うこともできます。何かのようなもの:

foreach($result as &$row){
 foreach($row as &$value){
  if(is_numeric($value)){
   $value = (int) $value;
  }       
 }       
}

これは、数字のように見えるものをすべて、完全に完璧ではないものに変えます。

2
Chad Hedgcock

私のプロジェクトでは、通常、mysql_fetch_assocで取得したデータを「フィルタリング」する外部関数を使用します。

テーブル内のフィールドの名前を変更して、どのデータ型が保存されているかを直感的に理解できます。

たとえば、各数値フィールドに特別なサフィックスを追加できます。useridINT(11)の場合はuserid_iに名前を変更できます。また、UNSIGNED INT(11)の場合はuserid_uに名前を変更できます。この時点で、連想配列(mysql_fetch_assocで取得)を入力として受け取る単純なPHP関数を記述し、それらの特別な「キー」で保存された「値」にキャストを適用できます。

2
Didax

これは、接続でPDO::ATTR_EMULATE_PREPAREStrueに設定されている場合に発生します。

2
Charlie

MySQLには他の多くの言語用のドライバーがあり、データを文字列に変換してデータを「標準化」し、ユーザーに任せて値をintなどに型キャストします。

1
wolfgang

私の場合、mysqlnd.so拡張機能がインストールされていました。しかし、私はpdo_mysqlnd.soを持っていませんでした。そのため、pdo_mysql.sopdo_mysqlnd.soに置き換えることで問題を解決しました。

1
Anton

準備されたステートメントが使用される場合、タイプは適切な場合intになります。このコードは行の配列を返します。各行は連想配列です。すべての行に対してfetch_assoc()が呼び出された場合と同様ですが、型情報は保持されます。

function dbQuery($sql) {
    global $mysqli;

    $stmt = $mysqli->prepare($sql);
    $stmt->execute();
    $stmt->store_result();

    $meta = $stmt->result_metadata();
    $params = array();
    $row = array();

    while ($field = $meta->fetch_field()) {
      $params[] = &$row[$field->name];
    }

    call_user_func_array(array($stmt, 'bind_result'), $params);

    while ($stmt->fetch()) {
      $tmp = array();
      foreach ($row as $key => $val) {
        $tmp[$key] = $val;
      }
      $ret[] = $tmp;
    }

    $meta->free();
    $stmt->close();

    return $ret;
}
1
Fredrik

変数の前にプラス記号を付けることでもうまくいきます。

$a = "120";
$b = +$a;
echo gettype($b);

明らかに最善の方法ではありませんが、より良いドライバーをインストールするための環境にアクセスできない場合に機能します。

0
Ebrahim Byagowi

mastermind's technique が好きですが、コーディングはもっと簡単です:

function cast_query_results($result): array
{
    if ($result === false)
      return null;

    $data = array();
    $fields = $result->fetch_fields();
    while ($row = $result->fetch_assoc()) {
      foreach ($fields as $field) {
        $fieldName = $field->name;
        $fieldValue = $row[$fieldName];
        if (!is_null($fieldValue))
            switch ($field->type) {
              case 3:
                $row[$fieldName] = (int)$fieldValue;
                break;
              case 4:
                $row[$fieldName] = (float)$fieldValue;
                break;
              // Add other type conversions as desired.
              // Strings are already strings, so don't need to be touched.
            }
      }
      array_Push($data, $row);
    }

    return $data;
}

また、結果セットではなくfalseを返すクエリのチェックも追加しました。
そして、null値を持つフィールドを持つ行をチェックします。
そして、希望する型が文字列である場合、時間を無駄にしません-すでに文字列です。


ほとんどのphpコードでこれを使用することはありません。私はphpの自動型変換に依存しています。ただし、大量のデータを照会してから算術計算を実行する場合、事前に最適な型にキャストするのが賢明です。

0
ToolmakerSteve