webentwicklung-frage-antwort-db.com.de

Das MySQL Integer Feld wird als String in PHP zurückgegeben

Ich habe ein Tabellenfeld in einer MySQL-Datenbank:

userid INT(11)

Also rufe ich es mit dieser Abfrage auf meine Seite:

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

Dann für die Behandlung des Ergebnisses mache ich:

$row=$result->fetch_assoc();

$id=$row['userid'];

Wenn ich das tue:

echo gettype($id);

Ich bekomme einen String. Sollte das nicht eine ganze Zahl sein?

111
luca

Wenn Sie Daten aus einer MySQL-Datenbank mit PHP) auswählen, wird der Datentyp immer in eine Zeichenfolge konvertiert. Sie können ihn mit dem folgenden Code wieder in eine Ganzzahl konvertieren:

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

Oder mit der Funktion intval():

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

Verwenden Sie den mysqlnd (native Treiber) für PHP.

Wenn Sie auf Ubuntu sind:

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

Wenn Sie auf Centos sind:

Sudo yum install php-mysqlnd
Sudo service httpd restart

Der native Treiber gibt Ganzzahltypen entsprechend zurück.

Bearbeiten:

Wie @Jeroen bereits betont hat, funktioniert diese Methode nur für PDOs.
Wie @LarsMoelleken hervorgehoben hat, funktioniert diese Methode mit mysqli, wenn Sie auch die Option MYSQLI_OPT_INT_AND_FLOAT_NATIVE auf true setzen.

Beispiel:

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

Meine Lösung besteht darin, das Abfrageergebnis $rs und als Rückgabe ein Assoc-Array der übertragenen Daten erhalten:

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

Anwendungsbeispiel:

$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

Einfachste Lösung, die ich gefunden habe:

Sie können json_encode zwingen, tatsächliche Zahlen für Werte zu verwenden, die wie Zahlen aussehen:

json_encode($data, JSON_NUMERIC_CHECK) 

(seit PHP 5.3.3).

Oder Sie können Ihre ID einfach in eine Ganzzahl umwandeln.

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

Nein. Unabhängig vom in Ihren Tabellen definierten Datentyp dient der MySQL-Treiber von PHP immer als Zeichenfolge für Zeilenwerte.

Sie müssen Ihre ID in einen int umwandeln.

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

Ich mag die Antwort von Chad, besonders wenn die Abfrageergebnisse in einem Browser an Javascript weitergeleitet werden. Javascript behandelt numerisch ähnliche Entitäten sauber als Zahlen, erfordert jedoch zusätzliche Arbeit, um numerisch ähnliche Entitäten als Zeichenfolgen zu behandeln. muss parseInt oder parseFloat für sie verwenden.

Aufbauend auf Tschads Lösung verwende ich diese und es ist oft genau das, was ich brauche und erstellt Strukturen, die JSON-codiert werden können, um den Umgang mit Javascript zu vereinfachen.

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

Das Hinzufügen einer numerischen Zeichenfolge zu 0 erzeugt einen numerischen Typ in PHP und identifiziert den Typ korrekt, sodass Gleitkommazahlen nicht in Ganzzahlen abgeschnitten werden.

Sie können dies tun mit ...

  1. mysql_fetch_field ()
  2. mysqli_result :: fetch_field_direct oder
  3. PDOStatement :: getColumnMeta ()

... abhängig von der gewünschten Erweiterung. Die erste wird nicht empfohlen, da die mysql-Erweiterung veraltet ist. Der dritte ist noch experimentell.

Mit den Kommentaren zu diesen Hyperlinks lässt sich gut erklären, wie Sie Ihren Typ von einer einfachen alten Zeichenfolge auf den ursprünglichen Typ in der Datenbank setzen.

Einige Frameworks extrahieren dies ebenfalls (CodeIgniter bietet $this->db->field_data() ).

Sie können auch raten, indem Sie Ihre resultierenden Zeilen durchlaufen und jeweils is_numeric () verwenden. So etwas wie:

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

Dies würde alles, was wie eine Zahl aussieht, in eins verwandeln ... definitiv nicht perfekt.

2
Chad Hedgcock

In meinem Projekt verwende ich normalerweise eine externe Funktion, die mit mysql_fetch_assoc Abgerufene Daten "filtert".

Sie können Felder in Ihrer Tabelle umbenennen, um zu verstehen, welcher Datentyp gespeichert ist.

Beispielsweise können Sie jedem numerischen Feld ein spezielles Suffix hinzufügen: Wenn userid eine INT(11) ist, können Sie es umbenennen userid_i Oder wenn es eine UNSIGNED INT(11) Sie können userid_u umbenennen. An dieser Stelle können Sie eine einfache PHP) - Funktion schreiben, die als Eingabe das assoziative Array empfängt (abgerufen mit mysql_fetch_assoc) Und das Casting auf den mit diesen speziellen Funktionen gespeicherten "Wert" anwenden "Schlüssel".

2
Didax

Dies passiert, wenn PDO::ATTR_EMULATE_PREPARES ist für die Verbindung auf true gesetzt.

2
Charlie

MySQL verfügt über Treiber für viele andere Sprachen, die Daten in Zeichenfolgen "standardisieren" und es dem Benutzer überlassen, Werte in int oder andere einzutippen

1
wolfgang

In meinem Fall wurde die Erweiterung mysqlnd.so Installiert. ABER ich hatte nicht pdo_mysqlnd.so. Das Problem wurde also gelöst, indem pdo_mysql.so Durch pdo_mysqlnd.so Ersetzt wurde.

1
Anton

Wenn vorbereitete Anweisungen verwendet werden, wird der Typ gegebenenfalls int sein. Dieser Code gibt ein Array von Zeilen zurück, wobei jede Zeile ein assoziatives Array ist. Als ob fetch_assoc() für alle Zeilen aufgerufen wurde, jedoch mit beibehaltenen Typinformationen.

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

Ein Plus vor die Variable zu setzen, macht auch den Trick,

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

Offensichtlich nicht der beste Weg, funktioniert aber, wenn Sie keinen Zugriff auf die Umgebung haben, um einen besseren Treiber zu installieren.

0
Ebrahim Byagowi

Ich mag Masterminds Technik , aber die Codierung kann einfacher sein:

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

Ich habe auch das Prüfen auf Abfrage hinzugefügt, die falsch zurückgibt, anstatt eine Ergebnismenge.
Und nach einer Zeile mit einem Feld suchen, das einen Nullwert hat.
Und wenn der gewünschte Typ eine Zeichenfolge ist, verschwende ich keine Zeit darauf - es ist bereits eine Zeichenfolge.


Ich benutze das in den meisten PHP-Codes nicht. Ich verlasse mich nur auf die automatische Typkonvertierung von PHP. Wenn Sie jedoch viele Daten abfragen, um dann arithmetische Berechnungen durchzuführen, ist es sinnvoll, die optimalen Typen im Voraus zu setzen.

0
ToolmakerSteve