I'm quite new with PHP and need help coding an add script for my web site. I have coded the delete and update side and they are working perfectly. Basically, on secdtions of my web site you can add values to several text boxes and what I want is that when you click on 'Add' this will add the details from the textboxes to the database. To do this I am using PHP, Jquery and Ajax.
This is the code I have for the update script:
public function update($tableName,$fieldArray,$fieldValues,$rowId,$updateCondition)
{
// Get PDO handle
$PDO = new SQL();
$dbh = $PDO->connect(Database::$serverIP, Database::$serverPort, Database::$dbName, Database::$user, Database::$pass);
// Build query
$this->sql = 'UPDATE '.$tableName.' SET ';
$fieldCount = count($fieldArray);
for ($i = 0; $i < $fieldCount; $i++){
// If the index is at the last field...
$lastRow = $fieldCount - 1;
if ($i != $lastRow) {
// Add a comma
$this->sql .= $fieldArray[$i].'=:'.$fieldArray[$i].', ';
} else {
// Dont add a comma
$this->sql .= $fieldArray[$i].'=:'.$fieldArray[$i].' ';
}
}
// If row id is null (if we don't know the row id)...
if ($rowId == null || $rowId == "null") {
// Then use the update condition in it's place
$this->sql .= 'WHERE '.$updateCondition.' ';
} else {
// Use the ID
$this->sql .= 'WHERE Id = '.$rowId.' ';
}
try {
// Query
$stmt = $dbh->prepare($this->sql);
// Bind parameters
for ($i = 0; $i < $fieldCount; $i++){
$stmt->bindParam(':'.$fieldArray[$i].'', $fieldValues[$i]);
}
$stmt->execute();
$count = $stmt->rowCount();
echo $count.' row(s) affected by SQL: '.$stmt->queryString;
$stmt->closeCursor();
}
catch (PDOException $pe) {
echo 'Error: ' .$pe->getMessage(). 'SQL: '.$stmt->queryString;
die();
}
// Close connection
$dbh = null;
}
This is the part I am struggling to code, if you look at the code I have used for my update script.. I basically need something similiar to use for my 'add' script.
Any help will be much appreciated!!
Welcome to PHP! It is really a wonderful language :)
Try this:
<?php
public function insert($tableName,$fieldArray,$fieldValues)
{
$sql = "INSERT INTO " . $tableName . " (".implode(',', $fieldArray).") VALUES (".implode(',', $fieldValues).")";
// TODO: Execute $sql query
}
You should basically write out your functions and then at the end print out the resulting SQL statements it creates. Once you're able to see them from that level, you can try them in a query browser to see if you're constructing them correctly.
Related
I am working on a website where I can accept user data through multiple different forms to update tables in a database and instead of writing separate functions for each I thought it would be a good idea to use string concatenation and for loops to write the SQL statements for me. Basically it takes in 4 parameters a table, id, the columns that need to be updated (params) and an array of user input. I believe that I am pretty close to what I need but it fails to execute and gives me an error of
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(name,comment) VALUES ( 'sadf','asdf') WHERE music_work_ID=14' at line 1
This is what is displayed when I print out $sql,
sql = UPDATE music_work SET (name,comment) VALUES ( :name,:comment) WHERE music_work_ID=14
I don't know if theres a better way of creating something like this or if i'm not using the correct syntax but for now I am at a deadlock.
function music_work_update($userInput, $userID_selection){
foreach ($userInput as $k => $v) {
if($userInput[$k] === '') {
unset($userInput[$k]);
}
}
update("music_work", $userID_selection, ["name", "comment"], $userInput);
}
function update($table, $userID_selection, $params, $input){
$conn = connect();
try {
$sql = "UPDATE ".$table." SET (";
for ($i = 0; $i < sizeof($params); $i++) {
$sql .= "`".$params[$i]."`,";
}
$sql = substr_replace($sql ,"", -1);
$sql .= ") VALUES ( ";
for ($i = 0; $i < sizeof($params); $i++) {
$sql .= ":".$params[$i].",";
}
$sql = substr_replace($sql ,"", -1);
$sql .= ") WHERE `music_work_ID`=$userID_selection";
echo ("sql = $sql <br>");
$command = $conn->prepare($sql);
for ($i = 0; $i < sizeof($params); $i++) {
$command->bindParam(':'.$params[$i], $input[$params[$i]], PDO::PARAM_STR);
}
if ($command->execute()) {
echo "<script type= 'text/javascript'>alert('New Record Inserted Successfully');</script>";
}
else{
echo "<script type= 'text/javascript'>alert('Data not successfully Inserted.');</script>";
}
echo "failed before execute";
$conn = null;
}
catch(PDOException $e)
{
echo ($e->getMessage());
}
}
You confuse multiple INSERT INTO and multiple UPDATE.
For multiple UPDATE use:
UPDATE music_work SET name = x, comment = y WHERE id = z;
For multiple INSERT INTO:
INSERT INTO table_name (column_list)
VALUES
(value_list_1),
(value_list_2);
I'm trying to create a system, where my website generates an unique code (current date + 5 random characters) and that code is transferred to a table in my database.
Before function generateNumber() can insert the unique code into the database, it has to check if the code already exist in the database.
If the code doesn't exist, my function works flawlessly. But the problem is when the code can already be found on the database, my website just doesn't do anything (it should just re-run the function).
function generateNumber()
{
global $conn;
$rand = strtoupper(substr(uniqid(sha1(time())),0,5));
$result = date("Ydm") . $rand;
$SQL = $conn->query("SELECT code FROM test WHERE code='$result'");
$c = $SQL->fetch(PDO::FETCH_ASSOC);
if ($c['code'] > 0) { // test if $result is already in the database
generateNumber();
} else {
$sql2 = "INSERT INTO test (code) VALUES (?)";
$stmt2 = $conn->prepare($sql2);
$stmt2->execute([$result]);
return $result;
}
}
try {
$conn = new PDO("sqlite:db"/*, $username, $password*/);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo generateNumber();
}
catch(PDOException $e) {
echo "Error:" . $e->getMessage();
}
$conn = null;
?>
There are no error messages in the console, but I suspect the problem is this part of the code:
if ($c['code'] > 0) { // test if $result is already in the database
generateNumber();
}
Any idea how I can write this function in a better way?
Solution :
if ($c['code'] > 0) { // test if $result is already in the database
// if the code exists in db the function return nothing
// because you are missing a return :
return generateNumber();
}
I have a fairly basic script (i'm used to mysql but i'm moving to mysqli)
<?php
include("../includes/functions.php");
/////////////////////////////////////////////////////////////////////////
$debugMode = 1;
/////////////////////////////////////////////////////////////////////////
if (isset($_GET['u']))
{
// database connection
$c = mysqli_connect("localhost", "xxx", "xxx", "xxx");
// initial query to check if the domain is already in the database
$q = $c->query("SELECT * FROM `domains` WHERE `domain_name`='".trim($s[0])."'");
$v = $q->fetch_assoc();
$r = $q->num_rows;
// check if the string exists in the database
if ($r > 0)
{
// do not enter if greater than 0
} else {
// vars
$u = $_GET['u'];
// DEBUG
if ($debugMode)
{
$fp = fopen('u.txt', 'a');
fwrite($fp, "$u" . "\n");
fclose($fp);
}
// do a split of "|"
$s = explode("|", $u);
// check alexa rank and update
$alexa = alexa_rank($s[0]);
// check connection
if (mysqli_connect_errno())
{
echo mysqli_connect_error();
} else {
// insert query if there is no errors
$i = $c->query("INSERT INTO `domains` (`domain_id`,`domain_name`,`domain_pr`,`domain_alexa_rank`,`domain_moz_da`,`domain_moz_pa`,`domain_date`) VALUES ('','".$s[0]."','".$s[1]."','".$alexa."','".$s[2]."','".$s[3]."',NOW())");
}
}
} else {
header("Location: http://www.site.info/");
}
?>
It looks fairly simple, the problem is the count part isn't working, it's still adding to the database duplicate entries, i also tried:
mysqli_num_rows($q);
This still doesn't seem to work, am i missing something simple?
thanks guys
You should first be sure your query is right.
So please debug your code like that;
$SQL = "SELECT * FROM `domains` WHERE domain_name`='".trim($s[0])."'";
echo "My Query: ". $SQL;
$q = $c->query($SQL);
I guess you have problem on your $s variable. If your sql query is right you can check $v variable have any record if $v variable is an array and have value you have more than one record and you can pass to insert statements if not you can add.
ahh thank you! i found my top query was failing because i was using the explode further down the code! thanks guys.
Am trying to save the result of multiple check-boxes as separate records. my code is not functioning. please help!
<?php
session_start();
$id = $_SESSION['user_id'];
$db = new PDO('mysql:host=localhost;dbname=idp;charset=utf8','root', '');
foreach($_POST['comp'] as $val){
$tmp['user_id'] = $id;
$tmp['comp_id'] = $val;
$vars[] = $tmp;
}
$qry = "INSERT INTO compentency_result (user_id, result) VALUES (:user_id, :comp_id)";
try
{
$sql = $db->prepare($qry);
$numRows = 0;
foreach($vars as $insert){
$numRows += $sql->execute($insert);
}
print("<p>There were {$numRows} inserted into the database!</p>");
}
catch(PDOException $e)
{
print("<p>Oops! There was an issue - this is the message: {$e->getMessage()}</p>");
}
?>
The result is showing me that nothing is added to the database.
To bind the parameters individually you would do this:
try
{
$sql = $db->prepare($qry);
$numRows = 0;
foreach($vars as $insert){
$sql->bindParam(':user_id', $insert['user_id'], PDO::PARAM_STR);
$sql->bindParam(':comp_id', $insert['comp_id'], PDO::PARAM_STR);
$sql->execute();
$numRows += $sql->rowCount(); // get the rows affected this way
}
echo "<p>There were {$numRows} inserted into the database!</p>";
}
In addition, I added a more proper and reliable method of getting the affected rows, using rowCount().
If you don't want to bind the elements individually you can use execute() with an array as shown in Demystifying PDO
I am trying to create a PHP array of random "fruits" from a database.
The database class that I am using:
class Db
{
private static $_instance = null;
private $_pdo;
private function __construct()
{
try {
$this->_pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME .'', DB_USER, DB_PASS);
} catch (PDOException $e) {
die($e->getMessage());
}
}
public static function getInstance()
{
if (!isset(self::$_instance)) {
self::$_instance = new Db();
}
return self::$_instance;
}
public function prepare($sql)
{
return $this->_pdo->prepare($sql);
}
}
The class that is using the database to fetch "fruits" to create an array of a given size of random entries by using 3 seperate queries to calculate and retrieve "x" number of random items form the database.
class FruitBasket
{
private $_fruitArray = array(),
$_inputCode,
$_db;
public function __construct($input = null)
{
$this->_inputCode = $input;
$this->_db = Db::getInstance();
var_dump($this->_db);
}
public function pickFruit($count)
{
$doubleCount = $count * 2;//double the count used in calculation with the random number
$fruitIDs = ''; //the choosen fruits (id's)
$i = 0;
//#1 get total count of fruits table
$sql = "SELECT COUNT(*) FROM `fruits`";
if ($query = $this->_db->prepare($sql)) {
if ($query->execute()) {
$allFruits = $query->fetch(PDO::FETCH_NUM);
} else {
print_r("ERROR QUERY DID NOT EXECUTE #1");
}
} else {
print_r("ERROR CHECK SQL SYNTAX #1");
}
//#2 calculate random number to pull from all of id's
$sql = "SELECT id FROM `fruits` WHERE RAND()* ? < ? ORDER BY RAND() LIMIT 0, ? ";
if ($query = $this->_db->prepare($sql)) {
$query->bindParam(1, $allFruits[0], PDO::PARAM_INT);
$query->bindParam(2, $doubleCount, PDO::PARAM_INT);
$query->bindParam(3, $count, PDO::PARAM_INT);
if ($query->execute()) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
if ($i == 0) {
$fruitIDs .= "'" . $row['id'] . "'";
} else {
$fruitIDs .= ", '" . $row['id'] . "'";
}
$i++;
}
} else {
print_r("ERROR QUERY DID NOT EXECUTE #2");
}
} else {
print_r("ERROR CHECK SQL SYNTAX #2");
}
//#3 get the fruits
$sql="SELECT NAME FROM `fruits` WHERE `id` IN( ? )";
if ($query = $this->_db->prepare($sql)) {
$query->bindParam(1, $fruitIDs, PDO::PARAM_STR);
if ($query->execute()) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$this->_fruitArray[] = $row['name'];
}
} else {
print_r("ERROR QUERY DID NOT EXECUTE #3");
}
} else {
print_r("ERROR CHECK SQL SYNTAX #3");
}
return $this->_fruitArray;
}
}
The table that I am attempting has a bunch of "fruits" in it, an example of how the table is structured:
==================================
| ID | NAME |
==================================
| 01 | Apple |
==================================
I am attempting to test this all out by using the following:
echo "<pre>";
echo "TESTING FRUIT ARRAY:</br></br>";
$basket = new FruitBasket();
echo"</br></br> PRINT_R: </br></br>";
print_r($basket->pickFruit(10));
echo "</br></br> VARDUMP: </br></br>";
var_dump($basket->pickFruit(10));
The sql query prepares and executes properly, I can do a vardump of the prepares and the binds and they return TRUE. Nothing is returned on the last query however.
In the first query that executes Doing a print statement of $allFruits shows the correct total count from the table.
The second query seems to be working properly,the string $fruitIDs, gets random id's from the table, I can echo this out and confirm that indeed the correct number of ID's are returned.
The problem occurs (I think) with the third query:
Nothing is returned form this query. The prepare statement returns true on a var dump as does the execute, however there is no results!
If I manually take the ID's that are output from query#2 and run it myself in mysql, the correct "fruit" names are returned.
Am I binding the variables incorrectly? I read the pages from the PHP manual but clearly I am doing something wrong.
Please help! :)
Thanks to the links and input provided by Your common sense, using the following:
Reference - frequently asked questions about PDO
and
Can I bind an array to an IN() condition?
I was able to resolve this by changing my query as follows:
//#2 calculate random number to pull from all of id's
$sql = "SELECT id FROM `fruits` WHERE RAND()* ? < ? ORDER BY RAND() LIMIT 0, ? ";
if ($query = $this->_db->prepare($sql)) {
$query->bindParam(1, $allFruits[0], PDO::PARAM_INT);
$query->bindParam(2, $doubleCount, PDO::PARAM_INT);
$query->bindParam(3, $count, PDO::PARAM_INT);
if ($query->execute()) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$fruitIDs[] = $row['id'];
}
} else {
print_r("ERROR QUERY DID NOT EXECUTE #2"); }
} else {
print_r("ERROR CHECK SQL SYNTAX #2");
}
//#3 get the fruits
$inQuery = implode(',', array_fill(0, count($fruitIDs), '?'));
$sql="SELECT NAME FROM `fruits` WHERE `id` IN($inQuery)";
if ($query = $this->_db->prepare($sql)) {
if ($query->execute($fruitIDs)) {
while ($row = $query->fetch(PDO::FETCH_NUM)) {
$this->_fruitArray[] = $row[0];
}
} else {
print_r("ERROR QUERY DID NOT EXECUTE #3");
}
} else {
print_r("ERROR CHECK SQL SYNTAX #3");
}
return $this->_fruitArray;
}
I do not fully understand the security benefits or ramifications of binding the parameters or simply including them in the actual execute() but for now the query is performing as intended, so thank you for the input!