PHP और MySql में मौद्रिक मूल्यों को कैसे संभालें?


16

मुझे एक MySQL डेटाबेस के शीर्ष पर PHP में लिखित विरासत कोड का एक बड़ा ढेर विरासत में मिला है। मैंने देखा कि बात यह है कि आवेदन doublesडेटा के भंडारण और हेरफेर के लिए उपयोग करता है ।

अब मैंने कई पोस्टों में उल्लेख किया है कि कैसे doubleगोल त्रुटियों के कारण मौद्रिक संचालन के लिए अनुकूल नहीं हैं। हालाँकि, मुझे अभी तक एक संपूर्ण समाधान नहीं मिला है कि मौद्रिक मूल्यों को PHP कोड में कैसे संभाला जाए और एक MySQL डेटाबेस में संग्रहीत किया जाए।

जब PHP में विशेष रूप से पैसे को संभालने की बात आती है तो क्या सबसे अच्छा अभ्यास होता है?

जिन चीजों की मुझे तलाश है वे हैं:

  1. डेटाबेस में डेटा कैसे संग्रहीत किया जाना चाहिए? स्तंभ प्रकार? आकार?
  2. डेटा को सामान्य जोड़, घटाव में कैसे नियंत्रित किया जाना चाहिए। गुणा या भाग?
  3. मुझे मूल्यों को गोल कब करना चाहिए? यदि कोई हो तो कितनी गोलाई स्वीकार्य है?
  4. क्या बड़े मौद्रिक मूल्यों और कम लोगों को संभालने के बीच अंतर है?

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

$a= $_POST['price_in_dollars']; //-->(ex: 25.06) will be read as a string should it be cast to double?
$b= $_POST['discount_rate'];//-->(ex: 0.35) value will always be less than 1
$valueToBeStored= $a * $b; //--> any hint here is welcomed 

$valueFromDatabase= $row['price']; //--> price column in database could be double, decimal,...etc.

$priceToPrint=$valueFromDatabase * 0.25; //again cast needed or not?

मुझे आशा है कि आप इस नमूना कोड का उपयोग अधिक उपयोग के मामलों को बाहर लाने के साधन के रूप में करेंगे और न ही इसे शाब्दिक रूप से लेने के लिए।

बोनस प्रश्न यदि मैं ORM जैसे Doctrine या PROPEL का उपयोग कर रहा हूं, तो मेरे कोड में पैसे का उपयोग करना कितना अलग होगा।


1
मैं PHP नहीं जानता, लेकिन शब्दावली जानना Google-fu के लिए इन परिदृश्यों में अमूल्य है, आप जिस शब्द की तलाश कर रहे हैं, वह "मनमाना सटीक" है, जिसके लिए Google php.net/manual/en/book.bc.php के
जिमी होफा

1
@ जिमी हॉफ: मध्यस्थता की सटीकता आम तौर पर वह नहीं होती है जिसकी आपको आवश्यकता होती है, कुछ ऐसा जो दशमलव भिन्न के साथ सटीक रूप से प्रतिनिधित्व और काम कर सकता है। बेशक, आप अक्सर दोनों को संयुक्त पाते हैं, लेकिन उदाहरण के लिए decimalC # के प्रकार में सीमित परिशुद्धता है, लेकिन मौद्रिक मूल्यों के लिए पूरी तरह से अनुकूल है।
माइकल बॉर्गवर्ड

1
@MichaelBorgwardt सही, मैं तर्कसंगत प्रकारों के बारे में भूल जाता हूं क्योंकि बहुत सारी भाषाएं उनके पास नहीं हैं। अच्छा निर्णय।
जिमी हॉफ

मुद्राओं और विरासत कोड के साथ बहुत काम करने के बाद, मैं कहूंगा कि इसे पूर्णांकों में संग्रहीत करने और डॉलर के बजाय सेंट का उपयोग करने के लिए जाऊंगा। हालांकि सावधान रहें, 32 पूर्णांक एक आश्चर्यजनक रूप से छोटी राशि को पकड़ सकते हैं। 4) एक 32 बिट पूर्णांक केवल 21 मिलियन की राशि रख सकता है यदि अहस्ताक्षरित और सेंट का उपयोग कर रहा हो।
Pieter B

