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:
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()
}
}
So the above code does the following:
- Creates an encodable object called 'order'.
- Creates a POST request to my API.
- Passes the encoded JSON object via a POST parameter.
I've printed the json object that gets posted back to the console in XCode and that looks as follows:
{
collection = Delivery;
doorNum = 99;
idQty = (
{
itemId = 17;
qty = 5;
},
{
itemId = 1;
qty = 3;
}
);
name = James;
phone = 012345667;
postcode = LXU49RT;
street = Hope Street;
}
Next, I'll move over to my server/API which accepts the POST parameter.
Below is my AddOrder.php page:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
require_once dirname(__FILE__) . '/DbOperation.php';
$json = $_POST["json"];
$db = new DbOperation();
$json = $db->addOrder($json);
}
And below is my DbOperation addOrder function:
public function addOrder($json) {
require dirname(__FILE__) . '/../../dbconnect.php';
$decoded = json_decode($json);
$collection = $decoded{"collection"};
$stmt2 = $pdo->prepare("INSERT INTO TestTable (collection) VALUES (:collection)");
$stmt2->bindParam(':collection',$collection);
$stmt2->execute();
}
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.
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.
The full error is below:
[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->execute()\n#1 /var/www/api/AddOrder.php(16): DbOperation->addOrder(NULL)\n#2 {main}\n thrown in /var/www/api/DbOperation.php on line 111
What I've tried
I've tried altering my AddOrder.php page to the following:
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->addOrder($json);
}