2011-09-05 102 views
0

我正在为客户开发定制的定价矩阵,他们有代码来区分具有不同选项的产品,一个代码有6种不同的变体,因为有6种不同类型的材料不同的成本,其他螺栓也会根据材料改变代码和成本......等等。CSV到PHP到JSON到MySQL

,我会向您展示我的价格数据库结构(MySQL的)

|------ 
|Field|Type|Null|Default 
|------ 
|//**id**//|mediumint(9)|No| 
|jp_code|varchar(7)|No| 
|brand_rate|text|No| 
|price_25|text|No| 
|price_50|text|No| 
|price_100|text|No| 
|price_250|text|No| 
|price_500|text|No| 
|price_1000|text|No| 

我存储所有6种价格在价格和品牌率字段中的每个代码JSON开始,这是由JS稍后处理。

因此,对于该数据库的典型条目如下:

|1|JP6000|["F","F","n\/a","F","F","F"]|["2.92","2.92","n\/a","4.86","6.35","7.62"]|["2.77","2.77","n\/a","4.62","6.03","7.24"]|["2.55","2.55","4.21","4.25","5.55","6.66"]|["2.45","2.45","3.83","4.08","5.33","6.40"]|["2.38","2.38","3.64","3.96","5.17","6.20"]|["2.50","2.33","3.47","3.89","5.08","6.10"] 

客户需要能够上传CSV,它可以无缝地更新这些价格。

CSV文件看起来像这样: CSV File

如果你看看MySQL的行条目,你应该能够结婚了数据,所以在这个问题!

我用这与CSV文件的工作: parseCSV v0.4.3 Beta版 http://code.google.com/p/parsecsv-for-php/

我已经由JP这样的代码了这组中的所有结果:

