মাইএসকিউএল পূর্ণসংখ্যা ক্ষেত্রটি পিএইচপি-তে স্ট্রিং হিসাবে ফিরে আসে


127

আমার একটি মাইএসকিউএল ডাটাবেসে একটি টেবিল ক্ষেত্র রয়েছে:

userid INT(11)

সুতরাং আমি এই প্রশ্নের সাথে এটি আমার পৃষ্ঠায় কল করছি:

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

তারপরে আমি ফলাফলটি পরিচালনা করার জন্য:

$row=$result->fetch_assoc();

$id=$row['userid'];

এখন যদি আমি করি:

echo gettype($id);

আমি একটি স্ট্রিং পেতে। এটি কি পূর্ণসংখ্যা হওয়া উচিত নয়?


2
মাইএসকিউএল কোয়েরি সারি মান দেয় যা সারি প্রকার বা অন্য কোনও সম্পর্কিত তথ্য নয়। প্রতিটি টেবিল কক্ষে কেবলমাত্র কাঁচা ডেটা। আপনাকে পিএইচপি
ড্যান হ্যানলি

আপনি কলাম ধরনের প্রয়োজন হয়, তাহলে এখানে দেখতে forums.whirlpool.net.au/archive/526795
RichardTheKiwi

পাঠকদের জন্য, নির্বাচিত উত্তর ফলাফলের মাধ্যমে পুনরাবৃত্তি জড়িত। তবে এর চেয়ে আরও ভাল সমাধান রয়েছে। stackoverflow.com/a/1197424/5079380
আমর ElAdawy

1
@ ড্যানহ্যানলি - প্রযুক্তিগতভাবে, এমওয়াইএসকিউএল কোয়েরি (পিএইচপি-তে) সেল মানটির একটি স্ট্রিং প্রতিনিধিত্ব দেয় - 32-বিট পূর্ণসংখ্যার জন্য ডাটাবেসে সঞ্চিত প্রকৃত ঘর মান হ'ল ... 32-বিট পূর্ণসংখ্যা, অঙ্কের একটি স্ট্রিং নয় ।
টুলমেকারস্টেভ

আমার জন্য, আমি যখন $conn->query("your query")স্ট্রিং হিসাবে পূর্ণসংখ্যার ক্ষেত্রগুলি পেয়েছিলাম তবে যখন আমি ব্যবহার $conn->prepare("your query")করি তখন আমি প্যারামিটারগুলি পেয়েছিলাম যেমন তারা ডাটাবেসে ছিল
বার তাজাদোক

উত্তর:


129

আপনি যখন পিএইচপি ব্যবহার করে কোনও মাইএসকিউএল ডাটাবেস থেকে ডেটা নির্বাচন করেন তখন ডেটাটাইপ সর্বদা একটি স্ট্রিনে রূপান্তরিত হয়। আপনি নিম্নলিখিত কোডটি ব্যবহার করে এটি পুনরায় পূর্ণসংখ্যায় রূপান্তর করতে পারেন:

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

বা ফাংশন ব্যবহার করে intval():

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

79
পোস্টগ্রিসের পটভূমি থেকে মাইএসকিউএলে এসে আমি বলার প্রয়োজন বোধ করি এটি পাছার একটি বিশাল ব্যথা। আপনি পোস্টগ্রিসে একটি সারি আনার সময় আপনি নিশ্চিত হন যে সারি অ্যারেতে থাকা উপাদানগুলির যথাযথ ডেটা ছিল। এখন আমি যে উপাদানটি প্রত্যাশা করছি তা প্রতিটি উপাদান ম্যানুয়ালি কাস্ট করতে কোড লিখতে হচ্ছে।
গর্ডনএম

25
আমি উইন্ডোতে লারভেল এবং মাইএসকিএল দিয়ে খুব একই স্কিমা এবং ডাটাবেস সার্ভারে কিছু পরীক্ষা করেছি। উইন্ডোজটিতে প্রাথমিক কীটি পূর্ণসংখ্যা হিসাবে এবং লিনাক্সে এটি একটি স্ট্রিং হিসাবে ফিরে আসে।
আতুরস্যামস

