2

I have used tutorials, examples and looked at numerous other questions about my problem and I still can't get it to work, I am relatively new to PHP and do not have any understanding of PDO. I have changed my code to mysqli rather than mysql to get rid of the depreciated code my university gave me but they have been less than helpful during this situation.

If anyone could shed some light onto this issue for me I would be very grateful. Below are my code samples:

<?php /*connect to the db */
   $link=mysqli_connect("dbhost","user","pass");
   mysqli_select_db("db",$link);

   /*checking connection*/
      if ($link->connect_errno) 
        throw new exception(sprintf("Could not connect: %s", $link->connect_error));

session_start();



        $insert_query="
        INSERT INTO testone_tbl (age,hours,flexibility,fastpaced,retailexp,
        workedus,conviction,permit,education)
        VALUES ('$age','$hours','$flexibility','$fastpaced','$retailexp','$workedus',
        '$conviction','$permit','$education'); 
        INSERT INTO testtwo_tbl 
        (contribute,insales,initiative,success,alternatives,targets,
        newthings,custfeed,incdevelop,standards,confident,stretch,
        opportunities,polite,ideas,deadline,supported,duties)
        VALUES ('$contribute','$insales','$initiative',
        '$success','$alternatives','$targets','$newthings',
        '$custfeed','$incdevelop','$standards','$confident','$stretch',
        '$opportunities','$polite','$ideas','$deadline','$supported','$duties')";


    /*execute multi_query*/


mysqli_multi_query ($link, $insert_query);/*error1*/
/*close connection*/
if(!$link>connect_errno) $link->close(); /*error2*/

?>

The data is both from the form this is written in (the last form) and sessions from the previous forms. However I am also getting this error: Warning: mysqli_multi_query() expects parameter 1 to be mysqli and Warning: mysqli_close() expects parameter 1 to be mysqliand I have been stuck on this the past few days! Thank you in advance.

Ozzy
  • 8,244
  • 7
  • 55
  • 95
PurpleSmurph
  • 2,055
  • 3
  • 32
  • 52

2 Answers2

3

You should first check with your web host if they have enabled multi-SQL-queries.

Some web hosts only allow single-SQL queries to help prevent against injection attacks.

If, however, you want to multi-insert to the same table, you could do it like this:

INSERT INTO tbl_name (col1, col2)
     VALUES ('?', '?'),
            ('?', '?'),
            ('?', '?'); # inserts 3 records to the same table in one query

Also, if you do have PDO available to you, use it!

With a PDO object, your queries will be safer by using prepared statements. Example:

$db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);

$data = array($col1, $col2, $col3);
$sql = "INSERT INTO tbl_name (col1, col2, col3) VALUES ('?', '?', '?');";
$query = $db->prepare($sql); # prepares the sql statement
$query->execute($data); #binds the array of data to the ?
                        #question mark parameters, and executes.

If you create a database abstraction layer, you could change the database connection mode without having to rewrite your code which executes your queries.

Also, do you have a reason not to loop and query? Example:

$sql_array = array("INSERT INTO tbl_one(col1) VALUES '?';",
             "INSERT INTO tbl_two(col3) VALUES '?';");

function performAll($sql_array) {
    # execute all of the queries
}

It has occured to me that you may be using some function to access your database connection. Now that is not a problem, unless you actually try to access the database connection from within a function (in case you have not told us). Example:

$db = new PDO("...", $user, $pass);

$query = $db->prepare($sql); # works fine

function executeQuery($sql) {
    $query = $db->prepare($sql); # error: $db is not defined
                                 # within the scope of this function
    ...
}

To get around this, use the global keyword in PHP. Example:

$db = new PDO("...", $user, $pass);

function executeQuery($sql) {
    global $db; # use $db in the global scope
    $query = $db->prepare($sql); # works fine
    ...
}
Ozzy
  • 8,244
  • 7
  • 55
  • 95
  • My reason behind not looping is because I'm new to this, I do not understand PDO. However, the loop and query idea does seem to look good. I have emailed my web host for confirmation they have enabled mysqli_multi_query. I will look into the loop/array idea, thank you. What is the significance of (col) ? – PurpleSmurph Apr 17 '12 at 15:40
  • In this case `col` is your field name of `tbl_name`. I kept my answer generic rather than use your own table/field names. Out of interest, does executing a SINGLE-line query work in your code? @PurpleSmurf – Ozzy Apr 17 '12 at 15:42
  • It did when it was all mysql_ etc but I changed it to mysqli which is where I'm having trouble. AH thank you for clearing that up, wasn't sure what I was looking at. So for example: ("INSERT INTO tbl_one (age) VALUES 'data', (age2) VALUES 'data2'"; etc – PurpleSmurph Apr 17 '12 at 15:48
  • Lol, so your problem is not necessarily multi-line SQL because single-line isn't working for you either! Let me fix my answer... @PurpleSmurf – Ozzy Apr 17 '12 at 15:50
  • So PDO is the best way to get multi_query to work, does it mean I have to change all of the mysqli code to the PDO equivalent ? – PurpleSmurph Apr 17 '12 at 16:08
  • @PurpleSmurf No, PDO is preferred because your code is simplified, easier to read, but most of all it has functions to prepare SQL statements to prevent SQL injection attacks. (See: http://thehackerlounge.blogspot.co.uk/2009/05/full-sql-injection-tutorial-mysql.html) – Ozzy Apr 17 '12 at 16:19
0

From the warnings it is clear that $link is not a mysqli object. Either you did not connect, or at some point you reassigned $link to something else.

You also need to check your connection immediately after your connect. An intermediate action on the link (in this case, mysqli_select_db) will clear any errors that were set.

You should also not mix-and-match object-oriented and procedural style interfaces for mysqli. The object-oriented style is much clearer, but if it's too difficult to change the existing code then stick to the procedural style.

Connect like this instead:

$link = mysqli_connect("dbhost","user","pass", "db"); // no need for an extra db select
if (mysqli_connect_errno()) {
    throw new Exception("Could not connect: ".mysqli_connect_error());
}

Also, I hope this isn't your real code, because it is wide open to mysql injection attacks. Consider dropping the use of multi-queries entirely and using prepared statements with placeholders.

Francis Avila
  • 31,233
  • 6
  • 58
  • 96
  • Crap, I am SO sorry, I've uploaded the wrong code onto this, give me a moment to edit this, I apologise unreservedly for this! – PurpleSmurph Apr 17 '12 at 15:32