পিএইচপি কেন 0 কে স্ট্রিংয়ের সমান মনে করে?


111

আমার কাছে কোডের নীচের অংশ রয়েছে:

$item['price'] = 0;
/* Code to get item information goes in here */
if($item['price'] == 'e') {
    $item['price'] = -1;
}

এটি আইটেমের দাম 0 থেকে আরম্ভ করার এবং তারপরে এটি সম্পর্কে তথ্য পাওয়ার উদ্দেশ্য। যদি দামটি 'ই' হিসাবে অবহিত করা হয় তবে এর অর্থ বিক্রয়ের পরিবর্তে বিনিময়, যা একটি নেতিবাচক সংখ্যা হিসাবে একটি ডাটাবেসে সংরক্ষণ করা হয়।

0 হিসাবে দামটি ছাড়ারও সম্ভাবনা রয়েছে, হয় আইটেমটি বোনাস হওয়ায় বা পরে কোনও মুহুর্তে দাম নির্ধারণ করা হবে।

তবে, যখনই দাম সেট করা হয় না, যা এটি 0 এর প্রাথমিক মান দিয়ে ছেড়ে যায়, ifউপরে উল্লিখিত লুপটি সত্য হিসাবে মূল্যায়ন করে এবং দামটি -1 এ সেট করা হয়। এটি 0 কে 'ই' এর সমান বলে মনে করে।

কিভাবে এই ব্যাখ্যা করা যেতে পারে?

যখন দাম 0 হিসাবে দেওয়া হয় (আরম্ভের পরে), আচরণটি ত্রুটিযুক্ত: কখনও কখনও যদি সত্য হিসাবে মূল্যায়ন করা হয়, কখনও কখনও এটি মিথ্যা হিসাবে মূল্যায়ন করে *


1
আমি দেখতে পেয়েছি যে দ্বিগুণ == এর পরিবর্তে ট্রিপল === ব্যবহার করা প্রত্যাশিত আচরণ দেয়। তবে এটি এখনও অদ্ভুত।
সেরজিও ডমিংগস

2
(রেফারেন্স) অধ্যায় প্রকার জাগলিংয়ের পিএইচপি ম্যানুয়ালে যথেষ্ট ব্যাখ্যা করা হয়েছে এবং প্রকার তুলনা সারণীতে
গর্ডন

1
যদি কেবলমাত্র সম্ভাব্য স্ট্রিং টাইপটি 'ই' হয় তবে আপনি কি কেবল একটি_সেসিং ($ আইটেম ["দাম"]) পরীক্ষা করতে পারবেন না? এটি === এর চেয়ে কিছুটা বেশি দক্ষ হবে। [উদ্ধৃতি আবশ্যক]
জিমি লিন

মধ্যে দুর্বল তুলনা স্ট্রিং মধ্যে এবং পূর্ণসংখ্যা স্ট্রিং পূর্ণসংখ্যা রূপান্তরিত হয় (পরিবর্তে পূর্ণসংখ্যা স্ট্রিং "প্রচারিত" হচ্ছে)। if((string)$item['price'] == 'e')বিজোড় আচরণ স্থির করে। আরও তথ্যের জন্য স্ট্যাকওভারফ্লো.com/a/48912540/1579327 দেখুন
পাওলো

@ পাওলো দ্বারা নীচের মন্তব্যে অন্য একটি কেস নোট করুন যেখানে ডাবল ইক্যুয়াল অপারেটরটি ব্যবহার করার সময় 0 (পূর্ণসংখ্যা) অন্য কোনও স্ট্রিংয়ের সমান হয়।
হাইথাম স্লিলেম

উত্তর:


113

আপনি যা করছেন ==তা আপনার জন্য প্রকারভেদ করে।

0এটি একটি অন্তর্নিহিত, সুতরাং এই ক্ষেত্রে এটি 'e'একটি int যাও cast ালাই যাচ্ছে । যা এক হিসাবে পার্সেবল নয় এবং হয়ে যাবে 0। একটি স্ট্রিং '0e'হয়ে যাবে 0এবং মিলবে!

ব্যবহার ===


14
আলগা তুলনা আরেকটি অসুবিধা।
এমসি সম্রাট

5
কৌতুকময়। সবেমাত্র এটির মধ্যে umpুকিয়ে দিয়ে আশ্চর্য হয়ে গিয়েছিলেন কেন স্ট্রিং == ০. এটি মনে আছে।
গ্রেজগোর্জ

