Am trying to write a new record using the jquery function.
$.post("insertuser.php",$("#rohanStart").serialize(),function(data){
alert(data);
});
This seems to work and i do get an alert with the echo'ed statmenet. Problem is the values are not getting written into the database. Is there something wrong in the Query Statement?
mysql_query("INSERT INTO ajax_demo1( FirstName,LastName,Unit,Group,photo)
VALUES (
'".$arr['FirstName']."',
'".$arr['LastName']."',
'".$arr['Unit']."',
'".$arr['Group']."',
'".$arr['photo']."'
)");
echo $arr['Group'];
First don't use jQuery or any frameworks, they rely on the proprietary Microsoft JScript innerHTML method which does not work correctly with the DOM thus adding huge amounts of ambiguity in scripting.
Secondly you're NOT correctly escaping data going in to the database, that is a serious security issue.
Thirdly your approach to database queries is not taking error handling in to account, you're just dumping queries directly in and hoping for the best.
You should ALWAYS number your queries and enclose them as I have below. Note that besides errors it is good to fail conditions up-front however with database structure you should execute if successful first and THEN fail to increase your indentation (by a single space, not this tab waste where you have five screens to horizontally scroll) so you can visualize where you are in your own code.
$query1 = "SELECT * FROM table_name WHERE something='value'";
$result1 = mysql_query($query1);
if ($result1)
{
$row1 = mysql_fetch_assoc($result1);
}
else {mysql_error_report($query1,mysql_error(),__FUNCTION__);}
If your main header includes (you DO have a main header being included for all requests except AJAX correct?) you should have a universal MySQL error handling function that you can use to log SQL errors.
The following is the universal database error handler. You should have administrative error logs for HTTP, JavaScript, PHP and SQL errors so you can review and correct issues that your visitors encounter instead of if they only inconvenience you.
function mysql_error_report($q,$e,$f)
{
if (isset($_SESSION['database']))
{
if (isset($_SESSION['id_member'])) {$id = $_SESSION['id_member'];} else {$id = 0;}
if (isset($_SESSION)) {$session = mysql_real_escape_string(session_id());} else {$session = 0;}
$ip = mysql_real_escape_string(getenv('REMOTE_ADDR'));
$query = mysql_real_escape_string($q);
$error = mysql_real_escape_string($e);
$function = mysql_real_escape_string($f);
if (isset($_SESSION['type'])) {$type = mysql_real_escape_string($_SESSION['type']);} else if (isset($_SESSION['cms_browser'])) {$type = 'Browser';} else {$type = 'Unknown';}
if (isset($_SERVER['REQUEST_URI'])) {$url = $_SERVER['REQUEST_URI'];} else {$url = '';}
if (isset($_SERVER['HTTP_USER_AGENT'])) {$ua = mysql_real_escape_string($_SERVER['HTTP_USER_AGENT']);} else {$ua = '';}
$query1 = "INSERT INTO log_errors_sql (id_session, type, id_user, date, ip, function, mysql_error, mysql_query, url, user_agent) VALUES ('$session', '$type', '$id', NOW(), INET_ATON('$ip'), '$function', '$error', '$query', '$url', '$ua')";
$result1 = mysql_query($query1);
if (!$result1) {mysql_error_report_mail($q,$e,$f,$ua);}
}
else {mysql_error_report_mail($q,$e,$f);}
}
By using that approach you'll strengthen your coding practices to be much stricter. You don't want ambiguity, you want to be a total tightass about your code because the less subjectivity there is in your coding the more your code will be able to handle.
Also your white-space is very loose.
This...
INSERT INTO ajax_demo1( FirstName,LastName,Unit,Group,photo)
Should be formatted like this...
INSERT INTO ajax_demo1(FirstName, LastName, Unit, Group, photo)
You might ask why keeping your white-space like that is important, if you haven't spent a ton of time with find and replace (look up "Advanced Find & Replace", it works on wine/Linux and blows the crap away out of the native Linux console command performance wise and it's dirt cheap, supports regex, etc) you'll find yourself making mass site-wide edits in the blink of an eye because even your white-space is uniformly the same strict approach.
Should you heed my advice use a AFR (Advanced Find and Replace) to search for (but not replace) all instances of "mysql_query" and correct the formatting of everything you've written. Mix in a little AJAX notifications and you can see the errors instantly while you're still in the browser without a single alt-tab. That's how I roll.
...and of course doing this will make your debugging much easier. This isn't a fish, this is fishing and I hope it helps.
Related
I'm trying to insert into my database and have been frustratingly not been able to get my statement(s) to work. I'm using PHP's MySQL Improved (mysqli) procedural interface. It might be worth noting that I'm using the c9.io IDE (pre-AWS) and everything including the server that my application is running on is through c9.
What I've noticed is that the statements have been working randomly. Initially, I was making very subtle changes to my INSERT statements until it worked, but after the working trial, it would fail again. So, eventually I started hitting the refresh button (same inputs, no modifications to my code) repeatedly until I hit a success.
In terms of code:
$sql = "INSERT INTO `users` (`email`,`password`) VALUES ('example#mail.com','1234')";
$result = mysqli_query($connection,$sql);
gives
$result = false
very consistently, but every random nth trial
$result = true
(same inputs, no change to my code).
I do not believe it is an error with my SQL syntax considering the random successes, nor do I believe it is an error with my connection. All of my SELECT statements have been working fine.
Thus, I have a hunch that for some reason it may be an issue with c9? If you have ever had a similar issue with any of MySQL, SQL, PHP, or c9, please help!
You Should try this
<?php
if (!mysqli_query($connection,"INSERT INTO Persons (FirstName) VALUES ('Glenn')"))
{
echo("Error description: " . mysqli_error($connection));
}
?>
Use myqli_error() which will give you a error message which should help clarify the issue with your code
Okay, so I have some code here:
<?php
$rt = 'abc'; $imdb = 'defg';
if ($con = mysqli_connect($a,$b,$c,$d)) {
if (mysqli_query($con,"DELETE FROM blah WHERE a = '{$imdb}'")){
echo 'Deleted!';
if (mysqli_query($con, "INSERT INTO foo (c,d) VALUES ('{$rt}','{$imdb}')")){
echo 'Inserted after deletion!'
if (mysqli_query(...)) {
if (mysqli_query(....)) {
}
}
}
}
}
Some of my programs have many queries in a row, each of which is dependent on the result of a previous query. However, creating error handling for every single query and making sure that the logic of the code stays the same (not to mention staying readable) throughout can be a somewhat tedious and error prone process.
I would like to know a bit more about what is going on behind the scenes when a query is sent, because it would help me a lot with some of my questions. Namely, is it really necessary to write if (mysqli_query()) all the time for correct error handling, or is simply checking if the so-called 'master' connection exists enough?
That is, after I check mysqli_connect(), do I have to check every subsequent query within that connection to see if it went through (connection-wise, not logic-wise), or is it simply enough to check mysqli_connect() once, at the beginning of the program? It would sure make things a lot easier.
Also, while I'm looking at mysqli_multi_query() for more practical query management, I would prefer not to use it until I can fully understand the simpler query functions.
Thanks for your help!
Only few things for you to get it right
You have to distinguish an error from a query result. If your query depends on the result of the another one - it's all right to check the result. But if you want to check for the error - there are better ways.
In a properly written application a query error is a highly exceptional event, and there shouldn't be code written to handle it in place. It have to be done somewhere else.
mysqli can throw an exception in case of error, which is actually a Holy Grail you are looking for.
So, if you want to stop your code if one of queries failed, just set mysqli in exception mode and then pile your queries one after another.
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$con = mysqli_connect($a,$b,$c,$d);
$rt = 'abc'; $imdb = 'defg';
mysqli_query($con,"DELETE FROM ...");
mysqli_query($con, "INSERT INTO ...");
mysqli_query(...);
mysqli_query(...);
...
And two additional notes
if you want to undo a previous query if following one failed, then use transactions
you should NEVER write a query like you do, interpolating a variable directly into it. You ought to use prepared statements, substituting every variable with placeholder in the query.
At the moment I have some database wrapper functions like so:
function db_escape($str) {
return mysql_real_escape_string($str);
}
function db_query($sql) {
global $LINKID;
return mysql_query ($sql, $LINKID);
}
function db_fetch_array($result) {
return mysql_fetch_array ($result, MYSQL_ASSOC);
}
In my code I can then do things like:
$result = db_query('SELECT userid, first_name, last_name FROM user
WHERE email = "' . db_escape($email) . '"');
if ($result) {
$user = db_fetch_array($result);
}
One of the ideas behind this is that when I switch from mysql to mysqli, it'll take just a few minutes to update my wrapper functions and I don't have to replace hundreds of instances of mysql_real_escape_string(), mysql_query() and mysql_fetch_array() across hundreds of different projects.
The only issue with this is that the above can translate to standard procedural mysqli functions easily enough, but not prepared statements.
Does this matter? It seems like every tutorial says prepared statements are important for security and performance, however at the moment:
None of my projects have performance issues.
I am extremely anal about casting user input to the expected type (string, integer, float, etc.) and also manually escaping any user input that's used anywhere in a query.
With this in mind is it really necessary to switch to prepared statements, for either past or future projects?
I think you should think about the long term benefit. For example, if in the future you are no longer the developer of that project, the habit of using non-prepared statement will be passed down to the next developer and this:
I am extremely anal about casting user input to the expected type (string, integer, float, etc.) and also manually escaping any user input that's used anywhere in a query.
may not be true anymore. And even though you say you're very careful, at some point you will make mistake or forget (yes people did! and that's why things break) then it will be an issue.
Think about the following case as an example. Do you think it's safe ?
$id = $_POST['id'];
$result = db_query('SELECT userid, first_name, last_name FROM user
WHERE userid = ' . db_escape($id) );
Although I feel somewhat irritated seeing yet another Mr. Smart who come up with his Perpetuum Mobile, I cannot call his ideas totally unreasonable to some degree. But, unfortunately, they are all based on the wrong assumptions.
Which are
SQL formatting rules are limited to escaping and casting
whatever protection from SQL injection required
such a protection should be applied to user input
every PHP application is small and observable
like it was mentioned in the other answer, only one developer, who keeps all the code in his head, ever works on the project.
But again, all these assumptions are wrong.
As soon as you rethink them, you will come to conclusion that only the parameterized query can give you an insurance bill. Note that I am talking of the general idea of using parameters, not particular implementation used in mysqli. One can have the idea implemented even with old mysql ext all right.
Another thing to think of is code beauty and size. Look what you have now
$result = db_query('SELECT userid, first_name, last_name FROM user
WHERE email = "' . db_escape($email) . '"');
if ($result) {
$user = db_fetch_array($result);
}
and what it can be using parameters
$sql = 'SELECT userid, first_name, last_name FROM user WHERE email = ?';
$user = db_fetch_array($sql, $email);
I am trying to put a single article to the database, but fail:
$con = mysql_connect("localhost","root","") or die(mysql_error());
mysql_select_db("easy_db",$con);
mysql_query("INSERT INTO easy_db.article (Title, Article, Topics, author) VALUES($title, $data, $topic, $author)");
mysql_close();
I checked the spelling and printed all the variables ($title, $data, $topic, $author), that I got from the post-http..
Nothing is being inserted to the database with that statement. Why?
UPDATED
I have got an error in this one too:
= mysql_query("SELECT page FROM `easy_db`.`article` ORDER BY article_id DESC LIMIT 1") or die(mysql_error());
Use an error checking statement after your query, so you know what's going wrong. Also, beware of SQL INJECTION, and put single quotes around your values:
$con=mysql_connect("localhost","root","") or trigger_error(mysql_error());
mysql_select_db("easy_db",$con);
$title = mysql_real_escape_string($title);
$article = mysql_real_escape_String($article);
$topic = mysql_real_escape_string($topic);
$author = mysql_real_escape_string($author);
mysql_query("INSERT INTO easy_db.article (Title, Article, Topics, author)
VALUES('".$title."', '".$data."', '".$topic."', '".$author."')")
or die ('Error: '.mysql_error());
// mysql_close(); this is not necessary, though
Please replace
mysql_query("INSERT INTO easy_db.article (Title, Article, Topics, author) VALUES($title, $data, $topic, $author)");
with
mysql_query("INSERT INTO easy_db.article (Title, Article, Topics, author) VALUES($title, $data, $topic, $author)") or die(mysql_error();
And try again. If there is an error, tell us. Be sure that you of your variable where you got it.
You should use the global variables $_POST and $_GET.
As this question is an exact duplicate of thousands already answered others (but never be closed though), I am going to point out to one somewhat different thing.
It seems everyone in the world are writing SQL errors into the browser and even killing their scripts in the middle of execution. Leaving the user with a cyphered message and no controls, yet providing a potential attacker with quite useful information. And at the same time leaving programmer totally ignorant of the errors occurred on the site. Funny, eh?
That's the dark side of PHP language in general, which suffer from terrible code examples spread over the world and is a bad side of this site of Stack Overflow as well, as it takes huge part in spreading these bad practices, wrong code, ridiculous habits and weird superstitions.
Because answer quality will never affect its rep points. So, one can write any nonsense and it will be upvoted, accepted, and copied further.
So, if you want to make your code a little better - never use die(). In case of running queries use trigger_error() instead, it will populate the error information according to current PHP settings: on a test server it will go onto screeen, but on a live server it will be logged for the site programmer. And it won't kill your script.
You have no single-quotes around your VALUES('val1', 'val2'...) variables::
mysql_query("INSERT INTO easy_db.article (Title, Article, Topics, author) VALUES('$title', '$data', '$topic', '$author')");
You should check the success of the query like:
$result = mysql_query("INSERT INTO easy_db.article (Title, Article, Topics, author) VALUES('$title', '$data', '$topic', '$author')");
if (!$result) {
echo mysql_error(); // find out what went wrong...
}
We don't see the rest of your code, but please be sure you have also sanitized all your input variables from $_POST using mysql_real_escape_string():
$title = mysql_real_escape_string($_POST['title']);
// etc...
Most likely you've forgotten to quote your inserted data. The query should look more like:
INSERT ... VALUES ('$title', '$data', '$topic', '$author')
and your code should be:
$result = mysql_query(...) or die(mysql_error());
Had you had the 'or die()' portion included, you'd get a syntax error from mysql telling you why the query failed. It is almost never a good idea to NOT check for error conditions after running a query. Even if the SQL is syntactically perfect, there's far too many other reasons for a query to fail to NOT check.
I tried both
$query = "INSERT INTO reservation VALUES ('".$hour."','".$minute."','".$day."','".$month."','".$year."','".$name."','".$table."')";
$query = "INSERT INTO reservation VALUES ('$hour','$minute','$day','$month','$year','$name','$table')";
But none of them work, I get a blank page, and no errors in my error logs. I tried doing echo to all the variables and I got their values.
Here is the overall function:
function makeReservation($trtime,$hour,$minute,$day,$month,$year,$name,$table,&$db)
{
//$query = "INSERT INTO reservation VALUES ('".$hour."','".$minute."','".$day."','".$month."','".$year."','".$name."','".$table."')";
$query = "INSERT INTO reservation VALUES ('$hour','$minute','$day','$month','$year','$name','$table')";
$result = $db->query($query) or die(mysql_error());
}
I'll make a few suggestions. First, I'll assume that you actually know what you're doing when you say there is no error.
1) Make sure you work on the good database. You can do a SHOW TABLES query to see what tables it contains, or a SELECT * FROM reservation to see its content.
2) Right after you insert the row, do a SELECT * FROM reservation query and check if your row is there.
3) Make sure you call your function...
Then, as I said in comments, you should use the DATETIME type instead of using different columns for hours, minutes, etc. If you need to select a particular attribute, use the appropriate function (for example, SELECT HOUR(your_column))
The quotes around integers shouldn't make your query fails, but it's still better for clean code purposes to remove them if not necessary (and make sure you escape your data correctly, of course).
The php you posted looks fine.
If you're getting a blank page, it's likely that something is failing before the function calls. Maybe a parsing error?
If you're not seeing anything in the error logs, try changing your error logging settings in the php.ini.
display_errors = E_ALL
If you're on shared hosting, you can often override using .htaccess http://davidwalsh.name/php-values-htaccess