Проблема с записью числа в базу

diakon

Новичок
Есть скрипт rоторый выбирает курсы валют от ЦБРФ. Если его открывать через браузер данные в БД записываются полность корректно, но я его запускаю по крону и в этот момент при обновлении данных теряются знаки после запятой. Тип поля в бд DECIMAL.
При чем в лог пишется правильное значение например: 29.4905.
Подскажите в чем может быть проблема, а то уже всю голову сломал.

Код самого скрипта:
PHP:
$string_xml = file_get_contents('http://www.cbr.ru/scripts/XML_daily.asp?date_req='. date('d/m/Y'));
$dom = new MyDomDocument('1.0');
$dom->validateOnParse = true;

if (!$dom->loadXML( $string_xml )){
    $logs .= "Не валидный XML документ\n";
} else {
    $ob = new OBase( $conf['dbHost'], $conf['dbName'], $conf['dbUser'], $conf['dbPass'], $conf['SitedbName'] );
    $ob->Connect();

    $arItems = $ob->Select($ob->OBase .'_currency', 'id,cbrId', 'show_automat > 0');
    if (!$arItems[0]['id']){
        $logs .= "Нет валют для обновления\n";
    } else {
        foreach( $arItems as $arItem )
        {
            $itemNode = $dom->getElementById( $arItem['cbrId'] );
            if ( !$itemNode ){
                $logs .= "Элемент с ID ". $arItem['cbrId'] ." не найден\n";
            } else {
                $charCode  = $itemNode->getElementsByTagName('CharCode')->item(0)->textContent;
                $course    = trim(iconv('utf-8', 'windows-1251', $itemNode->getElementsByTagName('Value')->item(0)->textContent));
                $course    = (float) str_replace(',', '.', $course);
                if ( $course > 0 && is_float( $course )) {
                    $fUpdt  = $ob->Update($ob->OBase .'_currency', array('course_cbr'), array($course), 'id="'. $arItem['id'] .'"');
                    if ( $fUpdt ) {
                        $logs .= $charCode .": ". $course ."\n";
                    } else {
                        $logs .= "Не обновился элемент с ID ".$arItem['cbrId'];
                    }
                } else {
                    $logs .= "Значение курса не найдено ID ".$arItem['cbrId'];
                }
            }
        }
    }
}
 

С.

Продвинутый новичок
Надо в лог записать SQL-запрос и посмотреть.
 

baev

‹°°¬•
Команда форума
diakon: http://phpfaq.ru/debug
(Особенно, да, — про вывод SQL-запросов.)

P.S. Для финансовых вычислений float не используют.
 

diakon

Новичок
Запрос в логах:
[sql]UPDATE `prefix_currency` SET `course_cbr`='29.6904' WHERE id="86"[/sql]

попробовал дополнительно записать в поле тип varchar, там по какой то причине вместо точки оказалась запятая (29,6904). Как я понимаю из-за этого то и отбрасывались цифры после нее. Но в файл лога пишется все правильно, с точкой:
Date: 2011-09-10 00:00
USD: 29.6904
EUR: 41.2786

Вот не понятно почему мускул заменяет при записи точку на запятую

P.S запрос из лога сразу отдается mysql_query
 

С.

Продвинутый новичок
MySQL ничего не заменяет. Это вы чего-то там [не]заменяете:
PHP:
$course    = (float) str_replace(',', '.', $course);
Неплохо было бы также посмотреть, как вы пишите SQL-команду в лог.
 

diakon

Новичок
MySQL ничего не заменяет. Это вы чего-то там [не]заменяете:
PHP:
$course    = (float) str_replace(',', '.', $course);
Неплохо было бы также посмотреть, как вы пишите SQL-команду в лог.
Заменяю запятую на точку (т.к в xml от цбрф разделителем является запятая). На случай если не заменит стоит приведение к типу (что бы сразу в логах увидеть, что php отсек данные). В логах же пишется все правильно (с точкой).
PHP:
function Update($table, $flds, $vals, $expr = '')
{
    //Проверка соединения
    if(!$this->ConID) {
        return false;
    }
    
    //Проверка параметров
    if (empty($table)) {
        return false;
    }
    
    if (!is_array($flds) || !is_array($vals) || !count($flds) || count($flds) != count($vals)) {
        return false;
    }
    
    $temp = 'UPDATE `'.$table.'` SET ';
    foreach($flds as $key=>$str)
    {
        switch((string) $vals[$key])
        {
            case '_DEF':
                $temp .= $str.'=DEFAULT,';
                break;
            case '_NOW':
                $temp .= $str.'=NOW(),';
                break;
            default:
                if ($vals[$key][0] == '\'') $temp .= "`".$str.'`='.substr($vals[$key],1).',';
                else $temp .= "`".$str.'`=\''.$vals[$key].'\',';
                break;
        }
    }
    if (empty($expr)) $temp = substr($temp,0,-1);
    else $temp = substr($temp,0,-1).' WHERE '.$expr;
    

    // Пишем в лог запрос
    $_file = fopen($_SERVER['DOCUMENT_ROOT'].'/YML/course.sql', 'a+');
    fputs($_file, '['. date('Y-m-d H:i:s') .'] '. $temp ."\n"); fclose($_file);
    
    $res = mysql_query($temp, $this->ConID);
    return (bool) $res;
}
В логах запрос имеет вид приведенный выше, но цифры после точки отсекаются (а в доп. поле varchar пишется число с запятой)
 

savenko

Новичок
Могу посоветовать свое решение импорта курса валют под Mysql с полем Varchar, попробуйте поставить тип поля Float
PHP:
$data=  file_get_contents('http://www.cbr.ru/scripts/XML_daily.asp');
$spisok= simplexml_load_string($data);

$db=new mysqli($conf->host,$conf->user,$conf->password,$conf->db);
$db->set_charset('utf8');
$spisok['Date'];
foreach ($spisok as $key=>$value){
   
        $kurs=str_replace(",",".", $value->Value);
        $query="SELECT * FROM currences WHERE charcode='".$value->CharCode."'";
        $result=$db->query($query);
        $rows=$result->num_rows;
        if ($rows>0){           
          $query="UPDATE currences SET kurs='".$kurs."', date_obn='".$spisok['Date']."' WHERE charcode='".$value->CharCode."' ";
          $db->query($query);
        } else {
         $query="INSERT INTO currences (id,name,charcode,regim,kurs,active,date_obn) VALUES ('','".$value->Name."','".$value->CharCode."','".$kurs."', ,'".$spisok['Date']."')";
         $db->query($query);
        }
}
 

zerkms

TDD infected
Команда форума
diakon
А попробуй в лог вывести то, что setlocale(LC_ALL, 0); отдаёт
 

diakon

Новичок
setlocale возвращает "С".

Всем спасибо решил ситуацию по другому, т.к скрипт правильно отрабатывает если запускать его вручную, на стороннем сервере настроил cron + wget, сейчас записывает нормально, так что думаю тему можно закрыть.
 
Сверху