I came across with one of my old projects (using MySQL 5 and PHP 5.5). I've just wanted to test that project using MySQL 8 and PHP7.0. To install the DB i normally do:
...
mysql -u root -p < DBinstall/webAppDBinstall.sql
...
in a "install" script for my web app. The sql commands contain:
...
-- # ######################## SET PHP_SCRIPT & GRANTS FOR ############################
CREATE USER 'php_script'@'localhost' IDENTIFIED BY 'php_script';
GRANT INSERT,SELECT ON webApp.* TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.Orders TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.OrderItems TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.UserStatus TO 'php_script'@'localhost';
GRANT INSERT ON webApp.History TO 'php_script'@'localhost';
...
Then i get the following error from PHP when running the webApp:
$ cat /var/log/apache2/error.log
...
[Thu May 28 06:01:26.317867 2020] [:error] [pid 8906] [client 127.0.0.1:32960] PHP Warning: mysqli::query(): Couldn't fetch mysqli in /var/www/webApp/src_php/mylib.php on line 68, referer: http://webApp/index.php?error=0
...
Note: that this project was running flawlessly using MySQL 5 and PHP 5.
Then i thought that "it smells" like being a privilege matter. So i did the following:
mysql> select User,Table_name,Table_priv from mysql.tables_priv where User='php_script';
+------------+------------+------------+
| User | Table_name | Table_priv |
+------------+------------+------------+
| php_script | History | Insert |
| php_script | OrderItems | Update |
| php_script | Orders | Update |
| php_script | UserStatus | Update |
+------------+------------+------------+
4 rows in set (0.00 sec)
mysql>
Here is the proof:
I changed the my DBinstall/webAppDBinstall.sql
script FROM:
...
-- # ######################## SET PHP_SCRIPT & GRANTS FOR ############################
CREATE USER 'php_script'@'localhost' IDENTIFIED BY 'php_script';
GRANT INSERT,SELECT ON webApp.* TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.Orders TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.OrderItems TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.UserStatus TO 'php_script'@'localhost';
GRANT INSERT ON webApp.History TO 'php_script'@'localhost';
...
TO:
-- # ######################## SET PHP_SCRIPT & GRANTS FOR ############################
CREATE USER 'php_script'@'localhost' IDENTIFIED BY 'php_script';
GRANT INSERT,SELECT ON webApp.Users TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.UserStatus TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.Categories TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.ProductGroups TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.CategoriesGroups TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.Products TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.Orders TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.OrderItems TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.Messages TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON webApp.History TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.Orders TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.OrderItems TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.UserStatus TO 'php_script'@'localhost';
GRANT INSERT ON webApp.History TO 'php_script'@'localhost';
And THE RESULT IS:
mysql> select User,Table_name,Table_priv from mysql.tables_priv where User='php_script';
+------------+------------------+----------------------+
| User | Table_name | Table_priv |
+------------+------------------+----------------------+
| php_script | History | Select,Insert |
| php_script | Categories | Select,Insert |
| php_script | CategoriesGroups | Select,Insert |
| php_script | Messages | Select,Insert |
| php_script | OrderItems | Select,Insert,Update |
| php_script | Orders | Select,Insert,Update |
| php_script | ProductGroups | Select,Insert |
| php_script | Products | Select,Insert |
| php_script | UserStatus | Select,Insert,Update |
| php_script | Users | Select,Insert |
+------------+------------------+----------------------+
10 rows in set (0.00 sec)
mysql>
GRANT
s' ???(SORRY for duplicating my question BUT stackoverflow has BANNED me for answering my own questions)
My question is: Why the GRANT <PRIVS> ON <DB>.* TO <USER>;
wildcards syntax stopped "working"
Note: This problem is different from mysqli::query(): Couldn't fetch mysqli . My webApp application is a system that runs flawlessly with MySQL 5.x deployments. ITS HAS nothing to do with PHP (although the
mysqli
error seems to, IT DOES NOT).
I just made a test on a MySQL 8 server where I successfully ran the following:
CREATE DATABASE webApp;
CREATE USER 'php_script'@'localhost' IDENTIFIED BY 'php_script';
GRANT INSERT,SELECT ON webApp.* TO 'php_script'@'localhost';
As I expected, the wildcard grant worked without any issues. So, I'm afraid you will need to search the problem somewhere else.
For example, the target database on one of your example is named webApp
an on the next example is webAppDB
. So, better check the consistency of the names.
Otherwise, your code syntax looks ok for MySQL 8.
[Edit] - additional suggestions
skip-name-resolve
is set to OFF. Looks like it is OFF by default on MySQL 8, but it might happen that under some circumstances it is set to ON.
In my case, I run MySQL 8 in a docker container and that variable was set to ON.
If the variable is set to ON, mysql will not resolve localhost to the actual IP of localhost and in your case that might be the problem.
More details on skip-name-resolve here: https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_skip_name_resolve
Make sure you finish the GRANTs commands with a FLUSH PRIVILEGES;
Try to switch default-authentication-plugin
to mysql_native_password
By default on MySQL 8 default-authentication-plugin
is set to caching_sha2_password
. But looks like mysqli doesn't have support for this authentication method (according to this article from 2018: https://mysqlserverteam.com/upgrading-to-mysql-8-0-default-authentication-plugin-considerations/)