-1

I've already seen a lot of questions similar to mine but mine is different: My error is not caused by the use of a "keyword" in SQL!

when I run my code, if I cancel the WHERE clause or I use an hard coded value such as " WHERE customerNumber = 356" it works fine but if I try to use the value of the variable $custom_n, it throw an error.

<?php 
            $custom_n = $_POST["emp"];
            $servername = "localhost";
            $username = "root";
            $password = "";

            try {
                $conn = new PDO("mysql:host=$servername;dbname=classicmodels", $username, $password);
                $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

                $stmt = $conn -> prepare("SELECT phone, salesRepEmployeeNumber, creditLimit FROM customers WHERE customerNumber = $custom_n");
                $stmt -> execute();
                $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); 
                foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) { 
                    echo $v;
                }
            }
            catch(PDOException $e) {
                echo "Connection failed: " . $e->getMessage();
            }

            $conn = null;

        ?>

If i do an echo to custom_n and gettype i get: 353 string which is what i wanted.

This is the full error:

Connection failed: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

As suggested by Magnus Eriksson, If I do a var_dump($custom_n); i get this output: string(12) ""

Marc Delisle
  • 8,879
  • 3
  • 29
  • 29
Fabio Magarelli
  • 1,031
  • 4
  • 14
  • 47
  • 1
    You are wide open to SQL injections and should use parameterized Prepared Statements instead of injecting unescaped user data into your queries like that. You've already got the basics set up. In your query, change to: `customerNumber = :number` and change the execute to: `$stmt->execute([':number' => $custom_n]);` – M. Eriksson Dec 06 '18 at 11:39
  • I'm sorry can you explain better? This is the first time I use php, In other pages I used the same syntax and it's working... can you give me an example of what you mean by parameterized Prepared Statements? – Fabio Magarelli Dec 06 '18 at 11:43
  • replace E customerNumber = $custom_n" with '".$custom_n."'" or visit this link https://stackoverflow.com/questions/46143351/connection-failed-sqlstate42000-syntax-error-or-access-violation-1064 – Kamran Sohail Dec 06 '18 at 11:43
  • Look [at the manual for PDO::execute()](http://php.net/manual/en/pdo.prepare.php) and you'll see some examples. – M. Eriksson Dec 06 '18 at 11:44
  • IT will also resolve like `$stmt = $conn -> prepare("SELECT phone, salesRepEmployeeNumber, creditLimit FROM customers WHERE customerNumber = ".$custom_n);`. You also bind with param – Sudharshan Nair Dec 06 '18 at 11:45
  • @SudharshanNair - That would give the OP the exact same result as they already getting. – M. Eriksson Dec 06 '18 at 11:45
  • @MagnusEriksson. Nope here the variable will be printed – Sudharshan Nair Dec 06 '18 at 11:46
  • @SudharshanNair - Yes it would. The OP has the query (and the variable) inside double quotes so the value of the variable will be printed there as well. It's called variable interpolation. – M. Eriksson Dec 06 '18 at 11:47
  • In question error is that variable `$custom_n` is not getting evaluated, that the reason I have asked to append or you can also bind with param – Sudharshan Nair Dec 06 '18 at 11:48
  • @MagnusEriksson. Sorry my mistake, Modify it to `'".$custom_n."'` – Sudharshan Nair Dec 06 '18 at 11:49
  • 1
    @SudharshanNair - The only suggestion here should be to use parameterized prepared statements. Anything else is a bad and opens the query up for sql injection attacks. – M. Eriksson Dec 06 '18 at 11:51

4 Answers4

4
$stmt = $conn -> prepare("SELECT phone, salesRepEmployeeNumber, creditLimit FROM customers WHERE customerNumber = ?");
$stmt->execute(array($custom_n));

Your code seems fine so i assume your string escapes the query. Try to use prepared statements next time.

pr1nc3
  • 8,108
  • 3
  • 23
  • 36
  • hi, this doesn't solve, I mean I have no error but no data is returned from the query – Fabio Magarelli Dec 06 '18 at 11:55
  • 1
    Either then there is no data to be returned or you have an error you just don't display it. – pr1nc3 Dec 06 '18 at 11:56
  • 1
    @FabioMagarelli - Do `echo '
    '; var_dump($custom_n); echo '
    ';` and update your question with the complete ouput from it. There could be some extra white spaces or similar that could mess things up. Those are usually not visible when just doing an `echo`.
    – M. Eriksson Dec 06 '18 at 11:58
  • oh wait, with the var_dump i got: `string(12) ""` – Fabio Magarelli Dec 06 '18 at 12:06
  • yes if i do an echo i get the number `353` that is one of the customer ids – Fabio Magarelli Dec 06 '18 at 12:20
  • Ok then 2 things can happen either you conn does not work but you have the error disabled so you don't see. Or there are hidden characters so you need to remove them from your string (other than spaces). – pr1nc3 Dec 06 '18 at 12:24
  • i tried this `preg_replace('/\s+/','',$custom_n);` but it doesn't change anything, the conn is working: if i remove the where clause, it prints me out all the customers – Fabio Magarelli Dec 06 '18 at 12:28
  • @FabioMagarelli - Is the value `$_POST['emp']` coming from a form or is it some API call? How is it sent to your page? It's pretty strange that you get a 12 character long string if you're just expecting the number 353. – M. Eriksson Dec 06 '18 at 12:29
  • yes is sent by a form in another page... wait a min probably a light turned on in my brain '^.^ – Fabio Magarelli Dec 06 '18 at 12:33
0

Preferred way is binding. You can bind with param like this. You can refer to here

$stmt = $conn -> prepare("SELECT phone, salesRepEmployeeNumber, creditLimit FROM customers WHERE customerNumber = :customernumber");

$stmt->bindParam(':customernumber', $custom_n, PDO::PARAM_INT);
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sudharshan Nair
  • 1,152
  • 1
  • 10
  • 24
0

As suggested by Magnus Eriksson, there was a problem with my POST method... even if it seemed to be ok, my variable custom_n had a weird var_dump output string(12)"". I remember that I used the same code previously and was working, so I simply modify the code to be exactly the same: In the page in which I have the form which send the "POST variable", i used this code:

<?php 

            $servername = "localhost";
            $username = "root";
            $password = "";

            $custom_n = array();

            try {
                $conn = new PDO("mysql:host=$servername;dbname=classicmodels", $username, $password);
                $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

                $stmt = $conn -> prepare("SELECT checkNumber, paymentDate, amount, customerNumber FROM payments ORDER BY paymentDate DESC");
                $stmt -> execute();
                $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); 
                foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) { 
                    echo $v;
                    if ($k == 'customerNumber') {
                        array_push($custom_n, $v);
                    }
                }

                $tableCodes = "<table id='buttons'>";
                foreach ($custom_n as $c) {
                    $tableCodes .= "
                        <tr>
                            <td>
                                <form action='customers.php' method='post' target='POPUPW' onsubmit=\"POPUPW = window.open('about:blank','POPUPW', 'width=800px,height=600px');\">
                                    <button type='submit' name='code' value='$c'>Details</button>
                                </form>
                            </td>
                        </tr>
                    ";
                }
                $tableCodes .= "</table>";
                echo $tableCodes;
            }
            catch(PDOException $e) {
                echo "Connection failed: " . $e->getMessage();
            }

            $conn = null;

        ?>

