Already existed data query and bypassing new entry in php mysql - php

I have written a long program. Im just sharing here some lines to understand a concept which is my issue here. I want to check if the previous data is equal to the newly entered, if it is, then an error should occur that the data is already entered, without storing again in db. Following code is running but it duplicates data. It is not quite good. may you please check where I am wrong. thanks
Database Name Booking:
Table Name data:
Name: John, Anjel, Smith, David
CNIC: 33, 46, 33, 91
//// storing data in database from html form fields
<?php
$emp_name = addslashes($_POST['emp_name']);
$emp_cnic = addslashes($_POST['emp_cnic']);
?>
//// Selecting CNIC that is duplicated (already existed) on a new form submission
$already = mysql_query("SELECT CNIC FROM data WHERE CNIC = '$emp_cnic'");
//Dieing script without storing the data if it already exists.
if($already){
die('Sorry! you are already registered. For any query, contact the administrator. ');

You couls also REPLACE mysql function.
If not, just change your request with a COUNT() and check if the returned result is greater than 0.
I would also highly recommand you to go on PDO instead of still using mysql_* (which is deprecated / removed)

You could use mysql_num_rows
$already = mysql_query("SELECT CNIC FROM data WHERE CNIC = '$emp_cnic'");
$record_count = mysql_num_rows($already );
// $record_count > 0 means data already exist
if( $record_count > 0 ) {
// Show error
} else {
// Save data
}

The problem I see with your code is the following:
For SELECT, SHOW, DESCRIBE, EXPLAIN and other statements returning
resultset, mysql_query() returns a resource on success, or FALSE on
error.
For other type of SQL statements, INSERT, UPDATE, DELETE, DROP, etc,
mysql_query() returns TRUE on success or FALSE on error.
The error you mentioned when you use mysql_num_rows() is caused because of the false return of the unsuccessful query.
You are checking a value that might be not boolean, to solve this use:
if(!isset($already) OR mysql_num_rows($already) == 0){
// die
}
else{
// do stuff
}
This check if the query was unsuccessful or if it is empty, so you always get a boolean to check your result set.
As #Sakuto pointed out is important to use not deprecated functions, therefor instead of using mysql_query() you should use mysqli or PDO functions.For further information read this.

Related

PHP / mysqli: Prepared Statements with num_rows constantly returning nothing

In my test-surroundings there is a database containing some Person Information (Name, E-Mail, Adress etc.). These Informations can be inserted by anyone into the database via a form. In the background they are inserted with a parameterized INSERT into the database after submission.
What I now would like to do is to detect if some person tries to insert the same values into the database again, and if he does, not inserting the new values and instead showing an error message. (So every person name in the database is unique, there are no multiple rows linked to one name).
I had a numerous number of ideas on how to accomplish this. My first one was to use a query like REPLACE or INSERT IGNORE, but this method would not give me feedback so I can display the error message.
My second attempt was to first do a SELECT-query, checking if the row already exists, and if num_rows is greater than 0, exit with the error message (and else do the INSERT-part). For this to work I will have to use parameterized queries for the SELECT too, as I´m putting some user input into it. Figuring that parameterized queries need special functions for everything you could normally do with way less lines of code, I researched in the internet on how to get num_rows from my $statement parameterized-statement-object. This is what I had in the end:
$connection = new mysqli('x', 'x', 'x', 'x');
if (mysqli_connect_error()) {
die("Connect Error");
}
$connection->set_charset("UTF-8");
$statement = $connection->stmt_init();
$statement = $connection->prepare('SELECT Name FROM test WHERE Name LIKE ?');
flags = "s";
$statement->bind_param($flags, $_POST["person_name"]);
$statement->execute();
$statement->store_result();
$result = $statement->get_result(); //Produces error
if ($result->num_rows >= 1) {
$output = "Your already registered";
} else {
$output = "Registering you...";
}
exit($output);
After all, I can´t get why mysqli still won´t give me num_rows from my statement. Any help is appreciated, thanks in advance!
Oh, and if you guys could explain to me what I have to do to get affected_rows,that would be awesome!
EDIT: I know I could to this by using unique constraints. I also found out that I can find out if INSERT IGNORE skipped the INSERT or not. But that won´t answer my complete question: Why does the SELECT num_rows alternative not work?
ANOTHER EDIT: I changed the code snippet to what I now have. Although my mysql(i)-version seems to be 5.6.33 (I echo´d it via $connection->server_info) get_result() produces the following error message:
Fatal error: Call to undefined method mysqli_stmt::get_result() in X on line X (line of get_result)
The behaviour of mysqli_num_rows() depends on whether buffered or unbuffered result sets are being used. For unbuffered result sets, mysqli_num_rows() will not return the correct number of rows until all the rows in the result have been retrieved. Note that if the number of rows is greater than PHP_INT_MAX, the number will be returned as a string.
Also make sure that you declare ->store_result() first. Moreover the function doesn't work with LIMIT used jointly with SQL_CALC_FOUND_ROWS. If you want to obtain the total rows found you must do it manually.
EDIT:
If nothing from the suggestions does not work for you, then I would propose to rewrite your SQL query:
SELECT `Name`, (SELECT COUNT(*) FROM `Persons`) AS `num_rows` FROM `Persons` WHERE `Name` LIKE ?
This query will return the total number from your Persons table, as well as Name, if exist.

Getting a basic PDO statement to execute

I am attempting to get the following PDO statement to work and running into issues. When I am trying to get the number of rows, I keep getting 0, yet I know there should be 1 row. When I ran it as a mysqli statement( before trying to change it to PDO) it worked perfectly.
Here is the code:
require_once ('pdo.php');
$isbn = $_POST['isbn'];
// check to see if the isbn is a "problem" isbn or not
$problem = $conn->prepare("select isbn, note from problem where isbn = :isbn");
$problem->bindParam(":isbn", $isbn);
$problem->execute();
print_r($problem);
$num_rows = $problem->rowCount();
print_r($num_rows); die;
EDIT: Here is pdo.php:
<?php
function db_connect()
{
$db = new PDO("mysql:host=localhost; db=bookcell_BCOS_final", "xxxxx", "xxxxx");
return($db);
}
?>
I know that my connection works, but I get 0 for $num_rows. What mistakes am I making here?
Besides a little quirk and a optimalisation your code looks fine to me. The posted value isbn could be the reasong that you are getting no data:
$problem = $conn->prepare("select isbn, note from problem where isbn = :isbn");
$problem->bindParam(":isbn", $_POST['isbn'], PDO::PARAM_STR); // <-- thats what parameter binding is for
$problem->execute();
print_r($problem);
$num_rows = $problem->rowCount(); // <-- gives the number of rows, not columnCOunt
print_r($num_rows); die;
The Syntax for $num_rows = $problem->columnCount(); is totally correct. You may try,
$problem->execute(array("isbn" => $isbn));
instead of bindParam.
for getting the no. of rows, you need to use pdo::rowCount() -- manual here
In PDO to verfiy if your execute statement did work, check the return value (bool):
$success = $problem->execute();
if (!$success) {
$arr = $problem->errorInfo();
print_r($arr);
}
Also you might be looking for rowCount() instead of columnCount() but I think the error handling is your furthermost issue.
Additionally you can make PDO throw an exception each time an error appears, compare:
Switching from PHP's mysql extension to PDO. Extend class to reduce lines of code
How do I raise PDOException?
Depending on the database driver and the mode it's running, PDO may not be able to give you a row count. Look carefully at the documentation for PDOStatement::rowCount():
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
This is because in many cases the database uses a cursor rather than fetching the full results and buffering them (which is how the old mysql_* functions behave). In this case the database doesn't know how many rows there are until you have looked at all the rows. Think of a cursor as something like a filesystem pointer--you can't know the filesize until you seek to the end of the file.

PHP MySQL SELECT Query only returning resources

I'm currently working on building a download platform in which a user receives a random code and uses it to access an mp3 for download for up to three downloads. I generated a list of random codes using Python and imported them into a SQL table with an empty column for an associated email addresses and a default 0 for the use count. I wrote the following PHP script in order to associate an email with a certain code and add to the count so a download can be accessed up to three times.
$email = $_POST["email"];
$email = stripslashes($email);
$uniqueCode = $_POST["uniqueCode"];
$uniqueCode = stripslashes($uniqueCode);
// check that all fields are filled
if($uniqueCode=="" || $email=="")
apologize("Please fill out all fields.");
// check to make sure that the e-mail is valid
if (verifyEmail($email) == FALSE)
apologize("Please enter a valid e-mail address.");
// check if uniqueCode input is alphanumeric
if (verifyCode($uniqueCode) == FALSE)
apologize("Download codes are alphanumeric.");
// check to see if unique code is correct
$sql = mysql_query("SELECT * FROM wd009 where uniqueCode='$uniqueCode'");
$result = mysql_fetch_array($sql);
if($sql==FALSE)
{
apologize("Your download code is invalid. Please try again");
}
// only allow users with less than 3 downloads to proceed
else if ($result['count'] <= 3) {
if ($result['email'] == ""){
mysql_query("UPDATE wd009 SET email='$email', count=1 WHERE uniqueCode='$uniqueCode'");
apologize("added email");
}
else if ($result['email'] != $email)
apologize("different email from record!!");
else if ($result['email'] == $email){
mysql_query("UPDATE wd009 SET count=count+1 WHERE uniqueCode='$uniqueCode'");
apologize("updated the count!");
}
else
apologize("Your download code is used up!");
Obviously I use some functions in the above that aren't included in the code but I've checked all of them and none of them should interfere with the MySQL query. It may be of note that apologize() exits immediately after apologizing. When I input a correct code into the form, it works correctly and updates the SQL database. However, as long as the download code input is alphanumeric, the form will accept it even though the string definitely does not match any in the table. Namely, mysql_query returns a resource no matter the input. I've checked the database connection but since the table is correctly updated when the download code is correct, that doesn't seem to be the problem.
I've tried debugging this every way I could think of and am genuinely befuddled. Any help you could offer would be greatly appreciated!
As you can see in the manual, mysql_query always returns a resource for a valid query so you need to change your logic and count the number of rows it returns, not the result of mysql_query.
Apart from that, mysql_query, is deprecated and you should use mysqli or PDO.
You can count the number of rows with the - equally deprecated - mysql_num_rows function. 0 rows would be no valid code in your case.
This
if($sql==FALSE)
should probably be something like
if(mysql_num_rows($sql) == 0)
Edit: I agree, mysqli or PDO is preferred now.
The issue probably is this line:
if($sql==FALSE)
{
apologize("Your download code is invalid. Please try again");
}
Since the sql is a string it is accepting is as true and passing it as valid. One thing you also might like to do to avoid sql injection is use parameters instead of directly injecting user input.
$sql = mysql_query("SELECT * FROM wd009 where uniqueCode='$uniqueCode'");
Instead, do something like this:
$stmt = $mysqli->prepare("SELECT * FROM wd009 where uniqueCode=?");
$stmt->bind_param($uniqueCode);
$stmt->execute();
while ($stmt->fetch()) {
.....
You'll also want to do it this way for the update statement too.
If you have a lot of data in that table you may want to restrict the columns returned in the SQL statement so it lessens the load on the database.

php mysql_query returns nothing after insert (and nothing is inserted either)

I've got the following code:
<?php
if(!empty($error_msg))
print("$error_msg");
else
{
require_once("../include/db.php");
$link = mysql_connect($host,$user,$pass);
if (!$link)
print('Could not connect: ' . mysql_error());
else
{
$sql = "insert into languages values(NULL,'$_POST[language]','$_POST[country_code]');";
$res = mysql_query($sql);
print("$sql<br>\n");
print_r("RES: $res");
mysql_close($link);
}
}
?>
In one word: it does not work. mysql_query doesn't return anything. If I try the same
query within php_myadmin, it works. It does not insert anything either. Also tried it as
user root, nothing either. Never had this before. Using mysql 5.1 and PHP 5.2.
Any ideas?
mysql_query will return a boolean for INSERT queries. If you var_dump $res you should see a boolean value being printed. It will return TRUE for a successful query, or FALSE on error. In no cases it ever returns NULL.
In addition, never pass input data (e.g.: $_POST) directly to an SQL query. This is a recipe for SQL injection. Use mysql_real_escape_string on it first:
$language = mysql_real_escape_string($_POST['language']);
$sql = "INSERT INTO language SET language='$language'";
And don't forget to quote your array indices (e.g.: $_POST['language'] instead of $_POST[language]) to prevent E_NOTICE errors.
You need to specify a database so the system knows which database to run the query on...
http://php.net/manual/en/function.mysql-select-db.php
Without selecting a database, your data will not be inserted
mysql_query returns a boolean for INSERT queries. If used in string context, such as echo "$res", true will be displayed as 1 and false as an empty string. A query error has possibly occured. Use mysql_error() to find out why the query has failed.
$sql = "insert into languages values(NULL,'$_POST[language]','$_POST[country_code]');";
This is very bad practise, as a malicious user can send crafted messages to your server (see SQL Injection).
You should at least escape the input. Assuming your column names are named 'language' and 'country_code', this is a better replacement for the above code:
$sql = sprintf('INSERT INTO LANGUAGES (language, country_code) VALUES ("%s","%s")',
mysql_real_escape_string($_POST['language']),
mysql_real_escape_string($_POST['country_code'])
);
For a description of the mysql_real_escape_string function, see the PHP Manual. For beginners and experienced programmers, this is still the best resource for getting information about PHP functions.
Instead of using $_POST directly, I suggest using the filter_input() function instead. It's available as of PHP 5.2.
With an INSERT query, mysql_query returns true or false according as the query succeeded or not. Here it is most likely returning false. Change the line print_r("RES: $res"); to print_r("RES: ".(int)$res); and most likely you will see it print RES: 0.
The problem may be that MySQL expects a list of column names before the VALUES keyword.
Also, you appear to be inserting POST variables directly into SQL - you should read up on SQL injection to see why this is a bad idea.
--I retract the quote comment, but still not good to directly insert $_POST values.--
Second, I don't think i've seen print_r quite used like that, try just using an echo.
And mysql_query is only expected a boolean back on an INSERT, what are you expecting?
Now ive got this:
$language = mysql_real_escape_string($_POST['language']);
$country_code = mysql_real_escape_string($_POST['country_code']);
$sql = "insert into shared_content.languages (id,language,country_code) values(NULL,$language,$country_code);";
$res = mysql_query($sql);
print("$sql<br>\n");
var_dump($res);
print(mysql_error());
mysql_close($link);
And the output:
insert into shared_content.languages (id,language,country_code) values(NULL,NETHERLANDS,NL);
bool(false) Unknown column 'NETHERLANDS' in 'field list'

Php Numrows problem

I use query string to access my pages. I try to make if anyone type unknown query string manually, then redirect to somewhere..
For example:
Url: test.php?m=1 (this is a valid url)
test.php?m=1324234 (this is not a valid url )
test.php?m=1asdaa (this is not a valid url )
include("config/database.inc");
$qm=$_GET['m'];
$query = "select acc from test where acc=$qm";
$numresults=mysql_query($query);
$numrows=mysql_num_rows($numresults);
if ($numrows == 0){
header("Location: index.php");
exit;
}
In the database i have two line, LINE 1: acc=1; LINE 2: acc=2;
If i type to the url: test.php?m=12312431, then redirect to index.php 'coz $numrows=0. Thats ok.
But if i type: test.php?m=1sdfsfsf, then i got this error msg.:
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in..
How can i do that? Need to check the $_GET['m'] before query from database?
Thank you.
You should never be placing the value of a GET variable directly into an SQL query without properly filtering and escaping it. Your problem is that you're allowing things which aren't numbers to be put into your SQL query. In this particular case, your test is harmless and just errors, but a malicious user could also do things much more harmful via SQL injection.
Instead, what you really want to do is convert the variable's value to a type that you know is okay (in this case, an integer) and then query the database using that. Try this instead:
include("config/database.inc");
$qm=intval($_GET['m']);
$query = "select acc from test where acc=$qm";
$numresults=mysql_query($query);
$numrows=mysql_num_rows($numresults);
if ($numrows == 0){
header("Location: index.php");
exit;
}
Notice the call to intval() which forces the result to be an integer value, instead of potentially harmful strings.
Do this:
$qm=intval($_GET['m']);
if m is invalid, mysql_query will return $query = false.
If you provide "false" to mysql_num_rows, it does not know what query you sent, and correctly get an invalid numrows result, e.g. a failure.
Check that m is integer with intval($m);
As well as validating the input or forcing a typecast as others have suggested to make sure the input makes sense, try to get into the habit of enclosing user-submitted values passed to a query in quotes, e.g.
$query = "select acc from test where acc='$qm'";
Although here you're technically comparing an integer to a string, MySQL allows this (and will still use integer keys where available), and it provides one last line of defence if you forget to filter the input.

Categories