2
আমি যখন স্ট্রিং কীগুলিতে লুপিং করছিলাম তখন এটির উপরেও আমার মাথা আঁচড়ানো ছিল, তবে অ্যারেতে একটি প্রাথমিক 'শূন্য' সূচক আইটেম ছিল যা ফলস্বরূপ প্রথম স্ট্রিং কী তুলনায় সত্য রইল। আমি কি ছিল? কীভাবে ... সুতরাং, যথেষ্ট নিশ্চিত, এই উত্তরটি এটি পরিষ্কার করেছে! আমি বিস্মিত এই পুরো প্রশ্নের একটিও উত্তর গৃহীত হয় নি। কিছু প্রশ্ন জিজ্ঞাসারকে জার্ক দেখাতে চলেছে।
অবিশ্বাস্যভাবে

48

==তুলনামূলক অপারেটরটি যে তুলনা অপারেশনকে নির্দেশ করে তা পিএইচপি কীভাবে তুলনামূলক অপারেশন করে তার কারণে এটি ঘটে :

যদি আপনি একটি স্ট্রিংয়ের সাথে কোনও সংখ্যার তুলনা করেন বা তুলনাতে সংখ্যার স্ট্রিং জড়িত থাকে, তবে প্রতিটি স্ট্রিং একটি সংখ্যায় রূপান্তরিত হয় এবং তুলনাটি সংখ্যায় সম্পাদিত হয়। […] তুলনা করার সময় ধরণের রূপান্তর ঘটে না ===বা !==এটিতে প্রকারের সাথে মানের সাথে তুলনা করার সাথে জড়িত।

প্রথম অপারেন্ডটি একটি সংখ্যা ( 0) এবং দ্বিতীয়টি একটি স্ট্রিং ( 'e') হিসাবে, স্ট্রিংটি একটি সংখ্যায় রূপান্তরিত হয় ( বিভিন্ন প্রকারের সাথে টেবিলের তুলনাও দেখুন )। স্ট্রিং ডেটা টাইপের ম্যানুয়াল পৃষ্ঠাটি সংখ্যায় রূপান্তরটির স্ট্রিংটি কীভাবে সংজ্ঞায়িত করা হয়:

যখন একটি স্ট্রিংয়ের একটি সংখ্যার প্রসঙ্গে মূল্যায়ন করা হয়, ফলস্বরূপ মান এবং প্রকারটি নীচের হিসাবে নির্ধারিত হয়।

যদি স্ট্রিংটিতে ' .', ' e', বা ' E' অক্ষর থাকে না এবং সংখ্যার মানটি পূর্ণসংখ্যার টাইপ সীমাতে (সংজ্ঞায়িত হিসাবে PHP_INT_MAX) ফিট করে তবে স্ট্রিংটিকে পূর্ণসংখ্যা হিসাবে মূল্যায়ন করা হবে। অন্যান্য সমস্ত ক্ষেত্রে এটি একটি ভাসা হিসাবে মূল্যায়ন করা হবে।

এই ক্ষেত্রে স্ট্রিংটি হয় 'e'এবং সুতরাং এটি একটি ভাসা হিসাবে মূল্যায়ন করা হবে:

মানটি স্ট্রিংয়ের প্রাথমিক অংশ দ্বারা দেওয়া হয়। যদি স্ট্রিংটি বৈধ সংখ্যাযুক্ত ডেটা দিয়ে শুরু হয় তবে এটি ব্যবহৃত মান হবে। অন্যথায় মানটি 0(শূন্য) হবে। বৈধ সংখ্যাযুক্ত ডেটা হ'ল optionচ্ছিক চিহ্ন, তারপরে এক বা একাধিক অঙ্ক (allyচ্ছিকভাবে দশমিক পয়েন্ট থাকে) এবং তারপরে একটি alচ্ছিক উদ্দীপক হয়। প্রকাশকটি একটি ' e' বা ' E' এর পরে এক বা একাধিক অঙ্ক হয়।

'e'কোনও বৈধ সংখ্যাযুক্ত ডেটা দিয়ে যেমন শুরু হয় না, তেমনি এটি ভাসতেও মূল্যায়ন করে 0


