安装

phpMyAdmin 不会在 MySQL 数据库服务器上应用任何特别的安全措施。正确设置 MySQL 数据库的权限是系统管理员应该做的。phpMyAdmin 的 用户 页面可以帮助系统管理员设置权限。

Linux发行版

phpMyAdmin包含在大多数Linux发行版中。建议尽可能使用分发包 - 它们通常提供与您的发行版的集成,并且您将自动从您的发行版中获取安全更新。

Debian 和 Ubuntu

大多数 Debian 和 Ubuntu 版本中包含了 phpMyAdmin 软件包,但要注意配置文件是在 /etc/phpmyadmin 中维护的,并且可能在某些方面与官方的phpMyAdmin文档有所不同。具体来说它包括:

更多安装 Debian 或 Ubuntu 软件包的信息在`我们的 wiki <https://github.com/phpmyadmin/phpmyadmin/wiki/DebianUbuntu>`_ 页面有进一步的说明。

参见

更多信息可以在 README.Debian 中找到(它通过包安装到了 /usr/share/doc/phmyadmin/README.Debian)。

OpenSUSE

OpenSUSE已经附带了 phpMyAdmin 包,只需从 openSUSE Build Service 获取包。

Gentoo

Gentoo提供phpMyAdmin软件包,包括成品配置和 webapp-config 配置。使用 emerge dev-db/phpmyadmin 进行安装。

Mandriva

Mandriva在 contrib 分支中搭载着 phpMyAdmin 软件包,可以从通常的控制中心中安装。

Fedora

Fedora 搭载有phpMyAdmin软件包,但注意配置文件放在 /etc/phpMyAdmin/ 中,并且可能会和官方phpMyAdmin文档有不同。

红帽 Linux 企业版

红帽 Linux 企业版本身以及 CentOS 这样的衍生产品并没有搭载 phpMyAdmin,但 Fedora 驱动的软件库 Extra Packages for Enterprise Linux (EPEL) 包含了它,如果 它被启用 。但要注意的是,配置文件在 /etc/phpMyAdmin/ 中维护,可能在某些方面与官方的 phpMyAdmin 文档不同。

Windows安装

在Windows上获得phpMyAdmin最容易的方法是使用带有phpMyAdmin、数据库和网络服务器的第三方产品,比如 XAMPP

您可以从 维基百科(英文) 中找到更多这样的选择。

从Git安装

为了从 Git 安装,您需要一些支持的应用:

你可以从 https://github.com/phpmyadmin/phpmyadmin.git 克隆当前的phpMyAdmin源代码:

git clone https://github.com/phpmyadmin/phpmyadmin.git

此外,您需要使用 Composer 来安装依赖项:

composer update

如果您不打算开发,可以通过调用以下命令跳过开发人员工具的安装:

composer update --no-dev

最终,你需要用 Yarn 安装一些 JavaScript 依赖:

yarn install --production

用Composer安装

您可以使用 Composer tool 安装phpMyAdmin,因为4.7.0版本会自动镜像到默认的 Packagist 存储库。

注解

Composer存储库的内容是自动生成的,因此内容不必与下载tarball时的内容完全相同。但是应该没有功能上的差异。

要安装phpMyAdmin,只需运行:

composer create-project phpmyadmin/phpmyadmin

或者,您可以使用我们自己的composer存储库,其中包含发行版tar包,可从<https://www.phpmyadmin.net/packages.json>获取:

composer create-project phpmyadmin/phpmyadmin --repository-url=https://www.phpmyadmin.net/packages.json --no-dev

用Docker安装

phpMyAdmin 附带了一个可供轻松部署的 Docker 官方镜像 ,您可以使用以下方式下载它:

docker pull phpmyadmin

phpMyAdmin 服务器将监听端口 80。它支持几种配置数据库服务器链接的方法,可以通过 Docker 的链接功能将数据库容器链接到 phpMyAdmin 的 db (通过指定 --link your_db_host:db 参数)或环境变量(在这种情况下,由您决定在 Docker 中设置网络以允许 phpMyAdmin 容器通过网络访问数据库容器)。

Docker环境变量

您可以使用环境变量配置多个phpMyAdmin功能:

PMA_ARBITRARY

允许您在登录表单上输入数据库服务器主机名。

PMA_HOST

要使用的数据库服务器的主机名或IP地址。

PMA_HOSTS

用逗号分隔的主机名或要使用的数据库服务器的 IP 地址。

注解

仅在 PMA_HOST 为空的时候使用。

PMA_VERBOSE

数据库服务器的详细名称。

PMA_VERBOSES

逗号分隔的数据库服务器的详细名称。

注解

仅在 PMA_VERBOSE 为空的时候使用。

PMA_USER

用于 Config 认证方式 的用户名。

PMA_PASSWORD

用于 Config 认证方式 的密码。

PMA_PORT

要使用的数据库服务器的端口。

PMA_PORTS

要使用的数据库服务器的逗号分隔端口。

注解

仅在 PMA_PORT 为空的时候使用。

PMA_SOCKET

Socket file for the database connection.

PMA_SOCKETS

Comma-separated list of socket files for the database connections.

注解

Used only if PMA_SOCKET is empty.

PMA_ABSOLUTE_URI