ঠিক আছে এটি একটি ভাল ধারণা তবে আপনার যদি পুনরুদ্ধার করার জন্য কয়েক হাজার ক্ষেত্র থাকে? এই প্রক্রিয়াটি কিছুটা সময় নেয় .. আমার উদাহরণে আমি প্রতিটি পোস্টের জন্য ভিউ সংখ্যা পুনরুদ্ধার করি, তারপরে আমি আমার সমস্ত পোস্টটি একটি টেবিলের মধ্যে মুদ্রণ করি, আমি ব্যবহারকারীকে asc এবং desc অনুসারে বাছাই করতে অনুমতি দিই, তবে এটি "1" থেকে "9" অনুসারে সাজান "বা" 9 "থেকে" 1 "তাই প্রথম স্থানে আপনার" 9999 "," 91 "," 8111 "," 7 "ইত্যাদি থাকতে পারে ...
কেজারব্রিজ

@ জেহেলভিওন কি কখনও এর সমাধান পেয়েছেন?
ফিলিপ ফ্রান্সিসকো

2
প্রত্যাবর্তিত প্রতিটি ক্ষেত্রের স্ট্রিং OR নাল হবে
লিয়াম

73

পিএইচপি জন্য mysqlnd (নেটিভ ড্রাইভার) ব্যবহার করুন।

আপনি যদি উবুন্টুতে থাকেন:

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

আপনি Centos এ থাকলে:

sudo yum install php-mysqlnd
sudo service httpd restart

নেটিভ ড্রাইভার যথাযথভাবে পূর্ণসংখ্যার প্রকার ফেরত দেয়।

সম্পাদনা:

@ জিরোইন যেমন উল্লেখ করেছেন, এই পদ্ধতিটি কেবল পিডিওর বাইরে কাজ করবে।
@ লার্স মোলেলেকেন যেমন উল্লেখ করেছেন, আপনি যদি MYSQLI_OPT_INT_AND_FLOAT_NATIVE বিকল্পটিকে সত্য হিসাবে সেট করে থাকেন তবে এই পদ্ধতিটি mysqli এর সাথে কাজ করবে।

উদাহরণ:

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

আমি এই স্ট্যান্ডের কোন প্রমাণ দেখতে পাচ্ছি না। Mysqlnd এবং mysqli দিয়ে চলছে, স্পষ্টভাবে স্ট্রিংয়ের মানগুলি ফিরে আসবে।
জেরোইন

@ জিরোয়ান কি নিশ্চিত? প্রচুর ডকুমেন্টেশন উপলব্ধ। stackoverflow.com/questions/1197005/...
advait

হ্যাঁ. নীচের মন্তব্যগুলি দেখুন। তুমি কি নিজে পরীক্ষা করেছ? যেমনটি এখন দেখা যাচ্ছে, এমনকি আপনি প্রস্তুত স্টেটমেন্ট ব্যবহার করলেও মাইএসকিএলএনড উপযুক্ত প্রকারগুলি প্রদান করে। উদাহরণ: $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
আমি কীভাবে এটি বুঝতে পারি তা নয়, এটি পিডিও এবং মাইস্কলির সাথে সমানভাবে কাজ করা উচিত। এমনকি আপনি যে মন্তব্যে উপরের লিঙ্কটি পোস্ট করেছেন তাতে স্পষ্টভাবে বলা হয়েছে যে এটি কেবল প্রস্তুত প্রস্তুতির সাথে কাজ করে এবং ওপি অনুসারে ইনলাইন প্রশ্নের সাথে নয়। এই
জেরোইন

7
আপনি mysqli- এর জন্য "MYSQLI_OPT_INT_AND_FLOAT_NATIVE" ব্যবহার করতে পারেন
লার্স মোল্লেকেন

20

সবচেয়ে সহজ সমাধান আমি পেয়েছি:

সংখ্যার মতো দেখতে মানগুলির জন্য আপনি জসন_এনকোডকে আসল সংখ্যা ব্যবহার করতে বাধ্য করতে পারেন:

json_encode($data, JSON_NUMERIC_CHECK) 

(পিএইচপি 5.3.3 থেকে)।

অথবা আপনি কেবল আপনার আইডি একটি int- এ কাস্ট করতে পারেন।

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

1
একটি ব্যবহার json_encodeসম্ভব হলে int কাস্ট করতে স্ট্রিং মাইক্রোস্কোপ ব্যবহার নখ শ্বাসরোধ ভালো হয়।
লিবার্টিপল

7
এটি সমস্ত পোস্টকোড এবং টেলিফোন নম্বর ভেঙে দেবে। আপনার অ্যাপে বাগগুলি পরিচয় করিয়ে দেওয়ার ভাল উপায়। সমাধানটি মাইএসকিএল কলামের ডেটাটাইপকে সম্মান করা উচিত, মান থেকে অনুমান করার চেষ্টা করবেন না।
ম্যাক্স ক্যাটিনস

