PHP + PDO + MySQL: मैं PHP में पूर्णांक और संख्यात्मक के रूप में MySQL से पूर्णांक और संख्यात्मक कॉलम कैसे लौटाऊं?


85

मैंने इस सवाल को स्टैक ओवरफ्लो पर कुछ बार दोहराया लेकिन किसी ने भी समस्या का पर्याप्त रूप से पता नहीं लगाया (या कम से कम एक तरह से जो मददगार है)

समस्या यह है कि एक DB क्वेरी को पूर्णांक कॉलम के लिए PHP में पूर्णांक डेटा प्रकार वापस करना चाहिए। इसके बजाय क्वेरी प्रत्येक स्तंभ को स्ट्रिंग प्रकार के रूप में लौटाती है।

मैंने यह सुनिश्चित किया है कि "PDO :: ATTR_STRINGIFY_FETCHES" यदि केवल यह सुनिश्चित करने के लिए कि परिणाम सुनिश्चित करने के लिए गलत नहीं हैं

उत्तर जो मैंने देखे हैं:

  • यह नहीं किया जा सकता है
    • नहींं, यह मैक ओएस एक्स स्थापित PHP / MySQL पर काम कर रहा है
  • अपने कोड में अपने सभी मान टाइप करें
    • नहीं, मैं ऐसा नहीं करूंगा
  • इसके बारे में चिंता न करें, PHP शिथिल टाइप की है
    • मेरा डेटा JSON के रूप में आउटपुट है और कई अन्य सेवाओं द्वारा उपभोग किया जाता है, कुछ को सही प्रारूप में डेटा की आवश्यकता होती है

अपने शोध से मैं समझता हूं कि यह एक ड्राइवर कार्यान्वयन मुद्दा है।

कई स्रोतों का दावा है कि MySQL के मूल चालक संख्यात्मक प्रकारों को वापस करने का समर्थन नहीं करते हैं। यह सच नहीं लगता क्योंकि यह मैक ओएस एक्स पर काम करता है। जब तक वे कहने का मतलब यह नहीं है कि " लिनक्स पर MySQL के मूल चालक सुविधा का समर्थन नहीं करता है"।

इसका तात्पर्य यह है कि मैक ओएस एक्स पर मैंने जो ड्राइवर / पर्यावरण स्थापित किया है, उसके बारे में कुछ विशेष है। मैं फ़िक्स को लागू करने के लिए मतभेदों को पहचानने की कोशिश कर रहा हूं, लेकिन मैं अपने ज्ञान से सीमित हूं कि इन चीजों को कैसे जांचना है।

भिन्नताएं:

  • OS X पर PHP को होम ब्रू के माध्यम से संकलित और स्थापित किया गया था
  • Ubuntu पर PHP के माध्यम से स्थापित किया गया था "apt-get install php5-dev"
  • OS X पर PHP एक MySQL सर्वर से जुड़ रहा है जो OS X पर भी चल रहा है
    • सर्वर संस्करण: 5.1.71-लॉग स्रोत वितरण
  • उबंटू पर PHP एक Rackspace Cloud Database से कनेक्ट हो रही है
    • सर्वर संस्करण: 5.1.66-0 + निचोड़ 1 (डेबियन)

उबटन का वातावरण

  • संस्करण: 10.04.1
  • PHP 5.4.21-1 + debphp.org ~ ल्यूसिड + 1 (cli) (निर्मित: 21 अक्टूबर 2013 08:14:37)
  • php -आई

    pdo_mysql

    MySQL => सक्षम क्लाइंट API संस्करण => 5.1.72 के लिए PDO ड्राइवर

मैक ओएस एक्स पर्यावरण

  • 10.7.5
  • PHP 5.4.16 (cli) (निर्मित: अगस्त 22 2013 09:05:58)
  • php -आई

    pdo_mysql

    MySQL के लिए PDO ड्राइवर => सक्षम क्लाइंट 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,

किसी भी मदद और विशेषज्ञता की सराहना की जाएगी :) मैं निश्चित रूप से यहां वापस पोस्ट करूंगा अगर मुझे जवाब मिल जाए।


2
यह mysqlnd की जिम्मेदारी है। मुझे विश्वास है
आपका सामान्य ज्ञान

मेरे पास बिल्कुल वही सवाल है, लेकिन एमएस SQL ​​सर्वर के लिए। वहाँ एक दृढ़ता से टाइप की गई लाइब्रेरी है, जो कि mysqlnd के समान है? नवीनतम ड्राइवरों मैं मिल सकता है सभी सूत्र।
GSerg

जवाबों:


121

इसका समाधान यह सुनिश्चित करना है कि आप php के लिए mysqlnd ड्राइवर का उपयोग कर रहे हैं ।

आप कैसे जानते हैं कि आप mysqlnd का उपयोग नहीं कर रहे हैं?

देखते समय php -i, "mysqlnd" का कोई उल्लेख नहीं होगा । 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

