-1

This problem has got me absolutely stumped, I have looked through other answered questions on stack overflow and none of them answer my question.

**

Code:

**

    function inputVCA(){
    global $dbh;
    $count = 0;
    if(isset($_POST['vca'])){
        $pcid = mysql_real_escape_string($_POST['ID']);
        $vca = $_POST['vca'];
        $tok = strtok($vca, ";");
        while($tok !== false){      
            $countNew = countDataToHour($count);
            $stmt = $dbh->prepare("UPDATE $pcid SET $countNew = :token WHERE ID='1'");
            $stmt -> bindParam(':token', $tok);
            echo "<br>".$pcid."<br>";
            echo countDataToHour($count)."<br>";
            echo $tok."<br>";
            if($stmt->execute()){
                // do nothing
            }else{
                die("failed to execute query");
            }
            $count++;
            $tok = strtok(";");
        }
    }
 }

**

Output (including the error message):

**

888 00:00 40

Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\xampp\htdocs\practice\src\dataChecker.php on line 170 failed to execute query

**

What do I already know about the issue?

**

The reason this problem has me so stumped is because when I test variables etc. everything seems to output correctly. Anyway:

  • I've tested the sql query without the :variables. That works
  • The variables outputted are the ones I entered into the form so I assumed it cannot be a problem there

**

Extra info

**

The one bit of my program that I am unsure about is the:

WHERE ID='1'

in my sql query. The reason I do this is because I only will ever need one line in the sql table for the moment.


Any help appreciated, thank you :). Also as a sidenote, whoever voted me down should not have the privileges to vote anyone down. I presented my problem very clearly. My php code is a little bit sketchy but if you are voting me down for this reason this is counter productive and may discourage new users to posting questions on this site. If new users don't come then you will lose out to other competitors. Thank you to all those who gave helpful contributions.

user3918443
  • 105
  • 1
  • 13
  • 2
    Rule of thumb: would this query work if you replaced the placeholder with a literal string `'hello'` or number `42`? If not, then you cannot use a placeholder there. (And keep in mind, a *string* `'hello'` is a completely different beast than an *identifier* (table name, column name, index name, etc...)). You cannot use a placeholder for table name (`:pcid`)/column name (`:count`) and you don't need explicit quotes around `:token`. – DCoder Sep 15 '14 at 19:05
  • (As per your edit): For one thing, you're mixing two types of APIs, PDO and `mysql_` as in `mysql_real_escape_string` - You cannot mix those two together. Add `$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);` right after the connection is opened and add error reporting to the top of your file(s) right after your opening ` – Funk Forty Niner Sep 15 '14 at 19:52
  • Thankyou, the problem is apparent in my sql syntax: – user3918443 Sep 15 '14 at 19:55
  • You're welcome. Change `$pcid = mysql_real_escape_string($_POST['ID']);` to just `$pcid = $_POST['ID'];` but you have a function called `countDataToHour()` and we don't know what that does. I suggest you have a look at [**PDO with prepared statements**](http://php.net/pdo.prepared-statements) on PHP.net, follow that and start building your code one step/piece at a time. Make sure your DB connection is also PDO and not `mysql_`. Error reporting is a valuable tool when coding. I will reopen your question, but if if it gets closed for another reason, it will be out of my control. – Funk Forty Niner Sep 15 '14 at 20:05
  • For some reason my last edit only saved half of it. The problem was that I was not translating my $count to the one defined in my sql table (this is the countDataToHour() bit that I forgot to add). I have edited the code to the new format. However there is still an error: MySQL server version for the right syntax to use near '888 SET 00:00 = ':token' WHERE ID='1'' at line 1' – user3918443 Sep 15 '14 at 20:05
  • Remove the quotes around this `$count = ':token'` to read as `$count = :token` (placeholders cannot have quotes around them); that should solve it. Let me know if it solved it and I will put in an answer to close the question. – Funk Forty Niner Sep 15 '14 at 20:07
  • You might also have to put backticks `\`` around your `$pcid` in the UPDATE, combined with my other suggestion just above. – Funk Forty Niner Sep 15 '14 at 20:10
  • backticks aren't required as it is doing fine in displaying the $pcid variable. I have removed the backticks off :token. But it still hasn't quite solved it: '888 SET 00:00 = '40' WHERE ID='1''' at line 1' For some reason it doesn't seem to be reading ID='1' quite as I expected. Just wondering if that has anything to do with it? – user3918443 Sep 15 '14 at 20:13
  • `MySQL server version for the right syntax to use near '888 SET 00:00 = ':token' WHERE ID='1'' at line 1'` - look at what the error is telling you, `near '888` and those errors won't stop there. Table names **cannot** start with a number or be inclusively composed of numbers. If you want documentation on this, I will show you. Till then, wrap it in backticks. I have no other time to give you now. Take it up with Marc, I've helped you enough already where no one else did. Good luck. – Funk Forty Niner Sep 15 '14 at 20:15
  • I know your not supposed to tell people thank you on the comment section but YOU ARE A LIFE SAVER! i put backticks around $pcid and $countNew and now it works! Thanks so much!!! I will update my code for other peoples benefit. – user3918443 Sep 15 '14 at 20:25
  • one more thing, do not have to answer this now. But why am I getting voted down for my question? In my opinion I presented my problem very clearly. Yes I am a little sketchy on my php code however if that is the reason I am getting penalised this is very counter productive as it deters new users from asking for help on this site. – user3918443 Sep 15 '14 at 20:30
  • Some people are just strange that way and for many possible reasons, which I am unable to answer for them. – Funk Forty Niner Sep 15 '14 at 20:31

2 Answers2

1

Firstly, PDO and mysql_, those two APIs do not mix together.

Remove mysql_real_escape_string.

Remove the quotes around this $count = ':token' to read as $count = :token (placeholders cannot have quotes around them).

You will have to put backticks around your $pcid in the UPDATE, combined with my other suggestion(s) in my comments and my answer here.

$pcid = $_POST['ID'];
...
$stmt = $dbh->prepare("UPDATE `$pcid` SET `$countNew` = :token WHERE ID='1'");
...

This is error message as per one of your comments:

MySQL server version for the right syntax to use near '888 SET 00:00 = ':token' WHERE ID='1'' at line 1'

Look at what the error is telling you, near '888 and those errors won't stop there.

Table names cannot start with a number or be inclusively composed of numbers.

As per documentation:

Identifiers may begin with a digit but unless quoted may not consist solely of digits.

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
0

Placeholders can only represent VALUES in a query. Never a field/table name, or other SQL keyword.

UPDATE :pcid SET :count = ':token' WHERE ID='1'
       ^^^^^--field         ^^^^^^--value
                  ^^^^^--field

If you want to dynamically insert table/field names, you'll have to use good old sql-injection-vulnerable techniques like

$table = $source_of_pcid
$field = $source_of_count
$sql = "UPDATE $table SET $field = :token";
Marc B
  • 356,200
  • 43
  • 426
  • 500
  • Thank you, I will use your technique of reverting back to using anti-sql injection techniques and get back to you with the outcome. However I am about to have dinner so it might be a while – user3918443 Sep 15 '14 at 19:13
  • Okay I have updated my code, there is no error defined by my browser there any more but it is still failing to execute the query. – user3918443 Sep 15 '14 at 19:47
  • failing how? You get your "failed to execute query" message? Check `$dbh->errorInfo()` for actually useful messages. – Marc B Sep 15 '14 at 20:25