Ich habe diese Frage einige Male bei Stack Overflow wiederholt gesehen, aber keiner hat das Problem ausreichend untersucht (oder zumindest auf eine Weise, die für mich hilfreich ist).
Das Problem ist, dass eine DB-Abfrage ganzzahlige Datentypen in PHP für ganzzahlige Spalten zurückgeben sollte. Stattdessen gibt die Abfrage jede Spalte als Zeichenfolgentyp zurück.
Ich habe sichergestellt, dass "PDO :: ATTR_STRINGIFY_FETCHES" falsch ist, nur um sicherzustellen, dass die Ergebnisse nicht in Zeichenfolgen umgewandelt werden.
Antworten, die ich gesehen habe:
- Das geht nicht
- Nein, es funktioniert unter Mac OS X installiertem PHP / MySQL
- Geben Sie cast all Ihre Werte in Ihren Code ein
- Nein, das werde ich nicht tun
- Mach dir keine Sorgen, PHP ist lose geschrieben
- Meine Daten werden als JSON ausgegeben und von vielen anderen Diensten verwendet. Einige erfordern die Daten im richtigen Format
Aus meiner Forschung geht hervor, dass dies ein Problem bei der Treiberimplementierung ist.
Viele Quellen behaupten, dass der native MySQL-Treiber die Rückgabe numerischer Typen nicht unterstützt. Dies scheint nicht zu stimmen, da es unter Mac OS X funktioniert. Es sei denn, sie wollen sagen, dass "der native MySQL-Treiber unter Linux die Funktion nicht unterstützt".
Dies bedeutet, dass der Treiber / die Umgebung, die ich unter Mac OS X installiert habe, etwas Besonderes ist. Ich habe versucht, die Unterschiede zu identifizieren, um einen Fix anzuwenden, bin jedoch durch meine Kenntnisse zur Überprüfung dieser Dinge eingeschränkt.
Die Unterschiede:
- PHP unter OS X wurde über Home Brew kompiliert und installiert
- PHP unter Ubuntu wurde über "apt-get install php5-dev" installiert.
- PHP unter OS X stellt eine Verbindung zu einem MySQL-Server her, der auch unter OS X ausgeführt wird
- Serverversion: 5.1.71-log Quelldistribution
- PHP unter Ubuntu stellt eine Verbindung zu einer Rackspace Cloud-Datenbank her
- Serverversion: 5.1.66-0 + Squeeze1 (Debian)
Ubuntu-Umgebung
- Version: 10.04.1
- PHP 5.4.21-1 + debphp.org ~ lucid + 1 (cli) (erstellt: 21. Oktober 2013 08:14:37)
php -i
pdo_mysql
PDO-Treiber für MySQL => aktivierte Client-API-Version => 5.1.72
Mac OS X-Umgebung
- 10.7.5
- PHP 5.4.16 (cli) (erstellt: 22. August 2013, 09:05:58 Uhr)
php -i
pdo_mysql
PDO-Treiber für MySQL => aktivierte Client-API-Version => mysqlnd 5.0.10 - 20111026 - $ Id: e707c415db32080b3752b232487a435ee0372157 $
PDO-Flags verwendet
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
PDO::ATTR_EMULATE_PREPARES => false,
Jede Hilfe und Sachkenntnis wäre dankbar :) Ich werde auf jeden Fall wieder hier posten, wenn ich die Antwort finde.
Antworten:
Die Lösung besteht darin, sicherzustellen, dass Sie den mysqlnd- Treiber für PHP verwenden.
Woher wissen Sie, dass Sie mysqlnd nicht verwenden?
Beim Anzeigen
php -i
wird "mysqlnd" nicht erwähnt. Derpdo_mysql
Abschnitt wird so etwas wie diese:Wie installierst du es?
Die meisten Installationsanleitungen für L / A / M / P schlagen vor,
apt-get install php5-mysql
aber der native Treiber für MySQL wird von einem anderen Paket installiert :php5-mysqlnd
. Ich fand, dass dies mit dem ppa: ondrej / php5-oldstable verfügbar war .So wechseln Sie zum neuen Treiber (unter Ubuntu):
apt-get remove php5-mysql
apt-get install php5-mysqlnd
service apache2 restart
Wie überprüfe ich, ob der Treiber verwendet wird?
Jetzt
php -i
wird "mysqlnd" explizit impdo_mysql
Abschnitt erwähnt:PDO-Einstellungen
Stellen Sie sicher, dass dies der Fall
PDO::ATTR_EMULATE_PREPARES
istfalse
(überprüfen Sie Ihre Standardeinstellungen oder stellen Sie sie ein):$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
Stellen Sie sicher, dass dies der Fall
PDO::ATTR_STRINGIFY_FETCHES
istfalse
(überprüfen Sie Ihre Standardeinstellungen oder stellen Sie sie ein):$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
Rückgabewerte
† BIGINTs mit einem Wert größer als ein 64-Bit-Int (9223372036854775807) werden als Zeichenfolge zurückgegeben (oder 32 Bit in einem 32-Bit-System).
quelle
0.30
als"0.30"
statt0.3
. Dezimalstellen werden dafür verwendet ... also ist dies das richtige VerhaltenPDO::ATTR_EMULATE_PREPARES
einen benannten Parameter mehr als einmal verwendenDiese akzeptierte Antwort funktioniert und scheint die beliebteste Antwort auf Google für diese Frage zu sein. Mein Problem ist, dass ich eine Anwendung in mehreren Umgebungen bereitstellen muss und nicht immer die Möglichkeit habe, den richtigen Treiber zu installieren. Außerdem müssen Dezimalstellen numerisch und keine Zeichenfolgen sein. Deshalb habe ich vor der JSON-Codierung eine Routine zum Eingeben von Groß- und Kleinschreibung erstellt, die leicht angepasst werden kann. Es ist ein bisschen so, als würde man es aus dem Orbit holen.
Verwenden Sie zunächst "Spalten anzeigen von", um die Spalten aus der Tabelle abzurufen. MySQL-Abfrage "SHOW COLUMNS FROM Tabelle wie 'colmunname'": Fragen
Holen Sie sich dann die Typen in ein Array, das durch den Spaltennamen indiziert ist, um das Durchlaufen zu vereinfachen. Angenommen, die Ergebnismenge der Show-Spalten befindet sich in einer Variablen mit dem Namen $ columns_from_table. http://php.net/manual/en/function.array-column.php
Als nächstes wollen wir die Klammer aus dem Typ entfernen, der so etwas wie varchar (32) oder decimal (14,6) sein wird.
Jetzt haben wir ein zugeordnetes Array mit dem Spaltennamen als Index und dem formatierten Typ als Wert, zum Beispiel:
Wenn Sie nun Ihre Auswahl aus Ihrer Tabelle treffen, können Sie die Ergebnisse durchlaufen und den Wert in den entsprechenden Typ umwandeln:
Die switch-Anweisung kann leicht an die jeweiligen Anforderungen angepasst werden und Datumsfunktionen usw. enthalten. In meinem Fall werden beispielsweise Währungswerte von einem Drittanbieter als Dezimalzahl in die Datenbank übertragen, aber wenn ich diese Daten greife und sie als zurückgeben muss JSON, ich brauche Zahlen, keine Strings.
Getestet mit PHP 7, 7.2 und JQuery 2, 3.
quelle