在共享主机上使用PHP创建并导入MySQL数据库

3

我正在尝试编写一个PHP脚本,它可以:

  • 连接到mysql
  • 创建数据库
  • 创建用户和密码
  • 将用户添加到数据库
  • 将准备好的SQL文件导入到数据库中

问题在于它将位于共享主机上(我正在尝试使其通用并与不同的主机一起使用)。我猜数据库和数据库用户将以我的帐户名称为前缀(我用它来进行ftp、登录控制面板等)?像mylogin_dbname和mylogin_dbuser这样的东西。例如,在cpanel中可见-当我添加数据库时,我输入它的名称,创建后cpanel将其显示为mylogin_somedb。如何使我的脚本在多个不同的共享主机上自动添加我的前缀,具体取决于我的主要登录方式?

现在正在使用这样的代码(不知道它是否有效,这只是我想到的):

<?php
mysql_connect("host", "user", "password"); // Connection to MySQL

$query = "CREATE DATABASE somedb;
USE somedb;
SOURCE path/to/sqlfile.sql;
CREATE USER someuser IDENTIFIED BY PASSWORD 'somepass';
GRANT SELECT,INSERT,UPDATE,DELETE ON somedb.* TO 'someuser'@'host';";

$arr= explode( ';', $query );
foreach( $arr as $command )
{
mysql_query( $command );
}  
mysql_close(); // Disconnection from MySQL
?>

1
我使用过的许多共享主机都不允许您从控制面板以外的任何其他地方创建数据库或用户,这也是需要考虑的事情。 - grapefrukt
4个回答

1

使用mysql_error()函数http://us3.php.net/manual/en/function.mysql-error.php

这样你就可以看到出了什么问题。

例如:

if (mysql_query( $command ) === false) {
  echo mysql_error();
  die;
}

对于mysql_connect()也是一样的

if (($link = mysql_connect("host", "user", "password")) === false) {
  echo mysql_error();
  die;
}

您必须确保使用的用户具有创建数据库的权限。

对于CPanel,我相信您必须使用您的帐户用户名和密码。然后像您所说的那样,在您的用户名前缀下添加您的数据库名称,否则将无法创建。


1

KISS原则:只需使用phpMyAdmin?它几乎肯定已安装。如果没有安装,请安装它。

它的导入功能非常棒。如果您的数据库太大,可以gzip压缩它。如果仍然太大,请尝试将其分成几个部分。我怀疑您是否需要将其作为单个大事务传输?


在第一条评论的解释之后,我们来看看吧。这是我的非常简单的脚本,可以做到你想要的事情。但它没有考虑分隔符:一个查询等于一行。
<link rel="stylesheet" href="style/contents.css"/>
<?

function timesanitize($v) {
    if ($v > 0)
        return round($v, 4);
    else
        return 0;
}

$startmt = microtime();
include_once 'include/db.php';
$f = fopen("db.sql","r");
echo dbGetEngine() . "<br>";
echo "<ul>";
do {
    $l = rtrim(fgets($f));
    if (strlen($l) == 0)
        continue;
    if (substr($l, 0, 1) == '#')
        continue;
    $l = str_replace(
        array("\\n"),
        array("\n"),
        $l);
    if (dbGetEngine() == "pgsql")
        $l = str_replace(
            array("IF NOT EXISTS", "LONGBLOB"),
            array("", "TEXT"),
             $l);
    try {
        echo "<li>".nl2br(htmlspecialchars($l));
        $mt = microtime();
        $db->query($l);
        echo "<ul><li>ok - " . timesanitize(microtime() - $mt) . "</ul>";
    } catch (PDOException $e) {
        echo "<ul><li>".$e->getMessage() . "</ul>";
    }
} while (!feof($f));
fclose($f);

echo 'total: ' . timesanitize(microtime() - $startmt);
?>

