MySQL पूर्णांक क्षेत्र को PHP में स्ट्रिंग के रूप में लौटाया जाता है


127

मेरे पास एक MySQL डेटाबेस में एक टेबल फ़ील्ड है:

userid INT(11)

इसलिए मैं इसे इस प्रश्न के साथ अपने पृष्ठ पर बुला रहा हूं:

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

फिर परिणाम को संभालने के लिए मैं करता हूं:

$row=$result->fetch_assoc();

$id=$row['userid'];

अब अगर मैं:

echo gettype($id);

मुझे एक तार मिलता है। क्या यह पूर्णांक नहीं होना चाहिए?


2
MySQL क्वेरी पंक्ति मानों को पंक्ति प्रकार या अन्य संबद्ध जानकारी नहीं देती है। बस कच्चे डेटा जो प्रत्येक टेबल सेल में है। आपको इसके लिए PHP
Dan Hanly

आप स्तंभ प्रकार की जरूरत है, यहाँ देख forums.whirlpool.net.au/archive/526795
RichardTheKiwi

पाठकों के लिए, चयनित उत्तर में परिणामों के माध्यम से पुनरावृत्ति शामिल है। लेकिन एक बेहतर उपाय है। stackoverflow.com/a/1192424/5079380
ऐल एलावे

1
@DanHanly - तकनीकी रूप से, MYSQL क्वेरी (PHP में) सेल मान का एक स्ट्रिंग प्रतिनिधित्व लौटाता है - एक 32-बिट पूर्णांक के लिए डेटाबेस में संग्रहीत वास्तविक सेल मान है ... 32-बिट पूर्णांक, अंकों की एक स्ट्रिंग नहीं। ।
टूलमेकरसेव

मेरे लिए, जब मैंने उपयोग किया तो $conn->query("your query")मुझे पूर्णांक फ़ील्ड स्ट्रिंग के रूप में मिली, लेकिन जब मैंने उपयोग किया तो $conn->prepare("your query")मुझे पैरामीटर मिला क्योंकि वे डेटाबेस में थे
बार त्ज़ादोक

जवाबों:


129

जब आप PHP का उपयोग करके एक MySQL डेटाबेस से डेटा का चयन करते हैं तो डेटाटाइप हमेशा एक स्ट्रिंग में परिवर्तित हो जाएगा। आप निम्नलिखित कोड का उपयोग करके इसे एक पूर्णांक में बदल सकते हैं:

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

या फ़ंक्शन का उपयोग करके intval():

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

79
पोस्टग्रेज बैकग्राउंड से MySQL में आने के बाद मुझे यह कहने की जरूरत महसूस हुई कि यह गधे का बहुत बड़ा दर्द है। जब आप Postgres में एक पंक्ति प्राप्त करते हैं तो आप यह सुनिश्चित करते हैं कि पंक्ति सरणी में तत्वों में उपयुक्त डेटा प्रकार होते हैं। अब मैं मैन्युअल रूप से हर उस तत्व को टाइप करने के लिए कोड लिख रहा हूँ जिसकी मुझे अपेक्षा है।
गॉर्डन

25
मैंने बहुत ही स्कीमा और डेटाबेस सर्वर पर लारवेल और मैसकल के साथ विंडोज पर कुछ परीक्षण किए। विंडोज पर प्राथमिक कुंजी को एक पूर्णांक के रूप में लौटाया जाता है और लिनक्स पर यह एक स्ट्रिंग है।
AturSams

ठीक है यह एक अच्छा विचार है लेकिन क्या होगा यदि आपके पास पुनर्प्राप्त करने के लिए हजारों फ़ील्ड हैं? इस प्रक्रिया में थोड़ा समय लगता है .. मेरे उदाहरण में, मैं प्रत्येक पोस्ट के लिए विचारों की संख्या प्राप्त करता हूं, फिर मैं अपनी सभी पोस्ट को एक तालिका में प्रिंट करता हूं, मैं उपयोगकर्ता को व्यू एस्क और डीएससी द्वारा सॉर्ट करने की अनुमति देता हूं, लेकिन यह "1" से "9" तक सॉर्ट करता है "या" 9 "से" 1 "तो पहली जगह में आप" 9999 "," 91 "," 8111 "," 7 ", आदि हो सकते हैं ...
कीसरब्रीज

