php fgetcsv и целочисленное преобразование (UTF8 x UCS-2 Little Endian)

ОБНОВЛЕНИЕ 4:

Я обнаружил (как и подозревал), что за это отвечает файл enconding. Я преобразовал файл csv из UCS-2 Little Endian в UTF-8, и все работает нормально. В любом случае мне нужно найти способ заставить PHP правильно понимать входной файл. Пробовал уже sellocale безуспешно.

--- оригинальный вопрос ---

У меня есть некоторые данные, хранящиеся в файле csv в формате «таблица», и я хочу сохранить эти данные как (tag, tagtimestamp, tagvalue) в базе данных. Но не могу найти способ привести значения, хранящиеся в массиве $v, к целочисленным значениям:

$p=0;
$tag=array();
$dt=array();
$v=array();

$handle=fopen("sga/2013.10.054.vol2.csv", "r");

while(($row=fgetcsv($handle, 0, "\t"))!==FALSE){
    $num=count($row);
    $num--; // only even collumns
    if($p==0){
        for($c=1; $c<$num; $c+=2){
            array_push($tag, $row[$c]);
        }
    }else{
        array_push($dt, $row[0]);
        for($c=1; $c<$num;$c+=2){
            array_push($v, $row[$c]); // <<< here is my problem
        }
    }
    $p++;
}
fclose($handle);

echo "<pre>";
print_r($v);
echo "</pre>";

эхо:

