While Loop in SQL query - php

I'm not sure why this SQL query is not working.
I'm new to SQL/PHP so please forgive.
mysql_query("
SELECT * FROM table WHERE name = " . "'Bob'" .
while($i < $size)
{
$i++;
echo "OR name = '";
echo $array[$i] . "'";
} .
" ORDER BY id DESC "
);
Dreamweaver gives me an error saying it is not correct but does not tell me what is wrong.
Is it possible to put a while loop into an sql command?

you can not use a while in a string
$where = "";
if ($size > 0)
{
$where .= " WHERE ";
}
while($i < $size)
{
$i++;
$where .= "OR name = '".$array[$i]."' ";
}
$query = "SELECT * FROM table WHERE name = '".Bob."'".$where." ORDER BY id DESC";
mysql_query($query);
(this code is not tested)

Woot !
You just can't write this :D
Build your OR condition before writing the query and it will be just fine:
$myCondition = " ";
while($i < $size) {
$i++;
$myCondition .= "OR name = '" . $array[$i] . "'";
}
mysql_query(
"SELECT * FROM table WHERE name = " . "'Bob'" . $myCondition . " ORDER BY id DESC ");

echo is to output the string, and it won't return the string.
Something like $str = "aaa" . echo "bbb"; won't work.
For you case, use IN will be better.
foreach ($array as &$name) {
$name = "'".mysql_real_escape_string($name)."'";
}
mysql_query("SELECT * FROM table WHERE name IN (".implode(',', $array).")");

Or use
"SELECT * FROM table WHERE name IN(".implode( ',', $array).")";

Related

How can I make a php tag search field with AND and OR conditions?

I am trying to create a search field where people can search with tags that are saved in our database (ajax). The problem is that I want the user to be able to search with tags for content, where the content MUST have tags attached that include all the tags that were used for the search. So let's say I search for 'bwm red', I want to only show content with both the tags 'bmw' and 'red' attached to it. So NO content with only one of the two tags.
Additionally, the user can search for tags that are optional, so let's say the user searches for 'red yellow', the results should be content either with tags 'red' or 'yellow', where it also matches with the MUST search field. By doing so you get a very specific search.
In the photo here I have included the design how the search field should work, and it should be more clear what I am trying to create.
I have also written some code, but as you can see it is not working how I want to be.
Any idea how I can solve this problem?
<form action="search.php" method="post" >
  <h2>Search Keywords:</h2>
<h3>MUST</h3>
    <input type="text" name="must">
    <h3>Optional</h3>
<input type="text" name="keyword">
    <input type="submit" value="Search">
</form>
if(!empty($_POST))
{
$aMust = explode(" ", $_POST['must']);
$aKeyword = explode(" ", $_POST['keyword']);
$query ="SELECT * FROM table1 WHERE field1 like '%" . $aKeyword[0] . "%'";
for($i = 1; $i < count($aKeyword); $i++) {
if(!empty($aKeyword[$i])) {
$query .= " OR field1 like '%" . $aKeyword[$i] . "%'";
}
}
$result = $db->query($query);
echo "<br>You have searched for keywords: " . $_POST['keyword'];
if(mysqli_num_rows($result) > 0) {
$row_count=0;
echo "<br>Result Found: ";
echo "<br><table border='1'>";
While($row = $result->fetch_assoc()) {
$row_count++;
echo "<tr><td> ROW ".$row_count." </td><td>". $row['field1'] . "</td></tr>";
}
echo "</table>";
}
else {
echo "<br>Result Found: NONE";
}
}
You need to use UNION to get the records and show data like below
$aMust = explode(" ", $_POST['must']);
$aKeyword = explode(" ", $_POST['keyword']);
$query ="SELECT * FROM table1 WHERE (";
for($i = 0; $i < count($aMust); $i++) {
if( $i!=0 && $i != (count($aMust)-1) ) {
$query .=" AND ";
}
if(!empty($aMust[$i])) {
$query .=" field1 like '%" . $aMust[$i] . "%' ";
}
}
$query .=" ) ";
if( count($aKeyword) > 0 ) {
$query .= " AND (";
for($i = 0; $i < count($aKeyword); $i++) {
if( $i!=0 && $i != (count($aKeyword)-1) ) {
$query .=" OR ";
}
if(!empty($aKeyword[$i])) {
$query .= " field1 like '%" . $aKeyword[$i] . "%'";
}
}
$query .= " ) ";
}
$query .=" UNION ";
$query .=" SELECT * FROM table1 WHERE (";
for($i = 0; $i < count($aMust); $i++) {
if( $i!=0 && $i != (count($aMust)-1) ) {
$query .=" AND ";
}
if(!empty($aMust[$i])) {
$query .=" field1 like '%" . $aMust[$i] . "%' ";
}
}
$query .=" ) ";
This will give you those records which matches the optional values and which do not matches the optional values but matches the must values.
UNION do not gives duplicate records, so you don't have to worry for duplicate values coming.
In case any issue, let me know in comments.

search query in php

I am creating search query in php by passing variable through GET method. When the variable is null then it's passing the query like,
SELECT * FROM table WHERE column_name = null.
And it's showing error (obvious). I want to create query like. If user don't select anything from search options then it should fetch all the data from that column.
What's the correct logic for that?
Thanks.
Code:
if(isset($_GET['selPetType']) && $_GET['selPetType'] != '')
{
$searchParams['petType'] = $_GET['selPetType'];
$queryStr .= " PetType='" .$_GET['selPetType']. "'";
}
if(isset($_GET['txtPetBreed1']) && !empty($_GET['txtPetBreed1']))
{
$searchParams['breed'] = $_GET['txtPetBreed1'];
$queryStr .= " AND PetBreed1 ='". $_GET['txtPetBreed1'] . "'";
}
$clause1 = "SELECT * FROM pet WHERE $queryStr ORDER BY `Avatar` ASC LIMIT $startLimit, $pageLimit";
$totalRun1 = $allQuery->run($clause1);
Maybe something like this:
$get['param1'] = 'foo';
$get['param3'] = null;
$get['param2'] = '';
$get['param4'] = 'bar';
$where = null;
foreach ($get as $col => $val) {
if (!empty($val)) {
$where[] = $col . ' = "' . $val . '"';
}
}
$select = 'SELECT * FROM pet ';
if ($where) {
$select .= 'WHERE ' . implode(' AND ', $where);
}
$select .= ' ORDER BY `Avatar` ASC LIMIT $startLimit, $pageLimit';
Edit: I added if to remove empty values and added 2 new values to example so you can see this values will not be in query.
if(isset($_GET['your_variable'])){
$whr = "column_name = $_GET['your_variable']";
}
else{
$whr = "1 = 1";
}
$qry ="SELECT * FROM table WHERE ".$whr;
For example :
<?php
$userSelectedValue = ...;
$whereCondition = $userSelectedValue ? " AND column_name = " . $userSelectedValue : "" ;
$query = "SELECT * FROM table WHERE 1" . $whereCondition;
?>
Then consider it's more safe to use prepared statements.

creating a sql query dynamically

I want to create sql queries dynamically depending upon the data I receive from the user.
Code:
$test = $_POST['clientData']; //It can be an array of values
count($test); //This can be 2 or 3 or any number depending upon the user input at the client
$query = "select * from testTable where testData = ".$test[0]." and testData = ".$test[1]." and . . .[This would vary depending upon the user input]"
Is it possible to achieve the above scenario. I am relatively new in this area.Your guidance would be helpful.
Use:
<?php
$test=$_POST['clientData'];//It can be an array of values
$query = "select *from testtable where 1 ";
foreach($test as $value) {
$query .= " AND testData='" . $value . "'";
}
echo $query;
?>
Use prepared statements:
$query = $dbh->prepare("SELECT * FROM testtable WHERE testData=:test0 and testData=:test1");
$query ->bindParam(':test0', $test0);
$query ->bindParam(':test1', $test0);
$test0 = $test[0];
$test1 = $test[1];
$query->execute();
Rishi that's a very long chapter.
If you want to search into a single field then you can try to do:
<?php
$test = $_POST[ 'clientData' ];
if( is_array( $test ) ){
$select = implode( ",", $test );
} else {
$select = $test;
}
$query=select *from testtable where testData IN ( $select );
?>
This is valid only for searches into a specific field.
If you want to create searches on multiple fields then you need to do a lot of more work, having an associative mapping which can create a relation variable name -> field_to_search
$data = $_POST['data'];
$query = "SELECT";
if ( is_set($data['columns']) )
$query .= " ".implode(',',$data['columns']);
else
$query .= "*";
if ( is_set($data['table']) )
$query .= " ".$data['table'];
and ...
This is very much pseudo code as I don't really know PHP, but could you not do something like this
$query = "select * from testable";
$count = count($test);
if($count > 0)
{
$query .= " where ";
for ($x=0; $x<=$count; $x++)
{
if($x > 0)
{
$query .= " and ";
}
$query .= " testData='" . $test[x] . "'";
}
}
$test=$_POST['clientData'];
$query="select * from testtable where testData='".$test[0]."' and testData='".$test[1]."' and . . .[This would vary depending upon the user input]";
$result = mysql_query($query);
$test=$_POST['clientData'];//It can be an array of values
$dValuesCount = count($test);//This can be 2 or 3 or any number depending upon the user input at the client
$query="select *from testtable ";
if ($dValuesCount > 0 ){
$query .= " WHERE ";
for ($dCounter = 0; $dCounter <= $dValuesCount ; $dCounter++){
$query .= "testData=" . $test[$dCounter];
if ($dCounter != ($dValuesCount - 1)){
$query .= " AND ";
}
}
}
$q="select *from table where ";
$a=count($test)-1;
$b=0;
while($element = current($test)) {
$key=key($array);
if($b!=$a){
$q.=$key."=".$test[$key]." and ";
}
else {
$q.=$key."=".$test[$key];
}
next($array);
$b=$b+1;
}
for this your array must contain columnname as key
for example
$test['name'],$test['lastname']
then it will return
$q="select * from table where name=testnamevalue and lastname=testlastnamevalue";
hope it works

Multi word search in PHP/MySQL

I'm struggling to create a search that searches for multiple words. My first attempt yielded no results whatsoever and is as follows:
require_once('database_conn.php');
if($_POST){
$explodedSearch = explode (" ", $_POST['quickSearch']);
foreach($explodedSearch as $search){
$query = "SELECT *
FROM jobseeker
WHERE forename like '%$search%' or surname like '%$search%'
ORDER BY userID
LIMIT 5";
$result = mysql_query($query);
}
while($userData=mysql_fetch_array($result)){
$forename=$userData['forename'];
$surname=$userData['surname'];
$profPic=$userData['profilePicture'];
$location=$userData['location'];
echo "<div class=\"result\">
<img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
<p class=\"quickName\">" . $forename . " " . $surname . "</p>
<p class=\"quickLocation\"> " . $location . "</p>
</div>";
}
}
I also tried the following, which yielded results, but as you can imagine, I was getting duplicate results for every word I entered:
if($_POST){
$explodedSearch = explode (" ", $_POST['quickSearch']);
foreach($explodedSearch as $search){
$query = "SELECT *
FROM jobseeker
WHERE forename like '%$search%' or surname like '%$search%'
ORDER BY userID
LIMIT 5";
$result .= mysql_query($query);
while($userData=mysql_fetch_array($result)){
$forename=$userData['forename'];
$surname=$userData['surname'];
$profPic=$userData['profilePicture'];
$location=$userData['location'];
echo "<div class=\"result\">
<img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
<p class=\"quickName\">" . $forename . " " . $surname . "</p>
<p class=\"quickLocation\"> " . $location . "</p>
</div>";
}
}
}
I'm pretty much at a loss as to how to proceed with this, any help would be greatly appreciated.
EDIT:
if($_POST){
$quickSearch = $_POST['quickSearch'];
$explodedSearch = explode (" ", trim($quickSearch));
$queryArray = array();
foreach($explodedSearch as $search){
$term = mysql_real_escape_string($search);
$queryArray[] = "forename like '%" . $term . "%' surname like '%" . $term . "%'";
}
$implodedSearch = implode(' or ', $queryArray);
$query="SELECT *
FROM jobseeker
WHERE ($implodedSearch)
ORDER BY userID
LIMIT 5";
$result = mysql_query($query);
while($userData=mysql_fetch_array($result, MYSQL_ASSOC)){
$forename=$userData['forename'];
$surname=$userData['surname'];
$profPic=$userData['profilePicture'];
$location=$userData['location'];
echo "<div class=\"result\">
<img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
<p class=\"quickName\">" . $forename . " " . $surname . "</p>
<p class=\"quickLocation\"> " . $location . "</p>
</div>";
}
}
I've been working on the same subject (search with keywords) for a while and this how i did it :
$words = $_POST['keywords'];
if(empty($words)){
//redirect somewhere else!
}
$parts = explode(" ",trim($words));
$clauses=array();
foreach ($parts as $part){
//function_description in my case , replace it with whatever u want in ur table
$clauses[]="function_description LIKE '%" . mysql_real_escape_string($part) . "%'";
}
$clause=implode(' OR ' ,$clauses);
//select your condition and add "AND ($clauses)" .
$sql="SELECT *
FROM functions
WHERE
user_name='{$user_name}'
AND ($clause) ";
$results=mysql_query($sql,$connection);
if(!$results){
redirect("errors/error_db.html");
}
else if($results){
$rows = array();
<?php
while($rows = mysql_fetch_array($results, MYSQL_ASSOC))
{
// echo whatever u want !
}
?>
-- Now this is how it look when i tried to run it with FULLTEXT search :
But you should set the table type as "MyISAM"
<?php
$words = mysql_real_escape_string($_POST['function_keywords']);
if(empty($words)){
redirect("welcome.php?error=search_empty");
}
//if the columns(results)>1/2(columns) => it will return nothing!(use "NATURAL LANGUAGE"="BOOLEAN")
$sql="SELECT * FROM functions
WHERE MATCH (function_description)
AGAINST ('{$words}' IN NATURAL LANGUAGE MODE)";
$results=mysql_query($sql,$connection);
if(!$results){
redirect("errors/error_db.html");
}
else if($results){
$rows = array();
while($rows = mysql_fetch_array($results, MYSQL_ASSOC))
{
// echo
}
}
?>
Perhaps what you are looking for is a MySQL full-text search.
For your example, you could do something like:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$search = $_POST['quickSearch'];
// Todo: escape $search
$sql = "
SELECT
*,
MATCH (`forename`)
AGAINST ('{$search}' IN NATURAL LANGUAGE MODE) AS `score`
FROM `jobseeker`
WHERE
MATCH (`forename`)
AGAINST ('{$search}' IN NATURAL LANGUAGE MODE)";
// Todo: execute query and gather results
}
Note that you will need to add a FULLTEXT index to the column forename.
Take a look at MySQL fulltext searches, if you must use MySQL. Otherwise take a look at SOLR, which is a fulltext search engine. You can use MySQL and SOLR in combination to provide enterprise level search capabilities for your apps.
here's what i did
if (isset($_POST['search'])){
$words = mysql_real_escape_string($_POST['searchfield']);
$arraySearch = explode(" ", trim($words));
$countSearch = count($arraySearch);
$a = 0;
$query = "SELECT * FROM parts WHERE ";
$quote = "'";
while ($a < $countSearch)
{
$query = $query."description LIKE $quote%$arraySearch[$a]%$quote ";
$a++;
if ($a < $countSearch)
{
$query = $query." AND ";
}
}
$result=mysql_query($query) or die(error);
//you could just leave it here, short and sweet but i added some extra code for if it doesnt turn up any results then it searches for either word rather than boths words//
$num = mysql_num_rows($result);
if ($num == 0){
$a = 0;
$query = "SELECT * FROM parts WHERE ";
while ($a < $countSearch)
{
$query = $query."description LIKE $quote%$arraySearch[$a]%$quote ";
$a++;
if ($a < $countSearch)
{
$query = $query." OR ";
$msg = "No exact match for: $words. Maybe this is what you're looking for though? If not please try again.";
}
}
}
$result=mysql_query($query) or die($query);
if (mysql_num_rows($result) == 0){
$msg = "No results, please try another search";
}
}

