I have a web hosting that do not allow me to grant privileges to users.
So I only have one usable user, with SELECT/UPDATE/DELETE privileges.
I connect to MySQL using PHP with MySQLi.
Is there a way to tell either MySQL (the database itself) or MySQLi (the PHP object) to disallow updates/deletes only for the current session?
The aim is to have this kind of code:
$mysqli = new mysqli(MYSQLI_IP, MYSQLI_USER, MYSQLI_PASSWORD,n MYSQLI_DBNAME);
// I have SELECT privileges so it works
$mysqli->query('SELECT * FROM `table`');
// This should work too because I have UPDATE privilege
$mysqli->query('UPDATE `table` SET `date`=NOW()');
// This is the "command" I'm looking for
$mysqli->disallowUpdates();
// Ok, it still works
$mysqli->query('SELECT * FROM `table`');
// This must not work because I told mysqli (php)/mysql (db)
// to disallow updates for this session
$mysqli->query('UPDATE `table` SET `date`=NULL');
You cannot do that in any way mentioned. You need to do that logic by yourself, for example:
Grant or disallow on some condition:
session_start();
$_SESSION['isAllowedToUpdate'] = false;
Do updates:
if (isset($_SESSION['isAllowedToUpdate']) && $_SESSION['isAllowedToUpdate']) {
// do some updates
}
Related
i have two table in sql the 1st table is for account while the 2nd table is for testimonial . i am trying to update the two tables in single query. The update is successful if the account already have a testimonial but fails to update if the account has no testimonial yet .How can i fix this heres my code for the update ....
if(!$update=mysql_query(
"UPDATE
tblapplicant,
tbltestimonial
SET
tblapplicant.ImagePath='".$name."',
tbltestimonial.pic = '".$name."'
WHERE
tblapplicant.appid=tbltestimonial.appid"
)
)
1) You're working with a database, it defeats the purpose to use the same data being inserted into two different tables.
2) One gentleman also mentioned stop using MySQL... heres some reference code for you. Assuming you're using php.
3) If you want to use a single query to update 2 tables with the same info against recommendation. Use a stored procedure to update them both.
4) At which point are these account's interconnected in this query? I'm somehow intrigued if this system is in beta or testing?
With your "Where" conditions without matching a specific record, this will update every record that has a matching ID. This is highly not recommended until you add further conditions like username = .... or a condition that's specific to someone or a specific set of rows.
**I strongly advise you post the tables you're working with and what results you want achieve for the best advise. **
Can't really give a good consultation with you playing the whole overview close to the chest. Using this plain-Jane without further detail on what you're asking for is at your own risk my friend.
include/dbconnect.php optional recommended update
<?php
if (isset($mysqli)){
unset($mysqli);
}
define("HOST", "yo.ur.ip.addr"); // The host you want to connect to.
define("USER", "myfunctionalaccount"); // The database username.
define("PASSWORD", "superdoopersecurepassword!"); // The database password.
define("DATABASE", "thegoods");
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
if ( $mysqli->connect_error ) {
die('Connect Error: ' . $mysqli->connect_error);
}
?>
functions.php <-- shouldn't be called functions if its going to be your form response
<?php
// SHOULD BE SOME MASSIVE LOGIC UP HERE FOR FORM DATA DECISIONING
include_once "include/dbconnect.php";
$name = addslashes($_FILES['image']['name']);
$image = mysql_real_escape_string(addslashes(file_get_contents($_FILES['image']['tmp_name'])));
if ($stmt = $mysqli->prepare("CALL UpdateTestimonials(?,?,?)"){
$stmt->bind_param($name, $image, $userid);
$stmt->execute();
// optional to show affected rows
$stmt->affected_rows
//
// use if you want to return values from DB
// $stmt->bind_result($result);
// $stmt->fetch;
}
$stmt->close
?>
MySQL build a stored procedure - fyi; definer is optional. Definer will allow you to run a query that only elevated privileges can access due to the safety of such a query. You can use create procedure w/o the definer parameter. dT is just an abbreviation for datatype. You would put varchar or int... etc..
use 'database';
DROP procedure if exists 'UpdateTestimonials';
DELIMITER $$
use 'UpdateTestimonials' $$
CREATE DEFINER='user'#'HOSTNAME/LOCALHOST/%' PROCEDURE 'mynewprocedure' (IN varINPUT varchar, IN varIMG blob, IN varAppID int)
BEGIN
UPDATE tblapplicant
SET imagepath = varINPUT,
pic = LOAD_FILE(varIMG)
WHERE appid = varAppID
END $$
DELIMITER;
Use LEFT JOIN:
if (!$update = mysql_query(
"UPDATE
tblapplicant
LEFT JOIN tbltestimonial ON tblapplicant.appid = tbltestimonial.appid
SET
tblapplicant.ImagePath = '" . $name . "',
tbltestimonial.pic = '" . $name . "'"
)
)
Also, if you need some additional filters for tbltestimonial, add them into LEFT JOIN condition
You could try with a transaction. BTW also please use prepared statements to prevent SQL Injection attacks.
<?php
// prefer mysqli over mysql. It is the more modern library.
$db = new mysqli("example.com", "user", "password", "database");
$db->autocommit(false); // begin a new transaction
// prepare statements
$update_applicant =
$db->prepare("UPDATE tblapplicant
SET tblapplicant.ImagePath = ?"));
$update_applicant->bind_param("s", $name));
$update_applicant->execute();
$update_testimonial =
$db->prepare("UPDATE tbltestimonial
SET tbltestimonial.pic = ?"));
$update_testimonial->bind_param("s", $name))
$update_testimonial->execute();
$db->commit(); // finish the whole transaction as successful,
// when everything has succeeded.
?>
Of course that would not create any testimonials, that don't exist. It just updates those, that do. When you want to insert new entries in tbltestimonial, do so explicitly with an INSERT statement inside the transaction.
MySQL does not fully support transactions. The tables have to use a table type, that can handle them, e.g. innodb. When that is the case, the transaction will make sure, that everyone else either sees all changes from the transactions, or none.
In many cases transactions allow you to perform a group of simple steps, that otherwise would need complex single queries or would not be possible without transactions at all.
Alternative Solution
Another approach of course would be an update-trigger. Create a trigger in your database, that fires whenever e.g. tblapplicant is updated and updates tbltestimonial accordingly. Then you don't have to care about that in your application code.
I read a lot of answer about this problem, but my real problem is that I cant understand the real solving:
I follow the instruction to change password, set it with 24 characters, but nothing change!
I try:
SET SESSION old_passwords=0;
SET GLOBAL old_passwords = 0;
FLUSH PRIVILEGES;
SET PASSWORD = PASSWORD('xxxxxx');
but nothing change!
My web hosting dont permit change my.cnf!
Any solution?
You need to reload privileges because the server caches them. Just type "FLUSH PRIVILEGES" in a query window on phpmyadmin.
http://dev.mysql.com/doc/refman/5.0/en/flush.html
Ok, finally I solve so by launching a script with this sql:
SQL = "select user(), current_user()"
SQL = "SET Password = PASSWORD('password')"
SQL = "SET SESSION old_passwords = 0"
SQL = "SET Password = PASSWORD('old_password')"
WIthout Flush (for me is impossible with this hosting!).
mysql_query("UPDATE users SET `test` = '$unicornID' where id='$_SESSION[user_id]' ")
or die(mysql_error());
Now, when user clicks 'add to favorite'-button this line of code updates my database but also deletes all the old data from column test. What command should so that the old data is not deleted?
I think what you may be looking for is an "INSERT" sql query.
It would be something along the lines of;
"INSERT * INTO users WHERE test='$unicornID' and id='$_SESION['user_id']'";
Let me know how it goes. Cheers.
Another tip.
Use PDO with prepared statements:
$pdo = new PDO(sprintf('mysql:host=%s;dbname=%s', HOST, DATABASE), USER, PASSWORD);
And to insert something:
$params = array(':unicornID' => $unicornID, ':id' => $_SESSION['user_id']);
$stmt = $pdo->prepare("INSERT * INTO users WHERE test=:unicornID and id=:id");
$stmt->execute($params);
The old mysql(_query) commands are old and very vulnerable, PDO isn't as vulnerable.
The advantage of prepared statements are mainly that you can't inject via your variables some sql code.
Hope you understood my and my code
"Update" means that the old data row is changed; if you want to keep it, you have to insert a new one. In this case I think that you should copy the row (which may be done using "insert... select...") and then update the newly inserted line.
I've created a simple script using PHP and MySQLi. The purpose is to create a new user on a MySQL server, however I get this error message: "user create query failed:Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation."
$db = "xsxx";
$user = $_POST["user"];
$pass = $_POST["pass"];
$con=mysqli_connect('127.0.0.1',"root","",$db);
$cruser= "CREATE USER '".$user."'#'localhost' IDENTIFIED BY '".$pass."';";
#mysqli_query($con, $gruser) or die(mysqli_connect_error());
if(mysql_query($cruser)){
echo 'user created<br/>';
} else{
echo 'user create query failed:'.mysql_error().'<br/>';
}
mysqli_close($con);
Anyone know what I'm doing wrong? If it's important, I'm using XAMPP for the MYSQL server. Thanks in advance.
You are mixing the old and new style mysql calls (mysql vs mysqli).
The mysql_query call you are issuing will use whatever username and password was specified during the mysql_connect call, and importantly, not the username and password you specified in the mysqli_connect call.
If you are not issuing a mysql_connect() yourself (it's not shown in the code you posted) then the mysql_query will call mysql_connect with no arguments which leads to a blank username and password.
By whichever method it's being called, the mysql_connect user does not have the "CREATE USER" privilege and so the error message is generated.
You can use SHOW GRANTS FOR 'someuser'#'localhost'; to check what a user's permissions are.
You can also use the GRANT statement to add additional permissions to users.
An example of adding the create user permission would be:
GRANT CREATE_USER ON *.* TO 'someuser'#'localhost''
One way to resolve the issue, assuming root has all permissions, is to change your mysqli_connect to a mysql_connect such as: mysql_connect('127.0.0.1','root','')
I have been learning how to program websites lately and the time has come for me to add a database. I have in fact already successfully created a MySQL database and interacted with it with PHP.
My problem is I can't seem to access a SQLite database file with it. I am using MAMP to host locally for now. Here is a snippet of the code I am using to access the db and find and print out a value stored on it.
<?php
$dbhandle = sqlite_open('/Applications/MAMP/db/sqlite/Users');
if ($dbhandle == false) die ('Unable to open database');
$dbquery = "SELECT * FROM usernames WHERE username=trevor";
$dbresult = sqlite_query($dbhandle, $dbquery);
echo sqlite_fetch_single($dbresult);
sqlite_close($dbhandle);
?>
As you have access to the database (your code doesn't die), I'd say there's got to be an error later ;-)
Looking at your SQL query, I see this :
SELECT * FROM usernames WHERE username=trevor
Are you sure you don't need to put quotes arround that string ?
Like this :
SELECT * FROM usernames WHERE username='trevor'
Also, notice that sqlite_fetch_single will only fetch the first row of your data -- which means you might need to use sqlite_fetch_array or sqlite_fetch_object if you want to access all the fields of your resulset.