Sorry for the confusing question, I'm a beginner looking for some improvements to my code.
What I'm currently trying to do is "Linking" a mysql value to another.
Here's an example :
I'm creating a PHP-based fight
There is a database named "fightm" which contains important informations
Some of the informations are the ATTACKS and the COOLDOWN
I want to simplify my code by having ATTACK and COOLDOWN linked together
To clarify, I'll give you some code (Don't forget that I'm a beginner, if this is bad written you can correct me)
if (isset($_POST['fdd_attackbas1']) AND ($infomonstre["fightm_cdbas1"] < 1)) {
$query = $db->prepare('UPDATE users SET vieac=(vieac - :damage ) WHERE username=:username');
$query->bindValue(':username', $username, PDO::PARAM_INT);
$query->bindValue(':damage', $damage, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
$query = $db->prepare('UPDATE fightmonster SET
fightm_life=(fightm_life - :atqb),
fightm_dmgperso=:atqb,
fightm_dmgenemy=:damage,
fightm_cdfuite=GREATEST(0, fightm_cdfuite - 1),
fightm_cdbas1=(fightm_cdbas1 + 1),
fightm_cdbas2=GREATEST(0, fightm_cdbas2 - 1),
fightm_cdbas3=GREATEST(0, fightm_cdbas3 - 1),
fightm_cdrare1=GREATEST(0, fightm_cdrare1 - 1),
fightm_cdrare2=GREATEST(0, fightm_cdrare2 - 1),
fightm_cdultime=GREATEST(0, fightm_cdultime - 1)
WHERE player_id =:id');
$query->bindParam(':id', $donnees['id'], PDO::PARAM_INT);
$query->bindValue(':damage', $degatreduiteffet, PDO::PARAM_INT);
$query->bindValue(':atqb', $atkboosteffet, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
header("Refresh:0");
exit();
}
if (isset($_POST['fdd_attackbas2']) AND ($infomonstre["fightm_cdbas2"] < 1)) {
$query = $db->prepare('UPDATE users SET vieac=(vieac - :damage ) WHERE username=:username');
$query->bindValue(':username', $username, PDO::PARAM_INT);
$query->bindValue(':damage', $damage, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
$query = $db->prepare('UPDATE fightmonster SET
fightm_life=(fightm_life - :atqb),
fightm_dmgperso=:atqb,
fightm_dmgenemy=:damage,
fightm_cdfuite=GREATEST(0, fightm_cdfuite - 1),
fightm_cdbas1=GREATEST(0, fightm_cdbas1 - 1),
fightm_cdbas2=(fightm_cdbas2 + 1),
fightm_cdbas3=GREATEST(0, fightm_cdbas3 - 1),
fightm_cdrare1=GREATEST(0, fightm_cdrare1 - 1),
fightm_cdrare2=GREATEST(0, fightm_cdrare2 - 1),
fightm_cdultime=GREATEST(0, fightm_cdultime - 1)
WHERE player_id =:id');
$query->bindParam(':id', $donnees['id'], PDO::PARAM_INT);
$query->bindValue(':damage', $degatreduiteffet, PDO::PARAM_INT);
$query->bindValue(':atqb', $atkboosteffet, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
header("Refresh:0");
exit();
}
As you can see, i'm repeating myself for each "attack". Now, imagine that I have more than 20 attacks ! That would be insane.
What i would like to do is something this way (THE CODE I WANT BUT WITH COMMENTS FOR THE CODE PARTS I DON'T KNOW)
if (isset(//One of the attack//) AND (// The CD linked to the attack //)) {
$query = $db->prepare('UPDATE users SET vieac=(vieac - :damage ) WHERE username=:username');
$query->bindValue(':username', $username, PDO::PARAM_INT);
$query->bindValue(':damage', $damage, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
$query = $db->prepare('UPDATE fightmonster SET
fightm_life=(fightm_life - :atqb),
fightm_dmgperso=:atqb,
fightm_dmgenemy=:damage,
// COOLDOWN PART, SAME BUT WITHOUT NEEDING TO CHANGE //
WHERE player_id =:id');
$query->bindParam(':id', $donnees['id'], PDO::PARAM_INT);
$query->bindValue(':damage', $degatreduiteffet, PDO::PARAM_INT);
$query->bindValue(':atqb', $atkboosteffet, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
header("Refresh:0");
exit();
}
This would be very helpful, but I can't understand how it can be done.
Thanks you and sorry for the long text !
Restructure your code into a foreach loop like this:
$keys = ['fdd_attackbas1', 'fdd_attackbas2', ..];
foreach ($keys as $key) {
if (isset[$key] && ..) {
..
exit();
}
}
Related
Could someone please assist / advise on what I could do in order to make the last four search fields / inputs optional (along with AND statements) in the SQL query?
I have tried the code below but it doesn't seem to make the last four fields optional:
public static function findBySearch($location, $category, $type, $bedrooms, $bathrooms, $minamount, $maxamount)
{
$db = static::getDB();
$sql = 'SELECT * FROM posts
WHERE location = :location
AND category LIKE :category
AND type LIKE :type
AND
(:bedrooms IS NULL OR bedrooms = :bedrooms)
AND
(:bathrooms IS NULL OR bathrooms = :bathrooms)
AND
(:minamount IS NULL OR amount >= :minamount)
AND
(:maxamount IS NULL OR amount <= :maxamount)';
$stmt = $db->prepare($sql);
$stmt->bindValue(':location', $location, PDO::PARAM_STR);
$stmt->bindValue(':category', $category, PDO::PARAM_STR);
$stmt->bindValue(':type', $type, PDO::PARAM_STR);
$stmt->bindValue(':bedrooms', $bedrooms, PDO::PARAM_INT);
$stmt->bindValue(':bathrooms', $bathrooms, PDO::PARAM_INT);
$stmt->bindValue(':minamount', $minamount, PDO::PARAM_INT);
$stmt->bindValue(':maxamount', $maxamount, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_CLASS, get_called_class());
return $result;
}
The following code runs with no errors but on the DB i still get those values=0.
$id=$_REQUEST['id'];
$ectoTOT=9;
$mesoTOT=1;
$endoTOT=5;
$sql = 'UPDATE utenti2 SET ectoTOT=:ectoTOT,endoTOT=:endoTOT,mesoTOT=:mesoTOT WHERE id=:id';//:nome parametri
$rs = $db->prepare($sql);
//collego le variabili al parametro e faccio sanificazione
$rs->bindValue(':id', $id, PDO::PARAM_INT);
$rs->bindValue(':ectoTOT', $ectoTOT, PDO::PARAM_INT);
$rs->bindValue(':mesoTOT', $mesoTOT, PDO::PARAM_INT);
$rs->bindValue(':endoTOT', $endoTOT, PDO::PARAM_INT);
$rs->execute();
echo 'OK';
exit;
Now it works... had multiple query on the same page and left $result instead of $rs
Same column binded value twice ectoTOT .And missing to bind one column endoTOT
$rs->bindValue(':ectoTOT', $ectoTOT, PDO::PARAM_INT);
Change to
$rs->bindValue(':id', $id, PDO::PARAM_INT);
$rs->bindValue(':ectoTOT', $ectoTOT, PDO::PARAM_INT);
$rs->bindValue(':mesoTOT', $mesoTOT, PDO::PARAM_INT);
$rs->bindValue(':endoTOT', $endoTOT, PDO::PARAM_INT);
I have 3 queries named $stmt9, $stmt10 and $stmt11. I need to run the query in order, e.g. run 9, then 10, and finally 11. If there is something wrong, I want to rollback the queries that have been done, e.g. if the problem is on 10, it should rollback 9, or if on 11, then should roll back 10 and 9.
I have the following code, but when something is wrong, sometimes it still runs $stmt9 only, or $stmt9 and $stmt10 but not $stmt11.
How to fix it?
This is the update action:
$this->conn->beginTransaction();
$stmt9 = $this->conn->prepare("UPDATE tableONE SET condition= :condition WHERE `tb1_id`= :id LIMIT 1");
condition
$id = Check_Get_Param($_GET['id']);
$stmt9->bindParam(':condition' , $this->condition);
$stmt9->bindParam(':id' , $id, PDO::PARAM_INT);
$stmt9->execute();
$stmt10 = $this->conn->prepare("UPDATE tableTOW SET disterbute = :dis WHERE tb2_id = :tbl2id LIMIT 1");
$stmt10->bindParam(":counting", $this->counting, PDO::PARAM_INT);
$stmt10->bindParam(":tbl2id ", $this->tbl2id , PDO::PARAM_INT);
$stmt10->execute();
$stmt11 = $this->conn->prepare("DELETE FROM tableTHREE WHERE tb3_id = :id limit 1");
$stmt11->bindParam(":id",$id, PDO::PARAM_INT);
$stmt11->execute();
if($stmt9 && $stmt10 && $stmt11){
$this->conn->commit(); //This will save my changes
header('location:../success.php');
exit;
} else {
$this->conn->rollBack(); //This will undo your changes
echo '<meta http-equiv="refresh" content="0">'. $message;
}
}
}
What you are looking for is called a transaction.
I checked and it is implemented in pdo.
Example taken from the documentation:
<?php
/* Begin a transaction, turning off autocommit */
$dbh->beginTransaction();
/* Change the database schema and data */
$sth = $dbh->exec("DROP TABLE fruit");
$sth = $dbh->exec("UPDATE dessert
SET name = 'hamburger'");
/* Recognize mistake and roll back changes */
$dbh->rollBack();
/* Database connection is now back in autocommit mode */
?>
http://php.net/manual/en/pdo.begintransaction.php
I have two stored procedures in my database Postgres, both have the same name but the difference are the parameters.
procedure1(::string, ::integer, ::string, ::integer)
procedure1(::string, ::integer, ::integer)
In PDO doing bindParam correct, is coming STR, INT, INT but the prepere always performs procedure1.
How do I get him to understand what I call the procedure2?
Some information for more help? I clear? thanks
EDIT ===
...
$bounds = null; // forced for debug
if(!is_null($bounds)){
$query = "SELECT procedure1(:name, :domain, :geo, :userid)";
$stmt = $db->prepare($query);
$stmt->bindParam('name', $name, PDO::PARAM_STR);
$stmt->bindParam('domain', $idDomain, PDO::PARAM_INT);
$stmt->bindParam('geo', $geoString, PDO::PARAM_STR);
$stmt->bindParam('userid', $userId, PDO::PARAM_INT);
}else{
$query = "SELECT procedure1(:name, :domain, :userid)";
$stmt = $db->prepare($query);
$stmt->bindParam('name', $name, PDO::PARAM_STR);
$stmt->bindParam('domain', $idDomain, PDO::PARAM_INT);
$stmt->bindParam('userid', $userId, PDO::PARAM_INT);
}
$result = $stmt->execute();
...
The error it gives is that he is running a procedure that requires four parameters
Try changing your $query statements to explicitly tell PDO the types, and to avoid extra code switch to bindValue (PDO uses the PARAM flags to format SQL, not to cast data types):
$bounds = null; // forced for debug
if(!is_null($bounds)){
$query = "SELECT procedure1(:name::VARCHAR, :domain::INTEGER, :geo::VARCHAR, :userid::INTEGER)";
$stmt = $db->prepare($query);
$stmt->bindValue('name', $name);
$stmt->bindValue('domain', $idDomain);
$stmt->bindValue('geo', $geoString);
$stmt->bindValue('userid', $userId);
}else{
$query = "SELECT procedure1(:name::VARCHAR, :domain::INTEGER, :userid::INTEGER)";
$stmt = $db->prepare($query);
$stmt->bindValue('name', $name);
$stmt->bindValue('domain', $idDomain);
$stmt->bindValue('userid', $userId);
}
$result = $stmt->execute();
I have other PDO Statements that execute fine, but this one is screwed up.
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->execute( array( 0, 10 ) );
The above does NOT work, but the below does work:
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT 0,10' );
$sth->execute( array( 0, 10 ) );
So why won't the first way display any of my results when it should be giving the same response?
So here is what I have now
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, $start, PDO::PARAM_INT);
$sth->bindValue(2, $perpage, PDO::PARAM_INT);
$sth->execute();
this also does not work
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindParam(1, 0, PDO::PARAM_INT);
$sth->bindParam(2, 10, PDO::PARAM_INT);
$sth->execute();
The problem is likely that PDO will interpret any inputs as strings. You can try
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :low,:high' );
$sth->bindValue(':low', 0, PDO::PARAM_INT);
$sth->bindValue(':high', 10, PDO::PARAM_INT);
$sth->execute();
Or
$low = 0;
$high = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :low,:high' );
$sth->bindParam(':low', $low, PDO::PARAM_INT);
$sth->bindParam(':high', $high, PDO::PARAM_INT);
$sth->execute();
Source: How to apply bindValue method in LIMIT clause?
Not sure if you saw this question but have you tried casting the values you send as ints?
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, (int)$start, PDO::PARAM_INT);
$sth->bindValue(2, (int)$perpage, PDO::PARAM_INT);
$sth->execute();
Or it says to do this:
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, intval($start), PDO::PARAM_INT);
$sth->bindValue(2, intval($perpage), PDO::PARAM_INT);
$sth->execute();
This is because "prepare" and execute with array argument thinks your datas are string by default. So they escape them with ' '. THe problem is that when you deal with limits those quotes trigger error.
The solution is bindValue
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :number OFFSET :start' );
$sth->bindValue("number",10, PDO::PARAM_INT);
$sth->bindValue("start",0,PDO::PARAM_INT);
$sth->execute();
What database? MySQL? SQL Server? Oracle?
In MySQL the PDO with LIMIT clause should work as in GlaciesofPacis's post. However, if you are using SQL SERVER you're not using the correct syntax. Referenced from StackOverflow question:
$query = "
DECLARE #Sort
SET ROWCOUNT :startRow
SELECT #Sort = SortColumn FROM Table ORDER BY SortColumn
SET ROWCOUNT :pageSize
SELECT ... FROM Table WHERE SortColumn >= #Sort ORDER BY SortColumn
";
$dbh->prepare($query);
$sth->bindParam(':startRow',0, PDO::PARAM_INT);
$sth->bindParam(':pageSize',10, PDO::PARAM_INT);
$sth->execute();