问题
I am using PHP's PDO with MySQL to create a web application. I wish to put the web application in "demo" mode. What this means is all writes (updates, inserts, deletes) are disabled, and the applicable continues with out any errors. For arguments sake, the application is in demo mode if $_SESSION['demo_mode']=1. Without putting conditionals around each write statement, how can this be done.
$dbh->exec("INSERT INTO t1(c1, c2) VALUES ('v1', 'v2')");
$dbh->lastInsertId();
$q=$dbh->query("SELECT c1 FROM t2 WHERE c2=123");
$v=$q->fetchColumn();
回答1:
You can modify the rights of the user the application connects as, so that it only gets SELECTand similar rights.
Here is the comprehensive list of individual rights that you can grant to a user.
Example (to be adapted to your need, of course):
REVOKE ALL PRIVILEGES ON yourdatabase.* FROM 'application_user'@'host';
GRANT SELECT ON yourdatabase.* TO 'application_user'@'host';
Obviously, this will produce errors when your application tries to write anything. Your app should be prepared to fail graciously if you are planning to use this for a demo ;)
回答2:
The simplest thing I can think of would be to just start a transaction at the beginning of the request, never committing it. (In Mysql this does not work with Myisam tables, and you can't change table structure because it will autocommit.)
if (isset($_SESSION['demo_mode'])) $dbh->beginTransaction();
// Do whatever you want, never committing
// If you are using transactions and do want to commit, checkt the flag first
if (!isset($_SESSION['demo_mode'])) $dbh->commit(); // Same for rollbacks
A cleaner solution would be to wrap the PDO class so you can intercept commit and rollback calls. The nice thing about this idea is that subsequent queries during the same request will reflect the changes. They just won't persist across requests. A potential drawback is that it might not work, because I've never tried it :-)
来源:https://stackoverflow.com/questions/18105414/globally-disable-all-mysql-writes