array(2) { 
    ["JP6000"]=> 
    array(6) { 
    [0]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "2.92" 
     ["Price_50"]=> 
     string(4) "2.77" 
     ["Price_100"]=> 
     string(4) "2.55" 
     ["Price_250"]=> 
     string(4) "2.45" 
     ["Price_500"]=> 
     string(4) "2.38" 
     ["Price_1000"]=> 
     string(4) "2.33" 
     ["Material"]=> 
     string(10) "Belluno PU" 
    } 
    [1]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "2.92" 
     ["Price_50"]=> 
     string(4) "2.77" 
     ["Price_100"]=> 
     string(4) "2.55" 
     ["Price_250"]=> 
     string(4) "2.45" 
     ["Price_500"]=> 
     string(4) "2.38" 
     ["Price_1000"]=> 
     string(4) "2.33" 
     ["Material"]=> 
     string(9) "Torino PU" 
    } 
    [2]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(3) "n/a" 
     ["Price_25"]=> 
     string(3) "n/a" 
     ["Price_50"]=> 
     string(3) "n/a" 
     ["Price_100"]=> 
     string(4) "4.21" 
     ["Price_250"]=> 
     string(4) "3.83" 
     ["Price_500"]=> 
     string(4) "3.64" 
     ["Price_1000"]=> 
     string(4) "3.47" 
     ["Material"]=> 
     string(11) "Full Colour" 
    } 
    [3]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "4.86" 
     ["Price_50"]=> 
     string(4) "4.62" 
     ["Price_100"]=> 
     string(4) "4.25" 
     ["Price_250"]=> 
     string(4) "4.08" 
     ["Price_500"]=> 
     string(4) "3.96" 
     ["Price_1000"]=> 
     string(4) "3.89" 
     ["Material"]=> 
     string(8) "Finecell" 
    } 
    [4]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "6.35" 
     ["Price_50"]=> 
     string(4) "6.03" 
     ["Price_100"]=> 
     string(4) "5.55" 
     ["Price_250"]=> 
     string(4) "5.33" 
     ["Price_500"]=> 
     string(4) "5.17" 
     ["Price_1000"]=> 
     string(4) "5.08" 
     ["Material"]=> 
     string(5) "Nappa" 
    } 
    [5]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "7.62" 
     ["Price_50"]=> 
     string(4) "7.24" 
     ["Price_100"]=> 
     string(4) "6.66" 
     ["Price_250"]=> 
     string(3) "6.4" 
     ["Price_500"]=> 
     string(3) "6.2" 
     ["Price_1000"]=> 
     string(3) "6.1" 
     ["Material"]=> 
     string(8) "Richmond" 
    } 
    } 
    ["JP6010"]=> 
    array(6) { 
    [0]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "3.41" 
     ["Price_50"]=> 
     string(4) "3.24" 
     ["Price_100"]=> 
     string(4) "2.98" 
     ["Price_250"]=> 
     string(4) "2.86" 
     ["Price_500"]=> 
     string(4) "2.78" 
     ["Price_1000"]=> 
     string(4) "2.73" 
     ["Material"]=> 
     string(10) "Belluno PU" 
    } 
    [1]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "3.41" 
     ["Price_50"]=> 
     string(4) "3.24" 
     ["Price_100"]=> 
     string(4) "2.98" 
     ["Price_250"]=> 
     string(4) "2.86" 
     ["Price_500"]=> 
     string(4) "2.78" 
     ["Price_1000"]=> 
     string(4) "2.73" 
     ["Material"]=> 
     string(9) "Torino PU" 
    } 
    [2]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(3) "n/a" 
     ["Price_25"]=> 
     string(3) "n/a" 
     ["Price_50"]=> 
     string(3) "n/a" 
     ["Price_100"]=> 
     string(4) "4.77" 
     ["Price_250"]=> 
     string(4) "4.33" 
     ["Price_500"]=> 
     string(4) "4.13" 
     ["Price_1000"]=> 
     string(4) "3.93" 
     ["Material"]=> 
     string(11) "Full Colour" 
    } 
    [3]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "5.41" 
     ["Price_50"]=> 
     string(4) "5.14" 
     ["Price_100"]=> 
     string(4) "4.74" 
     ["Price_250"]=> 
     string(4) "4.55" 
     ["Price_500"]=> 
     string(4) "4.41" 
     ["Price_1000"]=> 
     string(4) "4.33" 
     ["Material"]=> 
     string(8) "Finecell" 
    } 
    [4]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(3) "6.9" 
     ["Price_50"]=> 
     string(4) "6.56" 
     ["Price_100"]=> 
     string(4) "6.04" 
     ["Price_250"]=> 
     string(3) "5.8" 
     ["Price_500"]=> 
     string(4) "5.63" 
     ["Price_1000"]=> 
     string(4) "5.52" 
     ["Material"]=> 
     string(5) "Nappa" 
    } 
    [5]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "8.28" 
     ["Price_50"]=> 
     string(4) "7.87" 
     ["Price_100"]=> 
     string(4) "7.25" 
     ["Price_250"]=> 
     string(4) "6.96" 
     ["Price_500"]=> 
     string(4) "6.76" 
     ["Price_1000"]=> 
     string(4) "6.62" 
     ["Material"]=> 
     string(8) "Richmond" 
    } 
    } 
} 
array(2) { 
    ["JP6000"]=> 
    array(6) { 
    [0]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "2.92" 
     ["Price_50"]=> 
     string(4) "2.77" 
     ["Price_100"]=> 
     string(4) "2.55" 
     ["Price_250"]=> 
     string(4) "2.45" 
     ["Price_500"]=> 
     string(4) "2.38" 
     ["Price_1000"]=> 
     string(4) "2.33" 
     ["Material"]=> 
     string(10) "Belluno PU" 
    } 
    [1]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "2.92" 
     ["Price_50"]=> 
     string(4) "2.77" 
     ["Price_100"]=> 
     string(4) "2.55" 
     ["Price_250"]=> 
     string(4) "2.45" 
     ["Price_500"]=> 
     string(4) "2.38" 
     ["Price_1000"]=> 
     string(4) "2.33" 
     ["Material"]=> 
     string(9) "Torino PU" 
    } 
    [2]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(3) "n/a" 
     ["Price_25"]=> 
     string(3) "n/a" 
     ["Price_50"]=> 
     string(3) "n/a" 
     ["Price_100"]=> 
     string(4) "4.21" 
     ["Price_250"]=> 
     string(4) "3.83" 
     ["Price_500"]=> 
     string(4) "3.64" 
     ["Price_1000"]=> 
     string(4) "3.47" 
     ["Material"]=> 
     string(11) "Full Colour" 
    } 
    [3]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "4.86" 
     ["Price_50"]=> 
     string(4) "4.62" 
     ["Price_100"]=> 
     string(4) "4.25" 
     ["Price_250"]=> 
     string(4) "4.08" 
     ["Price_500"]=> 
     string(4) "3.96" 
     ["Price_1000"]=> 
     string(4) "3.89" 
     ["Material"]=> 
     string(8) "Finecell" 
    } 
    [4]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "6.35" 
     ["Price_50"]=> 
     string(4) "6.03" 
     ["Price_100"]=> 
     string(4) "5.55" 
     ["Price_250"]=> 
     string(4) "5.33" 
     ["Price_500"]=> 
     string(4) "5.17" 
     ["Price_1000"]=> 
     string(4) "5.08" 
     ["Material"]=> 
     string(5) "Nappa" 
    } 
    [5]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6000" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "7.62" 
     ["Price_50"]=> 
     string(4) "7.24" 
     ["Price_100"]=> 
     string(4) "6.66" 
     ["Price_250"]=> 
     string(3) "6.4" 
     ["Price_500"]=> 
     string(3) "6.2" 
     ["Price_1000"]=> 
     string(3) "6.1" 
     ["Material"]=> 
     string(8) "Richmond" 
    } 
    } 
    ["JP6010"]=> 
    array(6) { 
    [0]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "3.41" 
     ["Price_50"]=> 
     string(4) "3.24" 
     ["Price_100"]=> 
     string(4) "2.98" 
     ["Price_250"]=> 
     string(4) "2.86" 
     ["Price_500"]=> 
     string(4) "2.78" 
     ["Price_1000"]=> 
     string(4) "2.73" 
     ["Material"]=> 
     string(10) "Belluno PU" 
    } 
    [1]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "3.41" 
     ["Price_50"]=> 
     string(4) "3.24" 
     ["Price_100"]=> 
     string(4) "2.98" 
     ["Price_250"]=> 
     string(4) "2.86" 
     ["Price_500"]=> 
     string(4) "2.78" 
     ["Price_1000"]=> 
     string(4) "2.73" 
     ["Material"]=> 
     string(9) "Torino PU" 
    } 
    [2]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(3) "n/a" 
     ["Price_25"]=> 
     string(3) "n/a" 
     ["Price_50"]=> 
     string(3) "n/a" 
     ["Price_100"]=> 
     string(4) "4.77" 
     ["Price_250"]=> 
     string(4) "4.33" 
     ["Price_500"]=> 
     string(4) "4.13" 
     ["Price_1000"]=> 
     string(4) "3.93" 
     ["Material"]=> 
     string(11) "Full Colour" 
    } 
    [3]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "5.41" 
     ["Price_50"]=> 
     string(4) "5.14" 
     ["Price_100"]=> 
     string(4) "4.74" 
     ["Price_250"]=> 
     string(4) "4.55" 
     ["Price_500"]=> 
     string(4) "4.41" 
     ["Price_1000"]=> 
     string(4) "4.33" 
     ["Material"]=> 
     string(8) "Finecell" 
    } 
    [4]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(3) "6.9" 
     ["Price_50"]=> 
     string(4) "6.56" 
     ["Price_100"]=> 
     string(4) "6.04" 
     ["Price_250"]=> 
     string(3) "5.8" 
     ["Price_500"]=> 
     string(4) "5.63" 
     ["Price_1000"]=> 
     string(4) "5.52" 
     ["Material"]=> 
     string(5) "Nappa" 
    } 
    [5]=> 
    array(9) { 
     ["Code"]=> 
     string(6) "JP6010" 
     ["Brand Rate"]=> 
     string(1) "F" 
     ["Price_25"]=> 
     string(4) "8.28" 
     ["Price_50"]=> 
     string(4) "7.87" 
     ["Price_100"]=> 
     string(4) "7.25" 
     ["Price_250"]=> 
     string(4) "6.96" 
     ["Price_500"]=> 
     string(4) "6.76" 
     ["Price_1000"]=> 
     string(4) "6.62" 
     ["Material"]=> 
     string(8) "Richmond" 
    } 
    } 
} 

