2010-09-29 69 views
27

Tôi cần phải thêm, nhân và so sánh các giá trị tiền tệ trong PHP và cần phải chắc chắn rằng nó là chính xác xuống một xu duy nhất.Thực tiễn tốt nhất để làm việc với các giá trị tiền tệ trong PHP?

Một cách là lưu trữ mọi thứ trong phao, sử dụng vòng trước và sau mỗi thao tác và máy tâm trí epsilon khi so sánh cho bình đẳng. Khá imh.

Một cách khác là lưu trữ toàn bộ thứ như xu trong các kiểu dữ liệu nguyên, cộng với nhớ chuyển đổi qua lại bất cứ lúc nào tôi làm việc với cơ sở dữ liệu (mysql, nơi tôi sử dụng kiểu dữ liệu thập phân). Inelegant, và nhiều cạm bẫy lỗi, imho.

Cách khác là phát minh "kiểu dữ liệu" của riêng tôi, lưu trữ tất cả các giá trị trong chuỗi ("34.12") và tạo các hàm thay thế toán học của riêng tôi. Hàm này sẽ chuyển đổi giá trị thành số nguyên bên trong, thực hiện phép tính và xuất kết quả lại thành chuỗi. Ngạc nhiên phức tạp, imho.

Câu hỏi của tôi: thực tiễn tốt nhất để làm việc với các giá trị tiền tệ trong PHP là gì? Cảm ơn!

Trả lời

5

Hãy để tôi tự trả lời câu hỏi này. Thực hành tốt nhất là tạo một lớp "số tiền". Lớp này lưu trữ số lượng nội bộ dưới dạng số nguyên trong các số nguyên, và cung cấp các getters, setters, các hàm toán học như cộng, trừ và so sánh. Sạch hơn nhiều.

+3

Điều này không đơn giản, thực hành tốt nhất và rất tệ khuyên bảo. Xin vui lòng, bằng mọi cách, đóng gói các hàm hoạt động với các hàm toán học chính xác tùy ý, nhưng vui lòng không làm theo lời khuyên ở trên. Câu trả lời tốt nhất là bởi Andrew Dunn. –

3

Cập nhật 2016:

Một vài năm sau đó và hy vọng một chút khôn ngoan hơn;)
Kể từ khi câu trả lời này vẫn nhận được cập nhật mới thường xuyên và xuống bỏ phiếu tôi cảm thấy sự cần thiết phải sửa đổi câu trả lời của tôi. Tôi hoàn toàn không khuyên bạn nên lưu trữ 'tiền' làm số nguyên nữa. Câu trả lời thực sự duy nhất là Andrew Dunn's: Sử dụng kiểu DECIMAL của Mysql và đóng gói các hàm bc_ * của php trong một lớp Currency.


tôi sẽ giữ câu trả lời cũ của tôi ở đây cho đầy đủ vì

Bạn nên thường xuyên làm việc với số nguyên. Lưu trữ các giá trị dưới dạng ints trong cơ sở dữ liệu của bạn, sử dụng int để thực hiện các phép tính và khi nào, và chỉ khi nào, bạn muốn in nó, chuyển đổi nó sang một số định dạng có thể đọc được.

Bằng cách này bạn completeley phá vỡ vấn đề điểm, trong đó, nói chung, là một vấn đề lớn khi làm việc với tiền nổi;)

Edit: Một điều đáng nói: Bạn cần phải suy nghĩ về chính xác trước khi bạn bắt đầu làm việc cách này. Như những người khác đã chỉ ra, bạn có thể cần phải làm việc với các giá trị nhỏ hơn một xu, vì vậy bạn cần phải thực hiện phép nhân/chia của bạn cho phù hợp. (Tức là tiền tệ * 1000 cho một độ chính xác .001)

+2

MySQL và các định dạng khác có định dạng DECIMAL/NUMERIC được thiết kế đặc biệt để phá vỡ các vấn đề về dấu chấm động và cho kết quả chính xác. –

+3

Tôi giả định mỉa mai, vì vậy tôi đã không bỏ phiếu bạn xuống. Vui lòng xác nhận tôi đã đúng :) – thomasmalt

+1

@Tatu Ulmanen: Chắc chắn rồi, Mysql. Nhưng nếu bạn sau đó đi về và làm một cái gì đó như kiểm tra bình đẳng trong php, bạn có thể nhận được kết quả bất ngờ. –

22

Tính đến MySQL v5.0.3, MySQLs DECIMAL cửa hàng datatype một số thập phân chính xác, ví dụ: không phải là một đại diện dấu chấm động không chính xác.

Để thao tác chính xác số chính xác trong PHP, hãy sử dụng arbitrary precision math functions. Nội bộ thư viện này thao tác chuỗi văn bản.

Đơn vị tiền tệ được dự định để được lưu dưới dạng số thập phân, bạn có thể nhận đơn vị tiền nhỏ hơn xu. Bạn chỉ nên làm tròn bất kỳ giá trị nào khi hiển thị các số liệu, không phải trong quá trình thao tác hoặc lưu trữ.

+1

Tôi xin lỗi nhưng tôi không hiểu bạn. Không có kiểu dữ liệu thập phân trong php. Nếu bạn có nghĩa là nổi: bạn không thể kiểm tra một cách đáng tin cậy cho sự bình đẳng bằng cách sử dụng chúng. – CruftyCraft

+10

PHP có một tập hợp các chức năng được thiết kế đặc biệt cho việc thao tác và so sánh các số chính xác: http://www.php.net/manual/en/ref.bc.php –

0

Giữ giá trị là xu và sử dụng số nguyên.Viết các lớp hoặc các hàm trợ giúp để đóng gói hiển thị trong giao diện người dùng và các giá trị xử lý trong các truy vấn cơ sở dữ liệu của bạn. Nếu bạn sử dụng phao, có quá nhiều rủi ro bạn sẽ mất một xu ở đâu đó.

Các vấn đề liên quan