@zehelvion क्या आपने कभी इसका समाधान ढूंढा है?
फेलिप फ्रांसिस्को

2
लौटाया गया प्रत्येक फ़ील्ड एक स्ट्रिंग या NULL होगा
लियाम

73

Php के लिए mysqlnd (देशी ड्राइवर) का उपयोग करें।

यदि आप उबंटू में हैं:

sudo apt-get install php5-mysqlnd
sudo service apache2 restart

यदि आप Centos पर हैं:

sudo yum install php-mysqlnd
sudo service httpd restart

मूल चालक पूर्णांक प्रकारों को उचित रूप से देता है।

संपादित करें:

जैसा कि @ जेरेन ने बताया है, यह विधि केवल पीडीओ के लिए आउट-ऑफ-द-बॉक्स काम करेगी।
जैसा कि @LarsMoelleken ने बताया है, यह तरीका mysqli के साथ काम करेगा यदि आप MYSQLI_OPT_INT_AND_FLOAT_NATIVE विकल्प को सही पर सेट करते हैं।

उदाहरण:

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

मुझे इस स्टेंट का कोई सबूत नहीं दिखता। Mysqlnd और mysqli के साथ चलने से स्पष्ट रूप से स्ट्रिंग मान वापस आ जाते हैं।
जीरोेन

@ जरीन क्या आपको यकीन है? बहुत सारे दस्तावेज उपलब्ध हैं। stackoverflow.com/questions/1197005/…
advait 18

हाँ। नीचे दिए गए टिप्पणियों को भी देखें। क्या आपने स्वयं इसका परीक्षण किया? जैसा कि यह अब दिखता है, यहां तक ​​कि 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($row);रिटर्न: array(1) { ["CAST('3.51' AS DECIMAL(3,2))"]=> string(4) "3.51" }
जीरोएन