所以我需要做的是将这些数据进一步分组并将其转换为JSON字符串,就像您在MySQL记录中使用每个代码的信息所看到的那样。

为price_25 JSON数组的第一个条目为JP6000将是2.92,并且第二2.92 - 第三个是N/A

这也需要遍历,并相应地更新每个MySQL的行基础上,JP代码是主键。

我希望这一切都有意义吗?非常棘手!

+0

标准答案,不要存放在JSON格式的数据。这是为了演示。 – ajreal

+0

感谢您的有用评论......不幸的是,并非所有工作都像魔术一样,所以我们必须找到解决方法避免向客户说'不',这是我们向他们提供此解决方案的唯一途径。 –

回答

1
$rows = array(); 
$format = array('brand_rate'=>'Brand Rate','price_25'=>'Price_25','price_50'=>'Price_50','price_100'=>'Price_100','price_250'=>'Price_250','price_500'=>'Price_500','price_1000'=>'Price_1000'); 

// Build $rows array 
foreach ($groupedData as $jpCode => $jpData) { 
    foreach ($jpData as $rowIndex => $rowData) { 
    foreach ($format as $csvCol) { 
     $rows[$jpCode][$csvCol][$rowIndex] = $rowData[$csvCol]; 
    } 
    } 
} 

// Loop through $rows and INSERT them 
foreach ($rows as $jpCode => $row) { 
    $cols = $vals = $duplicates = array(); 
    foreach ($format as $sqlCol => $csvCol) { 
    $val = mysql_real_escape_string(json_encode($row[$csvCol])); 
    $duplicates[] = "`$sqlCol` = '$val'"; 
    $cols[] = $sqlCol; 
    $vals[] = $val; 
    } 
    $query = "INSERT INTO `dbname`.`tablename` (`jp_code`,`".implode('`,`',$cols)."`) VALUES ('$jpCode','".implode("','",$vals)."') ON DUPLICATE KEY UPDATE ".implode(", ",$duplicates); 
    mysql_query($query); 
} 

