Это решение отлично работает, но оно не сработает, если вы используете PHPunit для модульного тестирования.
Использование пароля в командной строке генерирует предупреждение, которое перехватывается PHPUnit, и генерирует исключение (дадовольно большое дело ...)
Чтобы обойти это, используйте файл конфигурации.
В моем случае я не хочу сохранять пароль и пользователя как в файлах конфигурации, так и в коде PHP, поэтому я генерирую файл конфигурации из кода и проверяю, существует ли он (в противном случае я использую имя пользователя ипароль непосредственно в командной строке как резервный вариант).
Вот пример, в PHP, как скопировать базу данных установки, чтобы создать новую с другим именем (например, если вы управляетеосновной домен с отдельным поддоменом / базой данных для каждого вашего клиента):
/**
* If the $dbName doesn't exist, then create it.
*
* @param $errorMessage String to return the error message.
* @param $dbName String name of the database to create.
* @param $cleanExisting Boolean if the database exist, clear it to recreate it.
*
* @return boolean ($dbExists)
*/
private function createDatabase(&$errorMessage, $dbName, $clearExisting = false){
$command = "";
$configurationString = "[client]" . "\r\n" . "user=" . parent::$support_user . "\r\n" . "password=" . md5(parent::$support_pass);
$dbExist = false;
$path = realpath(dirname(__FILE__));
$connectionString = " --defaults-extra-file=" . $path . "\mysql.cnf ";
$dbName = strtolower($dbName);
if ($this->isDestinationDbNameValid($errorMessage, $dbName)) {
$dbExist = $this->isDestinationDbExist($errorMessage, $dbName);
if (empty($errorMessage) and ($dbExist === false or $clearExisting === true)) {
if (file_put_contents($path . '/mysql.cnf', $configurationString) === false) {
$connectionString = " --user=" . parent::$support_user . " --password=" . md5(parent::$support_pass). " ";
}
if ($dbExist and $clearExisting) {
$command = $path . '/../../../mysql/bin/mysql ' . $connectionString . ' --execute="DROP DATABASE ' . $dbName .';" &';
}
$command .= '"' . $path . '/../../../mysql/bin/mysql" ' . $connectionString . ' --execute="CREATE DATABASE ' . $dbName . ';" &"' .
$path . '/../../../mysql/bin/mysqldump" ' . $connectionString . ' --events --triggers --routines setup | "' .
$path . '/../../../mysql/bin/mysql" ' . $connectionString . $dbName;
exec($command);
$dbExist = $this->isDestinationDbExist($errorMessage, $dbName);
if (!$dbExist) {
$errorMessage = parent::getErrorMessage("COPY_SETUP_DB_ERR", "An error occurred during the duplication process of the setup database.");
}
}
}
return $dbExist;
}
Дополнительные примечания:
Мне пришлось использовать двойную кавычку (") вместоодиночные кавычки (') вокруг моих операторов SQL.
Мне пришлось использовать амперсанд (&) для разделения моей другой команды.
Thisпример не включает проверку для нового имени базы данных (метод isDestinationDbNameValid ()). Не нужно упоминать, что вы никогда не должны доверять пользовательскому вводу ...
Вы также должны написатьваш собственный метод для valукажите, что копия базы данных работала должным образом (метод isDestinationDbExist ()).Вы должны по крайней мере подтвердить, что база данных существует, таблица из вашей настройки существует и, опционально, проверить для сохраненных программ.
Используйте силу мудро, друзья мои,
Джонатан Родитель-Левеск из Монреаля