I have a search form to get some records. One of the restricting field for the form is record, being a dropdown box that looks like this:
<select name="record" id="record">
<option value="1">Highest Score</option>
<option value="2">Most runs</option>
</select>
Then when they search the following code runs:
if (isset($_GET['action']) and $_GET['action'] == 'search')
{
include $_SERVER['DOCUMENT_ROOT'] . '/stats/includes/db.inc.php';
$placeholders = array();
if($_GET['record'] == '1'){
$placeholders[':record'] = 'runs';
} else if($_GET['record'] == '2'){
$placeholders[':record'] = 'SUM(runs)';
}
$select = 'SELECT playerid, :record as record, user.usertitle';
$from = ' FROM cricket_performance p INNER JOIN user ON p.playerid = user.userid';
$where = ' WHERE TRUE';
if ($_GET['team'] != '')
{
$where .= " AND team = :team";
$placeholders[':team'] = $_GET['team'];
}
if ($_GET['record'] != '')
{
$where .= " ORDER BY :record DESC";
}
$where .= " LIMIT 10";
try
{
$sql = $select . $from . $where;
$s = $pdo->prepare($sql);
$s->execute($placeholders);
}
catch (PDOException $e)
{
$error = 'Error fetching record';
include 'form.html.php';
exit();
}
foreach ($s as $row)
{
$records[] = array('playerid' => $row['playerid'], 'record' => $row['record'], 'usertitle' => $row['usertitle'], '1' => $row['1']);
}
include 'form.html.php';
exit();
}
And that works perfectly fine, except for one thing. This: $placeholders[':record'] = 'runs'; is quite literally being printed in the SQL as 'runs', instead of the runs field being picked from the database, so $record['record'] will be printed as 'runs' for every entry, instead of the number being picked out of the table.
if the quotations are replaced by "" the same thing occurs, and if replaced by `` nothing happens (empty result)
You shouldn't use placeholders for table or field names. Use a variable instead, the value doesn't need to be sanitized anyway.
"SELECT playerid, ".$field." as record, user.usertitle"
PDO expects bound parameters to be values in e.g. WHERE clauses. Therefore
$s = $pdo->prepare($sql);
$s->execute($placeholders);
won't work as expected. PDO creates from
SELECT playerid, :record as record, user.usertitle
something like
SELECT playerid, 'runs' as record, user.usertitle
and tries to execute.
Related
I would like to add this line of code
<?php echo(isset($_POST['AgentID'])&&($_POST['AgentID']=='')?' selected="selected"':'');?>
inside
$agentData.='<option value="'.$row['AgentID'].'">'.$row['AgentID'].' - '.$row['AgentName'].'</option>';
I'm having difficulty because of " " and ' ' due to $_POST variables has ' ' also
The whole code is:
<select name="AgentID" id="agentIDSentakushi">
<option value="" <?php echo(isset($_POST['AgentID'])&&($_POST['AgentID']=='')?' selected="selected"':'');?>>--</option>
<?php
$setsu = dbSetsuzoku();
$sql = 'SELECT AgentID,AgentName FROM agentdb ORDER BY AgentID';
$agentData='';
$result = $setsu->query($sql);
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
$agentData.='<option value="'.$row['AgentID'].'">'.$row['AgentID'].' - '.$row['AgentName'].'</option>';
}
echo $agentData;
$setsu = null;
?>
</select>
To simplify it, do:
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
$selected = (isset($_POST['AgentID']) && $_POST['AgentID']==$row['AgentID'])?'selected="selected"':'';
$agentData.='<option value="'.$row['AgentID'].'"'.$selected.'>'.$row['AgentID'].' - '.$row['AgentName'].'</option>';
}
$selected here is a variable which checks if $_POST['AgentID'] is set and if it's equal to $_POST['AgentID'], if the conditions are true, that option will be selected.
I'd go about is using vsprintf like this:
$setsu = dbSetsuzoku();
$sql = "
SELECT
AgentID,
AgentID AS AgentID_2, -- notice how I duplicated it here
AgentName
FROM agentdb
ORDER BY AgentID
";
$agentData = '';
$result = $setsu->query($sql);
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
$selected = (isset($_POST['AgentID']) && $_POST['AgentID'] == $row['AgentID']) ? ' selected' : '';
$agentData .= vsprintf("<option value='%d'$selected>%d - %s</option>", $row);
}
echo $agentData;
$setsu = null;
The trick here is to select the parameters you will then later print in the same order (and quantity) in the SQL query since you will pass the returned array directly to vsprintf and the array returned from the SQL query needs to be in the same order as your vsprintf placeholders. Saves you a lot of confusing text :)
I have to create a dynamic query based on the value received by the user's input, the value of the variables are posted by GET
When I simply run this
$qry = "SELECT* FROM LAPTOP WHERE 1=1";
$resul = mysqli_query($qry);
retrieve($resul);
all the content of this table are displayed without any error,(retrieve function here displays all the results based on the query) but when I try to modify it like this, I get a blank page
$qry = "SELECT * FROM LAPTOP WHERE 1=1";
if(!empty($company))
{
$qry .= " AND company='$company'" ;
}
if(!empty($cpu))
{
$qry.= " AND cpu='$cpu' " ;
}
if(!empty($lifestyle))
{
$qry.= " AND lifestyle='$lifestyle' " ;
}
if(!empty($display))
{
$qry.= " AND display='$display'" ;
}
if(!empty($ram))
{
$qry.= " AND ram='$ram' " ;
}
if(!empty($HDD))
{
$qry.= " AND HDD='$HDD' " ;
}
echo $qry;
$result= mysqli_query($qry) || die(mysqli_error()) ;
retrieve($result) ;
$p = basename($_SERVER['REQUEST_URI']) ;
The result of echo $qry; is as expected, it displays this
SELECT * FROM LAPTOP WHERE 1=1 AND company='Asus' AND cpu='intel i3'
Is there a way to correct this? The reason I tried using WHERE 1=1 clause is that when all the variables are equal to NULL then the query returns all the rows from the table.
i guess you have no data in your database matched with your conditions . OR you have case sensitive with names.
example :
cpu='Intel i3' // with big I
cpu='intel I3' // with big I
cpu='intel i3' // double space.
OR if you have big string , think to use LIKE
$qry.= " AND cpu LIKE '%$cpu%' " ;
Is this a typo also ($resul_T_)?
$resul = mysqli_query($qry);
retrieve($resul);
How you managed to lose that 't' and later get it back? ;)
As others have pointed out it may simply be that your query does not match any records.
Anyway what I usually do in a similar case is put all the conditions in an array, and then implode the array with 'AND'. That way you don't have to bother with 1=1 and it doesn't matter whether you have 0, 1 or more conditions.
<?php
$qry = "SELECT * FROM LAPTOP";
$conditions = array();
$cpu = 'Intel';
$ram = '24GB';
if(!empty($cpu))
{
$conditions[] = "cpu='$cpu'";
}
if(!empty($lifestyle))
{
$conditions[] = "lifestyle='$lifestyle'";
}
if(!empty($display))
{
$conditions[] = "display='$display'";
}
if(!empty($ram))
{
$conditions[] = "ram='$ram'";
}
if(!empty($HDD))
{
$conditions[] = "HDD='$HDD'";
}
if( count( $conditions ) > 0 )
{
$qry .= " WHERE ";
$qry .= implode( " AND ", $conditions );
}
print_r($qry);
?>
<?php
if(isset($_POST['submit'])) {
$fields = array('field1', 'field2', 'field3');
$conditions = array();
foreach($fields as $field){
if(isset($_POST[$field]) && $_POST[$field] != '') {
$conditions[] = "`".$field."` like '%" . mysql_real_escape_string($_POST[$field]) . "%'";
}
}
$query = "SELECT * FROM customer ";
if(count($conditions) > 0) {
$query .= "WHERE " . implode (' AND ', $conditions);
}
$result = mysql_query($query);
$say = mysql_num_rows($result);
if ($say == 0) {
echo "<tr>no result.</tr>";
} else {
echo '...';
while($row = mysql_fetch_array($result))
{
...
}}
} ?>
Why doesn't this code checking empty fields? It returns results that has empty field even form submits empty.
The only improvement I think of is trim():
if(isset($_POST[$field]) && trim($_POST[$field]) != '') {
however, I am sure it is not the issue.
Have you ever thought of printing the resulting query out?
Look, you're writing a program to create some string (SQL query). But for some reason never interested in this program's direct result, judging it by some indirect results. May be it's data/query logic makes such results, but the query itself is okay?
if the query is still wrong - continue debugging.
Echo everything involved - print variables, condition results, intermediate results in the loop - and look for inconsistencies
$query = "SELECT * FROM customer ";
if(count($conditions) > 0) {
$query .= "WHERE " . implode (' AND ', $conditions);
}
When form is submitted empty ($conditions=0) it returns all table (select * from customer).
Added an else condition and fixed. Thanks for print query advices.
For checking something is empty or not. You can use empty() method.
Check this:
empty()
isset() only check whether that object/variable is set or not. For more details check this
isset()
I have a MYSQL full text search, matching against items in my database, which works great.
$select = "SELECT * from menu WHERE MATCH(item) AGAINST('$this->food') ";
From there I refine the query dependent on what the user wants to filter by. I have 2 filters, vegetarian and breadtype
if(isset($this->vegetarian)) {
echo $select .= " AND vegetarian='$this->vegetarian'";
}
if(isset($this->bread)) {
echo $select .= " AND bread='$this->bread'";
}
Which appends the fulltext statement, now this works perfectly, although my issue is that
if the user doesn't search anything (empty string) I want it to returns all results in the database.
if(empty($this->food)) { $select = "SELECT * from menu"; }
Which now means I can't append the $select statement with the above if statements, and would have to use a WHERE statement instead - but that would mean adding 2 extra if statements to compensate for that. Is there anyway for MYSQL to do it instead.
if(isset($this->vegetarian) && empty($this->food)) {
echo $select .= " WHERE vegetarian=$this->vegetarian";
}
You can simply use WHERE 1=1 and then append the rest. MySQL will simply ignore this part if there's no additional ANDs or ORs.
$select = "SELECT * from menu WHERE MATCH(item) AGAINST('$this->food') ";
if(empty($this->food)) {
$select = "SELECT * from menu WHERE 1=1"; // if food is empty we overwrite the $select variable
} else {
if(isset($this->vegetarian)) {
$select .= " AND vegetarian='$this->vegetarian'";
}
if(isset($this->bread)) {
$select .= " AND bread='$this->bread'";
}
}
Or am i missing something ?
When I run the following MySQL query via PHP and all of the elements of $_GET() are empty strings, all the records in the volunteers table are returned (for obvious reasons).
$first = $_GET['FirstName'];
$last = $_GET['LastName'];
$middle = $_GET['MI'];
$query = "SELECT * FROM volunteers WHERE 0=0";
if ($first){
$query .= " AND first like '$first%'";
}
if ($middle){
$query .= " AND mi like '$middle%'";
}
if ($last){
$query .= " AND last like '$last%'";
}
$result = mysql_query($query);
What is the most elegant way of allowing empty parameters to be sent to this script with the result being that an empty $result is returned?
my solution:
$input = Array(
'FirstName' => 'first',
'LastName' => 'last',
'MI' => 'mi'
);
$where = Array();
foreach($input as $key => $column) {
$value = trim(mysql_escape_string($_GET[$key]));
if($value) $where[] = "`$column` like '$value%'";
}
if(count($where)) {
$query = "SELECT * FROM volunteers WHERE ".join(" AND ", $where);
$result = mysql_query($query);
}
There's no point in running a (potentially) expensive query if there's nothing for that query to do. So instead of trying to come up with an alternate query to prevent no-terms being searched, just don't run the search at all if there's no terms:
$where = '';
... add clauses ...
if ($where !== '') {
$sql = "SELECT ... WHERE $where";
... do query ...
} else {
die("You didn't enter any search terms");
}
With your current code, if everything is empty, you will get the WHERE 0=0 SQL which is TRUE for all rows in the table.
All you have to do is remove the if statements...