这使得很多的假设,就像你正在使用MySQL,您使用的是老式的MySQL扩展,而不是PDO,你分析的数据存储在一个名为$groupedData变量,等等等等

会有相当多的优化,可以执行它,我讨厌使用那么多foreach循环,但这只是一个简单的例子。您可能希望在jp_code上添加唯一索引(如果还没有),并将ON DUPLICATE KEY UPDATE添加到查询中。

我没有测试过它,所以它可能不是100%正确的,但我相信它至少会给你一个正确的方向。

编辑

注意,这将会把你的领域到数据库中JSON对象,不是数组,但他们应该(希望)仍然以同样的方式工作,你希望他们在JS的一面。 ..

另请注意我还没有做任何与Material CSV字段,因为它是从您的数据库架构中缺少。

我也刚刚为查询代码添加了ON DUPLICATE KEY UPDATE子句。

+0

这工作很好,非常感谢你! –

0

你可能想考虑我的班级。它将CSV转换为MySQL将QUERY,Array,JSON和HTML表格插入。

/** 
* CSV_parser 
* 
* @package 
* @author Dave's Simple Project 
* @copyright MESMERiZE 
* @version 2012 
* @access public 
*/ 
class CSV_parser 
{ 
    private $source; 
    private $array; 
    private $length; 
    private $delimiter; 
    private $class; 
    private $padding; 
    private $border; 
    private $id; 
    private $width; 