3
পিএইচপি খুব সহজেই তুলনীয় হওয়ার জন্য সমস্ত কিছু ডিজাইন করে এবং তারপরে কেবল আমাদের দিনকে নষ্ট করার জন্য কয়েকটি গোচায় ফেলে দেয়। এটি পিএইচপি এর বাকী নকশার দর্শনের সাথে মানানসই নয়। প্রতারণা না হলে দর্শন হয় ???
ব্যবহারকারী 3338098

1
বিশেষত যেহেতু "ই" কাস্টগুলি সত্যে এবং "" কাস্টগুলি মিথ্যা
ব্যবহারকারী 3338098

20
"ABC" == 0

মূল্যায়ণ trueকারণ প্রথম "ABC" পূর্ণসংখ্যা রূপান্তরিত হয়ে যাবে 0 তারপর এটি তুলনা করা হয় 0

এটি পিএইচপি ভাষার একটি অদ্ভুত আচরণ: সাধারণত কেউ 0স্ট্রিংয়ে উন্নীত হতে পারে "0"এবং তারপরে "ABC"ফলাফলের সাথে তুলনা করে false। সম্ভবত জাভাস্ক্রিপ্টের মতো অন্যান্য ভাষায় এমন ঘটবে যেখানে দুর্বল তুলনা "ABC" == 0মূল্যায়ন করে false

কঠোর তুলনা করা সমস্যার সমাধান করে:

"ABC" === 0

মূল্যায়ন false

তবে আমার যদি সংখ্যাগুলির সাথে স্ট্রিং হিসাবে সংখ্যার তুলনা করার দরকার হয়?

"123" === 123

falseবাম এবং ডান শব্দটি বিভিন্ন ধরণের হওয়ায় মূল্যায়ন করে ।

আসলে যা প্রয়োজন তা হ'ল পিএইচপি টাইপ জাগলিংয়ের সমস্যাগুলি ছাড়া দুর্বল তুলনা।

সমাধানটি স্পষ্টভাবে স্ট্রিংয়ে পদোন্নতি দেওয়া এবং তারপরে একটি তুলনা করা (কঠোর বা দুর্বল কোনও বিষয় নয়)।

(string)"123" === (string)123

হয়

true

যখন

(string)"123" === (string)0

হয়

false


মূল কোডে প্রয়োগ করা হয়েছে:

$item['price'] = 0;
/*code to get item information goes in here*/
if((string)$item['price'] == 'e') {
    $item['price'] = -1;
}

9

== অপারেটর মানগুলি বিভিন্ন ধরণের হলেও মেলাতে চেষ্টা করবে। এই ক্ষেত্রে:

'0' == 0 will be true

আপনার যদি পাশাপাশি টাইপের তুলনাও প্রয়োজন হয় তবে === অপারেটরটি ব্যবহার করুন:

'0' === 0 will be false

9

আপনার সমস্যাটি হ'ল ডাবল সমান অপারেটর, যা ডান সদস্যকে বামের ধরণের টাইপকেস্ট করবে। আপনি চাইলে কঠোর ব্যবহার করুন।

if($item['price'] == 'e') {
    $item['price'] = -1;
}

আসুন আপনার কোডে ফিরে যান (উপরে অনুলিপি করা)। এই ক্ষেত্রে, বেশিরভাগ ক্ষেত্রে, $ আইটেম ['দাম'] হ'ল একটি পূর্ণসংখ্যা (যখন এটি ই এর সমান হয় তখন অবশ্যই)। যেমন, পিএইচপি এর আইন অনুসারে, পিএইচপি "e"পূর্ণসংখ্যায় টাইপকাস্ট করবে , যা ফল দেয় int(0)। (আমাকে বিশ্বাস করবেন না? <?php $i="e"; echo (int)$i; ?>)।

এ থেকে সহজেই দূরে যেতে, ট্রিপল সমান (সঠিক তুলনা) অপারেটরটি ব্যবহার করুন, যা প্রকারটি পরীক্ষা করবে এবং স্পষ্টতই টাইপকাস্ট করবে না।

পিএস: একটি পিএইচপি মজাদার ঘটনা: a == bএটি বোঝায় না b == a। আপনার উদাহরণটি ধরুন এবং এটিকে বিপরীত করুন: if ("e" == $item['price'])$ আইটেম ['দাম'] সর্বদা একটি পূর্ণসংখ্যার হয়ে থাকে তবে বাস্তবে কখনই তা পরিপূর্ণ হবে না।


7