नए ड्राइवर पर (उबंटू पर) स्विच करने के लिए:

  • पुराने ड्राइवर को निकालें:
    apt-get remove php5-mysql
  • नया ड्राइवर स्थापित करें:
    apt-get install php5-mysqlnd
  • Apache2 पुनरारंभ करें:
    service apache2 restart

मैं कैसे जांच करूं कि ड्राइवर का उपयोग किया जा रहा है?

अब अनुभाग php -iमें स्पष्ट रूप से "mysqlnd" का उल्लेख करेंगे pdo_mysql:

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

मान लौटाया

  • फ़्लोटिंग-पॉइंट प्रकार (FLOAT, DOUBLE) को PHP फ़्लोट के रूप में लौटाया जाता है।
  • पूर्णांक प्रकार (INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT EG) को PHP पूर्णांक के रूप में लौटाया जाता है।
  • फिक्स्ड-पॉइंट प्रकार (DECIMAL, NUMERIC) को तार के रूप में लौटाया जाता है।

64 64 बिट पर हस्ताक्षर किए गए इंट (9223372036854775807) से अधिक मूल्य वाले बिज़ एक स्ट्रिंग (या 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)

3
ध्यान दें कि mysqlnd सक्षम के इस संस्करण के साथ भी, DECIMALS अभी भी स्ट्रिंग्स के रूप में भेजा जाएगा ... (हालांकि फ़्लोट्स को फ़्लोट के रूप में लौटाया जाएगा!): / स्रोत: मैंने इसका परीक्षण किया था।
पेरे

4
यह भी ध्यान दें कि PDO :: ATTR_STRINGIFY_FETCHES का इससे कोई लेना-देना नहीं है - मैंने कोशिश की और इसका परिणाम पर कोई प्रभाव नहीं पड़ा, और इस पोस्ट में @Josh Davis का कहना है कि यह MySQL से असंबंधित है।
पेरे

1
धन्यवाद, मैंने आगे की जांच की है और DECIMAL प्रकार के बारे में नोट्स के साथ अपडेट किया है।
Stephenfrank 14

4
@ यह सही व्यवहार है। DECIMAL एक संख्यात्मक प्रकार नहीं है। यह संख्याओं के लिए एक स्ट्रिंग प्रारूप है। इसलिए आप वापस लौट सकते हैं: 0.30के "0.30"बजाय 0.3। इसके लिए दशमलव का उपयोग किया जाता है ... इसलिए यह सही व्यवहार है
मैक्स कटिन्स

यह एक समझौता क्यों है? मुझे PDO::ATTR_EMULATE_PREPARESएक नामित पैरामीटर का अधिक उपयोग करने की आवश्यकता है
Gaby_64

4

यह स्वीकृत उत्तर काम करता है, और इस प्रश्न के लिए Google पर सबसे लोकप्रिय उत्तर लगता है। मेरा मुद्दा यह है कि मुझे कई वातावरणों के लिए एक एप्लिकेशन को तैनात करने की आवश्यकता है और मेरे पास हमेशा सही ड्राइवर स्थापित करने की क्षमता नहीं है, साथ ही मुझे दशमलव को संख्यात्मक होने की आवश्यकता है, तार नहीं। इसलिए मैंने JSON एन्कोडिंग से पहले केस टाइप करने के लिए एक रूटीन बनाया, जिसे आसानी से सूट करने के लिए संशोधित किया गया है। यह कक्षा से इसे गुनगुनाने जैसा है।

तालिका से कॉलम प्राप्त करने के लिए सबसे पहले "शो कॉलम से" का उपयोग करें। mysql query "SHOW COLUMNS FROM table like 'colmunname'": questions

$query = 'SHOW COLUMNS FROM ' . $table; //run with mysqli or PDO 

फिर स्तंभ नाम से अनुक्रमित सरणी में टाइप करें ताकि इसे अधिक से अधिक आसानी से बनाया जा सके। शो कॉलम से सेट किए गए परिणामों को $ कॉलम_from_table नामक एक चर में है। http://php.net/manual/en/function.array-column.php

$column_types = array_column( $columns_from_table, 'Type', 'Field');

आगे हम पैरेंटिकल को उस प्रकार से हटाना चाहते हैं, जो कुछ वैरचर (32) या दशमलव (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;
}

स्विच स्टेटमेंट को आसानी से सूट करने के लिए संशोधित किया जा सकता है, और तिथि कार्यों आदि को शामिल किया जा सकता है, उदाहरण के लिए, मेरे मामले में एक तृतीय पक्ष एक दशमलव के रूप में डेटाबेस में मुद्रा मूल्यों को आगे बढ़ा रहा है, लेकिन जब मैं उस डेटा को हड़प लेता हूं और इसे वापस करने की आवश्यकता होती है JSON, मुझे उन नंबरों की आवश्यकता है, तार नहीं।

PHP 7, 7.2 और JQuery 2, 3 के साथ परीक्षण किया गया।

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