2012-03-18 90 views
0

我是一个试图在世界上找到我的方式的新手程序员。我已经掌握了我试图解析出来的SQL语句来填充多个数据库表的JSON数据。我想遍历数组的每个维度并抽出它的特定部分来创建一个我可以传递给MySQL的INSERT语句。我不确定这是用一个JSON文件中的数据填充单独表格的最佳方式,但这是我能想到的唯一方法。 MySQL表格是分开的,所以有一个人的表格,一个地址类型的表格,一个地址表格,一个电话表格,一个电子邮件表格等等。这是一个包含许多电话号码,电子邮件地址等等。解析JSON在PHP中创建SQL插入语句

我已经能够从外部URL解码JSON。以下是使用print_r的代码和输出示例。

$json_string = 'http://....'; 

$jsondata = file_get_contents($json_string); 

$data = json_decode($jsondata, TRUE); 

1记录样品:

Array ([objects] => Array ([0] => Array ([first_name] => Anthony [last_name] => Perruzza [name] => Anthony Perruzza [elected_office] => City councillor [url] => http://www.toronto.ca/councillors/perruzza1.htm [gender] => [extra] => Array () [related] => Array ([boundary_url] => /boundaries/toronto-wards/york-west-8/ [representative_set_url] => /representative-sets/toronto-city-council/) [source_url] => http://www.toronto.ca/councillors/perruzza1.htm [offices] => Array ([0] => Array ([tel] => 416-338-5335)) [representative_set_name] => Toronto City Council [party_name] => [district_name] => York West (8) [email] => [email protected] [personal_url] => [photo_url] =>)) [meta] => Array ([next] => /representatives/?limit=1&offset=1 [total_count] => 1059 [previous] => [limit] => 1 [offset] => 0)) 

JSON代码示例:

{"objects": [ 
    {"first_name": "Keith", 
    "last_name": "Ashfield", 
    "name": "Keith Ashfield", 
    "elected_office": "MP", 
    "url": "http://www.parl.gc.ca/MembersOfParliament/ProfileMP.aspx?Key=170143&Language=E", 
    "gender": "", 
    "extra": {}, 
    "related": { 
      "boundary_url": "/boundaries/federal-electoral-districts/13003/", 
      "representative_set_url": "/representative-sets/house-of-commons/" 
    }, 
    "source_url": "http://www.parl.gc.ca/MembersOfParliament/MainMPsCompleteList.aspx?TimePeriod=Current&Language=E", 
    "offices": [ 
     { "type": "legislature", 
      "fax": "613-996-9955", 
      "postal": "House of Commons\nOttawa, Ontario\nK1A 0A6", 
      "tel": "613-992-1067" 
     }, 
     { "type": "constituency", 
      "fax": "506-452-4076", 
      "postal": "23 Alison Blvd (Main Office)\nFredericton, New Brunswick\nE3C 2N5", 
      "tel": "506-452-4110" 
     } 
    ], 
    "representative_set_name": "House of Commons", 
    "party_name": "Conservative", 
    "district_name": "Fredericton", 
    "email": "[email protected]", 
    "personal_url": "", 
    "photo_url": "http://www.parl.gc.ca/MembersOfParliament/Images/OfficialMPPhotos/41/AshfieldKeith_CPC.jpg" 
    } 
], 
    "meta": { 
     "next": "/representatives/house-of-commons/?limit=1&offset=1", 
     "total_count": 307, 
     "previous": null, 
     "limit": 1, 
     "offset": 0 
    } 
} 

,你可以提供任何帮助将不胜感激。在过去的几天里,我一直在努力弄清楚自己的头发。

我试过自定义代码,如下所示,使其工作,但我一直没有能够击中甜蜜点。请不要,这段代码不会引用我的数据或变量。我删除了不适合我的东西。我只是包括它给你一个想法,我已经尝试过。

foreach ($data as $item) { 
    echo $item->{'first_name'} . "<br/>"; 
    echo $item->{'last_name'}; 
} 

如果你能指出我能够解析出数组的任何级别的数据的方向,将不胜感激。

最佳,

小号

+0

我认为json代码的代表性样本也会有用,如果您可以发布该代码? – vascowhite 2012-03-18 19:16:14

+0

阅读http://www.php.net/manual/en/language.types.array.php – Rob 2012-03-18 19:06:40

+0

感谢您的回复。刚刚发布了上面的JSON示例。我也阅读上面提供的手动链接,并通过我正在阅读的内容尝试其他几个。 – RawAnimal 2012-03-18 20:41:50

回答

3

据我所知,这是不可能插入到几个表有一个刀片。而且,你需要保持数据的完整性,所以相关的表有正确的外键。

一般的想法是迭代数据,插入记录并记住插入的id,然后将它们写为对应的外键。

你迭代通过你的对象,请将所有的原始属性字段,然后用mysql_last_insert_id,然后同时节省办公室(或他们的详细资料)得到id把那id及其相关对象ID。

E.g.我们有以下JSON。

{"authors": [ 
    {"first_name": "John", 
    "last_name": "Doe", 
    "books": [{ 
      "title": "Capture the flag", 
      "ISBN": "123-456789-12345", 
    },{ 
      "title": "Deathmatch", 
      "ISBN": "123-456789-12346", 
    }] 
]} 

然后把它插入用下面的代码数据:

foreach ($data as $author) { 
    mysql_query("INSERT INTO `authors` (`first_name`, `last_name`), VALUES('{$author->first_name}', '{$author->last_name}') "); 
    $author_id = mysql_last_insert_id(); 
    foreach ($author->books as $book) { 
     mysql_query("INSERT INTO `books` (`title`, `isbn`, `author_id`), VALUES('{$book->title}', '{$book->isbn}', '{$author_id}') "); 
    } 
} 

这是如果你有自动递增的ID在表中。

当然,你需要插入等

+0

嘿,那里。非常感谢您的指导。我不打算尝试使用一个插入插入多个表。我不知道关于mysql_last_insert_id()。这是黄金。非常感谢。我正在努力尝试一下。我能够弄清楚循环并让它遍历。但是,我收到一个错误,所以它不会超过第一条记录。下面的代码: “的foreach($数据作为$对象){ \t的foreach($对象作为$项目){ \t \t的foreach($的项目,如$密钥=> $项目){ \t \t \t回声“$ key:$ items“,”
“; \t \t} \t} }” 警告:提供的foreach无效的参数() – RawAnimal 2012-03-18 21:29:28

+0

好,仔细阅读约'mysql_last_insert_id'。你必须通过mysql连接链接,以免干扰其他mysql客户端的插入。 – kirilloid 2012-03-18 21:30:46

+0

我会让你知道它是怎么回事。我打算把一个临时数据库放到一起,直到我弄明白为止。对于我上面分享的循环的任何想法。我应该将它发布在主要问题中,以便阅读。 – RawAnimal 2012-03-18 21:35:54

1

这里之前验证和逃避数据的东西,你可以用它来获得一个JSON响应的结构。它以递归方式工作,因此它将为每个对象创建一个条目,并为每个对象的每个属性创建一个单独表中的条目。我希望得到其他人的反馈/改进,并将其转化为创建sql语句。

class DataDriller { 

    var $ext_obj_to_parse; 
    var $ext_type_name; 
    var $data; 
    var $recurse; 
    var $ext_type_id; 
    var $ext_related_id; 
    var $type_id; 
    var $auto_create; 
    var $sql; 
    var $error; 
    var $controller; 
    var $ExtType; 
    var $ExtStructure; 
    var $link; 
    var $ext_source_id; 

    function init($ExtType, $ExtStructure) { 
    $this->ExtType = $ExtType; 
    $this->ExtStructure = $ExtStructure; 
    } 

    function setup($ext_obj_to_parse, $ext_type_name, $ext_type_id = false, $ext_related_id = false, $auto_create = true, $ext_source_id) { 
    $this->ext_obj_to_parse = $ext_obj_to_parse; 
    $this->ext_type_name = $ext_type_name; 
    $this->ext_type_id = $ext_type_id; 
    $this->auto_create = $auto_create; 
    $this->error = false; 
    $this->ext_related_id = $ext_related_id; 
    $this->ext_source_id = $ext_source_id;  



    if ($this->get_ext_type_data() === false) { 
     if ($this->type_handling() === false) { 
     $this->error_data(); 
     } 
    } 

    if (gettype($this->ext_obj_to_parse) == "object" || gettype($this->ext_obj_to_parse) == "array") { 
     $this->to_struct(); 
    } else { 
     //single variable and data 
     $this->data[$this->ext_type_name] = gettype($this->ext_obj_to_parse); 
     $this->sql = "replace into ext_structures (name, data_type, ext_type_id) values ('$this->ext_type_name', '" . gettype($this->ext_obj_to_parse) . "', " . $this->ext_type_id . ")"; 
     $this->sql_it(); 
    } 
    } 

    function get_ext_type_data() { 
    if (is_numeric($this->ext_type_id)) { 
     return true; 
    } else if (strlen($this->ext_type_name) > 0) { 
     $this->sql = "select id From ext_types where name = '" . $this->ext_type_name . "' limit 1"; 
     $this->ext_type_id = $this->sql_it('id'); 
     return $this->ext_type_id; 
    } else { 
     return false; 
    } 
    } 

    function type_handling() { 
    if ($this->auto_create == true && gettype($this->ext_type_name) === "string") { 
     //$this->sql = "replace into types (name) values ('$this->ext_type_name')"; 
     // 
     //$this->type_id = $this->sql_it(); 
     //if ($this->type_id !== 0) { 
     //if ($this->ext_related_id) { 
     $this->sql = "insert into ext_types (name, ext_source_id, parent_id) values ('$this->ext_type_name', $this->ext_source_id, '$this->ext_related_id')"; 
     $this->ext_type_id = $this->sql_it(); 

     $this->sql = "replace into ext_type_rel (ext_type_id_1, ext_type_id_2) values ($this->ext_type_id, $this->ext_related_id)"; 
     $this->sql_it(); 
     /*} else { 
     $this->error = "Unable to obtain typeid from insert"; 
     $this->error_data(); 
     return false; 
     }*/ 
    } 
    //} 
    } 

    function to_struct() { 
    //keys are not objects but values can be 
    //always display keys, when value object - increase spacer - call self - reiterate 
    // if value is not object complete 
    foreach ($this->ext_obj_to_parse as $key => $value) { 
     if (gettype($value) == "object" || gettype($value) == "array") { 
     //check to see if object exists within the database with the data definitions and methods 
     //there are no existing data structure insert 
     //recurse into the drill-down again if it does not exist 
     if (is_numeric($key) || $key == "data" || $key == "statuses") { 
      $this->recurse = new DataDriller(); 
      if (!$this->ext_related_id > 0){ $this->ext_related_it = $this->ext_type_id; } 

      $this->recurse->setup($value, $this->ext_type_name, $this->ext_type_id, $this->ext_related_id, true, $this->ext_source_id); 
     } else { 
      $this->recurse = new DataDriller(); 
      $this->recurse->setup($value, $key, false, $this->ext_type_id, true, $this->ext_source_id); 
     } 

     $this->data[$key] = $this->recurse->data; 

     unset($this->recurse); 
     //this is where we insert the relationship between objects here 
     } else { 
     //not an ojbect just a field of the existing object 
     $this->data[$key] = gettype($value); 

     $this->sql = "replace into ext_structures (name, data_type, ext_type_id) values ('$key', '" . gettype($value) . "', " . $this->ext_type_id . ")"; 
     $this->sql_it(); 
     } 
    } 
    } 

    function sql_it($field_name = false) { 

    $VARDB_server = '192.168.10....'; 
    $VARDB_port = '3306'; 
    $VARDB_user = 'user'; 
    $VARDB_pass = 'pass'; 
    $VARDB_database = 'db_name'; 

    $this->link = mysql_connect("$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass"); 
    if (!$this->link) { 
     echo 'MySQL connect ERROR: ' . mysql_error(); 
     die(); 
    } 
    $res = mysql_select_db("$VARDB_database"); 
    if (!$res) { 
     echo mysql_error(); 
    } 


    $res = mysql_query($this->sql, $this->link); 
    if (mysql_error()) { 
     $this->error = mysql_error() . " MYSQL reported an error " . $this->sql; 
     CakeLog::write('datadriller', $this->sql . " error? " . mysql_error()); 
     die(); 
    } 

    if ($field_name === false) { 
     if (strpos($this->sql, 'insert') !== false || strpos($this->sql, 'replace') !== false) { 
     $id = mysql_insert_id(); 
     return $id; 
     } else { 
     $this->error = "field name is requeired for getting results"; 
     $this->error_data(); 
     return false; 
     } 
    } else { 
     if (mysql_num_rows($res) > 0) { 
     $r = mysql_fetch_array($res); 
     mysql_free_result($res); 
     if (array_key_exists($field_name, $r)) { 
      return $r[$field_name]; 
     } else { 
      $this->error = "field name does not exist in result set"; 
      $this->error_data(); 
      return false; 
     } 
     } else { 
     $this->error = "select statement returned no data "; 
     return false; 
     } 
    } 
    } 

    function error_data() { 
    echo "<B> $this->error MySQL error? <font color=red>" . mysql_error() . " </font> SQL: $this->sql </b><BR><BR>\n"; 
    echo "DUMP DATA\n"; 
    echo "<pre>"; 
    var_dump($this->data); 
    echo "RECURSED OBJECT \n\n"; 
    var_dump($this->recurse); 
    echo "</pre>"; 
    }