1
সর্বোচ্চ ক্যাটিনস, আপনার পয়েন্ট বৈধ। তবে, আপনি যদি ডিবি থেকে প্রত্যাশিত সমস্ত ডেটা ধরণের জন্য অ্যাকাউন্ট করতে পারেন তবে এটি গ্রহণের জন্য একটি নিখুঁত রুট হবে।
ইফেদী ওকনকভো

1
যখন আপনার মাঝে মাঝে '06' এর মতো আইডিস থাকে তখন এটি আপনার ক্ষতি করবে you এই পতাকাটি এটি 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 মান পরিবর্তন করে (মানগুলি যেখানে gettype () == 'NULL') 'স্ট্রিং' প্রকারের সাথে '' মান, 'পূর্ণসংখ্যার' সাথে 0 মান, বা '0.0' মান সহ 'ভাসমান' প্রকারে পরিবর্তিত হয়। Is_null ($ ডেটা [$ i] [$ নাম]) সত্য হলে আপনাকে সেট টাইপ কল করতে হবে না।
শীতকালীন ড্রাগননেস

আমি মাস্টারমাইন্ডের কৌশলটি পছন্দ করি তবে কোডিংটি সহজ হতে পারে
টুলমেকারস্টেভ

13

না। আপনার টেবিলগুলিতে ডেটা টাইপের সংজ্ঞা দেওয়া হোক না কেন, পিএইচপি-র মাইএসকিউএল ড্রাইভার সর্বদা সারি মান হিসাবে স্ট্রিং হিসাবে পরিবেশন করে।

আপনার আইডিটি কোনও ইনটকে কাস্ট করতে হবে।

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

6
এটি এইচএইচপি নয় যে এই আচরণের জন্য (সরাসরি) দায়বদ্ধ, এটি ডাটাবেস ড্রাইভার। আপনি যদি পিএইচপি থেকে পোস্টগ্রিস ডাটাবেসের সাথে হস্তক্ষেপ করছেন তবে আপনি উপযুক্ত ডেটা টাইপ ফিরে পাবেন।
গর্ডনএম

5

আমি চাদের উত্তরটি পছন্দ করি, বিশেষত যখন ক্যোয়ারির ফলাফলগুলি ব্রাউজারে জাভাস্ক্রিপ্টে দেওয়া হবে। জাভাস্ক্রিপ্ট সংখ্যার মতো সংখ্যার সাথে সংখ্যার সাথে পরিষ্কারভাবে ডিল করে তবে স্ট্রিংয়ের মতো সংখ্যার মতো সংখ্যার সাথে কাজ করার জন্য অতিরিক্ত কাজ প্রয়োজন। অর্থাত্ তাদের উপর অবশ্যই পার্সেন্ট বা পার্সফ্লোট ব্যবহার করা উচিত।

চাদের সমাধানের উপর ভিত্তি করে আমি এটি ব্যবহার করি এবং এটি প্রায়শই আমার প্রয়োজন মতো হয় এবং জাভাস্ক্রিপ্টে সহজেই ডিল করার জন্য 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 তে একটি সংখ্যার স্ট্রিং যুক্ত করা পিএইচপি-তে একটি সাংখ্যিক প্রকারের উত্পাদন করে এবং সঠিকভাবে টাইপটি সনাক্ত করে যাতে ভাসমান পয়েন্ট সংখ্যাগুলি পূর্ণসংখ্যার মধ্যে কাটা যাবে না।


5

সংযোগে PDO::ATTR_EMULATE_PREPARESসেট করা থাকলে এটি ঘটে true

সতর্কতা অবলম্বন করে, এটি falseপরামিতিগুলির একাধিকবার ব্যবহার নিষিদ্ধ করতে সেট করে । আমি বিশ্বাস করি এটি ত্রুটি বার্তাগুলি ফিরে আসার মানকেও প্রভাবিত করে।


2

আপনি এটি দিয়ে এটি করতে পারেন ...

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

... আপনি যে এক্সটেনশনটি ব্যবহার করতে চান তার উপর নির্ভর করে। প্রথমটি সুপারিশ করা হয় না কারণ মাইএসকিএল এক্সটেনশানটি অবচিত করা হয়। তৃতীয়টি এখনও পরীক্ষামূলক।

এই হাইপারলিঙ্কগুলিতে দেওয়া মন্তব্যগুলি কীভাবে আপনার টাইপটিকে প্লেইন পুরাতন স্ট্রিং থেকে ডাটাবেসে তার মূল ধরণে সেট করতে হয় তা ব্যাখ্যা করার ভাল কাজ করে।