পিএইচপি-তে "0", "মিথ্যা", "বন্ধ" হিসাবে == মিথ্যা এবং "1", "অন", "সত্য" হিসাবে == সত্য যা প্রায়ই উপেক্ষা করা হয় তার মিশ্রণকে বৈধ করার জন্য একটি সহজ ব্যবস্থা রয়েছে। এটি জিইটি / পোষ্ট যুক্তি পার্স করার জন্য বিশেষভাবে কার্যকর:

filter_var( $item['price'], FILTER_VALIDATE_BOOLEAN );

এটি এই ব্যবহারের ক্ষেত্রে পুরোপুরি প্রাসঙ্গিক নয় তবে সাদৃশ্য এবং সত্যের ভিত্তিতে এটি ফলাফল অনুসন্ধানটি ভ্রান্ত (স্ট্রিং) "0" বৈধ করার প্রশ্নটি মিথ্যা হিসাবে জিজ্ঞাসা করার সময় খুঁজে পেতে থাকে বলে আমি ভেবেছিলাম এটি অন্যকে সহায়তা করবে।

http://www.php.net/manual/en/filter.filters.validate.php


6

===পরিবর্তে আপনার ব্যবহার করা উচিত ==, কারণ সাধারণ অপারেটর ধরণের তুলনা করে না। পরিবর্তে এটি আইটেমগুলি টাইপকাস্ট করার চেষ্টা করবে।

ইতিমধ্যে ===আইটেম বিবেচনার ধরণ নেয়।

  • === অর্থ "সমান",
  • == মানে "আইহী .. কন্ডা দেখতে দেখতে"

1
আমি দেখি. এটি এখন (একটি টাইপকাস্ট সহ) কাজ করে:if((string)$item['price']=='e'){ $item['price'] = -1; }
সর্জিও ডমিংগস

তবে আপনার এটি করা উচিত নয়। কেবল ===অপারেটরটি ব্যবহার করুন
টেরিকো

3

আমি মনে করি যে একই অদ্ভুত আচরণের দিকে চালিত হয়ে আমি যে উদাহরণগুলি দিয়েছি তা প্রদর্শন করা ভাল। আমার পরীক্ষার কেসটি দেখুন এবং আশা করি এটি আপনাকে আচরণটি আরও ভালভাবে বুঝতে সহায়তা করবে:

// Normal comparison using the == Operator
echo (0 == "0"); // true
echo (0 == "a"); // true
echo (0 == "safta!"); // true
echo (1000 == "bla"); // false. It appears that PHP has a weird behavior only with the number / string 0 / "0" according to the past 3 examples.
echo (23 == "23"); // true. So as we said, PHP has a problem (not a problem but weird behavior) only when the number / string 0 (or "0") is present
echo (23 == "24"); // false. values aren't equal (unlike last example). The type is less relevant with the == operator as we can see.

// Now using the === and !== Operators
echo ("0" === 0); // false, since === requires both value and type to be the same. Here, type is different (int vs string)
echo ("0" !== 0); // true because they aren't the same in terms of === comparison (type is different and that's why it's true)
echo ("bla" === "blaa"); // false because the values are not the same. The type is the same, but === checks for both equal type and equal value.

//Now using casting and === Operator:
echo ((string)123 === "123"); // true. The casting of the int 123 to string changed it to "123" and now both variables have same value and are of same type
echo ((int)"123" === 123); // true. The casting of the string 123 to int, changed it to int, and now both variables are of same value and type (which is exactly what the === operator is looking for)

// Now using casting and == Operator. Basically, as we've seen above, the == care less for the
// type of var, but more to the value. So the casting is less relevant here, because even
// without casting, like we saw earlier, we can still compare string to int with the == operator
// and if their value is same, we'll get true. Either way, we will show that:
echo ((string)123 == "123"); // true. The casting of the int 123 to string changed it to "123" and now both vars have same value and are of same type
echo ((int)"123" == 123); // true. The casting of the string 123 to int, changed it to int, and now both vars are of same value and type (which is exactly what the === operator is looking for)

দুর্দান্ত পরীক্ষা, আমিও তাই করেছি তবে আমি একটি দুর্দান্ত টেবিল তৈরি করেছি। আমার উত্তর দেখুন
IAMTHEBEST

0

মূলত, ===প্রকারের সুরক্ষার গ্যারান্টি দিতে সর্বদা অপারেটরটি ব্যবহার করুন ।

এখানে চিত্র বিবরণ লিখুন

এখানে চিত্র বিবরণ লিখুন

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