I am looking to be able to search a SQL database using a form and output the finds on the screen.
This is my code:
$query = "SELECT * FROM documents WHERE DocumentName = '%".$DocumentName."%'AND county = '".$county."' OR acreage = '".$acreage."' AND grantor = '".$grantor."' OR grantee = '".$grantee."' ORDER by 'DocumentName'" ;
$result=$db->query($query);
$num_results=$result->num_rows;
echo "<p>Number of documents found: ".$num_results."</p>";
for($i=0; $i <$num_results; $i++){
$row=$result->fetch_assoc();
echo"<p>".($i+1).".County: ";
echo htmlspecialchars(stripslashes($row['county']));
echo "<br />Acreage: ";
echo stripslashes($row['acreage']);
echo "<br />Grantor: ";
echo stripslashes($row['grantor']);
echo "<br />grantee: ";
echo stripslashes($row['grantee']);
echo "<br />Lessor: ";
echo stripslashes($row['DocumentName']);
echo "<br />PDF: ";
echo stripslashes ("" .$row['PDF'] . "<br>");
echo "</p>";
}
$result->free();
$db->close();
It selects and outputs the information. The thing is I need people to be able to leave a field blank the search form however this causes all data to be displayed. If they type in the county and leave everything else blank I want it to pull only that county records.
You can break where clause conditions like:
$where = '';
$where .= empty(county) ? '' : "AND county='$county' ";
...
And inject $where in the query.
Try something like this (to display that data only if associated form field is send and not empty)
if(isset($_POST['country']) && strlen($_POST['country'])>0) echo ($i+1).".County: ". htmlspecialchars(stripslashes($row['county']));
if(isset($_POST['acreage']) && strlen($_POST['acreage'])>0) echo "<br />Acreage: ". stripslashes($row['acreage']);
// ...
I would recommend checking the post values are set and storing where conditions in an array and then using implode to make a string for use in your query.
if(isset($_POST['country']) && strlen($_POST['country'])) {
$where[] = "country = '$country'";
}
if(isset($_POST['acreage']) && strlen($_POST['country'])) {
$where[] = "acreage = '$acreage'";
}
....
$where = isset($where) ? ' WHERE '.implode(' AND ',$where) : '';
$query = 'SELECT * FROM documents'.$where;
It is also worth noting that you have no protection from SQL injection attacks, you need to sanitise your input.
Related
I cannot figure this out, it's not an error as such, but when i try to echo out the results of a query:
echo "SELECT * FROM `active_customers` WHERE `cus_email`='".$k."' AND `cus_product`='".$_GET['product']."'" . "<br />";
$q = mysql_query("SELECT * FROM `active_customers` WHERE `cus_email`='".$k."' AND `cus_product`='".$_GET['product']."'");
$a = mysql_fetch_array($r);
$n = mysql_num_rows($q);
echo "Number of rows:" . $n;
echo $a['cus_id'];
echo $a['cus_email'];
The number of posts is returning the correct number which is 1, these values $a['cus_id']; and $a['cus_email']; are not coming through at all, i even did a mysql query in phpmyadmin and it works there.
can anyone see what i have done wrong?
correct code can be
echo "SELECT * FROM `active_customers` WHERE `cus_email`='".$k."' AND `cus_product`='".$_GET['product']."'" . "<br />";
$q = mysql_query("SELECT * FROM `active_customers` WHERE `cus_email`='".$k."' AND `cus_product`='".$_GET['product']."'");
$n = mysql_num_rows($q);
echo "Number of rows:" . $n;
while($row = mysql_fetch_array($q, MYSQL_ASSOC)){
echo $row['cus_id'];
echo $row['cus_email'];
}
Although i would recommend using mysqli or PDO for sql databases
I am having an issue sorting my datatable by the column header.
I have a build-query mechanism on my site that can take in 1 or more values the user selects. The values get turned into PHP variables that then get passed into the query and prints out the datatable to the screen. The address bar URL is updated as well.
I want to be able to sort by the column headers of the table.
I will show you the PHP code bypassing the whole build-query function. I'll start right at the SORT portion and the query:
<?php
if ($_GET['sort'] == "") {
$sort_by = "BOL_NUMBER";
} else {
$sort_by = $_GET['sort'];
}
$select = "";
if ($_SESSION['where'] != "") {
$select = "SELECT * FROM `mainTable` WHERE (". $_SESSION['where'] . ") ORDER BY " . $sort_by . "";
}
// $_SESSION['where'] comes from the build query and can contain 1 or more values
$QueryResult = mysql_query($select) or die ();
$resnum = mysql_num_rows($QueryResult);
This next part is where the table gets populated:
if ($resnum == 0) {
echo "no results";
} else {
echo "<table>\n";
echo "<thead><tr>" .
"<th>BOL</th>" .
"<th>CONTAINER</th>" .
"<th>LOCATION</th>" .
"<th>STATUS</th>" .
"</tr></thead><tbody>\n";
while(($Row = mysql_fetch_assoc($QueryResult)) !== FALSE) {
echo "<tr>";
echo "<td>{$Row[BOL_NUMBER]}</td>";
echo "<td>{$Row[CONTAINER_NUMBER]}</td>";
echo "<td>{$Row[LOCATION_CITY]}</td>";
echo "<td>{$Row[STATUS_TYPE]}</td>";
echo "</tr>";
}
echo "</tbody></table>\n";
?>
There are many more columns. I just picked a couple.
I found this page for this next part:
Sorting html table with a href and php from sql database
So I tried to apply what I read in the link to the headers, like this:
"<th><a href='myPage.php?sort=BOL_NUMBER'>BOL</a></th>" .
"<th><a href='myPage.php?sort=CONTAINER_NUMBER'>CONTAINER</a></th>" .
"<th><a href='myPage.php?sort=LOCATION_CITY'>LOCATION</a></th>" .
"<th><a href='myPage.php?sort=STATUS_TYPE'>STATUS</a></th>" .
Now, I can click on the column headers, but when I do, it does not keep the user's selection and I can tell because the URL changes like this example below:
(this is just an example. it does not include the parameters in the table above)
(just keep note of the &sort in this url)
http://home.someCompany.com/myAPP/mypage.php?direction=I&type=&submit=Go&city=&pod=&terminal=&ramp=&container=&bol=&voyage=&conStatus=&con_location=&sort=&status=
Will change to this (if I select the header for CONTAINER):
http://home.someCompany.com/myAPP/mypage.php?&sort=CONTAINER_NUMBER
When this happens, the datatable is no longer on the screen. It's like it removes everything from the query and just adds the sort. But there is now nothing to sort.
The $_SERVER['QUERY_STRING'] superglobal variable give you access to the GET parameters. By using it you can keep the current parameters of the request.
So by changing your link by this :
$urlQuery = str_replace(array('&sort=BOL_NUMBER', '&sort=CONTAINER_NUMBER', '&sort=LOCATION_CITY', '&sort=STATUS_TYPE'), '', $_SERVER['QUERY_STRING']); // To clean previous sorting, maybe replace by a regex
"<th><a href='myPage.php?' . $urlQuery . '&sort=BOL_NUMBER'>BOL</a></th>" .
"<th><a href='myPage.php?' . $urlQuery . '&sort=CONTAINER_NUMBER'>CONTAINER</a></th>" .
"<th><a href='myPage.php?' . $urlQuery . '&sort=LOCATION_CITY'>LOCATION</a></th>" .
"<th><a href='myPage.php?' . $urlQuery . '&sort=STATUS_TYPE'>STATUS</a></th>" .
You should reach your goal.
I have a table with about 500,000 rows, and need to query it to retrieve results. Basically the user just inputs a case number, and then I want to execute the following query and display the results using a while loop
if (!empty($_POST["casenum"])) {
$result2 = mysql_query("SELECT Box_Content.case_number, Transfer.number, Transfer.location, Box.number FROM Box_Content, Transfer, Box WHERE Box_Content.box_id = Box.id and Box.transfer_id = Transfer.id and Box_Content.case_number = '".$_POST['casenum']."'");
while ($row = mysql_fetch_array($result2)) {
echo "Case number: ".$casenum." text ";
echo "<br />";
}
} else {
echo "<h4>WARNING!!! Search criteria entered not valid. Please search again.</h4>";
}
What am I doing wrong here?
EDIT:
It works now if only one row is returned, but for two rows, it seems to be trying to print the entire table...
$casenum = $_POST["casenum"];
echo "<br />The case number entered is: $casenum<br />";
if (!empty($_POST["casenum"]))
{
$result2 = mysql_query("SELECT Box_Content.case_number, Transfer.number as transfer_number, Transfer.location as transfer_location, Box.number as box_number FROM Box_Content, Transfer, Box WHERE Box_Content.box_id = Box.id and Box.transfer_id = Transfer.id and Box_Content.case_number = '" . $_POST['casenum'] . "'");
while($row = mysql_fetch_array($result2))
{
print_r ($row);
echo "<br />";
echo "<b>Case number: </b>" . $row['case_number'] ."<br />";
echo "<b>Transfer number: </b>" . $row['transfer_number'] ."<br />";
echo "<b>Transfer location: </b>" . $row['transfer_location'] ."<br />";
echo "<b>Box number: </b>" .$row['box_number'] ."<br />";
}
}
else
{
echo "<h4>WARNING!!! Search criteria entered not valid. Please search again.</h4>";
}
var_dump($_POST);
Try:
while ($row = mysql_fetch_array($result2)) {
echo "Case number: ". $row['Box_Content.case_number'] ." text ";
echo "<br />";
}
$row['case_number'] will output the case_number retrieved for each row in your resultset.
However, you should look into doing one of two things:
Start using best practices.
Start using a non-deprecated SQL library (mysqli, PDO).
This query is susceptible to SQL injection:
"SELECT Box_Content.case_number, Transfer.number, Transfer.location, Box.number
FROM Box_Content, Transfer, Box
WHERE Box_Content.box_id = Box.id and Box.transfer_id = Transfer.id
and Box_Content.case_number = '".$_POST['casenum']."'"
Use mysql_real_escape_string($_POST['casenum']) to patch this.
Reference: http://php.net/manual/en/function.mysql-real-escape-string.php
The mysql_* functions have long been deprecated due to unprepared statement operations. Look into either mysqli or PDO for your project instead.
What am I doing wrong here?
1) $casenum isn't set in your code... (Please tell me it is nothing and you don't have register superglobals turned on?!) You would probably want $row['case_number']
2) But anyway, that's not really what you are doing wrong... Your biggest mistake is using user input without any kind of validation or sanitization...
Imagine if $_POST["casenum"] was equal to...
' or 1=2 union select user,password,email,salt from users
You seem to be using $casenum from nowhere.
Try:
while($row = mysql_fetch_assoc($result2))
echo "Case number: ".$row['number']." text <br />";
When using the mysql_fetch functions assoc will bring back named indexed data, num will bring back numberic indexed data and array will bring back both, so try to use one or the other.
Then when you do $row = mysql_fetch_assoc($result2) your essentially saying for each row of data returned store it as a (in this case associative) array in $row, so you can then access your data via the standard array commands ($row['foo']).
I'm a little bit confused why it does not work.
What i want is that control db if for ex 2012-02-21 exist in DB delete it and insert again but it does not work why
my full code is that but else statement doesnt work :S
$ga->requestAccountData();
$mysql = new mysql();
$mysql->connect();
// $startDate = date("Y-m-d");
$startDate = "2012-02-21";
$dbResult = mysql_query("select * from profiles where profile_Date='".$startDate."'");
$query = mysql_num_rows($dbResult);
if($query > 0)
{
mysql_query("delete from profiles where profile_Date='".$startDate."'");
foreach ($ga->getResults() as $result) {
$ga->requestReportData($result->getProfileId(),array('eventCategory','eventAction'),array('totalEvents'),$sort_metric=null,$filter='eventAction==InitPlayer',$start_date=$startDate,$end_date=$startDate);
foreach($ga->getResults() as $result2)
{
echo $result;
echo $result2->geteventCategory()."<br />";
echo $result2->geteventAction();
echo $result2->gettotalEvents();
"<br />";
"<br />";
"<br />";
$mysql->query("insert into profiles values(" . $result->getProfileId() . ",'" . $result . "','".$result2->geteventCategory()."','".$result2->geteventAction()."','".$result2->gettotalEvents()."','".$startDate."')");
}
}
}
else
{
foreach ($ga->getResults() as $result) {
$ga->requestReportData($result->getProfileId(),array('eventCategory','eventAction'),array('totalEvents'),$sort_metric=null,$filter='eventAction==InitPlayer',$start_date=$startDate,$end_date=$startDate);
foreach($ga->getResults() as $result2)
{
echo $result;
echo $result2->geteventCategory()."<br />";
echo $result2->geteventAction();
echo $result2->gettotalEvents();
"<br />";
"<br />";
"<br />";
$mysql->query("insert into profiles values(" . $result->getProfileId() . ",'" . $result . "','".$result2->geteventCategory()."','".$result2->geteventAction()."','".$result2->gettotalEvents()."','".$startDate."')");
}
}
}
You should use mysql_num_rows to count the results selected and not mysql_affected_rows which applies to queries altering data (insert, update, delete etc.)
$result = mysql_query("select * from profiles where profile_Date='".$startDate."'");
$count = mysql_num_rows($result);
if($count > 0) {
...
}
http://php.net/manual/en/function.mysql-num-rows.php
Why you need to first delete and then insert? you can use update query as well. Also what is the data type of the field profile_Date ? Is it set date or date and time?
You can use MySQL's REPLACE functionality (docs).
It basically works like INSERT, with the exception that if a value with the same key already exists in the database, at first the existing value will be removed and afterwards the new value will be inserted as completely new entry. If there is no existing value, it will behave like INSERT.
Watch out for the differences to UPDATE
The difference to UPDATE is hidden in the details:
since an existing value will actually be removed, all referenced foreign keys constraints will be removed too.
UPDATE will just update the values provided, with INSERT the other columns will get the default value (practical example: a field name timestamp_created with the default value of CURRENT_TIMESTAMP will be unchanged in an UPDATE statement, but will display the current time in a REPLACE statement)
Why am I not able to echo those things like adm_no, adm_dt, etc.?
require_once("lib/connection.php");
$adm_no = $_POST['adm_no'];
if (!$adm_no == "intval") echo "You Entered wrong Admission no Recheack Admission no";
exit();
$clas = $_POST['clas'];
$query = "SELECT * FROM $clas WHERE adm_no = $adm_no";
$result = mysql_query($query);
//searchs the query in db.
while ($result1 = mysql_fetch_array($result)) {
$adm_no = $result1['adm_no'];
$adm_dt = $result1['adm_dt'];
$name = $result1['name'];
$dob = $result1['dob'];
$f_name = $result1['f_name'];
$f_office = $result1['f_office'];
$f_o_no = $result1['f_o_no'];
$m_name = $result1['m_name'];
$m_office = $result1['m_office'];
$addr = $result1['addr'];
};
echo "Admission no = ";
$adm_no;
echo " <p>Admission Date </p>";
echo " <p>Name </p>";
echo " <p>Class </p>";
echo " <p>D.O.B </p>";
echo " <p>Father s name </p>";
echo " <p>Office address </p>";
echo " <p>Office No </p>";
echo " <p>Mother s name </p>";
echo " <p>Office Address </p>";
echo " <p>Address </p>";
echo " <p>Phone no </p>";
You have a syntax error
echo "Admission no = " ;$adm_no ;
Should be
echo "Admission no = " ;
echo $adm_no ;
or
echo "Admission no = " . $adm_no ;
Well, the following does print a string and then does nothing with the variable:
echo "Admission no = " ;$adm_no ;
You where probably going for:
echo "Admission no = " . $adm_no;
Apart from that, are you aware that the print logic is only evaluated once after the while loop has iterated all the results (if more than one). That is, the variables will hold the values of the last record only.
Here is the problem your exit(); is executing every time even if the input $adm_no is okay.
Change this
if (!$adm_no=="intval")
echo "You Entered wrong Admission no Recheack Admission no" ;
exit();
to
if (!$adm_no=="intval")
{
echo "You Entered wrong Admission no Recheack Admission no" ;
exit();
}
As I told you in the previous (deleted) question, you have an SQL-injection hole.
Here's how to fix it.
Change this code:
Coding horror
$adm_no = $_POST['adm_no'];
if (!$adm_no == "intval")
echo "You Entered wrong Admission no Recheack Admission no";
exit();
$clas = $_POST['clas'];
$query = "SELECT * FROM $clas WHERE adm_no = $adm_no";
Into this code, which is not exposed to SQL-injection dangers
$adm_no = mysql_real_escape_string($_POST['adm_no']);
if (!$adm_no == "intval") {
echo "You Entered wrong Admission no Recheack Admission no"; exit();
}
$allowed_tables = array('table1', 'table2');
$clas = $_POST['clas'];
if (in_array($clas, $allowed_tables))
{
$query = "SELECT * FROM `$clas` WHERE adm_no = '$adm_no'";
}
I know that the If will only accept integers, but the if in your previous question was commented out, therefor it comes and goes, so always escape your inputs before injecting them into your query!
Note how the if in your code does not work because you forgot to enclose the body after the then in brackets {}, causing the exit(); to always be executed.
For more info on SQL-injection see: How does the SQL injection from the "Bobby Tables" XKCD comic work?
And for info on why mysql-real-escape_string or PDO doesn't work with dynamic table names
see: How to prevent SQL injection with dynamic tablenames?
And: Sample code to fix this particular SQL-injection hole
XSS hole
To fix a possible XSS hole, don't do
Coding horror
echo "Admission no = ".$adm_no;
But do this instead:
echo "Admission no = ".htmlspecialchars($adm_no);
In your case it seems that $adm_no can only hold an integer, but I don't have the table definition so I cannot be sure of that. It's best to be on the safe side and always escape dynamic output using htmlspecialchars.
See: What are the best practices for avoiding xss attacks in a PHP site
Statement 1: echo "Admission no = " ;
Statement 2: $adm_no ;
You aren't echoing the variables.
You should probably have something like:
<p>Admission no = <?php echo htmlspecialchars($adm_no); ?></p>
The way you assign the variables in the loop doesn't make any sense: if your SQL query returns more than 1 row, your code will simply replace the values. You probably want to echo the results inside the loop.
There is a syntax error here: echo "Admission no = " ;$adm_no ;.. it should be echo "Admission no = ".$adm_no;
When you are echoing the results, you are not actually echoing the variables: echo " <p>Admission Date: $adm_dt </p>";
Because echo accepts parameters as comma-separated list, like
echo $one, "two"
Using comma is also possible, but better just use heredoc syntax which support variable substitution, if you need to output large chunk of text with newlines
echo <<<HEREDOC
Your text with $variables or {$variables} here
with newlines and other nifty plaintext formatting
HEREDOC;