PHP和MySQL数据库搜索-从php代码中删除数据库凭据

时间:2018-09-07 02:15:11

标签: php mysql mysqli

我找到了一些使用PHP和MySQL进行简单数据库搜索的代码,并且能够使它工作。但是,我决定将数据库用户名和密码保留在根文件夹中的PHP代码中可能不是一个好主意。因此,我找到了另一个代码示例,该示例演示了如何在根外部创建config.ini文件,以及如何使用dbconnect.php文件访问数据库凭据。我尝试实现这一点,但是我没有任何运气,并且想知道是否有人可以向我展示我所缺少的东西(我只是对编码有基本的了解,并试图一点一点地学习)。我已经包含了所有组件文件的代码(并且我将所有用户名/密码/服务器名都更改为通用占位符)。在代码下方,我粘贴了提交搜索表单时当前显示的错误。谢谢!

index.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Search</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
        <form action="search.php" method="GET">
            <input type="text" name="query" />
            <input type="submit" value="Search" />
        </form>
    </body>
</html>

search.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Search</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <?php require_once('./includes/dbconnect.php'); ?>
    </head>
    <body>
        <?php
            $query = $_GET['query']; 

            // gets value sent over search form
            $min_length = 3;

            // you can set minimum length of the query if you want
            if(strlen($query) >= $min_length) { // if query length is more or equal minimum length then
                $query = htmlspecialchars($query); 

                // changes characters used in html to their equivalents, for example: < to &gt;
                $query = mysql_real_escape_string($query);

                // makes sure nobody uses SQL injection
                $raw_results = mysql_query("SELECT * FROM details WHERE (`title` LIKE '%".$query."%') OR (`text` LIKE '%".$query."%')") or die(mysql_error());

                // * means that it selects all fields
                // details is the name of our table
                // '%$query%' is what we're looking for, % means anything, for example if $query is Hello
                if(mysql_num_rows($raw_results) > 0) { // if one or more rows are returned do following
                    while($results = mysql_fetch_array($raw_results)) {

                        // $results = mysql_fetch_array($raw_results) puts data from database into array, while it's valid it does the loop
                        echo "<p><h3>".$results['title']."</h3>".$results['text']."</p>";

                        // posts results gotten from database(title and text) you can also show id ($results['id'])
                    }

                } else { // if there is no matching rows do following
                    echo "No results";
                }
            } else { // if query length is less than minimum
                echo "Minimum length is ".$min_length;
            }
    ?>
    </body>
</html>

dbconnect.php:

<?php
    function db_connect() {
        // Define connection as a static variable, to avoid connecting more than once 
        static $connection;

        // Try and connect to the database, if a connection has not been established yet
        if(!isset($connection)) {
            // Load configuration as an array. Use the actual location of your configuration file
            $config = parse_ini_file('/home/cpanelusername/private/config.ini');
            $connection = mysqli_connect($config['servername'],$config['username'],
            $config['password'],$config['dbname']);
        }

        // If connection was not successful, handle the error
        if($connection === false) {
            // Handle error - notify administrator, log to a file, show an error screen, etc.
            return mysqli_connect_error(); 
        }

        return $connection;
    }

    // Connect to the database
    $connection = db_connect();

    // Check connection
    if ($connection->connect_error) {
        die("Connection failed: " . $connection->connect_error);
    }
?> 

config.ini:

[database]
servername = localhost
username = username
password = password
dbname = username_database
  

警告:mysql_real_escape_string():拒绝用户访问   根目录中的'root'@'localhost'(使用密码:NO)   /home4/cpanelusername/public_html/...../search.php,第29行

     

警告:mysql_real_escape_string():无法链接到服务器   在/home4/cpanelusername/public_html/......./search.php中建立   第29行

     

警告:mysql_query():拒绝用户“ root” @“ localhost”的访问   (使用密码:否)在   /home4/cpanelusername/public_html/......../search.php,第33行

     

警告:mysql_query():无法建立到服务器的链接   在/home4/cpanelusername/public_html/......./search.php在第33行   用户'root'@'localhost'的访问被拒绝(使用密码:NO)

2 个答案:

答案 0 :(得分:-1)

这是因为mysql_real_escape_string考虑了连接的当前字符集。因此,它需要一个连接。 :-)

请尝试使用以下代码连接数据库,如果有任何问题,请告诉我。

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

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

答案 1 :(得分:-2)

清除来自用户区的字符串不足以防止SQL注入攻击。标准方法是使用准备好的查询。例如:

    $stmt = mysqli_stmt_init($this);
    $result = array();
    $okay = mysqli_stmt_prepare($stmt, "SELECT * FROM details WHERE (title LIKE ?) OR (text LIKE ?)");
    if ($okay)
        $okay = mysqli_stmt_bind_param($stmt, "ss", "%$query%", "%$text%")
    else
        [handle error]
    if ($okay)
        $okay = mysqli_stmt_execute($stmt);
    else
        [handle error]
    if ($okay)
        $okay = mysqli_bind_result($stmt, $row);
    else
        [handle error]
    if ($okay)
        while (mysqli_stmt_fetch($stmt))
            array_push($result, $row);
    else
        [handle error]
    mysqli_stmt_close($stmt);