0

I am new to PHP programming, and I am working on my first program.. This is for the beginnings of a warehouse management system, so I am needing to be able to query part numbers, EANs, item names, etc. Occasionally, all info will be known, or an exact match when input by the user, but sometimes the user will only know part of an EAN, or want to check all items with a similar name, so the results need to be LIKE the input given by the user.

Everything works okay when the user inputs info in only one input in the form (ex. ONLY the entire or portion of a part number is added to the 'partnumber' input, and it correctly returns relevant rows with the info query'd), but when there are multiple inputs added by the user to query table (ex. user inputs data into 'partnumber' AND 'EAN' input), then the result ends up being every item from the table.. same as 'SELECT * FROM table;'.

Is there a way to query and output data from multiple inputs over multiple columns? I have searched this everywhere, but have yet to find an answer relevant to my need... (or at least one with my level of understanding). Any help in the right direction would be great!

SQL query's I have used so far:

$query = "
SELECT partNumber
     , EAN
     , UPC
     , itemDescription
     , SNFlag
     , idClass
     , idType 
  FROM productinfo_table 
 WHERE partNumber LIKE '$partNumber' 
    OR EAN LIKE '$EAN' 
    OR itemDescription LIKE '$itemDescription' 
    OR SNFlag LIKE '$SNFlag'
";

And:

$query = "
SELECT partNumber
     , EAN
     , UPC 
     , itemDescription
     , SNFlag
     , idClass
     , idType 
  FROM productinfo_table 
 WHERE (partNumber,EAN,itemDescription,SNFlag) IN LIKE ('$partNumber','$EAN','$itemDescription','$SNFlag')";

Among a few others...

testissue.php

<?php //testissue.php
//establish connection
require_once "login.php";
$db_server = mysqli_connect($db_hostname,$db_username,$db_password,$db_database);
if(!$db_server) printf('Error connecting to database: %s',mysqli_error($db_server));

//if loop to acquire variables
//if all post array elements are NOT empty
if(!empty($_POST['partNumber']) ||
   !empty($_POST['EAN']) ||
   !empty($_POST['itemDescription']) ||
   !empty($_POST['SNFlag'])) {
    //if partNumber is not empty
    if(!empty($_POST['partNumber'])) {
        $partNumber = '%';
        $partNumber .= $_POST['partNumber'];
        $partNumber .= '%';
    } else {
        $partNumber = '';
    }
    //if EAN is not empty
    if(!empty($_POST['EAN'])) {
        $EAN = '%';
        $EAN .= $_POST['EAN'];
        $EAN .= '%';
    } else {
        $EAN = '';
    }
    // if itemDescription is not empty
    if(!empty($_POST['itemDescription'])) {
        $itemDescription = '%';
        $itemDescription .= $_POST['itemDescription'];
        $itemDescription .= '%';
    } else {
        $itemDescription = '';
    }
    //if SNFlag is not empty
    if(!empty($_POST['SNFlag'])) {
        $SNFlag = '%';
        $SNFlag .= $_POST['SNFlag'];
        $SNFlag .= '%';
    } else {
        $SNFlag = '';
    }
    //echo variables to confirm set, for testing
    echo "$partNumber<br/>";
    echo "$EAN<br/>";
    echo "$itemDescription<br/>";
    echo "$SNFlag<br/>";

    //query to pull data to insert into table rows
    //$query = "SELECT partNumber,EAN,UPC,itemDescription,SNFlag,idClass,idType FROM productinfo_table WHERE partNumber LIKE '$partNumber' OR EAN LIKE '$EAN' OR itemDescription LIKE '$itemDescription' OR SNFlag LIKE '$SNFlag'";
    $query = "SELECT partNumber,EAN,UPC,itemDescription,SNFlag,idClass,idType FROM productinfo_table WHERE (partNumber,EAN,itemDescription,SNFlag) IN LIKE ('$partNumber','$EAN','$itemDescription','$SNFlag')";
    $result = mysqli_query($db_server,$query);
    if(!$result) printf("Error querying database: %s",mysqli_error($db_server));
    $rows = mysqli_num_rows($result);   
} 
//if all post array elements ARE empty
else {
    echo "empty post array";
    $rows = '';
}
//echo form input
echo <<<HERE
<pre>
<form action='testissue.php' method='post'>
  Part No. <input type='text' name='partNumber' />
       EAN <input type='text' name='EAN' />
Item Desc. <input type='text' name='itemDescription' />
   SN Flag <input type='text' name='SNFlag' />
           <input type='submit' value='Search' />
</form>
</pre>
HERE;
//print post array to confirm set values, for testing
echo "<br/>";
print_r($_POST);
echo "<br/><br/>";
//echo table for output
echo <<<HERE
<table>
<tr><th>Part No.</th> <th>EAN</th> <th>UPC</th> <th>Item Desc.</th> <th>SN Flag</th> <th>Class ID</th> <th>Type ID</th></tr>
HERE;
// for loop function to populate items in table
for($a=0;$a<$rows;++$a){
    echo "<tr>";
    $col = mysqli_fetch_row($result);
    for($b=0;$b<7;++$b) echo "<td>$col[$b]</td>";
    echo "</tr>";
}
echo "</table>";
//close connection
mysqli_close($db_server);

?>

Please let me know if you need anything else to help or offer any improvements.

Thanks a lot!

Strawberry
  • 33,750
  • 13
  • 40
  • 57
Arikari
  • 3
  • 1
  • Note: The object-oriented interface to `mysqli` is significantly less verbose, making code easier to read and audit, and is not easily confused with the obsolete `mysql_query` interface. Before you get too invested in the procedural style it’s worth switching over. Example: `$db = new mysqli(…)` and `$db->prepare("…")` The procedural interface is an artifact from the PHP 4 era when `mysqli` API was introduced and should not be used in new code. – tadman Jan 11 '18 at 06:40
  • **WARNING**: When using `mysqli` you should be using [parameterized queries](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) and [`bind_param`](http://php.net/manual/en/mysqli-stmt.bind-param.php) to add user data to your query. **DO NOT** use string interpolation or concatenation to accomplish this because you have created a severe [SQL injection bug](http://bobby-tables.com/). **NEVER** put `$_POST`, `$_GET` or **any** user data directly into a query, it can be very harmful if someone seeks to exploit your mistake. – tadman Jan 11 '18 at 06:40
  • Going down the `mysqli` road may be a bad investment if your time. PDO is a much more flexible, more fully featured database layer that can do everything `mysqli` can and then some. It's not MySQL specific, it has named placeholders, and above all else, a much more sensible API. If you're not too committed, it's worth switching. There's also ORMs like [Doctrine](http://www.doctrine-project.org/), [Propel](http://propelorm.org/) or [Eloquent](https://laravel.com/docs/master/eloquent) worth checking out. – tadman Jan 11 '18 at 06:41
  • A lot of problems can be detected and resolved by [enabling exceptions in `mysqli`](https://stackoverflow.com/questions/14578243/turning-query-errors-to-exceptions-in-mysqli) so mistakes aren't easily ignored. – tadman Jan 11 '18 at 06:41
  • Well, you definitely haven't used the second query! The first query looks fine to me, though obviously we don't know what the values for $ean etc. Are – Strawberry Jan 11 '18 at 06:47
  • Hello @tadman, thanks a lot for your input! I will definitely look into the object oriented interface. Like i said, i am new to PHP, so i have not invested too much time. Still learning everything i can. I will also look into parameterized queries and enabling exceptions based on the links you provided. Do you think you could give me an example of them based on the code that i have already to see how i could possibly incorporate them into my existing program? – Arikari Jan 11 '18 at 17:55
  • If you're just getting started but want to build full applications with PHP, not just toy scripts, you should steer towards using a framework. These are bundled with an ORM that vastly simplifies how you interact with the database, as well as gives you a lot of powerful tools for composing queries, managing migrations, and more. Doing it from the ground up is a painful, exhausting, and ultimately counter-productive way of learning. – tadman Jan 11 '18 at 17:57
  • Also @tadman, regarding PDO's, from what i understand, this can be used for not just mysql in specific, but for other RDBMS's, correct? I will look into this as well, as having the option to switch and still use the same interface sounds much more efficient than learning something new for each DBM. Thanks! – Arikari Jan 11 '18 at 18:00
  • Yeah, PDO is a lot better for a few reasons: Cleaner API, named placeholders, easier binding of values (associative array to `execute()`!) and it also works with other databases. It's the absolute minimum you should be using. `mysqli` is really clunky by comparison. – tadman Jan 11 '18 at 18:02

2 Answers2

0
$sql="SELECT *FROM table where partNumber = '$partnumber'order by id ASC";
  • 2
    Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation would greatly improve its long-term value](//meta.stackexchange.com/q/114762/350567) by showing *why* this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – iBug Jan 11 '18 at 08:37
  • Hello @lucky yadav, thanks for your input. I am aware how SQL queries work, and for this case, i need it to work for more than one column at a time. Like i was stating in my question, the user may need to input multiple values at a time to narrow search results based on 'LIKE' values in the database, so only searching based on partnumber would not gain the outcome that is needed. – Arikari Jan 11 '18 at 17:40
  • then just use this $sql="SELECT *FROM table order by id ASC"; – lucky yadav Jan 12 '18 at 05:46
0

You need to use AND clause rather than OR.

AND will give you rows that match all conditions in WHERE clause

OR will return rows that match any of the conditions in WHERE clause

$query = "
SELECT partNumber
    , EAN
    , UPC
    , itemDescription
    , SNFlag
    , idClass
    , idType 
FROM productinfo_table 
WHERE partNumber LIKE '$partNumber' 
    AND EAN LIKE '$EAN' 
    AND itemDescription LIKE '$itemDescription' 
    AND SNFlag LIKE '$SNFlag'
";

Note: Please note the suggestions provided in the comments to prevent SQL injection

Samir Selia
  • 7,007
  • 2
  • 11
  • 30
  • Hello @Samir , I have tried using 'AND', and that will only work if all values match. For ex. using 'AND' and having the user only input a value in one single 'input' will not return any results in the table as not all inputs match the table column values. However, using 'OR' will return all relevant results based on a single input, but will return ALL results in the table if multiple inputs are added by the user. How would i incorporate the user to be able to input a single value if the exact data is known, or multiple values to narrow down search results as much as possible? Thanks! – Arikari Jan 11 '18 at 17:48
  • You need to add handling in `PHP` to include only those columns in `WHERE` clause for which user has added input. For e.g. if user has added only `partNumber` then `WHERE partNumber LIKE '$partNumber'` . If user has added `partNumber` and `itemDescription` then `WHERE partNumber LIKE '$partNumber' AND itemDescription LIKE '$itemDescription'` – Samir Selia Jan 12 '18 at 06:33
  • This suggestion worked perfectly! I moved $query to the beginning to initialize with "SELECT partNumber,EAN,UPC,itemDescription,SNFlag,idClass,idType FROM productinfo_table WHERE " and based on inputs added by user, added to the query with relevant WHERE... LIKE statements. Thanks a lot! Great to have other sets of eyes (with more experience) to help! I will also be looking into preventing SQL injection, but like I just wanted to get something started first and then slowly move in the security direction based on need. – Arikari Jan 12 '18 at 07:16
  • I did try to upvote, and I was told the vote ‘counted’ but as I have ‘less than 15 reputation’, it does not affect the post score.. sorry! I’ll remember to come back and upvote when I can – Arikari Jan 12 '18 at 07:30