• PHP Help
  • mysqli_real_escape_string() expects parameter 1 to be mysqli, null given in

<?php session_start(); ?>
<?php require_once('Connections/config.php'); ?>
<?php
if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
{
if (PHP_VERSION < 6) {
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
}

$theValue = function_exists("mysqli_real_escape_string") ? mysqli_real_escape_string($connection_vote, $theValue) : mysqli_escape_string($connection_vote, $theValue);

    It means you need to do some debugging to figure out why $connection_vote is null when you make that call (maybe in your Connections/config.php file?).

    Correctly converting old DreamWeaver produced php code from using the mysql extension to using the mysqli extension is going to be a lot of work, because you should supply the connection variable as a parameter to each GetSQLValueString() call, in case you have multiple different database connections in your application. Given the specific name of the connection variable you have added to the mysqli statements, I suspect that you may have more than one connection in your application.

    If you are sure you don't have and will never have more than one database connection, you can use the GLOBAL keyword to access the connection inside the GetSQLValueString() function definition. You should also be getting an undefined variable error in addition to the error you are receiving. Perhaps the error_reporting on your system isn't set to E_ALL?

    Next, the logic in this function was never correct and the conversion you did to mysqli has added a problem -

    1) There was never a php version 6 and the logic test for it was never needed in this code. The get_magic_quotes_gpc() function (currently) exists and returns the correct value for the stripslashes logic to work for all current and past versions of php. However, magic_quotes was removed in php5.4, which was a long time ago and no one should be using such an old version, so there's no real need for the stripslashes logic at all.

    2) There is no mysqli_escape_string() function at all and the logic trying to pick between mysqli__real_escape_string() and mysqli_escape_string() won't work correctly. If the mysqli extension is not present, there will be no mysqli_real_escape_string() function (there won't be a mysqli connection either), and the logic will attempt to use mysqli_escape_string() which doesn't exist and will result in a fatal runtime error. The code should just directly use mysqli_real_escape_string().

    Lastly, if you are going to the trouble of converting old code, your time would be better spent converting it to use the php PDO extension and to use prepared queries when supplying data values to the sql query statement. Doing this will eliminate the GetSQLValueString function and its calls entirely and it will actually simplify the sql query syntax, while only adding one statement to the code, for the prepare() method call.

    pbismad 1) There was never a php version 6 and the logic test for it was never needed in this code. The get_magic_quotes_gpc() function (currently) exists and returns the correct value for the stripslashes logic to work for all current and past versions of php. However, magic_quotes was removed in php5.4, which was a long time ago and no one should be using such an old version, so there's no real need for the stripslashes logic at all.

    Which, to be clear, means that since PHP 5.4.0, get_magic_quotes_gpc() always returns false.

      NogDog thank you for your response. I have done some debugging and I can tell you that the problem is not from my Connections/config.php file.
      I think some else could be the problem.

        pbismad
        Thanks a lot for your detailed remark. I am trying to convert the page to PDO extension. won't that be better?
        but how do I go about it?

        thank you

          The reason the old mysql statements worked inside a function, was because php made the last mysql connection available globally. Only the mysql extension did this, so no other extension you use will work without doing more to get the connection into the function. My reply mentioned the two methods that can be used to get the connection into a function. The first method requires making changes to all of the function calls (and if those calls are inside of other functions, even more changes) and the second method has an issue if there is or will ever be more than one connection.

          The reasons for converting to use the php PDO extension are -

          1) It is simpler and more consistent than the msyqli extension, especially when using prepared queries. You should use prepared queries when supplying data to an sql query statement because it both simplifies the code (all code attempting to escape data, like the subject in this thread can be removed) and it simplifies the sql query syntax, while preventing sql injection. Sql injection is still possible when using the ...._escape_string() functions if the character set that php is using is not the same as the character set you are using in your database and it is rare that older code even sets up the character set.

          2) Once you learn the php statements needed for the PDO extension, with any database type, you can use those same statements with other database types. You will need to make any database type changes to the connection Data Source Name (DSN) and the sql queries, but the php statements will remain the same.

          To convert code to use the PDO extension, you will need to learn enough about the php PDO statements to be able to identify which ones to use and how to use them. The php.net documentation contains all the basic information you need to do this, along with examples.

          PDO uses OOP (Object Oriented Programming) classes. There are two PDO classes to learn, the PDO class and the PDOStatement class.

          For most simple web applications, you should start by looking at the documentation for the following -

          PDO class - __construct(), lastInsertId(), prepare(), query(), and setAttribute()
          PDOStatement class - execute(), fetch(), fetchAll(), and rowCount()

          When you make the connection you need to set the character set, set the error mode to exceptions (using exceptions for errors and let php catch the exception, will further simplify the code your have to write or covert), set emulated prepared queries to false, and set the default fetch mode to assoc. See the following typical connection code -

          $DB_HOST = 'localhost'; db host name/host ip - change to match your's
          $DB_USER = 'your_database_username';
          $DB_PASS = 'your_database_password';
          $DB_NAME = 'your_database_name';
          $DB_ENCODING = 'utf8'; // db character encoding - change to match your's
          
          $pdo = new pdo("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=$DB_ENCODING",$DB_USER,$DB_PASS);
          $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // set the error mode to exceptions
          $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); // run real prepared queries
          $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC); // set default fetch mode to assoc
          

          If you post an example of the query related code you are trying to convert, someone will show how it would look using the PDO extension and if it has data being supplied to the query, what a prepared query looks like.

          pbismad thanks and this is the code that i would like to convert to PDO extension from mysqli

          <?php session_start(); ?>
          <?php require_once('Connections/config.php'); ?>
          <?php
          if (!function_exists("GetSQLValueString")) {
          function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
          {
          if (PHP_VERSION < 7) {
          $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
          }

          $theValue = function_exists("GetSQLValueString") ? mysqli_real_escape_string($connection,$theValue) : mysqli_escape_string($connection, $theValue);

          switch ($theType) {
          case "text":
          $theValue = ($theValue != "") ? "'" . $theValue . "'" : "''";
          break;

          case "long":
          case "int":
          $theValue = ($theValue != "") ? intval($theValue) : "NULL";
          break;
          case "double":
          $theValue = ($theValue != "") ? doubleval($theValue) : "NULL";
          break;
          case "date":
          $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
          break;
          case "defined":
          $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
          break;
          }
          return $theValue;
          }
          }

          $colname_rstrack = "-1";
          if (isset($SESSION['trackid'])) {
          $colname_rstrack = $
          SESSION['trackid'];
          }
          mysqli_select_db($connection, $spider_money);
          $query_rstrack = sprintf("SELECT * FROM account WHERE Tracking_ID= %s", GetSQLValueString($colname_rstrack, "text"));
          $rstrack = mysqli_query($connection, $query_rstrack) or die(mysql_error());
          $row_rstrack = mysqli_fetch_assoc($rstrack);
          $totalRows_rstrack = mysqli_num_rows($rstrack);
          ?>
          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-GB"><head><meta content="Percussion Rhythmyx" name="generator"><title>AGES LOGISTICS</title><meta content="Rentokil Initial Web Development" name="author"><meta content="City Link" name="owner"><meta content="en-GB" http-equiv="content-language"><meta content="city link, courier, delivery, courier service, same day delivery, international delivery services" name="keywords" lang="en"><meta content="City Link - Premium Express Delivery Services, visit our site for courier services throught the uk and worldwide" name="description"><meta content="text/html; charset=utf-8" http-equiv="Content-Type"><link href="http://www.city-link.co.uk/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon"><link href="http://www.city-link.co.uk/favicon.ico" rel="icon" type="image/vnd.microsoft.icon"><link href="index_files/reset.css" media="screen, print" rel="stylesheet" type="text/css"><link href="index_files/main.css" media="screen, print" rel="stylesheet" type="text/css"><link href="index_files/mods.css" media="screen, print" rel="stylesheet" type="text/css"><link href="index_files/print.css" media="print" rel="stylesheet" type="text/css"><script src="index_files/jquery-latest.js" type="text/javascript"></script><script src="index_files/common.js" type="text/javascript"></script><!--[if lte IE 7]>
          <link rel="stylesheet" href="/static/c/ie.css" type="text/css" media="screen" />
          <script type="text/javascript" src="/static/j/ie_dom_hack.js"></script>
          <![endif]--><!--[if IE 7]>
          <link rel="stylesheet" href="/static/c/ie7.css" type="text/css" media="screen" />
          <![endif]-->
          <style type="text/css">
          a:link {
          color: #FFF;
          text-decoration: none;
          }
          a:visited {
          text-decoration: none;
          }
          a:hover {
          text-decoration: underline;
          }
          a:active {
          text-decoration: none;
          }
          </style>
          </head><body class="">
          <div class="contact_us_person">
          <table width="1112" border="0" align="center" cellpadding="0">
          <tr>
          <td width="1105" height="143"><div id="navimage">
          <div class="flash">
          <table width="512" border="0">
          <tr>
          <th height="139" scope="col"><img src="http://www.ycslogisticsinc.com/images/services_bo.jpg" alt="" width="565" height="137" align="top" /></th>
          <th scope="col"><img src="http://www.postnetcapetown.co.za/photos/courimg1.jpg" alt="" width="565" height="137" align="top" /></th>
          </tr>
          </table>
          </div>
          </div></td>
          </tr>
          </table>
          <table width="1114" align="center">
          <tr>
          <td height="28" align="center" valign="top"><div class="clearfix" id="main">
          <h2>
          <!-- <div style="border:2px solid #FD0;padding:0 1.2em 1.2em 1.2em;margin-top:1em;background:#FFC">
          <h1>Network Service Update - 31st December 2010</h1>
          <p>As the weather conditions have much improved across the UK we are now able to offer a normal collection and delivery service with the exception of our Ashford, Belfast, Cardiff, Durham, Glenrothes and Maidstone depots. <a href="/static/f/NSU-20101231.pdf">Please click here for more information</a>.</p>
          <p>A small number of our depots are currently unable to offer a 'collect from depot' service, <a href="/static/f/PCP-20101231.pdf">please click here for more information</a>.</p>
          <p>We apologise for any inconvenience this may cause and we thank you for your patience and understanding at this time.</p>
          </div> -->
          Your Parcel Details....................................................................................<a href="AGES Logistics – Moving Your Goods World-wide.html"> <font color="#FF0000">Logout</font></a></h2>
          </div></td>
          </tr>
          <tr bgcolor="#FADD05">
          <td height="399" align="center" valign="top" bgcolor="#13314C"><table width="1107" border="0" cellpadding="5">
          <tr align="center" valign="middle" bgcolor="#105631">
          <td width="132"><strong><font color="#FFFFFF">Parcel No.</font></strong></td>
          <td width="160"><strong><font color="#FFFFFF">From</font></strong></td>
          <td width="128"><strong><font color="#FFFFFF">To</font></strong></td>
          <td width="175"><strong><font color="#FFFFFF">Parcel Name</font></strong></td>
          <td width="143"><strong><font color="#FFFFFF">Status</font></strong></td>
          <td width="128"><strong><font color="#FFFFFF">Departure Date</font></strong></td>
          <td width="152"><strong><font color="#FFFFFF">Delivery Date</font></strong></td>
          </tr>
          <tr align="center" bgcolor="#FFFFFF">
          <td height="99"><strong><?php echo $row_rstrack['ParcelNo']; ?></strong></td>
          <td><strong><?php echo $row_rstrack['From']; ?></strong></td>
          <td><strong><?php echo $row_rstrack['To']; ?></strong></td>
          <td><strong><?php echo $row_rstrack['ParcelName']; ?></strong></td>
          <td><strong><?php echo $row_rstrack['Status']; ?></strong></td>
          <td><strong><?php echo $row_rstrack['date']; ?></strong></td>
          <td><strong><?php echo $row_rstrack['deldate']; ?></strong></td>
          </tr>
          </table>
          <p>&nbsp;</p>
          <table width="1108" border="0" cellpadding="0">
          <tr>
          <td width="208" height="83"><img src="http://www.ycslogisticsinc.com/images/currier.png" alt="" width="201" height="177" align="top" /></td>
          <td width="441" align="center"><img src="http://bluelineexpres.com/images/service.jpg" alt="" width="441" height="177" /></td>
          <td width="451"><img src="https://cdn.expertise.com/dir/courier-services.jpg" alt="" width="451" height="177" /></td>
          </tr>
          <tr>
          <td height="23">&nbsp;</td>
          <td align="right"><strong><blink>Always on time</blink></strong></td>
          <td>&nbsp;</td>
          </tr>
          </table></td>
          </tr>
          </table>
          </div>
          <script type="text/javascript">
          var firstTracker = gat.getTracker("UA-4697557-1");
          firstTracker.initData();
          firstTracker.
          trackPageview();
          var secondTracker = gat.getTracker("UA-4498214-1");
          secondTracker.initData();
          secondTracker.
          trackPageview();
          </script>
          </body></html>
          <?php
          mysqli_free_result($rstrack);
          ?>

            Try writing that again between ```triple backquotes`​`` so that it remains legible. Also try to cut down the irrelevant dross that need to wade through to find the query-related code you want us to actually look at. We don't for example, need all your CSS and HTML tables (P.S. does anyone actually still use IE7 these days?).

            Weedpacket
            '''<?php session_start(); ?>
            <?php require_once('Connections/config.php'); ?>
            <?php
            if (!function_exists("GetSQLValueString")) {
            function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
            {
            if (PHP_VERSION < 7) {
            $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
            }

            $theValue = function_exists("GetSQLValueString") ? mysqli_real_escape_string($connection,$theValue) : mysqli_escape_string($connection, $theValue);

            switch ($theType) {
            case "text":
            $theValue = ($theValue != "") ? "'" . $theValue . "'" : "''";
            break;

            case "long":
            case "int":
            $theValue = ($theValue != "") ? intval($theValue) : "NULL";
            break;
            case "double":
            $theValue = ($theValue != "") ? doubleval($theValue) : "NULL";
            break;
            case "date":
            $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
            break;
            case "defined":
            $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
            break;
            }
            return $theValue;
            }
            }

            $colname_rstrack = "-1";
            if (isset($SESSION['trackid'])) {
            $colname_rstrack = $SESSION['trackid'];
            }
            mysqli_select_db($connection, $spider_money);
            $query_rstrack = sprintf("SELECT * FROM account WHERE Tracking_ID= %s", GetSQLValueString($colname_rstrack, "text"));
            $rstrack = mysqli_query($connection, $query_rstrack) or die(mysql_error());
            $row_rstrack = mysqli_fetch_assoc($rstrack);
            $totalRows_rstrack = mysqli_num_rows($rstrack);
            ?>'''

            Backquotes, aka "backticks", are generally on the key with the tilde at the top keyboard left (could depend on locality). You used single quotes, not the same thing, won't help.

            And yeah, I'd prefer to avoid the markup as well. I fight enough of that at the office.

              This dreamweaver based code still has unnecessary and wasteful things and it is missing at least one important user experience thing.

              Mensah $colname_rstrack = "-1";
              if (isset($SESSION['trackid'])) {
              $colname_rstrack = $SESSION['trackid'];
              }

              The above code should be using $_SESSION and it should only run the SELECT query logic if the session variable isset(). Setting up a value to use in the query that won't be found in the data and running the SELECT query anyways wastes server resources and would produce php errors in the rest of the current code trying to use the result from the query.

              Mensah $totalRows_rstrack = mysqli_num_rows($rstrack);

              The program logic isn't even using the $totalRows_xxxx value, which it should be. If the query didn't find a matching row, the code should output a message on the page telling the user that the requested trackid wasn't found, instead of trying to display data that doesn't exist.

              Back to the problem at hand. The query has a data value being supplied to it, so, you need to use a prepared query. The following is what converting the existing sql query statement to a PDO prepared query would look like -

              $sql = "SELECT * FROM account WHERE Tracking_ID = ?"; // form the sql query statement with a ? place-holder for each value being supplied
              

              You would also get rid of the individual xxxx_select_db() statement(s), since the database is selected when the connection is made.

              You would then prepare and execute the query -

              $stmt = $pdo->prepare($sql); // prepare the query
              $stmt->execute([$_SESSION['trackid']]); // execute the query, with the value(s) supplied as an array parameter
              

              Since this query is expected to match at most one row, you would fetch the data using the fetch() method -

              $row_rstrack = $stmt->fetch();

              To calculate the $totalRows value, assuming you are going to change the code to use it, you can either use the following logic for a single row query or you can just directly test if the $row_rstrack is true or false at the point that you would output a message or use the existing output logic

              $totalRows_rstrack = $row_rstrack ? 1 : 0; - $totalRows_xxxx is not used in the current code
              

              For a query that is expected to match a set of data, that you would loop over, the above logic would instead use the fetchAll() method, would calculate the totalRows using count() on the array of fetched data, and the dreamweaver produced do/while loop would be converted into a foreach() loop.

              You would also remove the xxxx_free_result() statement at the end of the code. Unless you are dealing with multiple large result sets on a page, there's no need to do this and doing it for a single result right before the php script ends is pointless since php will destroy all variables/resources used on the page anyways.

                22 days later

                if we use prepared statement, do we still need to use mysqli_real_escape_string?

                  No. You no longer use any string escaping function in your code when you use a prepared query.

                  You should also start your own threads for your questions.

                  4 days later

                  pbismad

                  "You should also start your own threads"

                  While that is true & traditional (and good form), there's no place on this page you can click to do that as far as I can see. The main index, and the "t" script (comparable to vB's "forumdisplay.php" ) have "Start a Discussion" buttons, but I can't find it on the "d" pages (comparable to "showthread.php") ....

                  I think the new board software is going to make us re-think a few things. Or, at the very least, to see if we can attach .sigs with links to how to use it, similar to what we always did on vB ... and I don't see anyone using .sigs here now ... so ...

                  Write a Reply...