私はこの質問をStack Overflowで数回繰り返しましたが、問題を十分に調査したものはありません(または少なくとも私に役立つ方法で)
問題は、DBクエリが整数列に対してPHPで整数データ型を返す必要があることです。代わりに、クエリはすべての列を文字列型として返します。
結果が文字列にキャストされていないことを確認するためだけに、falseの場合、「PDO :: ATTR_STRINGIFY_FETCHES」を確認しました。
私が見た答え:
私の研究から、これはドライバー実装の問題であることを理解しています。
多くのソースは、MySQLネイティブドライバーが数値型を返すことをサポートしていないと主張しています。 Mac OS Xで動作するため、これは事実ではないようです。「Linux上のMySQLネイティブドライバーはこの機能をサポートしていません」と言わない限り。
これは、Mac OS Xにインストールしたドライバー/環境に何か特別なものがあることを意味します。修正を適用するために違いを特定しようとしていましたが、これらのことを確認する方法に関する知識に制限があります。
php -i
pdo_mysql
PDO Driver for MySQL =>有効なクライアントAPIバージョン=> 5.1.72
php -i
pdo_mysql
PDO Driver for MySQL =>有効なクライアントAPIバージョン=> mysqlnd 5.0.10-20111026-$ Id:e707c415db32080b3752b232487a435ee0372157 $
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,
どんな助けと専門知識もありがたいと思います:)答えが見つかったら、ここに間違いなく投稿します。
解決策は、PHPでmysqlndドライバーを使用していることを確認することです。
_php -i
_を表示すると、「mysqlnd」のno言及があります。 _pdo_mysql
_セクションには次のようなものがあります。
_pdo_mysql
PDO Driver for MySQL => enabled Client API version => 5.1.72
_
L/A/M/Pのほとんどのインストールガイドでは_apt-get install php5-mysql
_を推奨していますが、MySQLのネイティブドライバーは別のパッケージ_php5-mysqlnd
_によってインストールされます。これはppa:ondrej/php5-oldstableで利用可能であることがわかりました。
新しいドライバーに切り替えるには(Ubuntuの場合):
apt-get remove php5-mysql
_apt-get install php5-mysqlnd
_service Apache2 restart
_これで、_php -i
_は_pdo_mysql
_セクションで明示的に「mysqlnd」に言及します。
_pdo_mysql
PDO Driver for MySQL => enabled
Client API version => mysqlnd 5.0.10 - 20111026 - $Id: e707c415db32080b3752b232487a435ee0372157 $
_
_PDO::ATTR_EMULATE_PREPARES
_がfalse
であることを確認してください(デフォルトを確認するか、設定してください):$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
_PDO::ATTR_STRINGIFY_FETCHES
_がfalse
であることを確認してください(デフォルトを確認するか、設定してください):$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
†64ビットの符号付き整数(9223372036854775807)より大きい値を持つBIGINTは、文字列(または32ビットシステムでは32ビット)として返されます
_ object(stdClass)[915]
public 'integer_col' => int 1
public 'double_col' => float 1.55
public 'float_col' => float 1.5
public 'decimal_col' => string '1.20' (length=4)
public 'bigint_col' => string '18446744073709551615' (length=20)
_
この受け入れられた回答は機能し、この質問に対するGoogleで最も人気のある回答のようです。私の問題は、アプリケーションを複数の環境に展開する必要があり、適切なドライバーをインストールできるとは限らないことに加えて、文字列ではなく数値である小数が必要なことです。そこで、JSONエンコードの前に大文字と小文字を入力するルーチンを作成しました。これは簡単に変更できます。それは軌道からそれを弱めるようなものです。
まず、「show columns from」を使用して、テーブルから列を取得します。 mysql query "'colmunname'のようなテーブルから列を表示":questions
$query = 'SHOW COLUMNS FROM ' . $table; //run with mysqli or PDO
次に、列名でインデックス付けされた配列に型を取得して、簡単に反復できるようにします。 show columnsからの結果セットは、$ columns_from_tableという名前の変数にあると想定しています。 http://php.net/manual/en/function.array-column.php
$column_types = array_column( $columns_from_table, 'Type', 'Field');
次に、型から括弧を削除します。これは、varchar(32)またはdecimal(14,6)のようなものになります
foreach( $column_types as $col=>$type )
{
$len = strpos( $type, '(' );
if( $len !== false )
{
$column_types[ $col ] = substr( $type, 0, $len );
}
}
これで、インデックスとして列名を、値としてフォーマットされた型を使用して、関連付けられた配列が作成されました。たとえば、
Array
(
[id] => int
[name] => varchar
[balance] => decimal
...
)
これで、テーブルから選択を行うと、結果を反復処理し、値を適切な型にキャストできます。
foreach( $results as $index=>$row )
{
foreach( $row as $col=>$value )
{
switch( $column_types[$col] )
{
case 'decimal':
case 'numeric':
case 'float':
case 'double':
$row[ $col ] = (float)$value;
break;
case 'integer':
case 'int':
case 'bigint':
case 'mediumint':
case 'tinyint':
case 'smallint':
$row[ $col ] = (int)$value;
break;
}
}
$results[ $index ] = $row;
}
Switchステートメントは、それに合わせて簡単に変更でき、日付関数などを含めることができます。たとえば、私の場合、サードパーティが通貨値を10進数としてデータベースにプッシュしますが、そのデータを取得し、 JSON、文字列ではなく数字にする必要があります。
PHP 7、7、7.2 and JQuery 2、3.でテスト済み.