即時匯率換算系統的實作 === 帶入金額-及時換算匯率-的程式 === ###帶入金額-和貨幣代碼 轉換成顯示出含貨幣前置符號的金額 **D:\wamp\www\o03\system\library\cart\currency.php 這支** ```php $this->currency->format($result['tax'], $this->config->get('config_currency')),//帶入金額-和貨幣代碼 轉換成顯示出含貨幣前置符號的金額 $this->currency->format(金額, 貨幣代碼一般是TWD) //帶入金額-轉換成顯示出含貨幣前置符號的金額 //$this->currency->format(金額, 貨幣代碼一般是TWD,匯率=不輸入就是用資料庫的,是否不顯示貨幣符號) currency ``` ----------------------------------------------- 使用Yahoo API 抓取即時匯率 === http://myskilltree.blogspot.tw/2016/03/yahoo-api.html 您可以在 http://www.xe.com/iso4217.php 找到完整的 ISO 貨幣代碼及設定。 ----------------------------------------------- ```php http://download.finance.yahoo.com/d/quotes.csv?e=.csv&f=c4l1&s=TWDUSD=x,TWDJPY=x 2總幣的兌換比例 http://download.finance.yahoo.com/d/quotes.csv?e=.json&f=c4l1&s=TWDUSD=x,TWDJPY=x ``` 其中URL裡的f=c4l1是只取下兌換幣別(美金)的代碼與匯率 如果想取下更詳細的資料可以換成f=sl1d1t1,分別指定了代碼(含原始幣別跟對換幣別)、匯率、日期、時間這四個欄位 而s=TWDUSD=x ,其中TWD (新台幣) 為原始幣別 USD (美金)為兌換幣別,可以依需求自行更換,如果要查詢多筆資料則在後在後接續即可。 ----------------------------------------------- #OPENCART 3.0 的匯率系統 解析 ----------------------------------------------- 1.它用curl抓取了yahoo的關於匯率的數據, D:\wamp\www\o06\admin\model\localisation\currency.php 這只有首頁 才會讀取 $curl = curl_init(); //就是這裡了,看到木有 curl_setopt($curl, CURLOPT_URL, 'http://download.finance.yahoo.com/d/quotes.csv?s=' . implode(',', $currency_data) . '&f=sl1&e=.json'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 它用curl抓取了yahoo的關於匯率的數據,結合這2段代碼可以看出,其實它的功能就是打開這個頁面的時候自動更新數據庫中匯率數據。 到此問題找到原因了,那麼解決的方法總結一下: 可以關閉自動更新匯率(Dashboard>System>Setting>Your Store>edit>local>Auto Update Currency 選擇No) 系統管理=>商店管理.編輯=>本地化設定=>匯率自動更新 系統管理=>在地化管理=>幣別管理 後台一天抓一次匯率的程式 === **D:\wamp\www\o03\admin\controller\common\dashboard.php** ```php // Run currency update if ($this->config->get('config_currency_auto')) { $this->load->model('localisation/currency'); $this->model_localisation_currency->refresh(false);//執行後台一天抓一次匯率的程式 } ``` **D:\wamp\www\o03\admin\model\localisation\currency.php** ```php //抓取匯率資料-入資料庫 參數=false 是自己國家以外,更新資料抓取時間大於1天的 ,參數=true自己國家以外資料全更新 public function refresh($force = false) { $data = array(); if ($force) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency WHERE code != '" . $this->db->escape($this->config->get('config_currency')) . "'"); } else { //SELECT * FROM oc_currency WHERE code != 'TWD' AND date_modified < '2017-08-30 14:20:18' 自己國家以外,更新資料抓取時間大於1天的 $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency WHERE code != '" . $this->db->escape($this->config->get('config_currency')) . "' AND date_modified < '" . $this->db->escape(date('Y-m-d H:i:s', strtotime('-1 day'))) . "'"); } //組合文字把貨幣代碼加上=X foreach ($query->rows as $result) { $data[] = $this->config->get('config_currency') . $result['code'] . '=X'; } $url='http://download.finance.yahoo.com/d/quotes.csv?s=' . implode(',', $data) . '&f=sl1&e=.csv'; //去線上抓取資料 $curl = curl_init(); curl_setopt($curl, CURLOPT_URL,$url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($curl, CURLOPT_TIMEOUT, 30); $content = curl_exec($curl); curl_close($curl); /* 送出去的網址 http://download.finance.yahoo.com/d/quotes.csv?s=TWDCNY=X,TWDHKD=X,TWDGBP=X,TWDUSD=X,TWDEUR=X&f=sl1&e=.csv"TWDCNY=X",0.2180 抓回來資料 "TWDHKD=X",0.2587 "TWDGBP=X",0.0256 "TWDUSD=X",0.0331 "TWDEUR=X",0.0279 echo $url,"<br>\n";print($content); */ $lines = explode("\n", trim($content)); /*把抓回來的資料處理*/ foreach ($lines as $line) { $currency = utf8_substr($line, 4, 3); $value = utf8_substr($line, 11, 6);//匯率 //更新全部匯率 if ((float)$value) { $this->db->query("UPDATE " . DB_PREFIX . "currency SET value = '" . (float)$value . "', date_modified = '" . $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE code = '" . $this->db->escape($currency) . "'"); } } //更新我國匯率為1.00000 $this->db->query("UPDATE " . DB_PREFIX . "currency SET value = '1.00000', date_modified = '" . $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE code = '" . $this->db->escape($this->config->get('config_currency')) . "'"); $this->cache->delete('currency');//刪除緩存檔案 } ``` 帶入金額-及時換算匯率-的程式 === D:\wamp\www\o03\system\library\cart\currency.php 是這支 ```php <?php namespace Cart; class Currency { private $currencies = array(); public function __construct($registry) { $this->db = $registry->get('db'); $this->language = $registry->get('language'); $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency");//資料庫查出數據 foreach ($query->rows as $result) { $this->currencies[$result['code']] = array( 'currency_id' => $result['currency_id'],//貨幣代號 'title' => $result['title'],//貨幣名稱 'symbol_left' => $result['symbol_left'],//貨幣符號金額左邊顯示(eg:$32、¥45、) 'symbol_right' => $result['symbol_right'],//貨幣符號金額右邊顯示 'decimal_place' => $result['decimal_place'],//保留小數點後幾位有效數字 'value' => $result['value']//匯率 ); } } //帶入金額-轉換成顯示出含貨幣前置符號的金額$this->currency->format(金額, 貨幣代碼一般是TWD) //$this->currency->format(金額, 貨幣代碼一般是TWD,匯率=不輸入就是用資料庫的,是否不顯示貨幣符號) public function format($number, $currency, $value = '', $format = true) { $symbol_left = $this->currencies[$currency]['symbol_left']; $symbol_right = $this->currencies[$currency]['symbol_right']; $decimal_place = $this->currencies[$currency]['decimal_place']; if (!$value) { $value = $this->currencies[$currency]['value']; } //金額浮點數*匯率 $amount = $value ? (float)$number * $value : (float)$number; $amount = round($amount, (int)$decimal_place);//金額取到小數幾位 //是否不顯示貨幣符號 if (!$format) { return $amount; } //以下顯示貨幣符號 $string = ''; if ($symbol_left) { $string .= $symbol_left; } //千進位加標點函式 $string .= number_format($amount, (int)$decimal_place, $this->language->get('decimal_point'), $this->language->get('thousand_point')); if ($symbol_right) { $string .= $symbol_right; } return $string;//返回有貨幣符號的金額 } public function convert($value, $from, $to) { if (isset($this->currencies[$from])) { $from = $this->currencies[$from]['value']; } else { $from = 1; } if (isset($this->currencies[$to])) { $to = $this->currencies[$to]['value']; } else { $to = 1; } return $value * ($to / $from); } //返回貨幣代號 public function getId($currency) { if (isset($this->currencies[$currency])) { return $this->currencies[$currency]['currency_id']; } else { return 0; } } //返回貨幣符號 public function getSymbolLeft($currency) { if (isset($this->currencies[$currency])) { return $this->currencies[$currency]['symbol_left']; } else { return ''; } } public function getSymbolRight($currency) { if (isset($this->currencies[$currency])) { return $this->currencies[$currency]['symbol_right']; } else { return ''; } } public function getDecimalPlace($currency) { if (isset($this->currencies[$currency])) { return $this->currencies[$currency]['decimal_place']; } else { return 0; } } public function getValue($currency) { if (isset($this->currencies[$currency])) { return $this->currencies[$currency]['value']; } else { return 0; } } //返回貨幣資料 public function has($currency) { return isset($this->currencies[$currency]); } } ```