Mysql

Wordpress/PHP - 未擷取的錯誤:呼叫未定義的函式 mysql_connect()

  • February 24, 2021

我已經在我的 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 (在此處此處找到執行緒)時,搜尋似乎發生在 PHP 下。

我在 /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 is set to null on line 564 and $ 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 on a fresh install. I’ve tried setting it to true and after restarting php-fpm.service now get another error and enter the if ( $ 這-> $ use_mysqli){…} section only to fail on the first call to $ 這->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

EDIT2:它建議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]

我已經解決了這個問題,根本問題是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/

你是對的,這樣的干涉應該是不必要的。快速 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為網路伺服器載入了該模組。該命令php -m僅確認它是為命令行界面載入的,它可能使用不同的配置文件。您可以創建一個 php 文件phpinfo()來檢查這一點。在 PHP 中啟用 mysqli 模組後不要忘記重新啟動 Apache。

如果載入後仍然遇到錯誤,可以將變數WP_USE_EXT_MYSQL設置false為強制 WordPress 使用 mysqli。您只需要將其添加到您的 wp_config.php 中:

define("WP_USE_EXT_MYSQL", false);

引用自:https://serverfault.com/questions/971430