Multiple word string for database search using PHP and MySQLi - php

In trying to set up a contact database I'm trying to use a multi word string to search a database of people to narrow down search results.
I have the following code. My problem is taking the result of my forms input string converted to an array and inserting it into the $sql SELECT coding so that it checks every word against every column. The reason for that is so when doing a search you can either type in 'Joe Bloggs New York' or 'New York Joe Bloggs' and get the same result.
<?php
// **My String collection and conversion to an array**
// Get Form String
$input = $_POST['input'];
// Split String into an Array
$input = preg_split("/[\\/\s,]+/", $input);
// Checking That We Now Have An Array
print_r($input);
// Loop Through Array Values
for ($i = 0; $i < count($input); $i++) {
// Checking Array Output
echo '<br />';
echo $input[$i];
echo '<br />';
}
// **My database query**
// Connect To Database
require_once("connect.php");
// Query The Database
$sql="SELECT * FROM contact WHERE name LIKE '%$input[$i]%' AND lastName LIKE '%$input[$i]%' AND area LIKE '%$input[$i]%' ORDER BY name";
if ($result=mysqli_query($con,$sql))
{
// Fetch one and one row
while ($row=mysqli_fetch_row($result))
{
echo "<h2><u>$row[1]</u></h2><br />";
echo "<img src='img/$row[5]' style='width:300px; height: auto;'/>";
echo "<h3>Name - $row[1] $row[2]</h3>";
echo "<h3>Phone - $row[3]</h3>";
echo "<h3>Email - $row[4]</h3>";
echo "<br /><br />";
}
// Free result set
mysqli_free_result($result);
} else {
echo "No Results";
}
// Close Database Connection
mysqli_close($con);
?>
<h1>Contacts</h1>
<form method="post" action="search.php">
<table>
<tr>
<td>
<input type="text" name="input" size="30" maxlength="50"/>
</td>
<td>
<input type="submit" name="SEARCH" value="Search"/>
</td>
</tr>
</table>
</form>
If I could please get help putting both pieces of code together so that it takes the string, converts it to an array and then only gives me a return from the database of Joe Bloggs's that live in New York I'd be very grateful.

You might try changing your ANDs to ORs in the query, otherwise you are querying for john john who lives in john...

Related

Array is storing one character in each field PHP

I have a form
<form action="inserir.php" method="POST">
<tr>
<td><INPUT type='checkbox' name='chk'/></td>
<td><input type='text' name='ppdata[$x]'/></td>
<td><input type='text' size='40' name='ppempresa[$x]'></td>
<td><input type='text' name='ppfuncao[$x]' size='40'></td>
</tr>`
</form>`
In my code, the user can insert more rows to the table, insert data and send it to a new file (insert.php)
foreach ($_POST["ppdata"] as $dat){
echo $dat. ' ';
}
foreach ($_POST["ppempresa"] as $empresa){
echo $empresa. ' ';
}
foreach ($_POST["ppfuncao"] as $funcao){
echo $funcao. ' ';
}
$data = count($dat);
$emp = count($empresa);
$func = count($funcao);
if($data == $emp){
for($x = 0; $x < $emp; $x++){
$str[] = "('{$dat[$x]}','{$empresa[$x]}','{$funcao[$x]}','{$id}')";
}
$s = implode(',',$str);
$sql = mysql_query("INSERT INTO pp (data,empresa,descricao,id_user) VALUES $s;");
}
The array i'm seng only saves one char per field.
if i do:
echo '$dat';
It'll echo the whole array.
If i do this:
echo '$dat[0]';
It'll only show the first letter of the string. If i write 'Hello' on the input, It will only show 'H'.
EDIT: I need to insert data in the database, depending on how much rows the user adds. but right now, the array only inserts the last letter of the last word of each field.
Let's look at what happens when you write "Hello".
The following POST array is sent:
$_POST = array(
"ppdata" => array(
"Hello"
)
);
Now, you run this:
foreach ($_POST["ppdata"] as $dat){
echo $dat. ' ';
}
At this point, $dat is equal to "Hello".
Notably, $dat is a string. This means that $dat[0] is the first character of the string, namely "H". That is how accessing a string as an array of characters works.
You probably meant to use $_POST['ppdata'] everywhere you used $dat (in count, in the loop etc.) as this is your array.

