Skip to content
Advertisement

Swift not passing variables to PHP Web Service to query my SQL database

I have a PHP Web Service that can insert a new row to my database if I hardcode the values in to the SQL query directly. But when I try to do this using variables passed to the PHP script from my Swift function it breaks down. I have add print statements to my Swift so I am confident that the values are being passed to the function correctly and the error must lie in the lines afterwards.

PHP: I have commented the SQL query line out with the hardcoded values – Carrots, but this query does work so I think PHP->SQL is working ok, but Swift->PHP is the problem.

 <?php
$servername = "localhost";
$username = "*******";
$password = "*****";
$dbname = "*******";

$product_name = $_POST['product_name'] ?? 'DefaultProduct';
$code = $_POST['code'] ?? 'DefaultCode';
$Brands = $_POST['brands'] ?? '1';
$Comp1Mat = $_POST['Comp1Mat'] ?? 'DefaultMat';
$Comp2Mat = $_POST['Comp2Mat'] ?? '1';

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}

//$sql = "INSERT INTO Products (product_name, code) VALUES ('Carrots', '0135')";

$sql = $conn->prepare("INSERT INTO Products (product_name, code, brands, Comp1Mat, Comp2Mat) VALUES (?, ?, ?, ?, ?)";
$sql->bind_param("isssi", $product_name, $code, $Brands, $Comp1Mat, $Comp2Mat);
$sql->execute();
$sql->close();

if ($conn->query($sql) === TRUE) {
  echo "New record created successfully";
} else {
  echo "Error: " . $sql . "<br>" . $conn->error;
}

$conn->close();
?> 

Swift:

func addProduct(product_name: String, code: String, brands: String, Comp1Mat: String, Comp2Mat: String){
        
        print(product_name)
        print(code)
        print(brands)
        print(Comp1Mat)
        print(Comp2Mat)
        
        let insertProductURL = URL(string: "http://recyclingmadesimple.xyz/insertproduct.php")!
        var urlRequest = URLRequest(url: insertProductURL)
        urlRequest.httpMethod = "POST"
        // Set HTTP Request Headers
        urlRequest.setValue("application/json", forHTTPHeaderField: "Accept");
        urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type");
        
        let postString = "product_name=(product_name)&code=(code)&brands=(brands)&Comp1Mat=(Comp1Mat)&Comp2Mat=(Comp2Mat)"
        urlRequest.httpBody = postString.data(using: .utf8)
        
        let task = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            if error != nil {
                print("error = (String(describing: error))")
                return
            }
            print("response - (String(describing: response))")
            let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            print("response string - (String(describing: responseString))")
        }
        task.resume()

    }

Error:

response - Optional(<NSHTTPURLResponse: 0x281191600> { URL: http://recyclingmadesimple.xyz/insertproduct.php } { Status Code: 500, Headers {
    Connection =     (
        "Upgrade, close"
    );
    "Content-Length" =     (
        0
    );
    "Content-Type" =     (
        "text/html; charset=UTF-8"
    );
    Date =     (
        "Thu, 17 Jun 2021 12:38:25 GMT"
    );
    Server =     (
        Apache
    );
    Upgrade =     (
        "h2,h2c"
    );
    Vary =     (
        "User-Agent"
    );
    "X-Powered-By" =     (
        "PHP/7.4.16"
    );
} })
response string - Optional()

Many thanks.

Advertisement

Answer

I got this working after taking on board the suggestions. Thank you all. I changed the parsing to JSON in swift and improved the binding of variables in the PHP file.

PHP:

<?php

$code = $_POST["code"];

// Create connection
$con=mysqli_connect("localhost","X","X","X");

// Check connection
// Return the error code if the connection is not successful.
if (mysqli_connect_errno())
{
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
}


/* create a prepared statement */
// A prepared statement is one that is loaded initially and then executed many times over and over when we attach (bind) new variables to the placeholders we have inserted. We use ? marks to signify placeholders than must be later filled with values.
$stmt = mysqli_prepare($con, "SELECT product_name, brands, Comp1Mat, Comp2Mat, Comp3Mat, Comp1Name, Comp2Name, Comp3Name FROM Products WHERE code=?");


// Bind the parameters the user has entered with the ? marks in the SQL query
mysqli_stmt_bind_param($stmt, "s", $code);

/* execute query */
mysqli_stmt_execute($stmt);

// Bind the results we get with some new variable that we will output in the print statement.
mysqli_stmt_bind_result($stmt, $product_name, $brands, $Comp1Mat, $Comp2Mat, $Comp3Mat, $Comp1Name, $Comp2Name, $Comp3Name);

/* fetch value */
mysqli_stmt_fetch($stmt);

//create an array
$emparray = array("code" => $code, "product_name" => $product_name, "brands" => $brands, "Comp1Mat" => $Comp1Mat, "Comp2Mat" => $Comp2Mat, "Comp3Mat" => $Comp3Mat, "Comp1Name" => $Comp1Name, "Comp2Name" => $Comp2Name, "Comp3Name" => $Comp3Name);
printf(json_encode($emparray));

 
// Close connections
mysqli_close($con);
?><?php

Swift:

func findSingleProduct(code: String){
        // Completes an SQL query on the Products database to find a product by it's barcode number.
        // prepare json data
        let insertProductURL = URL(string: "http://recyclingmadesimple.xyz/service.php")!
        var urlRequest = URLRequest(url: insertProductURL)
        urlRequest.httpMethod = "POST"
    
        let postString = "code=(code)"
        urlRequest.httpBody = postString.data(using: String.Encoding.utf8)
        
        let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
            guard let data = data, error == nil else {
                print(error?.localizedDescription ?? "No data")
                return
            }
            let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
            if let responseJSON = responseJSON as? [String: Any] {
                let code = responseJSON["code"]!
                let product_name = responseJSON["product_name"]!
                let brands = responseJSON["brands"]!
                let Comp1Mat = responseJSON["Comp1Mat"]!
                let Comp2Mat = responseJSON["Comp2Mat"]!
                let Comp3Mat = responseJSON["Comp3Mat"]!
                let Comp1Name = responseJSON["Comp1Name"]!
                let Comp2Name = responseJSON["Comp2Name"]!
                let Comp3Name = responseJSON["Comp3Name"]!

                
                print(code, brands, product_name, Comp1Mat, Comp2Mat, Comp3Mat, Comp1Name, Comp2Name, Comp3Name)
                
            }
        }

        task.resume()
    }
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement