Make WordPress Core

Opened 3 years ago

Closed 15 months ago

Last modified 15 months ago

#51988 closed defect (bug) (fixed)

Call to undefined function mysql_connect()

Reported by: bgin's profile bgin Owned by: sergeybiryukov's profile SergeyBiryukov
Milestone: 6.2 Priority: normal
Severity: normal Version: 5.6
Component: Database Keywords: php8 has-patch needs-testing has-testing-info add-to-field-guide
Focuses: Cc:

Description

Call to undefined function mysql_connect() in D:\xamppCF\htdocs\wp-includes\wp-db.php:1685

Attachments (2)

51988.diff (4.9 KB) - added by SergeyBiryukov 15 months ago.
51988.alt.diff (2.1 KB) - added by SergeyBiryukov 15 months ago.

Download all attachments as: .zip

Change History (26)

#1 @desrosj
3 years ago

  • Component changed from General to Database
  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

Hi @bgin,

Welcome to Trac! I'm sorry you are experiencing issues with WordPress 5.6. However, this Trac instance is not for general support requests.

The information provided is also not enough to begin troubleshooting your exact issue.

However, this does not appear to be an issue with PHP 8. The mysql_connect() function was deprecated in PHP 5.5 and removed in 7.0.0 (see the PHP documentation). It's possible that the PHP installation you have set up in XAMPP is not built correctly, causing WordPress to incorrectly use mysql instead of mysqli, which the original extension.

If you require further support, I recommend opening a support topic in the WordPress.org Support Forums.

#2 @SergeyBiryukov
3 years ago

  • Summary changed from wordpress 5.6 not ok with php 8 to Call to undefined function mysql_connect()

Just to clarify a bit more, since version 3.9, WordPress uses mysqli on PHP 5.5 or later instead of the deprecated mysql extension. See this post for more context: MySQL in WordPress 3.9.

I would suggest checking that the mysqli extension is available and the WP_USE_EXT_MYSQL constant is not defined in wp-config.php.

#3 @dimadin
3 years ago

Another ticket (#52001) was opened for the same error, again on WP 5.6 / PHP 8.

#4 @desrosj
3 years ago

#52001 was marked as a duplicate.

#5 @desrosj
3 years ago

#52001 was marked as a duplicate.

#6 @desrosj
3 years ago

From @ipajen on #52001:

I was using PHP 7.4 (where the mysql_connect() was removed already and everything worked fine) until before upgrading to PHP 8. No changes has been made except upgrading to PHP 8. So the question is why does it want to use mysql_connect instead of correct mysqli. Got 3 word press installltions on same hosting and all has the same problem, one of is very newly installed.

As of the release of PHP 8, the @ operator will no longer suppress errors fatal errors.

Looking at the code in WordPress, unless WP_DEBUG mode is enabled, the @ operator preceded the mysql_connect() call. In previous versions of PHP, it's likely that this just failed silently, and just happened to work on accident.

As noted above, if mysqli_connect() is present on the server running WordPress, it will always be used unless WP_USE_EXT_MYSQL is defined as true.

The only ways to encounter this issue would be a PHP install with mysqli missing or improperly configured, or the WP_USE_EXT_MYSQL being set to true. I would search in the mu-plugins directory, check your active plugins/wp-config.php file, or reach out to your hosting provider for more help. It's possible the hosting environment has incompatibilities with PHP 8 at the system level.

This ticket was mentioned in Slack in #core by desrosj. View the logs.


3 years ago

#8 @SergeyBiryukov
3 years ago

  • Milestone set to 5.6.1
  • Resolution invalid deleted
  • Status changed from closed to reopened

Replying to desrosj:

As of the release of PHP 8, the @ operator will no longer suppress errors fatal errors.

Looking at the code in WordPress, unless WP_DEBUG mode is enabled, the @ operator preceded the mysql_connect() call. In previous versions of PHP, it's likely that this just failed silently, and just happened to work on accident.

Since the error is now more prominent with PHP 8, I think we could display a better error message here for clarity, with some action items for the user to check, and a link to support forums.

#9 @SergeyBiryukov
3 years ago

  • Keywords php8 added

#10 @hellofromTonya
3 years ago

display a better error message here for clarity, with some action items for the user to check, and a link to support forums.

@SergeyBiryukov What are you envisioning for this?

  • Better error message or doing it wrong?
  • Will it be for PHP 8 only? Or do we want to check if the function exists and, if no, then through an error with the additional info and support forums link?
  • What "action items for the user to check" should we include?

#11 @ipajen
3 years ago

Following links helped to find the error for my hosting provider (my hostingprovider is using clodlinux that will provide a fix soon)

To test mysqli connection on server
https://www.php.net/manual/en/function.mysqli-connect.php

To see if mysqli is enabled
https://www.php.net/manual/en/function.phpinfo.php

This ticket was mentioned in Slack in #core by metalandcoffee. View the logs.


3 years ago

#13 @whyisjake
3 years ago

  • Milestone changed from 5.6.1 to 5.6.2

Since we are coming up on the 5.6.1 release date, I am going to push this to the next release while we work out a change for this issue.

#14 @desrosj
3 years ago

  • Milestone changed from 5.6.2 to Future Release

5.6.2 RC is going to be packaged in a few hours. Since this one still lacks a patch, I'm going to punt to Future Release.

#15 @SergeyBiryukov
3 years ago

Just noting that comment:62:ticket:50913 might be related.

#16 follow-up: @SergeyBiryukov
22 months ago

Fatal error: Uncaught Error: Call to undefined function mysql_connect() in wp-includes/class-wpdb.php:1963

I was able to reproduce this error message by accidentally using a non-thread safe version of PHP as an Apache module, instead of the thread safe version recommended in that case. Switching to the latter resolved the issue.

Not 100% sure why, but with exactly the same configuration, phpinfo() shows that mysqli is only available in thread safe version, while mysqlnd is available in both.

Last edited 22 months ago by SergeyBiryukov (previous) (diff)

#17 follow-up: @sc0ttkclark
18 months ago

Seems like we'd want to check if the function mysql_connect exists before calling it in that else statement for wpdb::db_connect(). If it does not exist, call $this->bail() if $allow_bail is true and pass it the error message saying MySQL is not available or whatever we want that text to be. Otherwise if $allow_bail is false then return false.

For testing this, I'm not sure of a great way to do this but that's because I haven't ever tried to do that kind of test case.

#18 in reply to: ↑ 17 @azaozz
18 months ago

  • Keywords needs-patch added

Replying to sc0ttkclark:

Seems like we'd want to check if the function mysql_connect exists

+1, sounds better than just allowing a fatal error :)