I thought I could have spared some time getting the custom_n from another query that I do to populate a table in that page instead of making another query. I'm not really sure what's wrong with that but with this changing i solved the problem:

<?php 

            $servername = "localhost";
            $username = "root";
            $password = "";

            try {
                $conn = new PDO("mysql:host=$servername;dbname=classicmodels", $username, $password);
                $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

                $stmt = $conn -> prepare("SELECT checkNumber, paymentDate, amount, customerNumber FROM payments ORDER BY paymentDate DESC");
                $stmt -> execute();
                $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); 
                foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) { 
                    echo $v; 
                }

                $customQuery = $conn -> prepare("SELECT customerNumber FROM payments ORDER BY paymentDate DESC");
                $customQuery -> execute();
                $custom = $customQuery->fetchAll(PDO::FETCH_COLUMN);
                $tableCodes = "<table id='buttons'>";
                foreach ($custom as $c) {
                    $tableCodes .= "
                        <tr>
                            <td>
                                <form action='customers.php' method='post' target='POPUPW' onsubmit=\"POPUPW = window.open('about:blank','POPUPW', 'width=800px,height=600px');\">
                                    <button type='submit' name='emp' value='$c'>Details</button>
                                </form>
                            </td>
                        </tr>
                    ";
                }
                $tableCodes .= "</table>";
                echo $tableCodes;
            }
            catch(PDOException $e) {
                echo "Connection failed: " . $e->getMessage();
            }

            $conn = null;

        ?>

I have to thanks everyone, in particular MagnusEriksson, MasivuyeCokile and Pr1nc3 whithout whom I wouldn't ever known about parameterized Prepared Statements. Thank you very much and if you find out why the previous code wasn't working, feel free to comment :D.

Fabio Magarelli
  • 1,031
  • 4
  • 14
  • 47
-2

This error may thrown because of using MySQL reserved keywords as your table or column names. so make sure not to use reserved keywords in your table or column name.

Here is the MySQL reserved keywords link