它还输出了每个查询花费的时间的小统计信息。它基于PDO;我相信PDO是在PHP5.1或PHP5.2中引入的。如果您出于某种原因更喜欢直接使用mysql_*()函数,我认为将其修改为与之兼容应该很容易。

再次强调:是的,我知道它很糟糕。但只要它对我(和可能对您)有效... :-)


为了完成代码,这里有include/db.php和一个示例include/config.php:

include/db.php:

<?
include_once 'include/config.php';

try {

        $attribs =  
                array(
                        PDO::ATTR_PERSISTENT => $config['db']['persistent'],
                        PDO::ATTR_ERRMODE => $config['db']['errormode']
                );


        $db = new PDO(
                $config['db']['uri'],
                $config['db']['user'],
                $config['db']['pass'],
                $attribs
        );
        $db->query("SET NAMES 'utf8'");
        $db->query("SET CHARACTER SET 'utf8'");

} catch (PDOException $e) {
        print "Error!: " . $e->getMessage() . "<br/>";
        die();
}

function dbGetEngine() {
        global $config;
        return substr($config['db']['uri'], 0, strpos($config['db']['uri'], ':'));
}
?>

include/config.php:

<?

//$config['db']['uri'] = 'sqlite:' . realpath('.') . '/site.db'; // PDO's database access URI
$config['db']['uri'] = 'mysql:host=localhost;dbname=sitedb'; // server should be : 195.78.32.7
//$config['db']['uri'] = 'pgsql:host=localhost;dbname=sitedb';
$config['db']['user'] = 'user_goes_here'; // database username
$config['db']['pass'] = 'pass_goes_here'; // database password
$config['db']['persistent'] = false; // should the connection be persistent
$config['db']['errormode'] = PDO::ERRMODE_EXCEPTION; // PDO's error mode

?>

本文提供了SQLite、MySQL和PostgreSQL的连接字符串示例。


我正在尝试制作通用脚本并避免使用phpmyadmin curl(尽管如果grapefrukt所说的在我的主机上会有问题,我想curl将是我的唯一选择)。这将是一个用于多个网站的脚本,而不是仅限于一个网站。 - Phil
谢谢 :). include_once 'include/db.php'; 中包含了什么?我在哪里指定要创建的数据库名称、用户名等信息? - Phil
db.php包含数据库初始化例程。 叹气我会把它们放在上面;这是与PDO相关的东西,但代码应该立即运行 :-) - Ivan Vučica
顺便提一下,另一个简单的想法。 它将防止您甚至在字符串中使用分号,但是这里有:$lines = explode(';',file_get_contents($filename)); 然后foreach($lines as $line)$db->query($line); --或类似的东西。 我认为这很显然 :-) - Ivan Vučica
需要测试一下,但我认为你的评论是个好答案(我的意思是...有很多代码!非常有帮助 xD)。 - Phil

1

在我的观点中,这是在共享主机上并不会有太大的区别。无论您的环境如何,您都必须使用您的用户名,根据托管设置,数据库名称将被添加前缀或不添加前缀。话虽如此,最好采用以您的用户名为前缀或其他前缀命名约定。

至于您要尝试做什么,我有一些建议:

  1. 您应该单独运行每个语句(就像您所做的那样),但在每个步骤之间添加错误检查,以便在没有为数据库创建时不尝试源文件。
  2. 也许为每种操作创建单独的函数,并发送参数以获取值。这将在较长时间内清理代码。
  3. 如果您遇到自动添加前缀到您提供的名称的情况,并且您必须检测最终名称,则可以执行“show databases;”查询并在结果中搜索您提供的名称。然后使用完整名称进行结果查询。

0
关于导入,如果上传限制是一个问题,至少有一种替代方案可以使用,它允许您选择在 Web 服务器上的文件而不是上传它。例如,adminer(adminer.org)就提供了这样的功能。在 adminer 中,点击“SQL 命令”,然后点击“从服务器”。

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