我正在寻找备份MySQL数据库。在命令行中输入以下命令后,它将起作用:
SELECT * INTO OUTFILE 'backup.txt' FROM table_name;
创建文件backup.txt。一切都很好。
当上述命令通过MySQL查询提交到php文件中时:
mysql_query("SELECT * INTO OUTFILE 'backup.txt' FROM table_name");
这是行不通的。没有创建文件backup.txt。
接下来,查看特权,并使用命令行输入以下命令:
GRANT FILE ON *.* TO 'root'@'localhost';
该命令已被接受,但MySQL查询仍然无法正常工作。
完整的php文件如下所示:
// connect to db host
//mysql_connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD)
$connection = mysql_connect("localhost", "mysql -u root", "")
or die('Could not connect: ' . mysql_error($connection));
// select db
$db = mysql_select_db("test", $connection);
// change privileges
mysql_query("GRANT FILE ON *.* TO 'root'@'localhost'");
// create query
$query = "SELECT * INTO OUTFILE 'backup.txt' FROM table_name";
//perform query
mysql_query($query);
// close mysql connection
mysql_close($connection);
谁能解释这里发生的事情以及如何使MySQL查询工作并创建输出文件backup.txt。
Windows计算机上正在使用WampServer。
最佳答案
在我运行mysql命令行(MCL)的那一刻,我是一个o / s用户,它在一定程度上具有对所有o / s目录的权限(我们称它们为凭据的凭据)。假设信誉在这段代码尝试期间没有改变,无法想象它们会改变。关键是,我就是那些有信誉的用户。
没有像您一样的完整或相对路径,MCL会在outfile调用中写入模式的数据目录。因此,例如在我的系统上
C:\Users\All Users\MySQL\MySQL Server 5.6\data\so_gibberish
其中so_gibberish是我要通过
use so_gibberish
命令进入或作为db提供的模式/数据库名称,以便在通过开关运行mysql命令行时使用。否则,它将相当于一些Linux路径。通过MCL,我将进入db(
use
),而不是没有use
的MCL连接。这意味着我很可能在进入数据库沙箱之前就不会发出outfile命令(我稍后会指出这一点,因为它与错误1046有关)。而且您的命令会将.txt文件转储到了我的系统上(上述路径向上)。在我的测试中确实如此。现在开始使用PHP。
如果您正在运行连接但未使用
mysql_select_db
函数的PHP脚本,则错误1046:未选择数据库
仅当您运行下面的代码来检查错误时,该方法才会返回:
<?php
//error_reporting(E_ALL);
//ini_set('display_errors', 1);
...
... (load credential variables used below)
...
$link = mysql_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
//mysql_select_db($dbname) or die("Could not open the db '$dbname'");
echo "I made it here<br/>";
$test_query = "SELECT * INTO OUTFILE 'file456.txt' FROM mytable";
$result = mysql_query($test_query);
echo mysql_errno($link) . ": " . mysql_error($link) . "<br>";
mysql_close($link);
并不是说人们倾向于检查错误。我打赌你不在这个电话里。他们只是想着一切都很好。
请注意,尽管error_reporting对此没有影响。影响它的是您是否要在
mysql_query
之后检查错误。您可以像我一样撤消或清除rems并测试该理论。因此,您可能会收到1046错误,却不知道。现在,对于哪些操作系统用户来说,情况如此,因此,证明php到mysql进程伪装成一种信誉。这是由原始设置驱动的。现在为什么这很重要?因为该用户/凭据与操作系统提示时使用的凭据完全不同,所以您使用MCL完成了第一部分。
可能是通过php创建的文件,但是由于您未使用文件的完整路径进行路径查找,而只是文件名,因此如果您要检查错误和没有人到达。为了测试该理论,请在没有完整路径的mysql_user之后包含上述错误检查,并进行目录扫描以找到它。
因此,在我的测试中,在MCL中我写出file123.txt,在php中我写出file456.txt(或其他)。除非有任何错误消息,否则我将扫描文件系统以查看它们的显示位置。
您不会是第一个认为OUTFILE失败的人,只是稍后,也许是几个月后,在某个目录中找到残留文件,并产生了一个尤里卡的时刻:哦,是的,我记得那些文件,它们在这里做什么?
可能是由于PHP发出的问题导致调用完全失败,这与用户或组环境或某些其他设置chmod问题有关。
通过PHP,如果伪装的o / s用户具有信誉,则完全路径到输出文件(例如/full/path/here/out123.txt)可能是一个很好的解决方案。但是,在托管环境中,您不能简单地说成/tmp/out123.txt,因为在那里您将获得权限失败。因此,没有您需要的像样的修补课程,就没有广泛的笔触“插入此答案”可以解决该问题。
因此,对于PHP来说,总而言之,我将研究以下内容:
该文件正在被写出,您只是不知道在哪里。
文件失败,但是您不知道,因为之后没有错误检查
mysql_query(例如一般的mysql错误,未选择数据库,
随你)。
由于OS用户从PHP伪装成Creds问题
mysql,因此在o / s文件系统级别具有信誉
文件I / O。
至于错误1221错误(如注释中所述并链接到该部分),您不能在单个数据库上授予文件权限。提供了该答案类型here
关于php - 无法更改MySQL数据库的权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32803559/