Ive got the next code
if ($_FILES['intrebare_img']['size'] > 0) {
$tmpName = $_FILES['intrebare_img']['tmp_name'];
$intrebare_img=addslashes(file_get_contents($tmpName));
}
else
$intrebare_img = NULL;
if ($_FILES['opt1_img']['size'] > 0) {
$tmpName = $_FILES['opt1_img']['tmp_name'];
$opt1_img = addslashes(file_get_contents($tmpName));
}
else
$opt1_img = NULL;
if ($_FILES['opt2_img']['size'] > 0) {
$tmpName = $_FILES['opt2_img']['tmp_name'];
$opt2_img = addslashes(file_get_contents($tmpName));
}
else
$opt2_img = NULL;
if ($_FILES['opt3_img']['size'] > 0) {
$tmpName = $_FILES['opt3_img']['tmp_name'];
$opt3_img = addslashes(file_get_contents($tmpName));
}
else
$opt3_img = NULL;
$query = "INSERT INTO intrebari (intrebare_txt, intrebare_img, opt1_txt, opt1_img, opt2_txt, opt2_img, opt3_txt, opt3_img, raspuns_corect)
VALUES ('{$intrebare_txt}','{$intrebare_img}','{$opt1_txt}','{$opt1_img}','{$opt2_txt}','{$opt2_img}','{$opt3_txt}','{$opt3_img}','{$rsp_corect}')";
mysql_query($query) or die("Error, query failed");
When executed it's inserting values in the database, the only issue is that even when there is no file selected it's inserting [BLOB - 0 B] instead of NULL.
I think that my problem is generated by the ' ' around NULL values but can't figure a way around.
Thanks in advance !
The smart thing to do is use PDO or the like along with prepared statements. Let PDO do the heavy lifting and focus your efforts on solving other problems. It would also protect you from SQL injection vulnerabilities, which your code appears to be full of.
If you want to stick with depreciated mysql_ functions, you need to check each variable and remove the quotes from NULL values. Something along the lines of:
if ( $opt3_img !== NULL ) {
$opt3_img = "'".$opt3_img."'";
}
$query = sprintf('INSERT INTO intrebari SET opt3_img = %s', $opt3_img);
You would of course also want to put that functionality into a function to avoid repeating that code for every variable..
In the end, after a little research, I've rewritten the code so it uses PDO.
Here is the result :
$dbh = new PDO('mysql:dbname=dbname;host=127.0.0.1', user, password);
if ($stmt = $dbh->prepare ("INSERT INTO intrebari (intrebare_txt, intrebare_img, opt1_txt, opt1_img, opt2_txt, opt2_img, opt3_txt, opt3_img, raspuns_corect)
VALUES (:intrebare_txt, :intrebare_img, :opt1_txt, :opt1_img, :opt2_txt, :opt2_img, :opt3_txt, :opt3_img, :rsp_corect)"))
{
$stmt -> bindParam(':intrebare_txt', $_POST['intrebare_txt']);
$stmt -> bindParam(':opt1_txt', $_POST['opt1_txt']);
$stmt -> bindParam(':opt2_txt', $_POST['opt2_txt']);
$stmt -> bindParam(':opt3_txt', $_POST['opt3_txt']);
if ( isset ($_POST['rsp_corect']))
$stmt -> bindParam(':rsp_corect',$_POST['rsp_corect']);
else
echo '<script type="text/javascript">alert("Nu a fost selectat un raspuns valid!");window.location=\'intrebari.php\';</script>';
if ($_FILES['intrebare_img']['size'] > 0) {
$tmpName = $_FILES['intrebare_img']['tmp_name'];
$stmt -> bindParam(':intrebare_img', file_get_contents($tmpName));
}
else
$stmt -> bindValue(':intrebare_img', NULL);
if ($_FILES['opt1_img']['size'] > 0) {
$tmpName = $_FILES['opt1_img']['tmp_name'];
$stmt -> bindParam(':opt1_img', file_get_contents($tmpName));
}
else
$stmt -> bindValue(':opt1_img', NULL);
if ($_FILES['opt2_img']['size'] > 0) {
$tmpName = $_FILES['opt2_img']['tmp_name'];
$stmt -> bindParam(':opt2_img', file_get_contents($tmpName));
}
else
$stmt -> bindValue(':opt2_img', NULL);
if ($_FILES['opt3_img']['size'] > 0) {
$tmpName = $_FILES['opt3_img']['tmp_name'];
$stmt -> bindParam(':opt3_img', file_get_contents($tmpName));
}
else
$stmt -> bindValue(':opt3_img', NULL);
$stmt -> execute();
// close connection
$stmt->closeCursor();
$stmt = null;
$dbh = null;
sleep(60);
}
else echo "STM FAILED !!";
}
Due to a misleading answer from another question on this site first I've tried using a mysqli connection obviously that was a fail!
And another thing that I must mention for other people looking at the code is that in `
user and password are defined constants !
Related
try {$db=mysqli_connect( etc )
catch {
retry on time out
handle errors
}
try { if (!($errors = $db->prepare("insert into errors (`insert`,`error`) values(?,?);
print "\n*********prepare Error:" . $db->error;
}
}
catch { repeat above}
try {$errors->bind_param("ss",$sqlLoad,$errormsg); }
catch {repeat above)
....
try {$error->execute()} catch {repeat above error handling}
Now repeat all of that 10-40 times for different SQL queries on different fields.
That is a lot of duplicated code. Make my code hard to read, and if someone wants to add more sql queries they are forced to reduplicate large blocks of code.
I was thinking something like this but ran into a stumbling block with bind.
$sql[0]=array("name","select ? from <tablename>","s");
$sql[1]=array("name","select ?,? from <tablename>","ss");
$sql[2]=array("name","select ?,?,? from <tablename>","sss");
$sql[3]=array("name","select ?,?,?,? from <tablename>","ssss");
for(i=0;i<=3,i++){
try (
$preQuery[$sql[i][0]=$db->prepare($sql[i][1]);}
catch {}
try {$preQuery[$sql[i][0]]->bind_param($sql[i][2],????);} //Here is the trouble how do I define unique variables
catch { }
}
Here is some real code
It is a work in progress
foreach ($fieldspath as $field)
{
$filepath=$_SERVER[$field];
$result=$queryfile->execute();
$getres = $queryfile->get_result();
$numRows = -1;
$numRows = $getres->num_rows;
if ($numRows <>0)
{
$qryField = $getres->fetch_assoc();
$_SERVER[$field]=$qryField["id"];
$fileCount=$qryField["count"];
$fileRating=$qryField["rating"];
mysqli_query($db, "update Files set count=count+1 where `id` ='" . $qryField["id"] . "';");
continue;
}
else
{
$output = $insertFile->execute();
$result = $queryip->execute();
$getres = $queryip->get_result();
$qryField = $getres->fetch_assoc();
$_SERVER[$field]=$qryField["id"];
}
}
Notice: How I can re-execute a query just by:
$result=$queryfile->execute();
The query doesn't have to be re-stated, nor do the parameters. Everything is automatic. The actual queries are all listed at the top of the program, and I never have to see them, or restate them ever again. Also I don't need to cram my parameters into array before I can use them.
<?php
$pipeName = '/var/run/mysql/mysql.sock';
$username = 'user';
$password = 'password';
$db = new PDO('mysql:unix_socket='.$pipeName.";dbname=dbase", $username, $password);
$sql["errors"]="insert into errors (`insert`,`error`) values(:insert,:error);";
$sql["events"]="insert into event (`message`) values(?);";
$sql["queryip"]="select id,count,rating FROM ip where address=? limit 1;";
$sql["queryUsrAgent"]="select id,count,rating FROM http_user_agent where agent=? limit 1;";
$sql["insUsrAgent"]="insert into http_user_agent (`agent`) values (?);";
$sql["insertIP"]="insert into ip (`address`) values (?);";
$sql["insertReqURI"]="insert into request (`REQUEST_URI`) values (?);";
$sql["queryReqURI"]="select * FROM request where REQUEST_URI=? LIMIT 1;";
$sql["queryfile"]="select id,count,rating FROM Files where path=? limit 1;";
$sql["insertFile"]="insert into Files (`path`) values (?);";
$sql["cntIp"]="update ip set count=count+1 where `address` = :ip";
$sql["cntFiles"]="update Files set count=count+1 where `id` = :id;";
$sql["cntAgent"]="update http_user_agent set count=count+1 where `agent` = :agent;";
$sql["reqRequest"]="select * FROM request where REQUEST_URI= :requesturi LIMIT 1;";
$sql["cntRequest"]="update request set count=count+1 where `REQUEST_URI` = :requesturi;";
$ready=doPrepare($db,$sql);
$ready["errors"]->execute(array("insert"=>"stuff","error" =>"stuff"));
pdoRun($ready,"errors",array("iniisert"=>"iiiii","error" =>"yyyyyggg"));
function doPrepare($db, $enmass) {
foreach ($enmass as $key => $sql) {
try {
$stmt[$key] = $db->prepare($sql);
} catch (PDOException $e) {
print "\nStuff";
trigger_error($e);
return false;
}
}
return $stmt;
}
function pdoRun($ready,$query,$vals) {
try {
$ready[$query]->execute($vals);
} catch (PDOException $e) {
print "\nExecution fail";
}
}
// $stmt->execute(array_values($column_values));
?>
Making prepared queries like you are doing doesn't work like you seem to think it does. The parameter placeholders can only substitute for literal values. You can't use them for column names or table names or anything else.
You also can't prepare a query like "select ? from" because it names no table. It's not a syntactically complete query.
The better practice is to code a "helper function" that does the prepare and execute for you. You can reduce repetitive code that way.
By the way, I find PDO is much easier than Mysqli when coding a helper function like this, because you don't have to use the bind_param() with variable arguments. In PDO, you just pass an array of arguments to execute().
function doInsert($db, $sql, $params) {
try {
$stmt = $db->prepare($sql);
$stmt->execute($params);
} catch (PDOException $e) {
trigger_error($e);
return false;
}
return true;
}
Now call it this way:
$sql = "insert into errors (`insert`, `error`) values(?, ?)";
$success = doInsert($db, $sql, [$sqlLoad, $errormsg]);
You might even like the function to format your INSERT statement for you:
function doInsert($db, $table, $column_values) {
$placeholders = array_fill(1, count($column_values), '?');
$columns = implode(',', array_keys($column_values));
$sql = "INSERT INTO `$table` ($columns) VALUES ($placeholders)";
try {
$stmt = $db->prepare($sql);
$stmt->execute(array_values($column_values));
} catch (PDOException $e) {
trigger_error($e);
return false;
}
return true;
}
Then call it like this:
$success = doInsert($db, "errors", ["insert"=>$sqlLoad, "error"=>$errormsg]);
You'll have to do something to apply back-ticks to the column names too.
Ok, so I am having a lot of trouble with Prepared statements. I've done hours of research and still can't seem to fully understand everything...
I really feel like I need to understand Prepared statements because I was just about to release a few new free APIs on my website (which require API Key to execute API) but I recently realized how insecure everything is.... I can simply use SQL injection to bypass API Key check, e.g. 'OR'1'='1
Here is how I validate API Key:
$apikey = $_GET['key'];
$sql = "SELECT * FROM `table` WHERE `key` = '$apikey'";
$query = mysqli_query($con, $sql);
if($query)
{
$fetchrow = mysqli_fetch_row($query);
if(isset($fetchrow[0]))
{
echo "API Key is valid!";
}
else
{
echo "API KEY is invalid";
}
}
And like mentioned above this can easily be bypassed by executing my API like this
http://website.com/api.php?key='OR'1'='1
This really scared me at first, but then I did some research and learned a good way to prevent any form of SQL injection is to use prepared statement, so I did a lot of research and it just seems quite complicated to me :/
So I guess my question is, how can I take my above code, and make it function the same way using prepared statements?
Probably everything you need:
class Database {
private static $mysqli;
Connect to the DB:
public static function connect(){
if (isset(self::$mysqli)){
return self::$mysqli;
}
self::$mysqli = new mysqli("DB_HOST", "DB_USER", "DB_PASS", "DB_NAME");
if (mysqli_connect_errno()) {
/*Log error here, return 500 code (db connection error) or something... Details in $mysqli->error*/
}
self::$mysqli->query("SET NAMES utf8");
return self::$mysqli;
}
Execute statement and get results:
public static function execute($stmt){
$stmt->execute();
if ($mysqli->error) {
/*Log it or throw 500 code (sql error)*/
}
return self::getResults($stmt);
}
Bind results to the pure array:
private static function getResults($stmt){
$stmt->store_result();
$meta = $stmt->result_metadata();
if (is_object($meta)){
$variables = array();
$data = array();
while($field = $meta->fetch_field()) {
$variables[] = &$data[$field->name];
}
call_user_func_array(array($stmt, "bind_result"), $variables);
$i = 0;
while($stmt->fetch()) {
$array[$i] = array();
foreach($data as $k=>$v)
$array[$i][$k] = $v;
$i++;
}
$stmt->close();
return $array;
} else {
return $meta;
}
}
Class end :)
}
Example of usage:
public function getSomething($something, $somethingOther){
$mysqli = Database::connect();
$stmt = $mysqli->prepare("SELECT * FROM table WHERE something = ? AND somethingOther = ?");
$stmt->bind_param("si", $something, $somethingOther); // s means string, i means number
$resultsArray = Database::execute($stmt);
$someData = $resultsArray[0]["someColumn"];
}
Resolving your problem:
public function isKeyValid($key){
$mysqli = Database::connect();
$stmt = $mysqli->prepare("SELECT * FROM table WHERE key = ? LIMIT 1");
$stmt->bind_param("s", $key);
$results = Database::execute($stmt);
return count($results > 0);
}
PHP automatically closes DB connection so no worries about it.
$sql = "SELECT * FROM `table` WHERE `key` = ?";
if(stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $apikey);
$stmt->execute();
$stmt->bind_result($res);
$stmt->fetch();
$stmt->close();
}
See more - http://php.net/manual/en/mysqli.prepare.php
I want to make a consult to the MSSQLSERVER with a SELECT STATEMENT but the sqlsrv_query is returning FALSE to me.
I already tested the query and its working fine, am I passing the parameters correctly?
Here is my code:
if($conn === false)
{
die(print_r(sqlsrv_errors()));
}
try
{
$email = "somedbemail#email.com";
$sql = "select Usuario.Email, Usuario.Senha FROM Usuario WHERE Usuario.Email = (?)";
$params = array($email);
$stmt = sqlsrv_query( $conn, $sql, $params);
if($stmt != False)
{
if($row = sqlsrv_fetch_Array($stmt))
{
$email_Con = $row['Email'];
$psw_Con = $row['Senha'];
}
else
{
echo "alguma coisa";
}
}
else
{
echo "It always enters here!";
}
Two possible problems.
The first is the format of your query. You are using:
select Usuario.Email, Usuario.Senha FROM Usuario WHERE Usuario.Email = (?)
Where I think you should be doing:
select Usuario.Email, Usuario.Senha FROM Usuario WHERE Usuario.Email = ?
The second is that the An invalid parameter was passed to sqlsrv_query() message is common when the connection is not correct (Reference). So double check that your connection is a valid resource.
I am stuck up as to why my Update prepare statement is failing but though I do not see any SQL error:
<?php
include(dirname(__FILE__).'\config.php' );
$id = $_POST['id'] ;
$value = $_POST['value'] ;
$column = $_POST['columnName'] ;
$columnPosition = $_POST['columnPosition'] ;
$columnId = $_POST['columnId'] ;
$rowId = $_POST['rowId']
$response['status']='';
$mysqli = new mysqli($sql_details['host'],$sql_details['user'],$sql_details['pass'],$sql_details['db']);
$mysqli->autocommit(FALSE);
$stmt = $mysqli->stmt_init();
if ($stmt = $mysqli->prepare("UPDATE users SET ? = ? where id = ?")) {
$response['status']='OK';
//$stmt->bind_param("ssi", $column, $value, intval(ltrim(substr($id, -4),'0')));
//$stmt->execute();
//$response['status'] = $mysqli->affected_rows;
//if ($mysqli->affected_rows == 1 )
//$response['status'] = 'success';
$stmt->close();
//if (!$mysqli->commit())
//$response['status'] = 'fail';
$mysqli->close();
}
else
$response['status']=$mysqli->error;
}
echo json_encode($response);
?>
Even though I have commented most of the lines and expect to the conditional string 'OK' at my UI side - I never ever see that . No errors is also reported - what am I doing wrong?
It seems that the UPDATE prepared statement works fine when in case of column name is present rather than a bind value like the below one works:
if ($stmt = $mysqli->prepare("UPDATE users SET first_name = ? where id = ?"))
Is there any way to have it the way I have requested?
How to put PDO bindParam in if statement? I tried to do a different variations, but none of them worked.
function get_all_pages($subject_id, $public = true)
{
$db = new PDO('mysql:host=localhost;dbname=name;charset=utf8', 'root', 'whatewer');
$query = "SELECT * ";
$query.= "FROM pages ";
$query.= "WHERE subject_id =:id ";
if ($public)
{
$query.= " AND visible =:visible ";
}
$query.= "ORDER BY position ASC";
$query.= "ORDER BY position ASC";
$stmt = $db->prepare($query);
if ($public)
{
$stmt->bindParam(':id', $subject_id, PDO::PARAM_INT);
$stmt->bindValue(':visile', 2, PDO::PARAM_INT);
}
else
{
$stmt->bindParam(':id', $subject_id, PDO::PARAM_INT);
}
$stmt->execute();
$affected_rows = $stmt->rowCount();
if ($affected_rows == 1)
{
$subject = $stmt->fetch(PDO::FETCH_ASSOC);
return $subject;
}
}
else
{
return null;
}
}
Ok there was misunderstanding I got my cod "Wright" it was stackoverflow that messed my code up. i was struggling to put code in code area. In reality it looks like this.
http://imagizer.imageshack.us/v2/800x600q90/593/zvf8.png
$affected_rows = $stmt->rowCount(); might give you unexpected results as according to the manual:
For most databases, PDOStatement::rowCount() does not return the
number of rows affected by a SELECT statement.
You should fetch a row directly and see what the result is:
$stmt->execute();
if ($subject = $stmt->fetch(PDO::FETCH_ASSOC))
{
return $subject;
}
else
{
return null;
}
And I would recommend opening your database connection as I mentioned in my comment:
$db = new PDO('mysql:host=localhost;dbname=name;charset=utf8', 'root',
'whatewer', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
That will cause PDO to throw exceptions and that will give you a clear error message whenever something goes wrong on any of the db calls.