2012-03-18 95 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>"; 
    }