एक तरफ के रूप में, आपका नमूना कोड जो मूल्य और छूट दिखाता है वह मुझे परेशान करता है। उम्मीद है कि यह इतना सरल है कि यह वास्तविक उपयोग को प्रतिबिंबित नहीं करता है, लेकिन अंकित मूल्य पर, ऐसा लगता है कि आप ब्राउज़र पर भरोसा कर रहे हैं कि आपको बताएंगे कि किसी छिपे हुए क्षेत्र को वापस करने या किसी वस्तु की कीमत क्या है।
कार्सन 63000

जवाबों:


6

PHP / MySQL के साथ संख्याओं को संभालने के लिए यह काफी मुश्किल हो सकता है। यदि आप दशमलव (10,2) का उपयोग करते हैं और आपकी संख्या लंबी है या उच्च परिशुद्धता है, तो इसे त्रुटि के बिना छोटा किया जाएगा (जब तक कि आप अपने डीबी सर्वर के लिए उचित मोड सेट नहीं करते)।

बड़े मूल्यों या उच्च परिशुद्धता मूल्यों को संभालने के लिए आप बीसीमैथ जैसे पुस्तकालय का उपयोग कर सकते हैं यह आपको बड़ी संख्या में बुनियादी संचालन करने और आवश्यक सटीकता रखने की अनुमति देगा।

मुझे यकीन नहीं है कि आप वास्तव में क्या गणना करेंगे लेकिन आपको यह भी ध्यान रखना होगा कि (0.22 * 0.4576) + (0.78 * 0.4576) 0.4576 के बराबर नहीं होगा यदि आप प्रक्रिया के माध्यम से उचित परिशुद्धता का उपयोग नहीं करेंगे।

MySQL में DECIMAL का अधिकतम आकार 65 है, इसलिए यह किसी भी उद्देश्य के लिए पर्याप्त से अधिक होना चाहिए। यदि आप DECIMAL फ़ील्ड प्रकार का उपयोग करते हैं, तो इसे ORM या केवल सादे PDO / mysql (i) के उपयोग की परवाह किए बिना स्ट्रिंग के रूप में लौटा दिया जाएगा।

डेटाबेस में डेटा कैसे संग्रहीत किया जाना चाहिए? स्तंभ प्रकार? आकार?

सटीक आप की जरूरत के साथ DECIMAL। यदि आप विनिमय दरों का उपयोग कर रहे हैं तो आपको कम से कम चार दशमलव स्थानों की आवश्यकता होगी

डेटा को सामान्य जोड़, घटाव में कैसे नियंत्रित किया जाना चाहिए। गुणा या भाग?

बीसीएमथ का उपयोग बचत पक्ष में करें और फ्लोट का उपयोग करना एक अच्छा विचार नहीं हो सकता है

मुझे मूल्यों को गोल कब करना चाहिए? यदि कोई हो तो कितनी गोलाई स्वीकार्य है?

मौद्रिक मूल्यों के लिए सामान्य दो दशमलव स्थान स्वीकार्य हैं, लेकिन आपको और अधिक की आवश्यकता हो सकती है उदाहरण के लिए आप विनिमय दरों का उपयोग कर रहे हैं।

क्या बड़े मौद्रिक मूल्यों और कम लोगों को संभालने के बीच अंतर है?

इस बात पर निर्भर करता है कि आप बड़े लोगों से क्या मतलब रखते हैं। उच्च परिशुद्धता के साथ संख्याओं को संभालने के बीच निश्चित रूप से अंतर है।


9

चारों ओर एक साधारण काम उन्हें पूर्णांक के रूप में संग्रहीत करना है। 99.99 9999 के रूप में संग्रहीत। यदि यह काम नहीं करेगा (और कई कारण हैं कि यह एक बुरा विकल्प हो सकता है) तो आप टाइप डेसीमल का उपयोग कर सकते हैं। http://dev.mysql.com/doc/refman/5.0/en/preaches-math-decimal-changes.html mysql साइड पर। Php की तरफ से मुझे यह /programming/3244094/decimal-type-in-php मिला, जो आपके बाद का हो सकता है।

