解析JSON以在PHP中创建SQL插入语句

时间:2012-03-18 18:52:24

标签: php mysql json

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

我已经能够从外部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] => councillor_perruzza@toronto.ca [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": "keith.ashfield@parl.gc.ca",
     "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'};
}

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

最佳,

取值

3 个答案:

答案 0 :(得分:3)

AFAIK,无法插入带有一个插入的多个表格。此外,您需要保持数据完整性,因此相关表将具有正确的外键。

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

您通过对象进行迭代,将所有基本属性作为字段插入,然后使用id获取mysql_last_insert_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的自动递增。

当然,您需要在插入之前验证和转义数据等。

答案 1 :(得分: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>";
  }

答案 2 :(得分:0)

function JSONTOInsertSQL($table,$obj){
    $keys   = implode('`,`', array_map('addslashes', array_keys($obj)));
    $values = implode("','", array_map('addslashes', array_values($obj)));
    return "INSERT INTO `$table` (`$keys`) VALUES ('$values')";
}