    /** 
    * CSV_parser::__construct() 
    * 
    * @param mixed $source 
    * @param integer $length 
    * @param string $delimiter 
    * @return 
    */ 
    public function __construct($source, $length = 8000, $delimiter = ',') 
    { 
     try 
     { 
      // Lets try to open the file and check if its readable else throw an error. 
      if (!isset($source) || !is_readable($source)) 
      { 
       throw new Exception('File Not Found!'); 
       return false; 
      } else 
      { 
       //set the source file 
       $this->source = $source; 
       $this->length = $length; 
       $this->delimiter = $delimiter; 
       return true; 
      } 
     } 
     catch (exception $e) 
     { 
      // Send an error message :) 
      echo $e->getMessage(); 
     } 
     parent::__construct(); 
    } 
    /** 
    * CSV_parser::toArray() 
    * 
    * @return 
    */ 
    public function toArray() 
    { 
     // 1. First open the source file 
     $handler = fopen($this->source, 'r'); 
     // 2. Turn the CSV to array 
     while (($data = fgetcsv($handler, $this->length, $this->delimiter)) !== false) 
     { 
      $a[] = $data; 
     } 
     // 3. Get the first index to be used as the key 
     $h = $a[0]; 
     // 4. Lets remove the $h variable's empty values 
     foreach ($h as $k => $v) 
     { 
      if ($v != '') 
      { 
       $headers[$k] = $v; 
      } 
     } 
     // 4. Remove the first index and leave the others to be used as the value 
     $a = array_slice($a, 1); 
     // 5. Make an empty array 
     $array = array(); 
     // 6. Lets loop the values 
     foreach ($a as $k => $v) 
     { 
      $i = 0; 
      // then loop the headers then for each headers lets get the values 
      // from variable $a based on how many the headers are. So we increment. 
      foreach ($headers as $key => $value) 
      { 
       $array[$k][$value] = $v[$i]; 
       $i++; 
      } 
     } 
     return $array; 
     fclose($handler); 
    } 
    /** 
    * CSV_parser::toTable() 
    * 
    * @param string $width 
    * @param integer $border 
    * @param integer $spacing 
    * @param integer $padding 
    * @param string $class 
    * @param mixed $id 
    * @return 
    */ 
    public function toTable($width = '100%', $border = 1, $spacing = 0, $padding = 5, 
     $class = 'mytable', $id = null) 
    { 
     $this->width = $width; 
     $this->class = $class; 
     $this->spacing = $spacing; 
     $this->padding = $padding; 
     $this->border = $border; 
     $this->id = $id; 

     $table = '<table width="' . $this->width . '" class="' . $this->class . 
      '" cellspacing="' . $this->spacing . '" cellpadding="' . $this->padding . 
      '" id="' . $this->id . '" border="' . $this->border . '">'; 
     // 1. Lets create some table headers 
     $table .= '<thead><tr>'; 
     foreach ($this->toArray() as $key => $value) 
     { 
      $headers = $value; 
     } 
     $headers = array_keys($headers); 
     foreach ($headers as $th) 
     { 
      $table .= '<th>' . $th . '</th>'; 
     } 
     $table .= '</tr></thead>'; 
     // Lets create the table body 
     $table .= '<tbody>'; 
     foreach ($this->toArray() as $key => $value) 
     { 
      $table .= '<tr>'; 
      foreach ($value as $val) 
      { 
       $table .= '<td>' . $val . '</td>'; 
      } 
      $table .= '<tr>'; 

     } 
     $table .= '</tbody>'; 
     $table .= '</table>'; 
     return $table; 

    } 
    /** 
    * CSV_parser::toJSON() 
    * 
    * @return 
    */ 
    public function toJSON() 
    { 
     return json_encode($this->toArray()); 
    } 
    public function toMYSQL($table_name = 'table_name') 
    { 
     $str = ''; 
     $the_array = $this->toArray(); 
     foreach($the_array as $array) 
     { 
      $k = implode(',',array_keys($array)); 
      $v = "'".implode("','",array_values($array))."'"; 
      $str .= "INSERT INTO $table_name($k) VALUES($v)\n"; 
     } 
     return $str; 
    } 

} 

用法:

$data = new CSV_parser('C:\wamp\www/sample.csv'); 
echo '<code>'; 
echo $data->toJSON(); 
echo '</code>'; 
echo $data->toTable(); 
echo '<pre>'; 
    echo $data->toMYSQL('',TRUE); 
echo '</pre>'; 
echo '<pre>'; 
    print_r($data->toArray()); 
echo '</pre>';