Wordpress/PHP - 未捕获错误:调用未定义的函数 mysql_connect()

Wordpress/PHP - 未捕获错误:调用未定义的函数 mysql_connect()

我在我的 VPS 上的 ArchLinux 下安装了 Wordpress,配置了 SQL 后端并编辑了 /usr/share/webapps/wordpress/wp-config.php。不幸的是,当我尝试访问页面时,我得到了...

2019/06/14 06:44:12 [error] 20812#20812: *394 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function mysql_connect() in /usr/share/webapps/wordpress/wp-includes/wp-db.php:1645
Stack trace:
#0 /usr/share/webapps/wordpress/wp-includes/wp-db.php(639): wpdb->db_connect()
#1 /usr/share/webapps/wordpress/wp-includes/load.php(427): wpdb->__construct('wp-user', 'pc&0wC<k%:o<AuI...', 'wordpress', 'localhost')
#2 /usr/share/webapps/wordpress/wp-settings.php(120): require_wp_db()
#3 /usr/share/webapps/wordpress/wp-config.php(90): require_once('/usr/share/weba...')
#4 /usr/share/webapps/wordpress/wp-load.php(37): require_once('/usr/share/weba...')
#5 /usr/share/webapps/wordpress/wp-blog-header.php(13): require_once('/usr/share/weba...')
#6 /usr/share/webapps/wordpress/index.php(17): require('/usr/share/weba...')
#7 {main}
thrown in /usr/share/webapps/wordpress/wp-includes/wp-db.php on line 1645" while reading response header from upstream, client:...

搜索后发现,在 PHP 中,当尝试使用 mysql 模块而不是 mysqli 时,似乎会发生这种情况(找到线程这里这里)。

我在 /etc/php/php.ini 中启用了 mysqli

extension=mysqli

...并且模块已加载...

php -m
[PHP Modules]
Core
ctype
curl
date
dom
fileinfo
filter
hash
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
Phar
posix
readline
Reflection
session
SimpleXML
SPL
standard
tokenizer
xml
xmlreader
xmlwriter
zip
zlib
[Zend Modules]

通过阅读 /usr/share/webapps/wordpress/wp-includes/wp-db.php 中有问题的行 (1645),我发现好像从第 1589 行开始有一系列 if{} else{} 语句,用于检查是否正在使用 use_mysqli,这失败了,因为其中没有 mysql 模块在 PHP7 中被删除而应该使用 mysqli。

grep '\$this->use_mysqli' /usr/share/webapps/wordpress/wp-includes/wp-db.php -A100 -n | grep 1589 -A100
1589:           if ( $this->use_mysqli ) {
1590-                   $this->dbh = mysqli_init();
1591-
1592-                   $host    = $this->dbhost;
1593-                   $port    = null;
1594-                   $socket  = null;
1595-                   $is_ipv6 = false;
1596-
1597-                   if ( $host_data = $this->parse_db_host( $this->dbhost ) ) {
1598-                           list( $host, $port, $socket, $is_ipv6 ) = $host_data;
1599-                   }
1600-
1601-                   /*
1602-                    * If using the `mysqlnd` library, the IPv6 address needs to be
1603-                    * enclosed in square brackets, whereas it doesn't while using the
1604-                    * `libmysqlclient` library.
1605-                    * @see https://bugs.php.net/bug.php?id=67563
1606-                    */
1607-                   if ( $is_ipv6 && extension_loaded( 'mysqlnd' ) ) {
1608-                           $host = "[$host]";
1609-                   }
1610-
1611-                   if ( WP_DEBUG ) {
1612-                           mysqli_real_connect( $this->dbh, $host,    $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
1613-                   } else {
1614-                           @mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
1615-                   }
1616-
1617-                   if ( $this->dbh->connect_errno ) {
1618-                           $this->dbh = null;
1619-
1620-                           /*
1621-                            * It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if:
1622-                             *  - We haven't previously connected, and
1623-                             *  - WP_USE_EXT_MYSQL isn't set to false, and
1624-                             *  - ext/mysql is loaded.
1625-                             */
1626-                           $attempt_fallback = true;
1627-
1628-                           if ( $this->has_connected ) {
1629-                                   $attempt_fallback = false;
1630-                           } elseif ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) {
1631-                                   $attempt_fallback = false;
1632-                           } elseif ( ! function_exists( 'mysql_connect' ) ) {
1633-                                   $attempt_fallback = false;
1634-                           }
1635-
1636-                           if ( $attempt_fallback ) {
1637:                                   $this->use_mysqli = false;
1638-                                   return $this->db_connect( $allow_bail );
1639-                           }
1640-                   }
1641-           } else {
1642-                   if ( WP_DEBUG ) {
1643-                           $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
1644-                   } else {
1645-                           $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
1646-                   }
1647-           }

之所以会失败,是因为通过进一步回顾 /usr/share/webapps/wordpress/wp-includes/wp-db.php,我可以看到 $is_mysql 在第 564 行被设置为 null 并且 $use_mysqli 被设置为 false,这解释了为什么测试是否使用 use_mysqli 会失败并且反而尝试使用 connect_mysql()...

