title: How to handle incoming JSON in PHP from a Swift (iOS) app?
body: <p>I have an iOS application (Swift) which encodes some data and does a JSONSerialization and creates a JSON object. My code is below, I've done my best to keep it tidy, so I hope it makes sense:</p>
  
  <pre><code>struct Order: Codable {
      let idQty: [FoodIdAndQuantity]
      let collection: String
      let name: String
      let phone: Int
      let doorNum: Int
      let street: String
      let postcode: String
  }
  
  struct FoodIdAndQuantity: Codable {
      let itemId: Int
      let qty: Int
  }
  
  class CheckoutServer: NSObject, URLSessionDataDelegate {
  
      var inputValuesForItemAndQuantity = [Int:Int]()
      var idQty = [FoodIdAndQuantity]()
      var collection = String()
      var name = String()
      var phone = Int()
      var doorNum = Int()
      var street = String()
      var postcode = String()
  
      var request = URLRequest(url: NSURL(string: "http://192.168.1.100/api/AddOrder.php")! as URL)
  
      func sendToDatabase() {
  
          for(key,value) in inputValuesForItemAndQuantity {
              idQty.append(FoodIdAndQuantity(itemId: key, qty: value))
          }
  
          let order = Order(idQty: idQty,collection: collection,name: name,phone: phone,doorNum: doorNum,street: street,postcode: postcode)
  
          let encodedOrder = try? JSONEncoder().encode(order)
  
          var json: Any?
  
          request.httpMethod = "POST"
  
          request.addValue("application/json", forHTTPHeaderField: "Content-Type")
          request.addValue("application/json", forHTTPHeaderField: "Accept")
  
          if let data = encodedOrder {
  
              json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
              if var json = json {
                  if JSONSerialization.isValidJSONObject(json) {
                      do {
                          json = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
                      } catch {
                          print("There was a problem creating the JSON object")
                      }
  
                  } else {
                      print("not valid JSON")
                  }
              }
          }
  
          let postParameters = "json="+String(describing: json!)
  
          print(String(describing: json!)) //Print JSON for debugging purposes
  
          request.httpBody = postParameters.data(using: .utf8)
  
          let defaultSession = URLSession(configuration: URLSessionConfiguration.default)
  
          let task = defaultSession.dataTask(with: request) { (data, response, error) in
  
              if error != nil {
                  print("Failed to download data at Menu Type Items")
              } else {
                  print("Data uploaded")
              }
          }
          task.resume()
      }
  }
  </code></pre>
  
  <p>So the above code does the following:</p>
  
  <ul>
  <li>Creates an encodable object called 'order'.</li>
  <li>Creates a POST request to my API.</li>
  <li>Passes the encoded JSON object via a POST parameter.</li>
  </ul>
  
  <p>I've printed the json object that gets posted back to the console in XCode and that looks as follows:</p>
  
  <pre><code>{
      collection = Delivery;
      doorNum = 99;
      idQty =     (
                  {
              itemId = 17;
              qty = 5;
          },
                  {
              itemId = 1;
              qty = 3;
          }
      );
      name = James;
      phone = 012345667;
      postcode = LXU49RT;
      street = Hope Street;
  }
  </code></pre>
  
  <p>Next, I'll move over to my server/API which accepts the POST parameter.</p>
  
  <p>Below is my AddOrder.php page:</p>
  
  <pre><code>if ($_SERVER['REQUEST_METHOD'] == 'POST') {
      require_once dirname(__FILE__) . '/DbOperation.php';
  
      $json = $_POST["json"];
  
      $db = new DbOperation();
  
      $json = $db-&gt;addOrder($json);
  
  }
  </code></pre>
  
  <p>And below is my DbOperation addOrder function:</p>
  
  <pre><code>public function addOrder($json) {
      require dirname(__FILE__) .  '/../../dbconnect.php';
      $decoded = json_decode($json);
      $collection = $decoded{"collection"};
  
      $stmt2 = $pdo-&gt;prepare("INSERT INTO TestTable (collection) VALUES (:collection)");
      $stmt2-&gt;bindParam(':collection',$collection);
      $stmt2-&gt;execute();
  }
  </code></pre>
  
  <p>It's worth noting that, whilst I try to fix this issue, I have created a test table in my Database which simply stores the collection element of the JSON. </p>
  
  <p>The problem I have is, when I run my application and send the data, nothing gets stored in the database, and my apache error.log file says the Column 'collection' cannot be null. So I assume I am handling the POST parameter incorrectly at some point of my PHP. Unless the fault lies at a Swift level, which I'll add the Swift tag to this post if asked by an admin.</p>
  
  <p>The full error is below:</p>
  
  <pre><code>[Wed Feb 28 15:44:55.178184 2018] [:error] [pid 520] [client 192.168.1.46:52400] PHP Fatal error:  Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'collection' cannot be null in /var/www/api/DbOperation.php:111\nStack trace:\n#0 /var/www/api/DbOperation.php(111): PDOStatement-&gt;execute()\n#1 /var/www/api/AddOrder.php(16): DbOperation-&gt;addOrder(NULL)\n#2 {main}\n  thrown in /var/www/api/DbOperation.php on line 111
  </code></pre>
  
  <p><strong>What I've tried</strong></p>
  
  <p>I've tried altering my AddOrder.php page to the following:</p>
  
  <pre><code>if ($_SERVER['REQUEST_METHOD'] == 'POST') {
      require_once dirname(__FILE__) . '/DbOperation.php';
  
      //$json = $_POST["json"];
  
      $json = json_decode(file_get_contents('php://input'),true);
  
      $db = new DbOperation();
  
      $json = $db-&gt;addOrder($json);
  
  }
  </code></pre>