Array(
[0] => 8701
[1] => 5281
[2] => 4341
[3] => 4360
[4] => 8701
[5] => 8239
[6] => 4631
[7] => 4115
[8] => 4123
[9] => 8239
[10] => 8409
[11] => 3978
[12] => 4192
[13] => 4216
[14] => 8409
[15] => 8916
[16] => 3325
[17] => 4444
[18] => 4472
[19] => 8916
[20] => 9550
[21] => 3286
[22] => 4763
[23] => 4789

...

пытался использовать

(int)$row[$c], 
intval($row[$c]), 
($row[$c]+0), 
settype($row[$c], "integer")
preg_replace('!\s+!', $row[$c]) // to clean up any messy char...

, так далее...

Я интерполирую значения, используя:

$nv=0;
$sqls="";
foreach ($tag as $kt=>$t){
    foreach($dt as $kd=>$d){
        $f=($kd*5)+$kt;
        $de=explode(" ", $d);
        $d=implode("-", array_reverse(explode("/", $de[0])))." ".$de[1];
        $nv=$v[$f]; // <<<<< here the values must become integers but only returns zeroes
        $sqls.="('$t', '$d', $nv), ";
    }
}

// здесь задается окончательный запрос

    $sql="";
$sql="INSERT IGNORE INTO aducao (tag, tagtime, tagvalue) VALUES "; 
$sqls=rtrim($sqls, ", ");
$sql.=$sqls;
echo $sql;

Мой файл имеет формат UTF.8 без спецификации.

и файл CSV разделен табуляцией (\t).

В любом случае, если я оставил «значения», как они исходят из csv, моя база данных mysql выдает ошибку, и если я попытаюсь преобразовать значения, они станут нулями.

ОБНОВЛЕНИЕ:

вот ошибка mysql, если значения не преобразованы. Я предполагаю, что если я копирую и вставляю строку sql непосредственно в браузер запросов mysql, ошибка не возникает, поэтому в эти значения входит какой-то тип "грязи"...

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

ОБНОВЛЕНИЕ 2:

var_dump($v) показывает:

array(3725) { [0]=> string(9) "8701" [1]=> string(9) "5281" [2]=> string(9) "4341" [3]=> string(9) "4360" [4]=> string(9) "8701" [5]=> string(9) "8239" [6]=> string(9) "4631" [7]=> string(9) "4115" [8]=> string(9) "4123" [9]=> string(9) "8239" [10]=> string(9) "8409" [11]=> string(9) "3978" [12]=> string(9) "4192" [13]=> string(9) "4216" [14]=> string(9) "8409" [15]=> string(9) "8916" [16]=> string(9) "3325" [17]=> string(9) "4444" [18]=> string(9) "4472" [19]=> string(9) "8916" [20]=> string(9) "9550" [21]=> string(9) "3286" [22]=> string(9) "4763" [23]=> string(9) "4789" [24]=> string(9) "9550" [25]=> string(11) "11506" [26]=> string(9) "3448" [27]=> string(9) "5738" [28]=> string(9) "5769" [29]=> string(11) "11506" [30]=> string(11) "11287" [31]=> string(9) "3690" [32]=> string(9) "5630" [33]=> string(9) "5656" [34]=> string(11) "11287" [35]=> string(11) "10639" [36]=> string(9) "4329" [37]=> string(9) "5312" [38]=> string(9) "5327" [39]=> string(11) "10639" [40]=> string(11) "11427" [41]=> string(9) "4973" [42]=> string(9) "5704" [43]=> string(9) "5721" [44]=> string(11) "11427" [45]=> string(11) "11688" [46]=> string(9) "5605" [47]=> string(9) "5841" [48]=> string(9) "5847" 

ОБНОВЛЕНИЕ 3:

часть вывода $sql

INSERT IGNORE INTO aducao (tag, tagtime, tagvalue) VALUES ('E054_VOL', '2013-10-01 00:00:00', 8701), ('E054_VOL', '2013-10-01 01:00:00', 8239), ('E054_VOL', '2013-10-01 02:00:00', 8409), ('E054_VOL', '2013-10-01 03:00:00', 8916), ('E054_VOL', '2013-10-01 04:00:00', 9550), ('E054_VOL', '2013-10-01 05:00:00', 11506), ('E054_VOL', '2013-10-01 06:00:00', 11287), ('E054_VOL', '2013-10-01 07:00:00', 10639), ('E054_VOL', '2013-10-01 08:00:00', 11427), ('E054_VOL', '2013-10-01 09:00:00', 11688), ('E054_VOL', '2013-10-01 10:00:00', 7973), ('E054_VOL', '2013-10-01 11:00:00', 2067), ('E054_VOL', '2013-10-01 12:00:00', 0), ('E054_VOL', '2013-10-01 13:00:00', 0), ('E054_VOL', '2013-10-01 14:00:00', 0), ('E054_VOL', '2013-10-01 15:00:00', 0), ('E054_VOL', '2013-10-01 16:00:00', 0), ('E054_VOL', '2013-10-01 17:00:00', 137), ('E054_VOL', '2013-10-01 18:00:00', 142), ('E054_VOL', '2013-10-01 19:00:00', 140), ('E054_VOL', '2013-10-01 20:00:00', 169), ('E054_VOL', '2013-10-01 21:00:00', 0), ('E054_VOL', '2013-10-01 22:00:00', 161), ('E054_VOL', '2013-10-01 23:00:00', 9275), ('E054_VOL', '2013-10-02 00:00:00', 7679), ('E054_VOL', '2013-10-02 01:00:00', 8996), ('E054_VOL', '2013-10-02 02:00:00', 9135), ('E054_VOL', '2013-10-02 03:00:00', 9569), ('E054_VOL', '2013-10-02 04:00:00', 10114), ('E054_VOL', '2013-10-02 05:00:00', 10612), ('E054_VOL', '2013-10-02 06:00:00', 10438), ('E054_VOL', '2013-10-02 07:00:00', 10945), ('E054_VOL', '2013-10-02 08:00:00', 11784), ('E054_VOL', '2013-10-02 09:00:00', 12355), ('E054_VOL', '2013-10-02 10:00:00', 12500), ('E054_VOL', '2013-10-02 11:00:00', 12045), ('E054_VOL', '2013-10-02 12:00:00', 12089), ('E054_VOL', '2013-10-02 13:00:00', 12413), ('E054_VOL', '2013-10-02 14:00:00', 13024), ('E054_VOL', '2013-10-02 15:00:00', 13444), ('E054_VOL', '2013-10-02 16:00:00', 12244), ('E054_VOL', '2013-10-02 17:00:00', 10139), ('E054_VOL', '2013-10-02 18:00:00', 8586), ('E054_VOL', '2013-10-02 19:00:00', 8146), ('E054_VOL', '2013-10-02 20:00:00', 8418), ('E054_VOL', '2013-10-02 21:00:00', 8857), ('E054_VOL', '2013-10-02 22:00:00', 9142), ('E054_VOL', '2013-10-02 23:00:00', 9296), ('E054_VOL', '2013-10-03 00:00:00', 10015), ('E054_VOL', '2013-10-03 01:00:00', 9256), ('E054_VOL', '2013-10-03 02:00:00', 9452), ('E054_VOL', '2013-10-03 03:00:00', 11136), ('E054_VOL', '2013-10-03 04:00:00', 110)

person Paulo Bueno    schedule 26.11.2013    source источник
comment
Эта ошибка SQL не очень помогает без фактического запроса. Вы не пометили вопрос как SQL, но если ошибка возникает в запросе, то, вероятно, вам следует выполнить кастинг. Это также более безопасное место для этого.   -  person Jasper    schedule 26.11.2013
comment
В ответ на ваш обновленный вопрос: как выглядит ваш запрос? Что выводит var_dump($sqls); (вне цикла)?   -  person Amal Murali    schedule 26.11.2013
comment
Что выводит echo $sql? Это то, что я искал, точная строка запроса, отправленная на сервер MySQL.   -  person Jasper    schedule 26.11.2013
comment
array_push($v, (int) $row[$c]);   -  person mcuadros    schedule 26.11.2013
comment
@Jasper на самом деле, если я вставляю вывод sql в браузер запросов mysql, sql выполняется без ошибок. Таким образом, проблема возникает только при выполнении внутри php с использованием mysql_query($sql).   -  person Paulo Bueno    schedule 27.11.2013
comment
@mcuadros действительно пробовал это. Это возвращает 0 для всех значений.   -  person Paulo Bueno    schedule 27.11.2013
comment
@PauloBueno Я не знаком с флагом IGNORE (?), который вы используете. Какова его цель?   -  person Jasper    schedule 27.11.2013
comment
@Jasper -IGNORE- означает, что mysql не будет работать в случаях, когда правило первичного ключа нарушено. Для целей этого вопроса это не имеет никакого влияния на мысль.   -  person Paulo Bueno    schedule 27.11.2013
comment
@PauloBueno Мой последний совет — убрать флаг IGNORE и посмотреть, что получится.   -  person Jasper    schedule 27.11.2013
comment
Как вы узнали, fgetcsv() действительно зависит от локали системы. Доступна ли в вашей системе локаль, на которую вы пытаетесь переключиться? (введите locale -a в консоли)   -  person RandomSeed    schedule 11.01.2016


Ответы (2)


Глядя на ваш вывод var_dump, похоже, что PHP прочитал некоторые непечатаемые/невидимые символы. Вот почему вы видите string(9) "8409", где вы можете четко посчитать, что цифр всего 4, а не 9.

Что бы я сделал в вашей ситуации:

1) понять, верны ли значения.

2) используйте какой-нибудь шестнадцатеричный просмотрщик/редактор и откройте файл, чтобы увидеть, какие символы там на самом деле.

3) одно из решений, вероятно, просто удалить все ненужные (невидимые) символы простым preg_replace('/[^0-9]+/', '', $value);, а затем вставить их в SQL-запрос.

person Ingus    schedule 12.01.2016
comment
Привет, @Ingus, я наградил твой ответ, но, к сожалению, еще не проверял его. КАК МОЖНО СКОРЕЕ Я приму ваш ответ, если он сработает. ты. - person Paulo Bueno; 14.01.2016

Вот как вы конвертируете все значения $v в числовые

<?php

//call array function to walk on each element of $v array and convert it to numeric value
array_walk($v, 'convert_to_num');

function convert_to_num(&$value, $key) {

    $value = $value * 1;


}

var_dump($v);

?>
person Alpesh Panchal    schedule 08.01.2016