For testing this, I'm not sure...

Yea, seems pretty hard to test. On the other hand this change is a super simple if... elseif... that would do function_exists(). Not sure it needs that much testing.

Last edited 18 months ago by azaozz (previous) (diff)

#19 in reply to: ↑ 16 ; follow-up: @SergeyBiryukov
15 months ago

  • Keywords has-patch needs-testing has-testing-info added; needs-patch removed
  • Milestone changed from Future Release to 6.3

Replying to SergeyBiryukov:

Fatal error: Uncaught Error: Call to undefined function mysql_connect() in wp-includes/class-wpdb.php:1963

I was able to reproduce this error message by accidentally using a non-thread safe version of PHP as an Apache module, instead of the thread safe version recommended in that case.

It appears that simply disabling the mysqli PHP extension on an existing installation has the same effect.

51988.diff implements comment:17 and moves some conditionals around to simplify the logic and avoid repeating code. It turned out that wpdb::bail() would also need to check if mysql_error() exists to avoid a fatal error.

Taking a step back though, it seems that checking for this in wpdb::db_connect() is perhaps a bit too late in the request, as we have a dedicated function, wp_check_php_mysql_versions(), which runs earlier on each request.

In my testing, wp_check_php_mysql_versions() does not bail here due to the extension_loaded( 'mysqlnd' ) check added in [36434] / #33261. The mysqlnd extension is reported as available on my environment, but does not appear to work as a fallback in case mysqli is not available, at least not on PHP 8.0+.

So 51988.alt.diff is an alternative patch which checks if either mysqli_connect() or mysql_connect() function exists, and returns early from wp_check_php_mysql_versions() otherwise with a more friendly message. This mirrors the existing function_exists( 'mysqli_connect' ) check in wpdb::__construct().

To test:

  • Use PHP 8.0 or later.
  • Disable the mysqli extension on an existing WordPress installation.
  • You'll get a Call to undefined function mysql_connect() fatal error.

With the patch (either of them), you'll get a message instead of a fatal error:

Your PHP installation appears to be missing the MySQL extension which is required by WordPress.

Please check that the mysqli PHP extension is installed and enabled.

If you are unsure what these terms mean you should probably contact your host. If you still need help you can always visit the WordPress Support Forums.

Last edited 15 months ago by SergeyBiryukov (previous) (diff)

#20 @SergeyBiryukov
15 months ago

  • Owner set to SergeyBiryukov
  • Status changed from reopened to accepted

#21 in reply to: ↑ 19 ; follow-up: @azaozz
15 months ago

Replying to SergeyBiryukov:

51988.alt.diff is an alternative patch which checks if either mysqli_connect() or mysql_connect() function exists, and returns early

Imho this is the better solution. Was trying to figure out if extension_loaded( 'mysqli' ) is 100% identical to function_exists( 'mysqli_connect' ) (mysqli_connect() is an alias of mysqli::__construct()) but couldn't find any discrepancies. Perhaps commit this patch and see if any possibly related errors are reported during testing.

Last edited 15 months ago by azaozz (previous) (diff)

#22 in reply to: ↑ 21 @SergeyBiryukov
15 months ago

  • Milestone changed from 6.3 to 6.2

Replying to azaozz:

Imho this is the better solution.

Thanks! Moving for 6.2 Beta 3 consideration. Initially moved to 6.3 just in case, but the patch seems safe enough and resolves a fatal error :)

#23 @SergeyBiryukov
15 months ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 55367:

Bootstrap/Load: Check that either mysqli_connect() or mysql_connect() is available.

This resolves a fatal error and displays an actionable message if the mysqli PHP extension is missing.

Previously, wp_check_php_mysql_versions() performed an early check whether mysql, mysqli, or mysqlnd extensions are loaded, but that did not work if the mysqlnd extension is the only one present.

Checking specifically for mysqli_connect() or mysql_connect() functions should be a more reliable approach and more closely mirrors the existing checks in the wpdb class.

Follow-up to [1955], [4489], [7234], [12732], [19760], [27257], [36434].

Props bgin, desrosj, dimadin, ipajen, hellofromTonya, sc0ttkclark, azaozz, SergeyBiryukov.
Fixes #51988.

#24 @milana_cap
15 months ago

  • Keywords add-to-field-guide added
Note: See TracTickets for help on using tickets.