2011-03-16 45 views
88

我有一個表中的字段在MySQL數據庫:MySQL的整數字段返回字符串中PHP

userid INT(11) 

所以,我就用這個查詢調用到我的網頁:

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

那麼對於處理結果我做的:

$row=$result->fetch_assoc(); 

$id=$row['userid']; 

現在,如果我做的:

echo gettype($id); 

我得到一個字符串。這不應該是一個整數?

+2

MySQL查詢給出的行值不是行類型或任何其他相關信息。只是每個表格單元格中的原始數據。您必須在PHP – 2011-03-16 09:24:26

+0

中對此進行解釋如果您需要列類型,請參閱http://forums.whirlpool.net.au/archive/526795 – RichardTheKiwi 2011-03-16 09:36:02

+0

對於讀者,所選答案包括遍歷結果。 但有一個更好的解決方案。 http://stackoverflow.com/a/1197424/5079380 – 2016-07-03 15:13:34

回答

101

當您使用PHP從MySQL數據庫中選擇數據時,數據類型將始終轉換爲字符串。

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

使用功能intval()或者:你可以把它用下面的代碼轉換回整數

$id = intval($row['userid']);
+55

從Postgres背景來到MySQL後,我覺得有必要說這是一個巨大的麻煩。在Postgres中獲取一行時,請確保行數組中的元素具有適當的數據類型。現在我不得不編寫代碼來手動將每個元素轉換爲我期望的數據類型。 – GordonM 2011-03-25 10:14:31

+20

我剛剛在Windows上用Laravel和Mysql在相同的架構和數據庫服務器上進行了一些測試。在Windows上,主鍵作爲Integer返回,在Linux上則是String。 – zehelvion 2014-10-28 15:38:21

+0

好吧,這是一個好主意,但如果你有成千上萬的領域檢索?這個過程需要一段時間..在我的例子中,我檢索每個帖子的視圖數量,然後我打印所有的帖子在一個表格中,我允許用戶按View asc和desc排序,但它按「1」到「9 「或」9「到」1「,所以首先你可以有」9999「,」91「,」8111「,」7「等... – KeizerBridge 2015-02-25 10:07:56

12

號不管你的表定義的數據類型的,PHP的MySQL驅動程序總是將行值作爲字符串提供。

您需要將您的ID轉換爲int。

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

這不是PHP負責(直接)這種行爲,它是數據庫驅動程序。如果您使用PHP與Postgres數據庫進行交互,則會返回適當的數據類型。 – GordonM 2011-03-25 10:15:52

2

在我的項目中,我通常使用一個外部函數來「過濾」用mysql_fetch_assoc檢索到的數據。

您可以重命名錶中的字段,以便直觀瞭解存儲哪種數據類型。

例如,您可以添加一個特殊的後綴爲每個數字字段: 如果useridINT(11)可以重命名userid_i,或者如果它是一個UNSIGNED INT(11)您可以重命名userid_u。 此時,您可以編寫一個簡單的PHP函數,接收關聯數組作爲輸入(使用mysql_fetch_assoc檢索),並將轉換應用到與這些特殊「鍵」一起存儲的「值」。

2

你可以...做到這一點

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

...取決於您要使用的擴展名。第一個不推薦,因爲mysql擴展已被棄用。第三個仍然是實驗性的。

這些超鏈接的評論在解釋如何將數據庫中的普通舊字符串設置爲原始類型方面做得很好。一些框架也提取了這個(CodeIgniter提供了$this->db->field_data())。

你也可以做猜測 - 就像循環遍歷你的結果行,並在每個行上使用is_numeric()。例如:

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

這會將任何看起來像數字的東西變成一個......絕對不是完美的。

+0

不適用於浮動。他們通過了is_numeric測試。你應該首先測試花車。 – 2016-07-06 09:12:30

+0

@MartinvanDriel或任何只包含數字,但應該是字符串的字符串 – treeface 2016-07-06 22:48:02

+0

@MartinvanDriel嘗試添加:'if(is_float()){$ value =(float)$ value; }' – adjwilli 2016-09-15 14:34:42

1

如果使用預準備語句,則在適當的情況下,類型將爲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; 
} 
14

我的解決辦法是通過查詢結果$rs和得到的鑄造數據作爲返回的ASSOC數組:

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 
56

使用mysqlnd(本地驅動程序)的PHP。

如果你在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); 
+0

我沒有看到這個sta sta的任何證明。使用mysqlnd和mysqli運行,返回明確的字符串值。 – Jeroen 2014-12-09 07:49:45

+0

@Jeroen你確定嗎?有很多可用的文檔。 http://stackoverflow.com/questions/1197005/how-to-get-numeric-types-from-mysql-using-pdo – advait 2014-12-09 18:04:36

+0

是的。另請看下面的評論。你自己測試過了嗎?就像現在看起來的那樣,即使mysqlnd只使用預準備語句也會返回適當的類型。例如: '$ link = mysqli_connect('localhost','root',''); mysqli_set_charset($ link,'utf8'); $ result = mysqli_query($ link,'SELECT CAST(\'3.51 \'AS DECIMAL(3,2))'); $ row = mysqli_fetch_assoc($ result); 的var_dump($行);' 回報: '陣列(1){ [ 「CAST( '3.51' AS DECIMAL(3,2))」] => 串(4) 「3.51」 }' – Jeroen 2014-12-10 08:59:25

4

我喜歡乍得的答案,尤其是當查詢結果將在瀏覽器中被傳遞給JavaScript。 Javascript像數字一樣乾淨地處理數字,但需要額外的工作來處理像數字一樣的字符串。即對它們必須使用parseInt或parseFloat。

建立在乍得的解決方案我使用這個,它通常正是我所需要的,並創建結構可以是JSON編碼,以便於在JavaScript中處理。

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中的數字類型和正確地識別類型,以便浮點數不會被截斷成整數。

2

MySQL有許多其他語言的驅動程序,將數據轉換成字符串「標準化」的數據,並留下它給用戶類型轉換價值爲int或他人

+1

我相信原始類型幾乎是一個「標準」?如果語言特定的驅動程序無法滿足該語言的需求,我會說非常令人失望 – Chung 2016-07-18 04:09:51

8

簡單的解決方案,我發現:

您可以強制json_encode用實際號碼看起來像數字值:

json_encode($data, JSON_NUMERIC_CHECK) 

(自PHP 5.3.3)。

或者您可以將您的ID轉換爲int。

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

如果可能的話,使用'json_encode'將字符串轉換爲int類似於使用顯微鏡來掐指甲。 – LibertyPaul 2017-08-06 17:37:06

0

放一個加號前的變量也做的伎倆,

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

顯然不是最好的方式,但是當你沒有獲得安裝好驅動程序的環境中工作。

0

在我的情況下,mysqlnd.so擴展已安裝。但我沒有pdo_mysqlnd.so。所以,通過用pdo_mysqlnd.so代替pdo_mysql.so解決了問題。