PHP mysql_real_escape_string():用户'www-data'@'localhost'被拒绝访问。

4

我刚刚将我的网站上传到生产服务器上,但出现了以下错误:

Warning: mysql_real_escape_string(): Access denied for user 'www-data'@'localhost' (using password: NO) in file.php on line 106

Warning: mysql_real_escape_string(): A link to the server could not be established in file.php on line 106

该函数的代码是

include('./../inc/conn.php');
if(isset($_GET['query']))$q = clean($_GET['query']);
function clean($var){
    return(mysql_real_escape_string($var));
}   

inc/conn.php的代码:

try {
  $dns = 'mysql:host=localhost;dbname=mydatabase';
  $user = 'root';
  $pw = 'rootpw';

  $options = array(
    PDO::MYSQL_ATTR_INIT_COMMAND    => "SET NAMES utf8",
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
  );

  $db = new PDO( $dns, $user, $pw, $options );
} catch ( Exception $e ) {
    echo "Connection error : ", $e->getMessage();
    die();
}

我真的不知道发生了什么事情,因为我的本地开发Ubuntu服务器没有任何问题。Mysql、apache和php版本都是一样的。唯一的区别是我在apache生产服务器上使用虚拟主机。不知道出了什么问题……在apache或php配置中是否有我遗漏的东西? 编辑 这是我的文件夹权限:
sudo ls -l /home/user/public/domain.com/www/
total 28
drwxrwxr-x 13 user www-data 4096 Aug 22 12:30 adodb5
drwxrwxr-x  2 user www-data 4096 Aug 22 12:30 ajax
drwxrwxr-x  2 user www-data 4096 Aug 22 12:31 css
drwxrwxr-x  9 user www-data 4096 Aug 22 12:33 gfx
drwxrwxr-x  2 user www-data 4096 Aug 22 12:33 inc
drwxrwxr-x  2 user www-data 4096 Aug 22 12:34 js

我的Apache虚拟主机配置

<VirtualHost *:80>
  # Admin email, Server Name (domain name), and any aliases
  ServerAdmin contact@domain.com
  ServerName  www.domain.com
  ServerAlias domain.com

  # Index file and Document Root (where the public files are located)
  DirectoryIndex index.html index.php
  DocumentRoot /home/user/public/domain.com/www
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /home/user/public/domain.com/www>
                Options FollowSymLinks
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            Order allow,deny
            Allow from all
    </Directory>

  # Log file locations
  LogLevel warn
  ErrorLog  /home/user/public/domain.com/log/error.log
  CustomLog /home/user/public/domain.com/log/access.log combined
</VirtualHost>

编辑2

好的,问题是我在mysql服务器上没有任何www-data用户。所以我只需在mysql中添加无密码和无特权的用户www-data,这样就可以正常工作了。将来我将尝试使用多数人提到的PDO引用。 感谢所有试图帮助我的人。


3
你为什么在使用PDO时要使用mysql_real_escape_string - Yogesh Suthar
1
在生产服务器上使用root用户,是吗? - Cathedral Zealot
你应该拥有生产服务器环境的访问权限。如果你是特权用户,请询问管理员。 - user1502952
@CathedralZealot 好的,我发现我需要使用 grant all on exampleDB.* to 'example_user' identified by 'pw'; 然后在我的连接脚本中使用它。 - Tamere Jlanik
这需要一个有效的MySQL连接处于活动状态。请参阅答案。 - Amal Murali
显示剩余8条评论
5个回答

11
你可以选择使用PDO或mysql扩展,但不要同时使用两者。函数mysql_real_escape_string是mysql扩展的一个功能,需要连接到数据库才能使用。调用此函数时,如果没有先使用mysql_connect建立连接,则它会尝试建立连接,并猜测所需的登录凭据。在你的本地机器上,显然没有密码保护,MySQL用户的帐户名称与Web服务器运行的名称相同,因此它可以幸运地工作。但在生产系统中,凭据是不同的,它无法建立连接。
停止在PDO中使用mysql_real_escape_string,而应使用PDO的字符串引用函数或更好的方法是使用预处理和参数化查询以及bind您的值

你很棒。我也遇到了同样的问题,通过添加到mysql的连接来解决mysql_real_escape_string问题。只需在正常连接后,在配置文件中的某个位置添加mysql_connect('localhost', 'mysql_user', 'mysql_password');即可。或者像我将来要做的那样,将所有的mysql_real_escape_string转换为PDO::quotebind - caglaror
2
请注意,那绝对不是一个解决方案!如果您正在使用PDO,请勿使用mysql_real_escape_string!没有商量! - deceze

3
mysql_real_escape_string需要一个有效的链接标识符(由mysql_connect()返回),请参见http://php.net/manual/en/function.mysql-real-escape-string.php

link_identifier: MySQL连接。如果未指定链接标识符,则假定为mysql_connect()打开的最后一个链接。如果没有找到这样的链接,它将尝试创建一个,就好像调用了没有参数的mysql_connect()函数一样。如果未找到或建立任何连接,则会生成一个E_WARNING级别的错误。

您的连接是通过PDO打开的,因此您没有任何有效的链接标识符可供使用mysql_real_escape_string

尝试使用PDO :: quote


请检查您的本地用户名,它是否作为用户存在于您的MySQL开发服务器上?您的生产服务器上是否有一个名为www-data的用户且没有密码? - Oliver
不,它不存在。我认为这就是为什么它无法工作的原因。那个用户需要什么样的特权? - Tamere Jlanik
www-data用户缺失了!现在它可以工作了。所以看起来PDO使用mysql_connect? - Tamere Jlanik
PDO::quote()是一个实例方法,不能静态调用。致命错误:非静态方法PDO :: quote()无法静态调用 - Stan

1
当数据库连接设置为mysqli时,通常会出现此问题。要解决此问题并使用mysql_real_escape_string(),即使设置了mysqli,请转到php.ini并查找:mysql.default_user参数,并将值设置为默认用户,例如:mysql.default_user = root,然后重新启动apache,你的问题现在已解决..享受吧。

1
当我尝试修改Wordpress后台的用户搜索时,遇到了同样的问题,缺乏适当的数据库连接(同时mysql_real_escape_string()已被弃用)。全局变量在wp-config.php中定义。
这是有效的函数。请注意$con变量。可以在这里找到更多解释。
if(is_admin()) {


add_action( 'pre_user_query', 'user_search_by_email' );
  function user_search_by_email($wp_user_query) {
    if(false === strpos($wp_user_query->query_where, '@') && !empty($_GET["s"])) {
      $con = mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME);
      $wp_user_query->query_where = str_replace(
              "user_nicename LIKE '%".mysqli_real_escape_string($con, $_GET["s"])."%'",
              "user_nicename LIKE '%".mysqli_real_escape_string($con, $_GET["s"])."%' OR user_email LIKE '%".mysqli_real_escape_string($con, $_GET["s"])."%'",
              $wp_user_query->query_where);
      mysqli_close($con);

    }
    return $wp_user_query;
  }
}

-14
请注意,这个答案很糟糕,会让您面临安全漏洞。这不是正确的解决方案,请不要这样做。请继续阅读以获取问题的实际解决方案。这个答案被接受只意味着两个人都不知道他们在做什么。
这是因为你的mysql数据库中没有www-data用户!
您可以通过phpmyadmin添加www-data用户,并给该用户不赋予权限,然后它应该可以工作。

9
最糟糕的回答。它对问题一无所知,并提出了一个有负面安全影响的可怕解决方案。当然,它被接受了。 捂脸 - deceze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接