1
यह नहीं कि मैं इसे कैसे समझता हूं, इसे पीडीओ और मैसकली के साथ समान रूप से काम करना चाहिए। यहां तक ​​कि लिंक पर आप टिप्पणी में ऊपर पोस्ट करते हैं, यह स्पष्ट रूप से कहा गया है कि यह केवल पूर्व निर्धारित कार्यों के साथ काम करता है और ओपी के अनुसार इनलाइन प्रश्नों को नहीं। उस पृष्ठ से उद्धरण: लेकिन यह केवल PHP 5.3 है (बशर्ते कि आपका PHP 5.3 का संस्करण mysqlnd (और पुराने libmysql) के साथ संकलित हो), और केवल तैयार किए गए बयानों के लिए ऐसा प्रतीत होता है :-(
Jeroen

7
आप mysqli के लिए "MYSQLI_OPT_INT_AND_FLOAT_NATIVE" का उपयोग भी कर सकते हैं
लार्स मोलेकेन

20

सबसे आसान समाधान मैंने पाया:

आप json_encode को उन मानों के लिए वास्तविक संख्याओं का उपयोग करने के लिए बाध्य कर सकते हैं जो संख्याओं की तरह दिखते हैं:

json_encode($data, JSON_NUMERIC_CHECK) 

(चूंकि PHP 5.3.3)।

या आप सिर्फ एक पहचान पत्र के लिए अपनी आईडी डाल सकते हैं।

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

1
json_encodeयदि संभव हो तो माइक्रोस्कोप का उपयोग करने के लिए एक कास्ट स्ट्रिंग का उपयोग करके नाखून को चोक करने के लिए माइक्रोस्कोप का उपयोग करना पसंद है।
लिबर्टीपॉल

7
इससे सभी पोस्टलकोड और टेलीफोन नंबर टूट जाएंगे। निःशुल्क अपने अनुप्रयोग में कीड़े को पेश करने का अच्छा तरीका है। समाधान चाहिए mysql कॉलम डेटाटाइप का सम्मान करें, मूल्य से अनुमान लगाने की कोशिश न करें।
मैक्स कटिन्स 12

1
मैक्स कटिन्स, आपकी बात सर्वमान्य है। हालाँकि, यदि आप DB से अपेक्षित सभी डेटा प्रकारों का हिसाब कर सकते हैं, तो यह लेने के लिए एक सही मार्ग होगा।
इफिडी ओकोंकवो

1
यह आपको चोट पहुँचाएगा जब आप कुछ समय के लिए '06' की तरह का आईडी बनाते हैं। यह ध्वज इसे 6. में बदल देगा जो कि गलत है क्योंकि उन आईडी को शून्य से पीछे रखना चाहिए।
हसन दाद खान

UNIX_TIMESTAMP()उदाहरण के लिए, द्वारा बनाए गए मूल्यों के लिए यह एक महान समाधान है ।
डेविड

18

मेरा समाधान क्वेरी परिणाम को पास करना $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

2
'NULL' को छोड़कर महान समाधान भी एक वैरिएबल प्रकार है जिसका उपयोग सेटपाइप () फ़ंक्शन द्वारा किया जाता है। तो आपका कोड डेटाबेस द्वारा लौटाए गए सभी NULL मान (मान जहां gettype () == 'NULL') को 'स्ट्रिंग' प्रकार में 'मान', 'पूर्णांक' प्रकार के साथ 0 मान या 0.0 मान के साथ 'फ़्लोट' प्रकार में बदलता है। अगर आपको is_null ($ data [$ i] [$ name]) सही है, तो आपको setype को कॉल करने की आवश्यकता नहीं है।
शीतकालीन ड्रैगन

मुझे मास्टरमाइंड की तकनीक पसंद है, लेकिन कोडिंग सरल हो सकती है
टूलमेकरसेव

13

आपके टेबल में परिभाषित डेटा प्रकार के बावजूद, PHP का MySQL ड्राइवर हमेशा पंक्ति मूल्यों को तार के रूप में कार्य करता है।

आपको अपनी आईडी एक इंट में डालने की आवश्यकता है।

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

6
यह PHP नहीं है जो इस व्यवहार के लिए जिम्मेदार (सीधे) है, यह डेटाबेस ड्राइवर है। यदि आप PHP से एक पोस्टग्रैज डेटाबेस के साथ हस्तक्षेप कर रहे हैं तो आपको उचित डेटा प्रकार वापस मिलेंगे।
गॉर्डन

5

मुझे चाड का उत्तर पसंद है, खासकर जब क्वेरी परिणाम एक ब्राउज़र में जावास्क्रिप्ट पर पारित किया जाएगा। जावास्क्रिप्ट संख्या के रूप में संस्थाओं जैसे संख्यात्मक के साथ सफाई से काम करता है लेकिन स्ट्रिंग्स जैसे संस्थाओं के साथ संख्यात्मक से निपटने के लिए अतिरिक्त काम की आवश्यकता होती है। यानी उन पर parseInt या parseFloat का उपयोग करना चाहिए।

चाड के समाधान पर बिल्डिंग मैं इसका उपयोग करता हूं और यह अक्सर वही होता है जिसकी मुझे आवश्यकता होती है और संरचनाएं बनाते हैं जो जावास्क्रिप्ट में आसान व्यवहार के लिए 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 में एक संख्यात्मक प्रकार का उत्पादन होता है और सही प्रकार से यह पता चलता है कि फ्लोटिंग पॉइंट नंबर पूर्णांक में नहीं काटे जाएंगे।


5

यह तब होता है जब कनेक्शन पर PDO::ATTR_EMULATE_PREPARESसेट trueकिया जाता है।

सावधान, हालांकि, यह falseएक से अधिक बार मापदंडों के उपयोग को अस्वीकार करने के लिए सेटिंग । मेरा मानना ​​है कि यह वापस आने वाले त्रुटि संदेशों की गुणवत्ता को भी प्रभावित करता है।


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

यह कुछ भी है कि एक में एक नंबर की तरह लग रहा होगा ... निश्चित रूप से सही नहीं है।


तैरने के लिए काम नहीं करता है। वे is_numeric टेस्ट पास करते हैं। आपको पहले तैरने के लिए परीक्षण करना चाहिए।
मार्टिन वैन ड्रेल

@MartinvanDriel या कोई भी स्ट्रिंग जिसमें केवल संख्याएँ होती हैं, लेकिन एक तार होना चाहिए
ट्रीफेस

@MartinvanDriel जोड़ने की कोशिश करें:if (is_float()) { $value = (float)$value; }
adjwilli

2

मेरी परियोजना में मैं आमतौर पर एक बाहरी फ़ंक्शन का उपयोग करता हूं जिसे "फ़िल्टर" डेटा के साथ पुनर्प्राप्त किया जाता है mysql_fetch_assoc

आप अपनी तालिका में फ़ील्ड का नाम बदल सकते हैं ताकि यह समझना आसान हो कि कौन सा डेटा प्रकार संग्रहीत है।

उदाहरण के लिए, आप प्रत्येक संख्यात्मक फ़ील्ड पर एक विशेष प्रत्यय जोड़ सकते हैं: अगर useridएक INT(11)आप इसे नाम बदल सकते हैं userid_iया अगर यह है एक UNSIGNED INT(11)आप नाम बदल सकते हैं userid_u। इस बिंदु पर, आप एक साधारण PHP फ़ंक्शन लिख सकते हैं जो इनपुट के रूप में प्राप्त करता है साहचर्य सरणी (साथ पुनर्प्राप्त mysql_fetch_assoc), और उन विशेष "कुंजियों" के साथ संग्रहीत "मूल्य" पर कास्टिंग लागू करें।


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

1

MySQL में कई अन्य भाषाओं के ड्राइवर हैं, डेटा को स्ट्रिंग में परिवर्तित करना "डेटा को मानकीकृत करता है" और इसे उपयोगकर्ता के लिए टाइप-कास्ट मानों को इंट या अन्य में छोड़ देता है।


1
मेरा मानना ​​है कि आदिम प्रकार बहुत "मानक" हैं? अगर कोई भाषा-विशिष्ट ड्राइवर उस भाषा की ज़रूरतों को पूरा नहीं कर पाता है, तो मैं कहूंगा कि यह बहुत निराशाजनक है
चुंग

1

मेरे मामले में mysqlnd.soविस्तार स्थापित किया गया था। लेकिन मुझे नहीं था pdo_mysqlnd.so। तो, समस्या की जगह द्वारा हल किया गया था pdo_mysql.soके साथ pdo_mysqlnd.so


0

मुझे मास्टरमाइंड की तकनीक पसंद है , लेकिन कोडिंग सरल हो सकती है:

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

मैंने परिणाम-सेट के बजाय क्वेरी को गलत तरीके से लौटाने के लिए जाँच भी जोड़ा।
और एक फ़ील्ड के साथ एक पंक्ति के लिए जाँच करना जिसमें एक शून्य मान है।
और अगर वांछित प्रकार एक स्ट्रिंग है, तो मैं उस पर कोई समय बर्बाद नहीं करता हूं - इसकी पहले से ही एक स्ट्रिंग।


मैं अधिकांश php कोड में इसका उपयोग करने से परेशान नहीं हूं; मैं सिर्फ php के स्वचालित प्रकार रूपांतरण पर भरोसा करता हूं। लेकिन अगर बहुत सारे डेटा को क्वेरी करना है, तो अंकगणितीय संगणना करने के लिए, यह अधिकतम प्रकार के सामने वाले हिस्से में डालने के लिए समझदार है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.