PHP MySQL: User selects the fields to create mysql query array variable

here's my problem:
I have a form in which user inputs 3 things (ID key, Date from and Date To) and also from a group o checkboxes he chooses which columns he wants to see in the result. (the form is way to big because its database table has about 15 columns each, so I don't post it here)
here is the (part of the) code which handles these inputs and generates the query. (I'll explain after it what exactly does)
<?php
//Check the columns that should be shown in the table
if(empty($_POST['vesselcolumns']) && empty($_POST['expeditioncolumns'])){
$columns='*';
}else if (isset($_POST['vesselcolumns']) || isset($_POST['expeditioncolumns'])) {
if (empty($_POST['vesselcolumns'])){
$columns='';
}else{
$vesselcolumns= implode(',', $_POST['vesselcolumns']);
$columns=$vesselcolumns;
}
if (empty($_POST['expeditioncolumns'])){
$columns.='';
}else{
$expeditioncolumns = implode(',', $_POST['expeditioncolumns']);
if($columns!=''){
$columns.=','.$expeditioncolumns;
}
}
}
//AMAS check
if(empty($_POST['searchv'])){
echo 'No AMAS given, will print ALL expedition data<br />';
}else{
$amas = $_POST['searchv'];
}
//Deploy Date FROM and TO check
if(empty($_POST['deploydatefrom'])){
$datefrom = '0000-00-00';
}else{
$datefrom = $_POST['deploydatefrom'];
}
if(empty($_POST['deploydateto'])){
$dateto = '9999-12-31';
}else{
$dateto = $_POST['deploydateto'];
}
if(isset($amas)){
$expeditionq="SELECT '$columns'
FROM vessel
INNER JOIN vessel_expeditions
ON vessel.AMAS=vessel_expeditions.vexpedition_AMAS AND vessel.AMAS= '$amas'
INNER JOIN expedition
ON vessel_expeditions.expedition_ID=expedition.expedition_ID
WHERE expedition.deployDate >= '$datefrom' AND expedition.deployDate <= '$dateto'";
$result=mysqli_query($con,$expeditionq);
if($columns=='*'){
$takefields=mysqli_query($con, "SHOW COLUMNS FROM vessel");
while ($vcol = mysqli_fetch_array($takefields)){
$vcolu= array( $vcol['Field']);
}
$takefieldse=mysqli_query($con, "SHOW COLUMNS FROM expedition");
while ($ecol = mysqli_fetch_array($takefieldse)){
$ecolu= array($ecol['Field']);
}
$vccounter = count($vcolu);
$eccounter = count($ecolu);
while($row = mysqli_fetch_array($result)){
for($i=0; $i<$vccounter; $i++){
echo $row[$vcolu[$i]] . '<br />';
}
for($i=0; $i<$eccounter; $i++){
echo $row[$ecolu[$i]] . '<br />';
}
}
}else{
$column = explode(',', $columns);
$counter = count($column);
$forexport='<table id="results">
<tr>';
for($i=0; $i<$counter; $i++){
$forexport .= '<th>' . $column[$i] . '</th>';
}
$forexport.='</tr>';
while($row = mysqli_fetch_array($result)){
for($i=0; $i<=$counter; $i++){
$forexport .= '<td>' . $row[$column[$i]] . '</td>';
}
$forexport.='</tr>';
}
$forexport .='</table>';
echo $forexport;
echo '<form name="exportanalysis" method="post" action="exportanalysis.php">
<input type="hidden" name="export" value="' . htmlspecialchars($forexport, ENT_QUOTES) . '" />
<label for="selectcsv"><img src="img/csv-icon.png" width="50" height="50" /> </label>
<input type="radio" name="filexport" value="csv" id="selectcsv" required />
<label for="selectxls"><img src="img/xls-icon.png" width="50" height="50" /> </label>
<input type="radio" name="filexport" value="xls" id="selectxls" />
<input type="submit" value="Download" />';
}
}else{
echo 'amas not set';
}
?>
First I check which columns has user selected (if none selected I put "*") and I break them in an array with implode (as from the checkboxes they come in string like this: column1,column2,column4, etc.).
Then I check the AMAS (which is the ID key user inputs) and finally I check the dates if given [strange thing here when I submitted the form without date values with isset() even though there was no value in them it kept passing the if(as they were set) so I changed it to empty()].
After multiple tests I've found out that the query ($expeditionq) works fine (I even tested it in MySQL directly). Also the "SHOW COLUMNS" queries work fine and I fetch their results and showed them.
The problem comes when I'm trying to show the results of the $expeditionq query and I assume that the problem is this: $row[$column[$i]] but I cannot figure out another way to do it :/
Puh. Sorry this code looks weired. Is this what you want to express:
if(!empty($_POST['vesselcolumns']) && !empty($_POST['expeditioncolumns'])){
$columns= implode(',', $_POST['vesselcolumns']) . ',' . implode(',', $_POST['expeditioncolumns']);
}
else if(!empty($_POST['vesselcolumns'])) {
$columns= implode(',', $_POST['vesselcolumns']);
}
else if(!empty($_POST['expeditioncolumns'])) {
$columns= implode(',', $_POST['expeditioncolumns'])
}
else {
$columns='*';
}
Anyway, the problem is just obvious:
SHOW COLUMNS will return all columns in that table.
You iterating over the result, which contains only the columns the user selected.
So you are trying to access alphanumeric indexes or "keys" within the row that dont exist unless the user has requested to show all columns.
EDIT: Sorry, this was an incomplete reading due to the unstructured way the source is organized. The query SHOW COLUMNS is only executed, when $columns == "*", so all fields are selected obviously.

Using a generated list of options to refine PHP/MySQL search

I want to user a generated list of links to refine a search.
I have a database of products (panel meters), each row with a unique model number and information about that model. I've created a search that allows a user to search against model number and input type (these are process meters that can recieve signals like standard 4-20mA or custom ranges). Along with the search, the script also creates 3 unique arrays of links that I'd like to be clickable to narrow the results. It does that, so far, with these snippets of php to create the link list:
//create a series list
$uniqueseries[] = "<a href='#' onclick='document.searchform.submit()'>{$row['series']}</a>";
//create a inputs list
$uniqueinputs[] = "<a href='#' onclick='document.searchform.submit()'>{$row['sio']}</a>";
//create a series list
$uniquepowers[] = "<a href='#' onclick='document.searchform.submit()'>{$row['pso']}</a>";
AND
//create array of unique series types
$uniqueseries = array_unique($uniqueseries);
//create array of unique input types
$uniqueinputs = array_unique($uniqueinputs);
//create array of unique power types
$uniquepowers = array_unique($uniquepowers);
Which are located in the "backend" script (just a bit below.)
For each set of links, it first creates an array of non unique links (one for EVERY result MySQL originally returned) and then I use array_unique to cut down the array to only unique links. Then on my search page I use something like ", $uniqueseries); ?> to print out the array of links.
What I would like to happen is when a user clicks a link it narrows search results by resubmitting the original MySQL query with the refining query appended. An example of this behavior appears on Amazon search where a user can click a link on the left that will keep the same search but narrow it down to a certain department or even an option unique to that product (ie. amount of ram when searching for a computer or pixel count when searching for cameras.)
In my case, if my user starts the search by searching against model number and input type (the default two keys), say with the term "4 to 20", my user will have over 3500 results returned to them (we have a very large catalog of products.) On the left will be the list of unique links that I'd like to have refine the result. So if the user sees under "Power" options "120 V AC with battery backed data", I want clicking that link to return all meters with 4 to 20 mA inputs (there's multiple variations as you can see under the generated Input Options) but only if they have "120 V AC with battery backed data" as a "Power" source.
I feel like I'm on the right track but I'm still a bit of a novice when it comes to PHP.
To help along, here is the code I'm using for my search "backend":
<?php
//creates DB connection
$dbHost = 'host';
$dbUser = 'user';
$dbPass = 'pass';
$dbDatabase = 'db';
$con = mysql_connect($dbHost, $dbUser, $dbPass) or trigger_error("Failed to connect to MySQL Server. Error: " . mysql_error());
mysql_select_db($dbDatabase) or trigger_error("Failed to connect to database {$dbDatabase}. Error: " . mysql_error());
$time_start = microtime(true);
//create arrays for results and errors
$error = array();
$results = array();
//creates arrays holding values for narrowing results
$uniqueseries = array();
$uniqueinputs = array();
$uniquepowers = array();
$uniquedigsize = array();
$uniquedignum = array ();
$uniquedigcol = array();
$uniquedistype = array();
//reset some variables if needed
isset($_GET['page'])?"":$_GET['page'] = 1;
isset($resultcount)?"":$resultcount = 0;
if (isset($_GET['search'])) {
//removes HTML/JS
$searchString = trim($_GET['search']);
$searchStripped = strip_tags($searchString);
//prevents SQL injections
$searchSan = mysql_real_escape_string($searchStripped);
if (count($error) <1) { //search continues if no errors exist
$searchSQL = "SELECT series, model, img, pso, sio, dig_size, dig_num, dig_col FROM meters WHERE levenshtein('%{$searchSan}%',model) < 4 OR levenshtein('%{$searchSan}%',sio) < 4 ORDER BY model";
$searchResult = mysql_query($searchSQL) or trigger_error("There was an error with MySQL. " . mysql_error() . "<br> Query was {$searchSQL}.");
if (mysql_num_rows($searchResult) < 1) {
$error[] = "The search term '{$searchString}' yielded no results.";
} else {
$i = 1;
while ($row = mysql_fetch_assoc($searchResult)) {
$results[] = "<tr><td align='center'>{$i}</td> <td align='center'><a href='/catalog/{$row['series']}.pdf'>{$row['series']}</a></td> <td align='center'><img src='/img/productimg/small/{$row['img']}'></td> <td align='center'>{$row['model']}</td> <td> {$row['sio']}</td> <td> {$row['pso']}</td> <td align='center'>{$row['dig_num']}</td> <td align='center'>{$row['dig_size']}\"</td> <td align='center'>{$row['dig_col']}</td></tr>";
//create a series list
$uniqueseries[] = "<a href='#' onclick='document.searchform.submit()'>{$row['series']}</a>";
//create a inputs list
$uniqueinputs[] = "<a href='#' onclick='document.searchform.submit()'>{$row['sio']}</a>";
//create a series list
$uniquepowers[] = "<a href='#' onclick='document.searchform.submit()'>{$row['pso']}</a>";
$i++;
}
}
//create array of unique series types
$uniqueseries = array_unique($uniqueseries);
//create array of unique input types
$uniqueinputs = array_unique($uniqueinputs);
//create array of unique power types
$uniquepowers = array_unique($uniquepowers);
//results paginator
$resultcount = count($results); //number of results
$perpage = 5; //number of results per page
$totalpages = ceil($resultcount / $perpage); //calculates total number of pages
$startresult = (($_GET['page'] - 1) * $perpage); //calculates the first result number for page
$brokenresults = array_slice($results, $startresult, $perpage); //slices array into groups set by $perpage
$nextpage = $_GET['page'] + 1; //calculate next page number
$lastpage = $_GET['page'] - 1; //calculates last page number
}
}
function removeEmpty($var) {
return (!empty($var));
}
$execution_time = (microtime (true) - $time_start); //calculates script processing time
?>
And this is the code I'm using for my "frontend":
<body>
<!-- Google Analytics Script -->
<?php include_once("scripts/analyticstracking.php") ?>
<div class="wrapper"> <!-- Sticky Footer Wrapper -->
<div id="panorama"></div>
<div id="header">
<?php include("include/header/banner.php") ?>
<?php include("include/header/nav.php") ?>
<?php include("include/header/quicksearch.php") ?>
</div>
<form method="GET" action="<?php echo $_SERVER['PHP_SELF'];?>" name="searchform" id="searchform">
<div id="content">
<?php include("scripts/searchbackend.php") ?>
<?php include("scripts/searchform.php") ?>
<?php include("scripts/searchoptions.php") ?>
<div id="searchresults">
<center>
<?php
echo (count($error) > 0)?"The following had errors:<br /><span id=\"error\">" . implode("<br />", $error) . "</span><br /><br />":"";
echo ($resultcount > 0)?"<table id='searchtable' ><thead align='center'><tr><th width='50px'></th><th width='50px'>Series</th><th width='50px'>Image</th><th width='85px'>Model</th><th width='50px'>Input</th><th width='50px'>Power Supply</th><th width='50px'># of Digits</th><th width='50px'>Digit Size</th><th width='50px'>Display Color</th></tr></thead><tbody>" . implode("", $brokenresults) . "</tbody></table>":""; //returns results
?>
<div id="resultsfooter">
<?php
if (count($results) > 5) {
echo ($_GET['page'] > 1)?"<br><a href='/search.php?search={$_GET['search']}&page={$lastpage}'>Previous</a>" . " Page {$_GET['page']}/{$totalpages} " . "<a href='/search.php?search={$_GET['search']}&page={$nextpage}'>Next</a>":"<br>Page {$_GET['page']}/{$totalpages} " . "<a href='/search.php?search={$_GET['search']}&page={$nextpage}'>Next</a>";
}
echo ($resultcount > 0)?" | Search found {$resultcount} results in {$execution_time} seconds.":""; //result count and time
?>
</div>
</center>
</div>
</div>
</form>
</div>
<div class="footer">
<?php include("include/footer/footer.php") ?>
</div>
</body>
As well, this is the contents of my "searchoptions.php" include:
<div id="searchoptions">
<fieldset id="searchin" class="searchoptions">
<legend>Serach In</legend>
<input type="checkbox" class="checkbox" name="model" <?php echo isset($_GET['model'])?"checked":''; ?> /><label class='checklabel'>Model</label><br>
<input type="checkbox" class="checkbox" name="input" <?php echo isset($_GET['input'])?"checked":''; ?> /><label class='checklabel'>Input</label>
</fieldset>
<fieldset class="searchoptions" style="<?php if (count($uniqueseries) < 2) {echo "Display: none;";} ?>">
<legend>Series</legend>
<?php echo implode("<br>", $uniqueseries); ?>
</fieldset>
<fieldset class="searchoptions" style="<?php if (count($uniqueinputs) < 2) {echo "Display: none;";} ?>">
<legend>Input</legend>
<?php echo implode("<br>", $uniqueinputs); ?>
</fieldset>
<fieldset class="searchoptions" style="<?php if (count($uniquepowers) < 2) {echo "Display: none;";} ?>">
<legend>Power</legend>
<?php echo implode("<br>", $uniquepowers) ?>
</fieldset>
<input type="submit" class="" value="Update Search" style="" <?php if (!isset($types)) { if (isset($_GET['model'])) {"`model` LIKE '%{$searchSan}%'";} elseif (isset($_GET['input'])) {"`input` LIKE '%{$searchSan}%'";} } ?> />
</div>
I have my latest changes live on our test site which you can reach here:
new.foxmeter.com
Try searching "FM" or "4 to 20" as that's what I used in my examples. As of now, "4-20" and "4 20" don't return the same results as "4 to 20" but that I can do and it's not at the top of my list yet.
I'd also like previous searches to persist. So the search starts off "4 to 20", then narrows down to only 4 to 20 process meters with "120 V AC with battery backed data" power supply, then narrowing again will keep the "4 to 20 process with 120 V AC with battery backed data" refinement from before WITH new refinements as well.
If I've been unclear at any point, I'll be here all day so don't be afraid to question or correct me if you've got an idea for me. Thanks in advance to any help from anyone. I've gotten most of the features for our new site completed except for this search which I've had some trouble with so completing this means my task is (almost) complete.

How to combine PHP array from user input with MySQL table for calculation (conceptually)?

I have a website, where a user can enter a time series (date; series) into a text area. The data is sent to the server using the POST method.
I have a few tables with different time series already stored in the MySQL database.
The user specified time series and those stored in the database should be combined for statistical calculations.
I store the user input into an array using explode and want to select the time series from the database using the date as the selector (WHERE date = $datefromuserinput).
I have two problems here:
The date format for the array does not match the one in MySQL (ISO, o-m-d) after several transformations (e.g. strtotime).
Also, the time series data type in MySQL is in DECIMAL (15,4) format, but the one in PHP is string (transformed to float).
Before trying to find solutions, I would like to know if my concept is right and best. Putting the user input into a MySQL table would make calculations faster (as I understand). However, several users can use the form simultaneously that would result in overwriting the entries in the new table in MySQL, right? Should I load the complete MySQL table into a PHP array (session necessary)?
I have read many solutions but could not find these answer. Any hint would be highly appreciated.
<?php
date_default_timezone_set('UTC');
//session_start();
//$datum = [];
if ($_POST['usersubmit']) {
if ($_POST['userinput1'] !=""){
if ($_POST['separator'] != ""){
if ($_POST['separator'] == comma){
$separatorsign = ",";
}
elseif ($_POST['separator'] == semicolon){
$separatorsign = ";";
}
else {
$separatorsign = "\t";
}
}
$userinput1 = $_POST['userinput1'];
$zeilen= explode("\n", $userinput1);
$daten = array();
foreach($zeilen as $zeile) {
list($datum, $zeitreihe) = explode($separatorsign, $zeile,2);
$datumkonv = strtotime($datum);
$daten[]['datum'] = date('o-m-d',$datumkonv);
$daten[]['zeitreihe'] = $zeitreihe;
}
$con = mysql_connect('localhost','username','pw');
if (!$con)
{
die('Could not connect: ' . mysql_error($con));
}
mysql_select_db("dbname");
$sql = "SELECT series FROM mytimeseries1 WHERE date = $daten[0]['datum']"; //[0] just for trying working with the first row
$result = mysql_query($sql);
$row = mysql_fetch_object($result);
echo "$row->series";//["series"].'<br>';
$row = floatval($row);
$ergebnis = $row + 22;
echo $ergebnis; // $row is 100.5000 but $ergebnis returns 100.5023 ??
mysql_free_result($result);
mysql_close($con);
echo "<pre>";
//print_r ($result);
print_r ($row);
var_dump($row);
var_dump($ergebnis);
}
}
?>
<table width="800">
<tr>
<td width="400">
<form action="test.php" method="post">
<p><textarea style="overflow-y:scroll;resize:none;" name="userinput1" id="userinput1" cols="28" rows="12"></textarea></p>
<p>Separator<br>
<input type="radio" name="separator" value="comma">Comma</p>
<p><input type="radio" name="separator" value="tab">Tab</p>
<p><input type="radio" name="separator" value="semicolon">Semicolon</p>
</td>
<td width="400">
<p>Date Format<br>
<input type="radio" name="dateformat" value="yyyy-mm-dd">YYYY-MM-DD</p>
<p><input type="radio" name="dateformat" value="yyyy-dd-mm">YYYY-DD-MM</p>
<p><input type="radio" name="dateformat" value="dd-mm-yyyy">DD-MM-YYYY</p>
<p><input type="radio" name="dateformat" value="mm-dd-yyyy">MM-DD-YYYY</p>
<p><input type="radio" name="dateformat" value="ddmmyyyy">DD.MM.YYYY</p>
<p><input type="submit" name="usersubmit" value="GO"></p>
</form>
</td>
</tr>
</table>
<?php
EDIT: After trying for hours I think that it makes more sense to upload the user input array into a temporary table in MySQL (date format is accepted etc). I had to change the foreach()-part in the code above to:
for($y = 0;$y < count($zeilen);$y++){
list($datum, $zeitreihe) = explode($separatorsign, $zeilen[$y], 2);
$daten[$y]['datum'] = $datum;
$daten[$y]['zeitreihe'] = $zeitreihe;
}

How to fill an HTML Form with (a lot) of records from database?

I've a HTML form with approx. 120 input text fields.
Then i've a PHP page with the same form where i've this code to show the value get from database.
<input type="text" id="field_1" name="field_1" value="<?php echo $myvalue1; ?>" />
Is there a way to retrieve data from database and fill the input text value for each field or doing it in a better way than specify more than 120 variables?
Thanks!
There's a trick in PHP. You can name your inputs using "[]" operator. like this:
<input type="text" id="field_1" name="field[]" value="<?php echo $myvalue1; ?>" />
As the result it will be treated as an array in the corresponding REQUEST array (POST or GET, depends of HTTP method for you form).
To fill the inputs, simply use a loop.
You can always store the results in an array, then loop through that.
$q = mysql_query ( ... );
for ($i = 1; $r = mysql_fetch_row ($q); ++$i)
printf ('<input tyle="text" id="field_%s" name="field_%s" value="%s"/>', $i, $i, $r[0]);
Loop through your results from the query and generate textboxs
<?php
$sql = "SELECT column FROM table";
if ($result = $mysqli->query($sql)) {
while($obj = $result->fetch_object()){
echo "<input type='text' name='field[]' value='". $obj->column ."'> <br>"; // Here is the where you put your textbox in loop
}
}
$result->close();
?>

Categories