grep 'public \$is_mysql = null' /usr/share/webapps/wordpress/wp-includes/wp-db.php -A30 -n
564:    public $is_mysql = null;
565-
566-    /**
567-     * A list of incompatible SQL modes.
568-     *
569-     * @since 3.9.0
570-     * @var array
571-     */
572-    protected $incompatible_modes = array(
573-            'NO_ZERO_DATE',
574-            'ONLY_FULL_GROUP_BY',
575-            'STRICT_TRANS_TABLES',
576-            'STRICT_ALL_TABLES',
577-            'TRADITIONAL',
578-    );
579-
580-    /**
581-     * Whether to use mysqli over mysql.
582-     *
583-     * @since 3.9.0
584-     * @var bool
585-     */
586-    private $use_mysqli = false;

鉴于 mysql 自 PHP7 以来已被删除,并且不是 /etc/php/php.ini 中列出的可能模块,我很惊讶在全新安装时 $use_mysqli = false。我尝试将其设置为 true,重新启动 php-fpm.service 后,现在出现另一个错误并进入 if ( $this->$use_mysqli){...} 部分,但在第一次调用 $this->dbh = mysqli_init() 时失败...

2019/06/14 07:10:25 [error] 1439#1439: *1 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function mysqli_init() in /usr/share/webapps/wordpress/wp-includes/wp-db.php:1591
Stack trace:
#0 /usr/share/webapps/wordpress/wp-includes/wp-db.php(640): wpdb->db_connect()
#1 /usr/share/webapps/wordpress/wp-includes/load.php(427): wpdb->__construct('wp-user', 'pc&0wC<k%:o<AuI...', 'wordpress', 'localhost')
#2 /usr/share/webapps/wordpress/wp-settings.php(120): require_wp_db()
#3 /usr/share/webapps/wordpress/wp-config.php(90): require_once('/usr/share/weba...')
#4 /usr/share/webapps/wordpress/wp-load.php(37): require_once('/usr/share/weba...')
#5 /usr/share/webapps/wordpress/wp-blog-header.php(13): require_once('/usr/share/weba...')
#6 /usr/share/webapps/wordpress/index.php(17): require('/usr/share/weba...')
#7 {main}
  thrown in /usr/share/webapps/wordpress/wp-includes/wp-db.php on line    1591" while reading response header from upstream, client:

我并不反对修改配置,但我对Arch Wiki:Wordpress文章中说不需要进行这种程度的修补。有人能告诉我哪里可能出错了吗?

编辑

mysqli 部分来自phpinfo()

mysqli
MysqlI Support  enabled
Client API library version  mysqlnd 5.0.12-dev - 20150407 - $Id: 7cc7cc96e675f6d72e5cf0f267f48e167c2abb23 $
Active Persistent Links     0
Inactive Persistent Links   0
Active Links    0
Directive   Local Value Master Value
mysqli.allow_local_infile   Off Off
mysqli.allow_persistent On  On
mysqli.default_host no value    no value
mysqli.default_port 3306    3306
mysqli.default_pw   no value    no value
mysqli.default_socket   /run/mysqld/mysqld.sock /run/mysqld/mysqld.sock
mysqli.default_user no value    no value
mysqli.max_links    Unlimited   Unlimited
mysqli.max_persistent   Unlimited   Unlimited
mysqli.reconnect    Off Off
mysqli.rollback_on_cached_plink Off Off

编辑2:建议php-fpm不要加载mysqli模块,我现在已经检查过了,似乎……

$ php-fpm -m
[PHP Modules]
cgi-fcgi
Core
ctype
curl
date
dom
fileinfo
filter
hash
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
Phar
posix
readline
Reflection
session
SimpleXML
SPL
standard
tokenizer
xml
xmlreader
xmlwriter
zip
zlib

[Zend Modules]

答案1

您说得对,这种干预是没有必要的。快速 grep 显示,$use_mysqli在 中的第 621 行设置了wp-db.php

            // Use ext/mysqli if it exists unless WP_USE_EXT_MYSQL is defined as true
            if ( function_exists( 'mysqli_connect' ) ) {
                    $this->use_mysqli = true;

                    if ( defined( 'WP_USE_EXT_MYSQL' ) ) {
                            $this->use_mysqli = ! WP_USE_EXT_MYSQL;
                    }
            }

因此,由于某种原因,WordPress 找不到该功能mysqli_connect()

请确保已mysqli为 Web 服务器加载模块。该命令php -m仅确认已为命令行界面加载模块,命令行界面可能使用不同的配置文件。您可以创建一个 php 文件来phpinfo()检查这一点。在 PHP 中启用 mysqli 模块后,不要忘记重新启动 Apache。

如果已加载但仍然遇到错误,则可以将变量设置WP_USE_EXT_MYSQLfalse强制 WordPress 使用 mysqli。您只需将其添加到 wp_config.php 中:

define("WP_USE_EXT_MYSQL", false);

答案2

我已经解决了这个问题,根本问题出password在后端 mariadb/mysql。

从报告的日志中根本看不清楚......

PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function mysqli_init() in /usr/share/webapps/wordpress/wp-includes/wp-db.php:1591

但是,我开始剥离一些东西,在检查mariadb.service运行情况后,尝试使用wp-user命令行中的现有密码以 身份连接到它,但失败了。更改密码后,我可以在命令行上连接并完成 的配置/usr/share/webapps/wordpress/wp-config.php。 \o/

答案3

sudo apt-get install php7.4-mysql
sudo service apache2 restart

相关内容