完全可信的路径(https://pma.example.net/),其中的反向代理使phpMyAdmin可用。

PMA_QUERYHISTORYDB

当设置为 true 时,启用将 SQL 历史存储至 $cfg['Servers'][$i]['pmadb'] 中。如果为 false ,历史会存储在浏览器中,当登出系统时会清除。

PMA_QUERYHISTORYMAX

当设置为整数值时,控制历史条目的数量的显示。

PMA_CONTROLHOST

When set, this points to an alternate database host used for storing the “phpMyAdmin配置存储” database.

PMA_CONTROLUSER

Defines the username for phpMyAdmin to use for the “phpMyAdmin配置存储” database.

PMA_CONTROLPASS

Defines the password for phpMyAdmin to use for the “phpMyAdmin配置存储” database.

PMA_CONTROLPORT

如果设置了此选项,会覆盖连接至控制主机的默认端口( 3306 )。

PMA_PMADB

When set, define the name of the database to be used for the “phpMyAdmin配置存储” database. When not set, the advanced features are not enabled by default: they can still potentially be enabled by the user when logging in with the 零配置 feature.

注解

Suggested values: phpmyadmin or pmadb

HIDE_PHP_VERSION

如果定义了本选项,会隐藏 PHP 版本(expose_php = Off ),设置为任何值(例如 HIDE_PHP_VERSION=true )。

UPLOAD_LIMIT

If set, this option will override the default value for apache and php-fpm (this will change upload_max_filesize and post_max_size values).

注解

Format as [0-9+](K,M,G) default value is 2048K

MEMORY_LIMIT

If set, this option will override the phpMyAdmin memory limit $cfg['MemoryLimit'] and PHP’s memory_limit.

注解

Format as [0-9+](K,M,G) where K is for Kilobytes, M for Megabytes, G for Gigabytes and 1K = 1024 bytes. Default value is 512M.

MAX_EXECUTION_TIME

If set, this option will override the maximum execution time in seconds for phpMyAdmin $cfg['ExecTimeLimit'] and PHP’s max_execution_time.

注解

Format as [0-9+]. Default value is 600.

PMA_CONFIG_BASE64

If set, this option will override the default config.inc.php with the base64 decoded contents of the variable.

PMA_USER_CONFIG_BASE64

If set, this option will override the default config.user.inc.php with the base64 decoded contents of the variable.

PMA_UPLOADDIR

If set, this option will set the path where files can be saved to be available to import ($cfg['UploadDir'])

PMA_SAVEDIR

If set, this option will set the path where exported files can be saved ($cfg['SaveDir'])

APACHE_PORT

If set, this option will change the default Apache port from 80 in case you want it to run on a different port like an unprivileged port. Set to any port value (such as APACHE_PORT=8090).

默认情况下,使用 Cookie 认证方式,但如果 PMA_USERPMA_PASSWORD 已设置,则切换到 Config 认证方式

注解

您需要登录的凭据存储在 MySQL 服务器中,如果是 Docker 镜像,则有多种方法可以设置它(例如:启动 MySQL 容器时的 MYSQL_ROOT_PASSWORD)。请查看 MariaDB容器MySQL容器 的文档。

自定义配置

Additionally configuration can be tweaked by /etc/phpmyadmin/config.user.inc.php. If this file exists, it will be loaded after configuration is generated from above environment variables, so you can override any configuration variable. This configuration can be added as a volume when invoking docker using -v /some/local/directory/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php parameters.

Note that the supplied configuration file is applied after Docker环境变量, but you can override any of the values.

For example to change the default behavior of CSV export you can use the following configuration file:

<?php
$cfg['Export']['csv_columns'] = true;

You can also use it to define server configuration instead of using the environment variables listed in Docker环境变量:

<?php
/* Override Servers array */
$cfg['Servers'] = [
    1 => [
        'auth_type' => 'cookie',
        'host' => 'mydb1',
        'port' => 3306,
        'verbose' => 'Verbose name 1',
    ],
    2 => [
        'auth_type' => 'cookie',
        'host' => 'mydb2',
        'port' => 3306,
        'verbose' => 'Verbose name 2',
    ],
];

参见

有关配置选项的详细说明,请参阅 设置

Docker 容器

You can use the following volumes to customize image behavior:

/etc/phpmyadmin/config.user.inc.php

Can be used for additional settings, see the previous chapter for more details.

/sessions/

Directory where PHP sessions are stored. You might want to share this for example when using Signon 认证方式.

/www/themes/

Directory where phpMyAdmin looks for themes. By default only those shipped with phpMyAdmin are included, but you can include additional phpMyAdmin themes (see 自定义主题) by using Docker volumes.

Docker 例子

要将 phpMyAdmin 连接到给定服务器,请使用:

docker run --name phpmyadmin -d -e PMA_HOST=dbhost -p 8080:80 phpmyadmin:latest

要将 phpMyAdmin 连接到更多服务器,请使用:

docker run --name phpmyadmin -d -e PMA_HOSTS=dbhost1,dbhost2,dbhost3 -p 8080:80 phpmyadmin:latest

要使用任意服务器选项:

docker run --name phpmyadmin -d --link mysql_db_server:db -p 8080:80 -e PMA_ARBITRARY=1 phpmyadmin:latest

你也可以使用 Docker 连接至数据库容器:

docker run --name phpmyadmin -d --link mysql_db_server:db -p 8080:80 phpmyadmin:latest

使用额外配置文件运行:

docker run --name phpmyadmin -d --link mysql_db_server:db -p 8080:80 -v /some/local/directory/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php phpmyadmin:latest

使用附加主题文件运行:

docker run --name phpmyadmin -d --link mysql_db_server:db -p 8080:80 -v /some/local/directory/custom/phpmyadmin/themeName/:/var/www/html/themes/themeName/ phpmyadmin:latest

使用 docker-compose

Alternatively, you can also use docker-compose with the docker-compose.yml from <https://github.com/phpmyadmin/docker>. This will run phpMyAdmin with an arbitrary server - allowing you to specify MySQL/MariaDB server on the login page.

docker compose up -d

使用docker compose自定义配置文件

你可以使用外部文件来自定义 phpMyAdmin 配置,并通过 volumes 指令传递它:

phpmyadmin:
    image: phpmyadmin:latest
    container_name: phpmyadmin
    environment:
     - PMA_ARBITRARY=1
    restart: always
    ports:
     - 8080:80
    volumes:
     - /sessions
     - ~/docker/phpmyadmin/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php
     - /custom/phpmyadmin/theme/:/www/themes/theme/

Running behind haproxy in a subdirectory

When you want to expose phpMyAdmin running in a Docker container in a subdirectory, you need to rewrite the request path in the server proxying the requests.

使用 haproxy 可以这样做:

frontend http
    bind *:80
    option forwardfor
    option http-server-close

    ### NETWORK restriction
    acl LOCALNET  src 10.0.0.0/8 192.168.0.0/16 172.16.0.0/12

    # /phpmyadmin
    acl phpmyadmin  path_dir /phpmyadmin
    use_backend phpmyadmin if phpmyadmin LOCALNET

backend phpmyadmin
    mode http

    reqirep  ^(GET|POST|HEAD)\ /phpmyadmin/(.*)     \1\ /\2

    # phpMyAdmin container IP
    server localhost     172.30.21.21:80

When using traefik, something like following should work:

defaultEntryPoints = ["http"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      regex = "(http:\\/\\/[^\\/]+\\/([^\\?\\.]+)[^\\/])$"
      replacement = "$1/"

[backends]
  [backends.myadmin]
    [backends.myadmin.servers.myadmin]
    url="http://internal.address.to.pma"

[frontends]
   [frontends.myadmin]
   backend = "myadmin"
   passHostHeader = true
     [frontends.myadmin.routes.default]
     rule="PathPrefixStrip:/phpmyadmin/;AddPrefix:/"

You then should specify PMA_ABSOLUTE_URI in the docker-compose configuration:

version: '2'

services:
  phpmyadmin:
    restart: always
    image: phpmyadmin:latest
    container_name: phpmyadmin
    hostname: phpmyadmin
    domainname: example.com
    ports:
      - 8000:80
    environment:
      - PMA_HOSTS=172.26.36.7,172.26.36.8,172.26.36.9,172.26.36.10
      - PMA_VERBOSES=production-db1,production-db2,dev-db1,dev-db2
      - PMA_USER=root
      - PMA_PASSWORD=
      - PMA_ABSOLUTE_URI=http://example.com/phpmyadmin/

IBM 云

我们的其中一个用户已经在 IBM 云平台 上撰写了安装 phpMyAdmin 的指引。

快速安装

  1. Choose an appropriate distribution kit from the phpmyadmin.net Downloads page. Some kits contain only the English messages, others contain all languages. We’ll assume you chose a kit whose name looks like phpMyAdmin-x.x.x-all-languages.tar.gz.
  2. 确保您下载了真实的存档文件,请参阅 验证 phpMyAdmin 发行版
  3. 解开这个压缩包(包括子目录):在您网站服务器的文档根目录中执行 tar -xzvf phpMyAdmin_x.x.x-all-languages.tar.gz。如果您不能直接访问服务器,请先把这些文件解压到您自己的电脑上,等完成第 4 步之后,再通过 FTP 等方式将文件上传到您的网站服务器。
  4. 确保所有的脚本都有正确的所有者(若 PHP 运行于安全模式,脚本间所有者的不同将会导致问题)。参见 4.2 What’s the preferred way of making phpMyAdmin secure against evil access?1.26 我刚刚在IIS的文档根目录中安装了phpMyAdmin,但在尝试运行phpMyAdmin时出现错误“未指定输入文件”。
  5. 现在开始设置您的安装。两种方法。以前,用户只能手动编辑一份 config.inc.php 文件,但现在我们为那些喜欢使用图形界面安装的用户提供了一个向导式的安装脚本。手动创建 config.inc.php 仍然是一个快速安装的方法且一些高级功能也需要手动编辑该文件。

手动创建文件

To manually create the file, simply use your text editor to create the file config.inc.php (you can copy config.sample.inc.php to get a minimal configuration file) in the main (top-level) phpMyAdmin directory (the one that contains index.php). phpMyAdmin first loads the default configuration values and then overrides those values with anything found in config.inc.php. If the default value is okay for a particular setting, there is no need to include it in config.inc.php. You’ll probably need only a few directives to get going; a simple configuration may look like this:

<?php
// The string is a hexadecimal representation of a 32-bytes long string of random bytes.
$cfg['blowfish_secret'] = sodium_hex2bin('f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851');

$i=0;
$i++;
$cfg['Servers'][$i]['auth_type']     = 'cookie';
// if you insist on "root" having no password:
// $cfg['Servers'][$i]['AllowNoPassword'] = true;

或者,若您不想每次都登录:

<?php

$i=0;
$i++;
$cfg['Servers'][$i]['user']          = 'root';
$cfg['Servers'][$i]['password']      = 'changeme'; // use here your password
$cfg['Servers'][$i]['auth_type']     = 'config';

警告

在配置文件中存储密码非常不安全,因为任何人都可以修改您的数据库。

所有设置的完整说明请参见本文档的 设置 一节。

使用安装脚本

不想手动编辑 config.inc.php 的话,您可以使用phpMyAdmin的设置功能。该文件可以使用安装程序生成,您可以下载该文件以上传到服务器。

接下来,打开你的浏览器,访问你安装 phpMyAdmin 的位置,后缀为 /setup 。这些变化不会被保存到服务器上,你需要使用 :guilabel:`Download`按钮把它们保存到你的电脑上,然后再上传到服务器上。

现在文件保存好了。您可以使用您最喜欢的编辑器来复查或编辑一些安装脚本中没有提供的高级选项。

  1. 若您使用“config” auth_type ,您应保护好 phpMyAdmin 的安装文件夹,因为 config 认证不要求用户输入密码即可访问 phpMyAdmin。我们建议使用其它认证方式,如在 .htaccess 文件中设置 HTTP 认证或修改 auth_type 为 cookie 或 http。参见 ISP 与多用户安装,特别要注意 4.4 使用 HTTP 认证时,phpMyAdmin 总会报错 “拒绝访问”。
  2. 在您的浏览器中打开 phpMyAdmin 主目录。现在 phpMyAdmin 应该显示一个欢迎页面和您的数据库,若使用 HTTP 或 cookie 认证方式则应显示一个登录对话框。

Debian、Ubuntu及其衍生产品的安装脚本

Debian 和 Ubuntu 改变了启用和禁用安装脚本的方法,对于每个动作有一个单独的执行命令。

要允许修改设置,请执行:

/usr/sbin/pma-configure

要拒绝修改设置,请执行:

/usr/sbin/pma-secure

openSUSE 使用的安装脚本

Some openSUSE releases do not include setup script in the package. In case you want to generate configuration on these you can either download original package from <https://www.phpmyadmin.net/> or use setup script on our demo server: <https://demo.phpmyadmin.net/master/setup/>.

验证 phpMyAdmin 发行版

Since July 2015 all phpMyAdmin releases are cryptographically signed by the releasing developer, who through January 2016 was Marc Delisle. His key id is 0xFEFC65D181AF644A, his PGP fingerprint is:

436F F188 4B1A 0C3F DCBF 0D79 FEFC 65D1 81AF 644A

and you can get more identification information from <https://keybase.io/lem9>.

Beginning in January 2016, the release manager is Isaac Bennetch. His key id is 0xCE752F178259BD92, and his PGP fingerprint is:

3D06 A59E CE73 0EB7 1B51 1C17 CE75 2F17 8259 BD92

and you can get more identification information from <https://keybase.io/ibennetch>.

Some additional downloads (for example themes) might be signed by Michal Čihař. His key id is 0x9C27B31342B7511D, and his PGP fingerprint is:

63CB 1DF1 EF12 CF2A C0EE 5A32 9C27 B313 42B7 511D

and you can get more identification information from <https://keybase.io/nijel>.

You should verify that the signature matches the archive you have downloaded. This way you can be sure that you are using the same code that was released. You should also verify the date of the signature to make sure that you downloaded the latest version.

Each archive is accompanied by .asc files which contain the PGP signature for it. Once you have both of them in the same folder, you can verify the signature:

$ gpg --verify phpMyAdmin-4.5.4.1-all-languages.zip.asc
gpg: Signature made Fri 29 Jan 2016 08:59:37 AM EST using RSA key ID 8259BD92
gpg: Can't check signature: public key not found

As you can see gpg complains that it does not know the public key. At this point, you should do one of the following steps:

$ gpg --import phpmyadmin.keyring
  • Download and import the key from one of the key servers:
$ gpg --keyserver hkp://pgp.mit.edu --recv-keys 3D06A59ECE730EB71B511C17CE752F178259BD92
gpg: requesting key 8259BD92 from hkp server pgp.mit.edu
gpg: key 8259BD92: public key "Isaac Bennetch <bennetch@gmail.com>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

This will improve the situation a bit - at this point, you can verify that the signature from the given key is correct but you still can not trust the name used in the key:

$ gpg --verify phpMyAdmin-4.5.4.1-all-languages.zip.asc
gpg: Signature made Fri 29 Jan 2016 08:59:37 AM EST using RSA key ID 8259BD92
gpg: Good signature from "Isaac Bennetch <bennetch@gmail.com>"
gpg:                 aka "Isaac Bennetch <isaac@bennetch.org>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 3D06 A59E CE73 0EB7 1B51  1C17 CE75 2F17 8259 BD92

The problem here is that anybody could issue the key with this name. You need to ensure that the key is actually owned by the mentioned person. The GNU Privacy Handbook covers this topic in the chapter Validating other keys on your public keyring. The most reliable method is to meet the developer in person and exchange key fingerprints, however, you can also rely on the web of trust. This way you can trust the key transitively though signatures of others, who have met the developer in person.

Once the key is trusted, the warning will not occur:

$ gpg --verify phpMyAdmin-4.5.4.1-all-languages.zip.asc
gpg: Signature made Fri 29 Jan 2016 08:59:37 AM EST using RSA key ID 8259BD92
gpg: Good signature from "Isaac Bennetch <bennetch@gmail.com>" [full]

Should the signature be invalid (the archive has been changed), you would get a clear error regardless of the fact that the key is trusted or not:

$ gpg --verify phpMyAdmin-4.5.4.1-all-languages.zip.asc
gpg: Signature made Fri 29 Jan 2016 08:59:37 AM EST using RSA key ID 8259BD92
gpg: BAD signature from "Isaac Bennetch <bennetch@gmail.com>" [unknown]

phpMyAdmin配置存储

在 3.4.0 版更改: Prior to phpMyAdmin 3.4.0 this was called Linked Tables Infrastructure, but the name was changed due to the extended scope of the storage.

若要使用一些额外功能( 书签 、注释、 SQL 历史、结构追踪、PDF 生成、 转换关系 等),您需要创建一系列特殊的表。 这些表可以放在您自己的数据库里,也可以在一个多用户的服务器上创建一个独立的中心数据库(该数据库将通过其对应的帐号访问,所以不应给其他用户访问该数据库的权限)。

零配置

In many cases, this database structure can be automatically created and configured. This is called “Zero Configuration” mode and can be particularly useful in shared hosting situations. “ZeroConf” mode is on by default, to disable set $cfg['ZeroConf'] to false.

The following three scenarios are covered by the Zero Configuration mode:

  • When entering a database where the configuration storage tables are not present, phpMyAdmin offers to create them from the Operations tab.
  • When entering a database where the tables do already exist, the software automatically detects this and begins using them. This is the most common situation; after the tables are initially created automatically they are continually used without disturbing the user; this is also most useful on shared hosting where the user is not able to edit config.inc.php and usually the user only has access to one database.
  • When having access to multiple databases, if the user first enters the database containing the configuration storage tables then switches to another database, phpMyAdmin continues to use the tables from the first database; the user is not prompted to create more tables in the new database.

手动配置

您可以在 ./sql/ 文件夹中找到 create_tables.sql 文件。(若您使用 Windows 服务器,请特别注意 1.23 我在 Win32 系统上使用 MySQL,每次我创建表的时候列名都会被自动设为全小写,这是怎么回事?)。

如果已经具有了这种结构并:

  • 已经升级 MySQL 到 4.1.2 或更高版本,请执行 examples/upgrade_tables_mysql_4_1_2+.sql
  • 已经将 phpMyAdmin 2.5.0 或更高版本 (<= 4.2.x),升级至 phpMyAdmin 4.3.0 或者更高的版本,请执行脚本 sql/upgrade_column_info_4_3_0+.sql
  • 已经将 phpMyAdmin 4.3.0 或较高版本,升级至 phpMyAdmin 4.7.0 或者更高的版本,请执行脚本 sql/upgrade_tables_4_7_0+.sql

且通过导入 sql/create_tables.sql 创建了新的表格。

您可以使用 phpMyAdmin 来创建这些表。但请注意您可能需要特殊(管理员)权限来创建数据库和表,而且可能还需要根据数据库名修改脚本。

在导入 sql/create_tables.sql 文件之后,您还需要在 config.inc.php 文件中设置表名。您可以在 设置 一节中找到相应的指令。

你需要拥有一个控制用户( $cfg['Servers'][$i]['controluser']$cfg['Servers'][$i]['controlpass'] 设置项),并给予他们对这些表格的合适的权限。例如,你可以用下列语句创建他们:

对于任何 MariaDB 版本来说:

CREATE USER 'pma'@'localhost' IDENTIFIED VIA mysql_native_password USING 'pmapass';
GRANT SELECT, INSERT, UPDATE, DELETE ON `<pma_db>`.* TO 'pma'@'localhost';

对于 MySQL 8.0 或更高版本:

CREATE USER 'pma'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'pmapass';
GRANT SELECT, INSERT, UPDATE, DELETE ON <pma_db>.* TO 'pma'@'localhost';

对于低于 8.0 的 MySQL 版本:

CREATE USER 'pma'@'localhost' IDENTIFIED WITH mysql_native_password AS 'pmapass';
GRANT SELECT, INSERT, UPDATE, DELETE ON <pma_db>.* TO 'pma'@'localhost';

Note that MySQL installations with PHP older than 7.4 and MySQL newer than 8.0 may require using the mysql_native_password authentication as a workaround, see 1.45 尝试登录时,我收到错误信息“未知的认证方法 caching_sha2_password” for details.

从旧版本升级

警告

永远 不要 将新版本 phpMyAdmin 直接覆盖解压于现有的安装上,要总是先移除旧文件,仅仅保留配置。

这样,你就不会在目录中留下任何旧的或过时的文件。这些文件可能会产生严重的安全问题,或可能导致各种故障。

只需复制您原来的 config.inc.php 到新版本即可。当某些选项被改变或取消时,也可能需要做一些修改。为了兼容 PHP 5.3 及更新版本,您需要删除可能出现在您配置文件最后的 set_magic_quotes_runtime(0); 语句。

The complete upgrade can be performed in a few simple steps:

  1. 你可以在 <http://www.phpmyadmin.net/> 获得 phpMyAdmin 的最新版本。
  2. Rename existing phpMyAdmin folder (for example to phpmyadmin-old).
  3. Unpack freshly downloaded phpMyAdmin to the desired location (for example phpmyadmin).
  4. Copy config.inc.php` from old location (phpmyadmin-old) to the new one (phpmyadmin).
  5. Test that everything works properly.
  6. Remove backup of a previous version (phpmyadmin-old).

若您将 MySQL 服务器从 4.1.2 之前的版本升级到了 5.x 或更高版本,并且您使用 phpMyAdmin 配置信息存储,您还要运行 SQL 脚本 sql/upgrade_tables_mysql_4_1_2+.sql

若您将 MySQL 服务器从 2.5.0 版本或更高版本(低于 4.2.x 版本)升级到了 4.3.0,并且您使用 phpMyAdmin 存储配置,您还要运行 SQL 脚本 sql/upgrade_column_info_4_3_0+.sql

别忘了退出并重新登录来清除浏览器缓存并清空旧的会话。

认证方式的使用

当您在 多用户环境 下想让用户只能访问各自的数据库时我们推荐您使用 HTTP 和 cookie 认证方式。但请注意直到 IE 6 时微软的 IE 浏览器仍然有处理 cookies 的缺陷。您也许在 单用户环境 下仍然会使用 HTTP 或 cookie 认证方式,因为这样您的用户名/密码将不会以明文出现在配置文件中。

HTTP 和 cookie 认证方式更加安全:不需要在 phpMyAdmin 配置文件中设置 MySQL 登录信息(除了 $cfg['Servers'][$i]['controluser'] )。但请注意除非您使用了 HTTPS 协议,否则密码总是以明文传输的。在 cookie 认证方式下,密码将通过 AES 算法加密后保存到一个临时 cookie 中。

每个*真实的*用户应在特定的数据库上拥有一定的权限。除非您很明白这些权限的作用(例如:需要创建一个超级用户),否则您不应轻易授予普通用户任何全局权限。如:授予用户 real_user 具有对数据库 user_base 的所有权限:

GRANT ALL PRIVILEGES ON user_base.* TO 'real_user'@localhost IDENTIFIED BY 'real_password';

现在用户可以做什么已经完全被 MySQL 用户管理系统所控制了。在 HTTP 或 cookie 认证方式下,您不需要填写 $cfg['Servers'] 中的 user/password 设置。

HTTP 认证方式

注解

There is no way to do proper logout in HTTP authentication, most browsers will remember credentials until there is no different successful authentication. Because of this, this method has a limitation that you can not login with the same user after logout.

Signon 认证方式

The very basic example of saving credentials in a session is available as examples/signon.php:

<?php
/**
 * Single signon for phpMyAdmin
 *
 * This is just example how to use session based single signon with
 * phpMyAdmin, it is not intended to be perfect code and look, only
 * shows how you can integrate this functionality in your application.
 */

declare(strict_types=1);

/* Use cookies for session */
ini_set('session.use_cookies', 'true');
/* Change this to true if using phpMyAdmin over https */
$secureCookie = false;
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', $secureCookie, true);
/* Create signon session */
$sessionName = 'SignonSession';
session_name($sessionName);
// Uncomment and change the following line to match your $cfg['SessionSavePath']
//session_save_path('/foobar');
@session_start();

/* Was data posted? */
if (isset($_POST['user'])) {
    /* Store there credentials */
    $_SESSION['PMA_single_signon_user'] = $_POST['user'];
    $_SESSION['PMA_single_signon_password'] = $_POST['password'];
    $_SESSION['PMA_single_signon_host'] = $_POST['host'];
    $_SESSION['PMA_single_signon_port'] = $_POST['port'];
    /* Update another field of server configuration */
    $_SESSION['PMA_single_signon_cfgupdate'] = ['verbose' => 'Signon test'];
    $_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(random_int(0, mt_getrandmax())), true));
    $id = session_id();
    /* Close that session */
    @session_write_close();
    /* Redirect to phpMyAdmin (should use absolute URL here!) */
    header('Location: ../index.php');
} else {
    /* Show simple form */
    header('Content-Type: text/html; charset=utf-8');

    echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
    echo '<!DOCTYPE HTML>
<html lang="en" dir="ltr">
<head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">
<meta charset="utf-8">
<title>phpMyAdmin single signon example</title>
</head>
<body>';

    if (isset($_SESSION['PMA_single_signon_error_message'])) {
        echo '<p class="error">';
        echo $_SESSION['PMA_single_signon_error_message'];
        echo '</p>';
    }

    echo '<form action="signon.php" method="post">
Username: <input type="text" name="user" autocomplete="username" spellcheck="false"><br>
Password: <input type="password" name="password" autocomplete="current-password" spellcheck="false"><br>
Host: (will use the one from config.inc.php by default)
<input type="text" name="host"><br>
Port: (will use the one from config.inc.php by default)
<input type="text" name="port"><br>
<input type="submit">
</form>
</body>
</html>';
}

Alternatively, you can also use this way to integrate with OpenID as shown in examples/openid.php:

<?php
/**
 * Single signon for phpMyAdmin using OpenID
 *
 * This is just example how to use single signon with phpMyAdmin, it is
 * not intended to be perfect code and look, only shows how you can
 * integrate this functionality in your application.
 *
 * It uses OpenID pear package, see https://pear.php.net/package/OpenID
 *
 * User first authenticates using OpenID and based on content of $AUTH_MAP
 * the login information is passed to phpMyAdmin in session data.
 */

declare(strict_types=1);

if (false === @include_once 'OpenID/RelyingParty.php') {
    exit;
}

/* Change this to true if using phpMyAdmin over https */
$secureCookie = false;

/**
 * Map of authenticated users to MySQL user/password pairs.
 */
$authMap = ['https://launchpad.net/~username' => ['user' => 'root', 'password' => '']];

// phpcs:disable PSR1.Files.SideEffects,Squiz.Functions.GlobalFunction

/**
 * Simple function to show HTML page with given content.
 *
 * @param string $contents Content to include in page
 */
function Show_page(string $contents): void
{
    header('Content-Type: text/html; charset=utf-8');

    echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
    echo '<!DOCTYPE HTML>
<html lang="en" dir="ltr">
<head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">
<meta charset="utf-8">
<title>phpMyAdmin OpenID signon example</title>
</head>
<body>';

    if (isset($_SESSION['PMA_single_signon_error_message'])) {
        echo '<p class="error">' . $_SESSION['PMA_single_signon_message'] . '</p>';
        unset($_SESSION['PMA_single_signon_message']);
    }

    echo $contents;
    echo '</body></html>';
}

/**
 * Display error and exit
 *
 * @param Exception $e Exception object
 */
function Die_error(Throwable $e): void
{
    $contents = "<div class='relyingparty_results'>\n";
    $contents .= '<pre>' . htmlspecialchars($e->getMessage()) . "</pre>\n";
    $contents .= "</div class='relyingparty_results'>";
    Show_page($contents);
    exit;
}

// phpcs:enable

/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', $secureCookie, true);
/* Create signon session */
$sessionName = 'SignonSession';
session_name($sessionName);
@session_start();

// Determine realm and return_to
$base = 'http';
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
    $base .= 's';
}

$base .= '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'];

$realm = $base . '/';
$returnTo = $base . dirname($_SERVER['PHP_SELF']);
if ($returnTo[strlen($returnTo) - 1] !== '/') {
    $returnTo .= '/';
}

$returnTo .= 'openid.php';

/* Display form */
if ((! count($_GET) && ! count($_POST)) || isset($_GET['phpMyAdmin'])) {
    /* Show simple form */
    $content = '<form action="openid.php" method="post">
OpenID: <input type="text" name="identifier"><br>
<input type="submit" name="start">
</form>';
    Show_page($content);
    exit;
}

/* Grab identifier */
$identifier = null;
if (isset($_POST['identifier']) && is_string($_POST['identifier'])) {
    $identifier = $_POST['identifier'];
} elseif (isset($_SESSION['identifier']) && is_string($_SESSION['identifier'])) {
    $identifier = $_SESSION['identifier'];
}

/* Create OpenID object */
try {
    $o = new OpenID_RelyingParty($returnTo, $realm, $identifier);
} catch (Throwable $e) {
    Die_error($e);
}

/* Redirect to OpenID provider */
if (isset($_POST['start'])) {
    try {
        $authRequest = $o->prepare();
    } catch (Throwable $e) {
        Die_error($e);
    }

    $url = $authRequest->getAuthorizeURL();

    header('Location: ' . $url);
    exit;
}

/* Grab query string */
if (! count($_POST)) {
    [, $queryString] = explode('?', $_SERVER['REQUEST_URI']);
} else {
    // Fetch the raw query body
    $queryString = file_get_contents('php://input');
}

/* Check reply */
try {
    $message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
} catch (Throwable $e) {
    Die_error($e);
}

$id = $message->get('openid.claimed_id');

if (empty($id) || ! isset($authMap[$id])) {
    Show_page('<p>User not allowed!</p>');
    exit;
}

$_SESSION['PMA_single_signon_user'] = $authMap[$id]['user'];
$_SESSION['PMA_single_signon_password'] = $authMap[$id]['password'];
$_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(random_int(0, mt_getrandmax())), true));
session_write_close();
/* Redirect to phpMyAdmin (should use absolute URL here!) */
header('Location: ../index.php');

If you intend to pass the credentials using some other means than, you have to implement wrapper in PHP to get that data and set it to $cfg['Servers'][$i]['SignonScript']. There is a very minimal example in examples/signon-script.php:

<?php
/**
 * Single signon for phpMyAdmin
 *
 * This is just example how to use script based single signon with
 * phpMyAdmin, it is not intended to be perfect code and look, only
 * shows how you can integrate this functionality in your application.
 */

declare(strict_types=1);

// phpcs:disable Squiz.Functions.GlobalFunction

/**
 * This function returns username and password.
 *
 * It can optionally use configured username as parameter.
 *
 * @param string $user User name
 *
 * @return array<int,string>
 */
function get_login_credentials(string $user): array
{
    /* Optionally we can use passed username */
    if (! empty($user)) {
        return [$user, 'password'];
    }

    /* Here we would retrieve the credentials */
    return ['root', ''];
}

Config 认证方式

  • 该认证方式是最不安全的,因为它需要在配置文件中设置好 $cfg['Servers'][$i]['user']$cfg['Servers'][$i]['password'] (这将导致任何可以读取 config.inc.php 文件的人都能知道您的用户名和密码)。
  • ISP 与多用户安装 一节中将会说明如何保护您的配置文件。
  • 为了让该认证方式更加安全,您还可以考虑使用主机认证的 $cfg['Servers'][$i]['AllowDeny']['order']$cfg['Servers'][$i]['AllowDeny']['rules'] 指令。
  • 与 cookie 和 http 不同,在访问 phpMyAdmin 时 config 认证方式不会要求用户登录。虽然设计如此但这将导致任意用户都能访问。我们建议使用某些方式进行限制,如一个含有要求 HTTP 认证指令的 .htaccess 文件或者从路由器或防火墙设置禁止特定的 HTTP 访问(上述方法均不属于本文档的范围,但可以很容易地通过 Google 搜索到)。

加固您的 phpMyAdmin 安装

phpMyAdmin 团队致力于应用软件的安全性,而且总会有让您的安装变得更加安全的方法:

  • 遵循我们的 安全公告 <https://www.phpmyadmin.net/security/> _ 并在每次有漏洞发布时都将 phpMyAdmin 更新。

  • 仅使用 HTTPS 提供 phpMyAdmin 服务,最好一并使用 HSTS 机制,这样可以防御协议降级攻击。

  • 确保 PHP 安装遵循了生产环境站点的推荐配置,如应该禁用 display_errors

  • 除非你正在开发并需要测试套件,否则从phpMyAdmin中删除 test 目录。

  • 从phpMyAdmin中删除 setup 目录,初始设置后你可能不会使用它。

  • 正确选择认证方式 - Cookie 认证方式 是共享主机的最好选择。

  • 您应在您的网站服务器设置中禁止对 ./libraries./setup/lib 这两个子文件夹的访问。在 Apache 中您可以通过 .htaccess 文件设置,其它网站服务器请自行设置。通过该设置可预防路径泄露和跨站脚本攻击。

  • 禁止访问临时文件,参见 $cfg['TempDir'] ,如果它位于你的 web root,参见 Web 服务器上传/保存/导入目录

  • 您还可以禁止搜索引擎访问公开的 phpMyAdmin,因为这对它们没有任何用处。您可以使用网站服务器根文件夹的 robots.txt 文件或直接从网站服务器设置中限制其访问,参见 1.42 如何阻止爬虫机器人访问 phpMyAdmin?

  • 如果您不希望所有 MySQL 用户都能访问 phpMyAdmin,可以使用 $cfg['Servers'][$i]['AllowDeny']['rules'] 来限制它们,或者使用 cfg['Servers'][$i]['AllowRoot'] 来拒绝 root 用户访问。

  • 为您的账户启用 双因素身份验证

  • 考虑将 phpMyAdmin 隐藏在认证代理后面,这样用户在向 phpMyAdmin 提供 MySQL 凭证之前就需要进行认证。你可以通过配置你的 Web 服务器以请求 HTTP 认证来实现这一点。例如,在 Apache 中可以这样做:

    AuthType Basic
    AuthName "Restricted Access"
    AuthUserFile /usr/share/phpmyadmin/passwd
    Require valid-user
    

    一旦改变了配置,你需要创建一系列可供认证的用户。这可以通过 htpasswd 功能做到:

    htpasswd -c /usr/share/phpmyadmin/passwd username
    
  • 若您担心自动化的攻击,通过 $cfg['CaptchaLoginPublicKey']$cfg['CaptchaLoginPrivateKey'] 启用验证码会有一定作用。

  • Failed login attempts are logged to syslog (if available, see $cfg['AuthLog']). This can allow using a tool such as fail2ban to block brute-force attempts. Note that the log file used by syslog is not the same as the Apache error or access log files.

  • In case you’re running phpMyAdmin together with other PHP applications, it is generally advised to use separate session storage for phpMyAdmin to avoid possible session-based attacks against it. You can use $cfg['SessionSavePath'] to achieve this.

使用SSL连接到数据库服务器

推荐使用 SSL 连接至远程数据库服务器,这里有一些与 SSL 配置相关的选项:

$cfg['Servers'][$i]['ssl']`
决定是否使用 SSL。如果你只启用了这个,会加密连接,但不会经过认证——你无法知道是否与正确的服务器进行了通信。
$cfg['Servers'][$i]['ssl_key']$cfg['Servers'][$i]['ssl_cert']
用于客户端对服务器的认证。
$cfg['Servers'][$i]['ssl_ca']$cfg['Servers'][$i]['ssl_ca_path']
你信任的服务器证书机构。这是用来确保你正在与一个受信任的服务器对话。
$cfg['Servers'][$i]['ssl_verify']`
此配置项禁用了服务器证书认证,请小心使用。

当数据库服务器使用本地连接或私人网络,并且不能配置 SSL 时,您可以使用 $cfg['MysqlSslWarningSafeHosts'] 来明确列出安全的主机名。

已知问题

具有特定列权限的用户无法进行“浏览”操作

如果一个用户对一个表中的某些(而不是所有)列只有特定的权限,“浏览”会出错。

As a workaround, a bookmarked query with the same name as the table can be created, this will run when using the “Browse” link instead. Issue 11922.

使用 ‘http’ 认证注销后重新登录的问题

When using the ‘http’ auth_type, it can be impossible to log back in (when the logout comes manually or after a period of inactivity). Issue 11898.