How can I allow the user submitting a form, to update his entry on "re-submission"
for example
12345678910 (unique id) , submitted the form with selections,
12345678910 , re-submitted with new selections
what's the function responsible for "automatically" updating such kind of form entries.
I know that I can use a check if the entry exists, but how do I update it if it exists and insert it in a new row if it doesn't ...
function checkstudentid($studentid)
{
$con = connectvar();
mysql_select_db("database1", $con);
$result = mysql_query(
"SELECT * FROM table WHERE studentid='$studentid' LIMIT 1");
if(mysql_fetch_array($result) !== false)
....
// I want to add the entry here since it doesn't exist...with checkboxes
// else , I want to update if it already exists
}
Now I'm also not completely positive if the above code will work...but this is what I have for starters, if there is any other way or if the method I'm using is "wrong" , I would appreciate the heads up...or if what I'm trying to is even possible (the way I'm doing it)...
NOTES
I only have one php file which the form submits to.
I am not using a login/registration system
I do not want to display all the data in a table using HTML, just an
"automatic" update if the studentid already exists in the table
If I were using a deprecated method to interact with a database, I would probably just do this:
<?php
function checkstudentid($studentid) {
$con = connectvar();
mysql_select_db("database1", $con);
$result = mysql_query(
"SELECT * FROM table WHERE studentid='$studentid' LIMIT 1");
$query = '';
if (mysql_num_rows($result) > 0) {
$query = "UPDATE table SET column1='$value_one', column2='$value_two' WHERE studentid='$studentid'";
} else {
$query = "INSERT INTO table VALUES('$new_id', '$value_one', '$value_two')";
}
if (mysql_query($query)) {
return true;
} else {
return false;
}
}
?>
But then again, I would use PDO to interact with the DB.
Here is a simple PDO example (you just have to write the function to return the connection):
<?php
function checkstudentid($studentid) {
$update = false;
$dbh = formPDOConnection();
$query = "SELECT studentid FROM table WHERE studentid=:id";
$stmt = $dbh->prepare($query);
$stmt->bindValue(':id', $studentid, PDO::PARAM_STR);
if ($stmt->execute()) {
if ($stmt->rowCount()) {
$update = true;
}
} else {
return 'failure to execute query';
}
// if we just need to update
if ($update) {
$update = "UPDATE table SET value1=:v1,
value2=:v2 WHERE studentid=:id";
$stmt = $dbh->prepare($update);
$stmt->bindValue(':id', $studentid, PDO::PARAM_STR);
$stmt->bindValue(':v1', $value_one, PDO::PARAM_STR);
$stmt->bindValue(':v2', $value_two, PDO::PARAM_STR);
} else {
$insert = "INSERT INTO table VALUES(:id,:v1,v2)";
$stmt = $dbh->prepare($insert);
$stmt->bindValue(':id', $new_id, PDO::PARAM_STR);
$stmt->bindValue(':v1', $value_one, PDO::PARAM_STR);
$stmt->bindValue(':v2', $value_two, PDO::PARAM_STR);
}
return $stmt->execute();
}
?>
Save yourself a headache and stop using mysql_*
You can use INSERT... ON DUPLICATE KEY UPDATE... on your mysql code instead use the logic in your PHP.
Here's a sample:
INSERT INTO `category` (`id`, `name`) VALUES (12, 'color')
ON DUPLICATE KEY UPDATE `name` = 'color';
Reference: http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
Related
I want to check if user already liked the post, if so than delete the user from database likes.
I've tried to do an if statement but it wont get to the else and only add likes even when user_id and post_id are the same.
Like.class.php
private function Addlike(){
$conn = db::getInstance();
$query = "insert into likes (post_id, user_id) values
(:post_id, :user_id)";
$statement = $conn->prepare($query);
$statement->bindValue(':post_id',$this->getPostId());
$statement->bindValue(':user_id',$this->getUserId());
$statement->execute();
}
private function Deletelike(){
$conn = db::getInstance();
$query = "DELETE FROM likes WHERE post_id = :post_id
AND user_id =:user_id";
$statement = $conn->prepare($query);
$statement->bindValue(':post_id',$this->getPostId());
$statement->bindValue(':user_id',$this->getUserId());
$statement->execute();
}
public function CheckLike(){
$conn = db::getInstance();
$query = "SELECT COUNT(*) FROM likes WHERE
post_id=:post_id AND user_id=:user_id";
$statement = $conn->prepare($query);
$statement->bindValue(':post_id',$this->getPostId());
$statement->bindValue(':user_id',$this->getUserId());
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
if($result["COUNT(*)"] == 0){
$this->Addlike();
}else{
$this->Deletelike();
}
return $result;
}
If you press like for the first time you should like the post and it should be stored in the database, if you press again you unlike the post and it gets deleted from the database. But now it only does the Addlike function...
I think PDO::FETCH_ASSOC returns a multidimensional array when used with PDOStatement::fetchAll, according to https://www.php.net/manual/en/pdostatement.fetchall.php#refsect1-pdostatement.fetchall-examples.
Try changing your code to something like this and see if it works. You could also try dumping the $result variable to see what the structure looks like.
if($result[0]["COUNT(*)"] == 0){
$this->Addlike();
}else{
$this->Deletelike();
}
If an array index doesn't exist, PHP considers it false, which would explain why you're always adding likes, since false == 0 in PHP.
If you want to avoid this equivalency of false and 0, use the identical operator to also compare types:
if ($result["COUNT(*)"] === 0) {
...
please help me out and sorry for my bad English,
I have fetch data , on basis of that data I want to update the rows,
Follows my code
I fetched data to connect API parameters
<?php
$stmt = $db->stmt_init();
/* publish store for icube*/
$stmt->prepare( "SELECT id,offer_id,name,net_provider,date,visible,apikey,networkid FROM " ."affilate_offer_findall_icube WHERE visible='1' ");
$stmt->execute();
mysqli_stmt_execute($stmt); // <--------- currently missing!!!
mysqli_stmt_store_result($stmt);
$rows = mysqli_stmt_num_rows($stmt);
$stmt->bind_result( $id, $offer_id, $name, $net_provider, $date, $visible,$apikey,$networkid);
$sql = array();
if($rows>0)
{
while($info = $stmt->fetch() ) {
$jsondataicube = file_get_contents('filename/json?NetworkId='.$networkid.'&Target=Affiliate_Offer&Method=getThumbnail&api_key='.$apikey.'&ids%5B%5D='.$offer_id.'');
$dataicube = json_decode($jsondataicube, true);
foreach($dataicube['response']['data'][0]['Thumbnail'] as $key=>$val)
{
$offer_id = $dataicube['response']['data'][0]['Thumbnail']["$key"]['offer_id'];
$display = $dataicube['response']['data'][0]['Thumbnail']["$key"]['display'];
$filename = $dataicube['response']['data'][0]['Thumbnail']["$key"]['filename'];
$url = $dataicube['response']['data'][0]['Thumbnail']["$key"]['url'];
$thumbnail = $dataicube['response']['data'][0]['Thumbnail']["$key"]['thumbnail'];
$_filename = mysqli_real_escape_string($db,$filename);
$_url = mysqli_real_escape_string($db,$url);
$_thumbnail = mysqli_real_escape_string($db,$thumbnail);
$sql[] = '("'.$offer_id.'","icube","'.$_thumbnail.'","'.$_url.'")';
}
}
As I store values which have to be inserted in 'sql'
now
$stmt->prepare( "SELECT offer_id FROM " ."affilate_offer_getthumbnail_icube ORDER BY 'offer_id' ASC");
$stmt->execute();
mysqli_stmt_execute($stmt); // <--------- currently missing!!!
mysqli_stmt_store_result($stmt);
$rows = mysqli_stmt_num_rows($stmt);
$stmt->bind_result($offer_id);
$sqlimplode = implode(',', $sql);
if($rows>0)
{
$query = "UPDATE affilate_offer_getthumbnail_icube WHERE offer_id='".$offer_id."' SET '".$sqlimplode."'";
$stmt->prepare( $query);
$execute = $stmt->execute();
}
else
{
$query= "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode;
$stmt->prepare( $query);
$execute = $stmt->execute();
}`
`
Insert query working well,but how can I update all the data like insert query ?
My Answer is refering to a "set and forget"-strategy. I dont want to look for an existing row first - probably using PHP. I just want to create the right SQL-Command and send it.
There are several ways to update data which already had been entered (or are missing). First you should alter your table to set a problem-specific UNIQUE-Key. This is setting up a little more intelligence for your table to check on already inserted data by its own. The following change would mean there can be no second row with the same value twice in this UNIQUE-set column.
If that would occur, you would get some error or special behaviour.
Instead of using PHPMyAdmin you can use this command to set a column unique:
ALTER TABLE `TestTable` ADD UNIQUE(`tablecolumn`);
After setting up your table with this additional intelligence, you alter your Insert-Command a little bit:
Instead of Insert you can drop and overwrite your Datarow with
REPLACE:
$query= "REPLACE INTO affilate_offer_getthumbnail_icube
(offer_id, net_provider,logo2020,logo100) VALUES (".$sqlimplode.")";
See: Replace Into Query Syntax
Secondly you can do this with the "On Duplicate Key"-Commando.
https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
$query= "INSERT INTO affilate_offer_getthumbnail_icube
(offer_id, net_provider,logo2020,logo100)
VALUES (".$sqlimplode.")
ON DUPLICATE KEY UPDATE net_provider = ".$newnetprovider.",
logo2020 = ".$newlogo2020.",
logo100 = ".$newlogo100.";";
Note: I think you missed some ( and ) around your $sqlimplode. I always put them around your implode. Maybe you are missing ' ' around strings as well.
Syntax of UPDATE query is
UPDATE table SET field1 = value1, field2 = value2 ...
So, you cannot pass your imploded array $sql to UPDATE query. You have to generate another sql-string for UPDATE query.
This is clearly incorrect:
$query = "UPDATE affilate_offer_getthumbnail_icube
WHERE offer_id='".$offer_id."' SET '".$sqlimplode."'";
If the intention is to INSERT offer_id='".$offer_id."' and then UPDATE ... SET offer_id = '".$sqlimplode."'";
You have to use two separate queries, one for INSERT and then another one for UPDATE
An Example:
$query = "INSERT INTO affilate_offer_getthumbnail_icube
(col_name) VALUES('".$col_Value."')";
//(execute it first);
$query2 = "UPDATE affilate_offer_getthumbnail_icube SET
col_name= '".$col_Value."'" WHERE if_any_col = 'if_any_Value';
//(execute this next);
Try this:
$sqlimplode = implode(',', $sql);
if($rows>0)
{
/*$fields_values = explode(',',trim(array_shift($sql), "()"));
$combined_arr = array_combine(['offer_id','net_provider','logo2020','logo100'],$fields_values);
$sqlimplode = implode(', ', array_map(function ($v, $k) { return $k . '=' . $v; }, $combined_arr, array_keys($combined_arr))); */
$query = "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode." ON duplicate key update net_provider = values(net_provider),logo2020 = values(logo2020),logo100 = values(logo100)";
$stmt->prepare( $query);
$execute = $stmt->execute();
}
else
{
$sqlimplode = implode(',', $sql);
$query= "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode;
$stmt->prepare( $query);
$execute = $stmt->execute();
}
Im having problems getting an update function to work. The function marks badges as seen so that they are hidden from a notification window.
The function is called when the user clicks a button to mark them as seen.
I have two triggers on the table its trying to update which I think may be causing the problem.
The problem is : Can't update table 'users' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Triggers:
Function:
function markAsSeen() {
require "connect.php";
$seen = mysqli_query($connection,"Update userbadges
INNER JOIN users ON users.id = userbadges.user_id
SET seen='1'
WHERE studentid = '".$_SESSION["studentid"]."' && seen=0") or die(mysqli_error($connection));
while ($data = mysqli_fetch_array($seen)) {
echo 'Done';
}
}
Is there any way around this?
Your issue is that the update_users_trigger trigger makes changes to the contents of the table users, while the query that is triggering the execution of this trigger also uses the table users.
You will need to adjust your query so that this deadlock doesn't occur. It isn't clear which fields are from each table, but I suspect that in your initial query you need to join on users so that you can query on studentid.
You could create a different function to get the userID that you need something like the following:
require_once "connect.php";
function getUserIDFromStudentID($student_id, mysqli $connection)
{
$query = 'SELECT id FROM users WHERE studentid = ? LIMIT 1';
$stmt = $connection->prepare($query);
// Replace the below s to an i if it's supposed to be an integer
$stmt->bind_param("s", $student_id);
$stmt->execute();
$result = $stmt->get_result();
$record = $result->fetch_object();
$result->free();
if ($record) {
return $record->id;
}
}
function markAsSeen(mysqli $connection) {
$user_id = getUserIDFromStudentID($_SESSION["studentid"], $connection);
if (! $user_id) {
throw new Exception('Unable to get user id');
}
$seen_query = 'UPDATE userbadges SET seen = 1 WHERE user_id = ? and seen = 0';
$stmt = $connection->prepare($seen_query);
// Replace the below s to an i if it's supposed to be an integer
$stmt->bind_param("s", $user_id);
$result = $stmt->execute();
if (! $result) {
die(mysqli_error($connection));
}
echo 'Done';
}
Passing the connection object around rather than requiring a global file to be required every time will allow for more flexibility.
I can do it with php/mysqli with multiple step.
So, table have only two column.
ID, Name
Both of then will be unique.
I want to check if Name is available in the database, get the ID if it is available.
If it is not available, add Name on the database and get the ID.
I can do it with php/mysql which need multiple sql query.
Is there a way do it (checking database, if not exist add it and get the ID) only with one mysql query and get the ID?
Thanks in advance!
My code (MySQLi Procedural)
function abc($name) {
global $conn;
$checkName = mysqli_query($con,"SELECT * FROM category WHERE name=".mysql_real_escape_string($name));
if (mysqli_num_rows($checkName) > 0) {
$inputName = mysqli_query($con,"INSERT INTO category (name) VALUES ('".mysql_real_escape_string($name)."')");
if (!$inputName) { die(mysqli_error($conn)); }
$checkName2 = mysqli_query($con,"SELECT * FROM category WHERE name=".mysql_real_escape_string($name));
while($blahblah = mysqli_fetch_assoc($checkName2)) {
$returnData[] = $blahblah;
}
} else {
while($blahblah = mysqli_fetch_assoc($checkName)) {
$returnData[] = $blahblah;
}
}
return $blahblah;
}
This can be done with just one line. Use "INSERT IGNORE INTO.." or "REPLACE INTO....". This page refers.
If you use the Object-Oriented MySQLi, this is how you do it:
$mysqli = new mysqli(...);
$name = "Something";
$query = $mysqli->prepare("SELECT id, name FROM table WHERE name=?");
$query->bind_param('s', $something);
$query->execute();
$query->bind_result($id, $name);
$query->store_result();
if($query->num_rows == 1) {
return $id;
} else {
$queryTwo = $this->mysqli->prepare("INSERT INTO table VALUES('', ?);");
$queryTwo->bind_param('s', $name);
$queryTwo->execute();
$queryTwo->close();
$queryThree = $this->mysqli->prepare("SELECT id FROM table WHERE name=?");
$queryThree->bind_param('s', $name);
$queryThree->execute();
$queryThree->bind_result($id);
$queryThree->store_result();
while($queryThree->fetch()) {
return $id;
}
$queryThree->free_result();
$queryThree->close();
}
$query->free_result();
$query->close();
I have the follow Model class, which all my models extends.
class Model {
[...]
protected static $_query; // Query preparated
public function prepare($query = null) {
[...] // Connect to PDO, bla bla bla
self::$_query = self::$link->prepare($query);
}
[...]
}
class Login extends Model {
public function getUser($username = null) {
self::prepare('SELECT * FROM usuarios WHERE usuario = :username LIMIT 1');
self::bindValue('username', $username);
return self::fetch();
}
}
The problem is, I need to insert prefix to my mysql, to avoid table conflicts, but don't want to edit all my querys.
clientone_tablename
clienttwo_tablename
clientthree_tablename
How I can do this, parse and insert table prefix when prepare the query?
I have not tried nothing because what I know is, extend my custom PDO to PHP PDO class, which is not much now..
I have seen this: PDO - Working with table prefixes. But don't worked propertly..
Thanks!
So i've assume you have only 1 MySQL database (minimum package on your webhost) and need to store a copy of a system for each of your clients.
What I was suggesting, is that you create a separate set of tables as you already are (for each client), but the name wont matter because you have a look-up of the table names in your clients table.
Heres my example for you: The clients table should store the table names of their own tables
(e.g. users_tbl = clientone_users for client id:1) So that later on you can just query the clients table and get his/her table names, then use that result to query on his/her user, news, pages, and files tables.
# SQL: new table structure
-- store the names of the clients tables here
CREATE TABLE clients(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
name VARCHAR(50),
address VARCHAR(250),
email VARCHAR(50),
pass BLOB,
/* table names*/
users_tbl VARCHAR(70),
news_tbl VARCHAR(70),
pages_tbl VARCHAR(70),
files_tbl VARCHAR(70)
) ENGINE = InnoDB;
# PHP: Some definitions for the table structure
$tbl_names = array("_users","_news","_pages","_files");
$tbl_fields = array();
$tbl_fields[0] = array("id INT","users_col1 VARCHAR(10)","users_col2 VARCHAR(20)");
$tbl_fields[1] = array("id INT","news_col1 DATE",...);
$tbl_fields[2] = array(...);
$tbl_fields[3] = array(...);
// refers to YOUR clients table field names (see above)
$clients_fields = array("users_tbl", "news_tbl", "pages_tbl", "files_tbl");
# PHP: Create a user and create the users database
function createUser($name, $address, $email, $pass, $salt) {
global $db, $tbl_names, $tbl_fields;
$success = false;
if ($db->beginTransaction()) {
$sql = "INSERT INTO clients(name, address, email, pass)
VALUES (?, ?, ?, AES_ENCRYPT(?, ?));"
$query = $db->prepare($sql);
$query->execute(array($name, $address, $email, $pass, $salt));
if ($query->rowCount() == 1) { # if rowCount() doesn't work
# get the client ID # there are alternative ways
$client_id = $db->lastInsertId();
for ($i=0; $i<sizeof($tbl_names); $i++) {
$client_tbl_name = $name . $tbl_names[$i];
$sql = "CREATE TABLE " . $client_tbl_name . "("
. implode(',', $tbl_fields[$i]) . ");";
if (!$db->query($sql)) {
$db->rollBack();
return false;
} else {
$sql = "UPDATE clients SET ".clients_fields[$i]."=? "
."WHERE id=?;";
$query = $db->prepare($sql);
if (!$query->execute(
array($client_tbl_name, (int)$client_id)
)) {
$db->rollBack();
return false;
}
}
}
$db->commit();
$success = true;
}
if (!$success) $db->rollBack();
}
return $success;
}
# PHP: Get the Client's table names
function getClientsTableNames($client_id) {
$sql = "SELECT (users_tbl, news_tbl, pages_tbl, files_tbl)
FROM clients WHERE id=?;";
$query = $db->prepare($sql);
if ($query->execute(array((int)$client_id)))
return $query->fetchAll();
else
return null;
}
# PHP: Use the table name to query it
function getClientsTable($client_id, $table_no) {
$table_names = getClientsTableNames($client_id);
if ($table_names != null && isset($table_names[$table_no])) {
$sql = "SELECT * FROM ".$table_names[$table_no].";";
$query = $db->prepare($sql);
if ($query->execute(array((int)$client_id)))
return $query->fetchAll();
}
return null;
}
Just rewrite your queries to use a table prefix found in a variable somewhere. Parsing all your queries for tablenames is more trouble than it is worth. (Do you really want to write an SQL parser?)