SQL Multiple WHERE Clause Problem

I'm attempting the modify this Modx Snippet so that it will accept multiple values being returned from the db instead of the default one.
tvTags, by default, was only meant to be set to one variable. I modified it a bit so that it's exploded into a list of variables. I'd like to query the database for each of these variables and return the tags associated with each. However, I'm having difficulty as I'm fairly new to SQL and PHP.
I plugged in $region and it works, but I'm not really sure how to add in more WHERE clauses for the $countries variable.
Thanks for your help!
if (!function_exists('getTags')) {
function getTags($cIDs, $tvTags, $days) {
global $modx, $parent;
$docTags = array ();
$baspath= $modx->config["base_path"] . "manager/includes";
include_once $baspath . "/tmplvars.format.inc.php";
include_once $baspath . "/tmplvars.commands.inc.php";
if ($days > 0) {
$pub_date = mktime() - $days*24*60*60;
} else {
$pub_date = 0;
}
list($region, $countries) = explode(",", $tvTags);
$tb1 = $modx->getFullTableName("site_tmplvar_contentvalues");
$tb2 = $modx->getFullTableName("site_tmplvars");
$tb_content = $modx->getFullTableName("site_content");
$query = "SELECT stv.name,stc.tmplvarid,stc.contentid,stv.type,stv.display,stv.display_params,stc.value";
$query .= " FROM ".$tb1." stc LEFT JOIN ".$tb2." stv ON stv.id=stc.tmplvarid ";
$query .= " LEFT JOIN $tb_content tb_content ON stc.contentid=tb_content.id ";
$query .= " WHERE stv.name='".$region."' AND stc.contentid IN (".implode($cIDs,",").") ";
$query .= " AND tb_content.pub_date >= '$pub_date' ";
$query .= " AND tb_content.published = 1 ";
$query .= " ORDER BY stc.contentid ASC;";
$rs = $modx->db->query($query);
$tot = $modx->db->getRecordCount($rs);
$resourceArray = array();
for($i=0;$i<$tot;$i++) {
$row = #$modx->fetchRow($rs);
$docTags[$row['contentid']]['tags'] = getTVDisplayFormat($row['name'], $row['value'], $row['display'], $row['display_params'], $row['type'],$row['contentid']);
}
if ($tot != count($cIDs)) {
$query = "SELECT name,type,display,display_params,default_text";
$query .= " FROM $tb2";
$query .= " WHERE name='".$region."' LIMIT 1";
$rs = $modx->db->query($query);
$row = #$modx->fetchRow($rs);
$defaultOutput = getTVDisplayFormat($row['name'], $row['default_text'], $row['display'], $row['display_params'], $row['type'],$row['contentid']);
foreach ($cIDs as $id) {
if (!isset($docTags[$id]['tags'])) {
$docTags[$id]['tags'] = $defaultOutput;
}
}
}
return $docTags;
}
}
You don't add in more WHERE clauses, you use ANDs and ORs in the already existing where clause. I would say after the line $query .= " WHERE stv.name = '".$region... you put in
foreach ($countries as $country)
{
$query .= "OR stv.name = '{$country}', ";
}
but I don't know how you want the query to work.

Categories