बोनस प्रश्न: कहना मुश्किल है। ऑरम चुने गए डेटा प्रकारों के आधार पर काम करने जा रहा है। मैं कहूंगा कि आप मदद करने के लिए अमूर्तता के साथ कुछ सामान कर सकते हैं, लेकिन इस विशिष्ट मुद्दे को केवल ORM पर ले जाकर संबोधित नहीं किया जाता है।


1
एफडब्ल्यूआईडब्ल्यू, ड्रुपल कॉमर्स अपनी कीमतों को स्टोर करने के लिए 9999 चाल का उपयोग करता है।
फ्लोरियन मार्गाइन

1
"और कई कारण हैं कि यह एक बुरा विकल्प क्यों हो सकता है" क्या आप इस अभ्यास में कुछ समस्याएं साझा करेंगे?
सोंगो


@MichaelBorgwardt जानकारी के लिए धन्यवाद,
गीत

3

मैं इसमें अपना अनुभव डालने की कोशिश करूंगा:

जिन चीजों की मुझे तलाश है वे हैं:

डेटाबेस में डेटा कैसे संग्रहीत किया जाना चाहिए? स्तंभ प्रकार? आकार?

मैं DECIMAL(10,2)समस्याओं के बिना mysql के लिए उपयोग कर रहा हूं (8 पूर्णता और 2 दशमलव == 99.999.999,99 == बड़ी राशि), लेकिन यह उस धन सीमा पर निर्भर करता है जिसे आपको कवर करने की आवश्यकता होगी। विशाल मात्रा को अतिरिक्त देखभाल के साथ लिया जाना चाहिए (उदाहरण के लिए ओएस अधिकतम फ्लोट मान)। दशमलव भाग पर मैं ट्रंकट से बचने के लिए 2 मानों का उपयोग करता हूं और न ही गोल मूल्यों से। पैसे के बारे में कुछ मामलों में जहां आपको और अधिक दशमलव की आवश्यकता होती है (जिस मामले में आपको यह सुनिश्चित करने की आवश्यकता है कि उपयोगकर्ता उन सभी के साथ काम करेगा, अन्यथा बेकार डेटा है)

डेटा को सामान्य जोड़, घटाव में कैसे नियंत्रित किया जाना चाहिए। गुणा या भाग?

एक मुद्रा और एक विनिमय तालिका (तिथियों के साथ) के साथ काम करें। इस तरह से आप सुनिश्चित करते हैं कि आपके पास हमेशा सही मात्रा में बचत होगी। एक अतिरिक्त: पूरा मान सहेजें और गणना परिणामों के साथ एक दृश्य बनाएं। यह आपको मक्खी पर मूल्यों को ठीक करने में मदद करेगा

मुझे मूल्यों को गोल कब करना चाहिए? यदि कोई हो तो कितनी गोलाई स्वीकार्य है?

फिर से, आपके सिस्टम मनी रेंज पर निर्भर करता है। हमेशा KISS संदर्भ में लगता है कि जब तक आप मुद्रा विनिमय के मेस में गिर करने की जरूरत है

क्या बड़े मौद्रिक मूल्यों और कम लोगों को संभालने के बीच अंतर है?

आपके ओएस और प्रोग्रामिंग भाषाओं के आधार पर आपको हमेशा अधिकतम और न्यूनतम मानों की जांच करने की आवश्यकता होती है


उत्तर के लिए धन्यवाद, लेकिन अगर मुझे कुछ संभालना है जैसे $valueToBeStored= $a * $b;कि $aऔर $bक्या दोनों को डेटाबेस से दशमलव के रूप में पढ़ा जाता है मुझे लगता है कि उन्हें doublePHP सही में डाला जाएगा ? कि संख्या को प्रभावित करेगा?
सोंगो

$aऔर $bdb से लिए गए हैं? इसलिए, मेरे उदाहरण में आपको कभी भी स्टोर करने की आवश्यकता नहीं है $valueToBeStoredक्योंकि आपके पास हमेशा स्रोत $aऔर $bडेटा होगा। तो आप किसी फ़ंक्शन में प्रोग्राम वैल्यू को काम कर सकते हैं या कॉलम परिणाम के साथ mysql दृश्य बना सकते हैं। इस तरह, अगर किसी भी मूल्य को बदलना है तो आपको कई स्थानों (त्रुटि प्रवण) को संशोधित करने के बारे में चिंता करने की ज़रूरत नहीं है
Alwin Kesler
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.