কিছু ফ্রেমওয়ার্কও এটিকে বিমূর্ত করে তোলে (কোডআইজিটার সরবরাহ করে) $this->db->field_data() )।

আপনি অনুমানের কাজটিও করতে পারেন - যেমন আপনার ফলস্বরূপ সারিগুলি লুপিং এবং প্রতিটিটিতে is_numeric () ব্যবহার করে। কিছুটা এইরকম:

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

এটি এমন একটি সংখ্যার মতো দেখতে যেটিকে একটিতে পরিণত করবে ... অবশ্যই নিখুঁত নয়।


ভাসমানদের জন্য কাজ করে না। তারা is_numeric পরীক্ষায় পাস করে। আপনার প্রথমে ভাসমানদের পরীক্ষা করা উচিত।
মার্টিন ভ্যান ড্রিল

@MartinvanDriel বা কোন স্ট্রিং, যাতে শুধুমাত্র সংখ্যা রয়েছে, কিন্তু হওয়া উচিত একটি স্ট্রিং
treeface

@ মার্টিনওয়ানড্রিয়েল যোগ করার চেষ্টা করুন:if (is_float()) { $value = (float)$value; }
অ্যাডউইলি

2

আমার প্রকল্পে আমি সাধারণত একটি বাহ্যিক ফাংশন ব্যবহার করি যা ডেটা "ফিল্টার" করে পুনরুদ্ধার করে mysql_fetch_assoc

আপনি আপনার টেবিলের ক্ষেত্রগুলির নাম পরিবর্তন করতে পারেন যাতে কোন ডেটা টাইপ সংরক্ষণ করা হয় তা বোঝার জন্য এটি স্বজ্ঞাত।

উদাহরণস্বরূপ, আপনি প্রতিটি সংখ্যার ক্ষেত্রে একটি বিশেষ প্রত্যয় যুক্ত করতে পারেন: যদি useridহয় তবে INT(11)আপনি এটির পুনরায় নামকরণ করতে পারেন userid_iবা এটির একটি হলে UNSIGNED INT(11)আপনি নাম পরিবর্তন করতে পারেন userid_u। এই মুহুর্তে, আপনি একটি সাধারণ পিএইচপি ফাংশন লিখতে পারেন যা এসোসিয়েটিভ অ্যারে ইনপুট হিসাবে প্রাপ্ত হয় (এর সাথে পুনরুদ্ধার করা mysql_fetch_assoc), এবং সেই বিশেষ "কীগুলির" সাথে সঞ্চিত "মান" এ কাস্টিং প্রয়োগ করতে পারেন।


1

যদি প্রস্তুত বিবৃতি ব্যবহার করা হয় তবে টাইপটি যথাযথ যেখানে উপযুক্ত হবে। এই কোডটি সারিগুলির একটি অ্যারে প্রদান করে, যেখানে প্রতিটি সারি একটি সহযোগী অ্যারে। 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

মাইএসকিউএলে অন্যান্য অনেক ভাষার ড্রাইভার রয়েছে, ডেটাটিকে "স্ট্যান্ডার্ডাইজড" ডেটা স্ট্রিংয়ে রূপান্তর করে এবং এটি ব্যবহারকারীর কাছে রেখে দেয় মূল্য বা অন্যকে টাইপ-কাস্ট করতে


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

আমি ফলাফল-সেটের পরিবর্তে কোয়েরি মিথ্যা ফেরত দেওয়ার জন্য চেকিংও যুক্ত করেছি।
এবং নাল মান সহ একটি ক্ষেত্রের সাথে একটি সারি সন্ধান করা।
এবং যদি পছন্দসই ধরণের স্ট্রিং হয় তবে আমি এতে কোনও সময় নষ্ট করব না - এটি ইতিমধ্যে একটি স্ট্রিং।


আমি বেশিরভাগ পিএইচপি কোডে এটি ব্যবহার করে বিরক্ত করি না; আমি কেবল পিএইচপি-র স্বয়ংক্রিয় ধরণের রূপান্তরের উপর নির্ভর করি। তবে যদি অঙ্কের প্রচুর ডেটা জিজ্ঞাসা করা হয়, তবে গাণিতিক গণনা সম্পাদনের জন্য, সর্বোত্তম ধরণের সামনে সামনে কাস্ট করা বুদ্ধিমানের কাজ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.