Dynamically create a SQL statment from passed values in PHP - php

I am passing a number of values to a function and then want to create a SQL query to search for these values in a database.
The input for this is drop down boxes which means that the input could be ALL or * which I want to create as a wildcard.
The problem is that you cannot do:
$result = mysql_query("SELECT * FROM table WHERE something1='$something1' AND something2='*'") or die(mysql_error());
I have made a start but cannot figure out the logic loop to make it work. This is what I have so far:
public function search($something1, $something2, $something3, $something4, $something5) {
//create query
$query = "SELECT * FROM users";
if ($something1== null and $something2== null and $something3== null and $something4== null and $something5== null) {
//search all users
break
} else {
//append where
$query = $query . " WHERE ";
if ($something1!= null) {
$query = $query . "something1='$something1'"
}
if ($something2!= null) {
$query = $query . "something2='$something2'"
}
if ($something3!= null) {
$query = $query . "something3='$something3'"
}
if ($something4!= null) {
$query = $query . "something4='$something4'"
}
if ($something5!= null) {
$query = $query . "something5='$something5'"
}
$uuid = uniqid('', true);
$result = mysql_query($query) or die(mysql_error());
}
The problem with this is that it only works in sequence. If someone enters for example something3 first then it wont add the AND in the correct place.
Any help greatly appreciated.

I would do something like this
criteria = null
if ($something1!= null) {
if($criteria != null)
{
$criteria = $criteria . " AND something1='$something1'"
}
else
{
$criteria = $criteria . " something1='$something1'"
}
}
... other criteria
$query = $query . $criteria

try with array.
function search($somethings){
$query = "SELECT * FROM users";
$filters = '';
if(is_array($somethings)){
$i = 0;
foreach($somethings as $key => $value){
$filters .= ($i > 0) ? " AND $key = '$value' " : " $key = '$value'";
$i++;
}
}
$uuid = uniqid('', true);
$query .= $filters;
$result = mysql_query($query) or die(mysql_error());
}
// demo
$som = array(
"something1" => "value1",
"something2" => "value2"
);
search( $som );

Here's an example of dynamically building a WHERE clause. I'm also showing using PDO and query parameters. You should stop using the deprecated mysql API and start using PDO.
public function search($something1, $something2, $something3, $something4, $something5)
{
$terms = array();
$values = array();
if (isset($something1)) {
$terms[] = "something1 = ?";
$values[] = $something1;
}
if (isset($something2)) {
$terms[] = "something2 = ?";
$values[] = $something2;
}
if (isset($something3)) {
$terms[] = "something3 = ?";
$values[] = $something3;
}
if (isset($something4)) {
$terms[] = "something4 = ?";
$values[] = $something4;
}
if (isset($something5)) {
$terms[] = "something5 = ?";
$values[] = $something5;
}
$query = "SELECT * FROM users ";
if ($terms) {
$query .= " WHERE " . join(" AND ", $terms);
}
if (defined('DEBUG') && DEBUG==1) {
print $query . "\n";
print_r($values);
exit();
}
$stmt = $pdo->prepare($query);
if ($stmt === false) { die(print_r($pdo->errorInfo(), true)); }
$status = $stmt->execute($values);
if ($status === false) { die(print_r($stmt->errorInfo(), true)); }
}
I've tested the above and it works. If I pass any non-null value for any of the five function arguments, it creates a WHERE clause for only the terms that are non-null.
Test with:
define('DEBUG', 1);
search('one', 'two', null, null, 'five');
Output of this test is:
SELECT * FROM users WHERE something1 = ? AND something2 = ? AND something5 = ?
Array
(
[0] => one
[1] => two
[2] => five
)
If you need this to be more dynamic, pass an array to the function instead of individual arguments.

Related

PHP Array sometimes returns just 'array'

I wonder why I haven't found any solutions for this strange problem.
Sorry if I haven't looked right but I am very desperate and try to fix this as much as I can.
In a recursive function, I collect sql data and store them in an array.
However, when I use print_r for outputting the array values, I get strange values like this:
a."parentMale" = '45273' OR a."parentFemale" = '44871' OR
a."parentMale" = '7625' OR a."parentFemale" = '7481' OR Array OR Array
OR Array OR Array OR a."parentMale" = ...
While my function looks like this:
public function getSelfAndAncestorsShort($id) {
$animalids = array();
if ($id != "")
{
$query = "SELECT a.\"parentMale\" AS sire, a.\"parentFemale\" AS dam
FROM animals a
WHERE a.id = ".$id;
$res = pg_query($query);
while ($row = pg_fetch_object($res))
{
if ($row->sire != "")
$animalids[] = "a.\"parentMale\" = '" .$row->sire ."'";
if ($row->dam != "")
$animalids[] = "a.\"parentFemale\" = '" .$row->dam ."'";
$animalids[] = $this->getSelfAndAncestorsShort($row->sire);
$animalids[] = $this->getSelfAndAncestorsShort($row->dam);
$animalids = implode (" OR ", $animalids);
}
}
return $animalids;
}
I hope someone can help me because I have really no idea.
You function returns an array if $id is empty. Also, you do not check the return of your function before to add into your $animalids array :
public function getSelfAndAncestorsShort($id) {
$animalids = array();
if ($id != "")
{
$query = "SELECT a.\"parentMale\" AS sire, a.\"parentFemale\" AS dam
FROM animals a
WHERE a.id = ".$id;
$res = pg_query($query);
while ($row = pg_fetch_object($res))
{
if ($row->sire != "")
$animalids[] = "a.\"parentMale\" = '" .$row->sire ."'";
if ($row->dam != "")
$animalids[] = "a.\"parentFemale\" = '" .$row->dam ."'";
$val = $this->getSelfAndAncestorsShort($row->sire);
if ($val) $animalids[] = $val; // Check here
$val = $this->getSelfAndAncestorsShort($row->dam);
if ($val) $animalids[] = $val; // Check here
}
}
if (empty($animalids)) return "" ; // Check here
return implode (" OR ", $animalids); // Only implode here
}

Issue in using arrays as parameters of method of PHP custom class

To explain my issue, here is a simple code at first:
public function sql($data) {
if (is_array($data)) {
$cells = $data['cells'];
$from = $data['from'];
$where = $data['where'];
$joins = $data['joins'];
$order_by = $data['order_by'];
$o_type = $data['order_by_type'];
$limit = $data['limit'];
/*****************************/
if ($cells == '') { $cells = "*"; }
if ($where != '') { $where = "where ".$where; }
if ($oredr_by != '') { $order_by = "order by ".$order_by." ".$o_type; }
if ($limit != '') { $limit = "limit ".$limit; }
//
$sql = "select ".$cells." from ".$from." ".$joins." ".$where." ".$order_by." ".$limit;
$run = mysqli_query($_SESSION['con'], $sql);
}else{
$run = mysqli_query($_SESSION['con'], $data);
}
}
When I start using this method, I pass a multidimensional array as a parameter, like this:
$sql = $class->sql([ "from" => "table", "order_by" => "id", "order_by_type" => "asc" ]);
/* This will generate and run this query: select * from table order by id asc */
// Notice that I've only used 3 keys, not the all above.
In Apache server, it works OK perfectly when I just use some of the keys of array, but in XAMPP it doesn't because it says that I have to pass all the parameters (cells, from, where, joins, ...) even if they are empty.
Please help me to resolve this, and thanks.
You can use isset to check if an array key is present, then get it's value like.
public function sql($data) {
if (is_array($data)) {
$cells = '';
if(isset($data['cells']) {
$cells = $data['cells'];
}
....
/*****************************/
if ($cells == '') { $cells = "*"; }
if ($where != '') { $where = "where ".$where; }
if ($oredrby != '') { $orderby = "order by ".$orderby." ".$od_type; }
if ($limit != '') { $limit = "limit ".$limit; }
$sql = "select ".$cells." from ".$table." ".$joins." ".$where." ".$orderby." ".$limit;
$run = mysqli_query($_SESSION['con'], $sql);
}else{
$run = mysqli_query($_SESSION['con'], $data);
}
}
Or simply just do error_reporting(1) before calling this function or in your index.php.
The problem is this.
$arr = ["a"];
echo $arr["b"];
You will get an error notice.
Notice: Undefined index: b
If you want to avoid this use it in this way.
$arr = ["a"];
$arr = ["b"] = "";
echo $arr["b"];
Change $from to $table, you have not $table variable
$from = $data['from'];
to
$table = $data['from'];
Also you have spelling mistake biggest spelling mistake which is very difficult to find.orderby and oredrby

Passing multiple dimension array in PHP

MySql query returns me a multi-dimensional array :
function d4g_get_contributions_info($profile_id)
{
$query = "select * from contributions where `project_id` = $profile_id";
$row = mysql_query($query) or die("Error getting profile information , Reason : " . mysql_error());
$contributions = array();
if(!mysql_num_rows($row)) echo "No Contributors";
while($fetched = mysql_fetch_array($row, MYSQL_ASSOC))
{
$contributions[$cnt]['user_id'] = $fetched['user_id'];
$contributions[$cnt]['ammount'] = $fetched['ammount'];
$contributions[$cnt]['date'] = $fetched['date'];
$cnt++;
}
return $contributions;
}
Now I need to print the values in the page where I had called this function. How do I do that ?
change the function like this:
while($fetched = mysql_fetch_array($row, MYSQL_ASSOC))
{
$contributions[] = array('user_id' => $fetched['user_id'],
'ammount' => $fetched['ammount'],
'date' => $fetched['date']);
}
return $contributions;
Then try below:
$profile_id = 1; // sample id
$result = d4g_get_contributions_info($profile_id);
foreach($result as $row){
$user_id = $row['user_id']
// Continue like this
}

SQL Array into Array based function

Default Set Up
$stream->setTrack (array('cookie'));
Trial
$sql = "SELECT DISTINCT text FROM keywords"; $query = mysql_query($sql) or die($sql . ' - ' . mysql_error());
$keys = array();
while ($row = mysql_fetch_array($query)) {
$keys[] = $row[0];
}$stream->setTrack ($keys);
The default set up takes the written word and places it into an array
The trial set up should retrieve a set of keywords from a mysql table as an array and insert them into the function.
It doesn't work. What's wrong?
public function setTrack($trackWords)
{
$trackWords = ($trackWords === NULL) ? array() : $trackWords;
sort($trackWords); // Non-optimal, but necessary
if ($this->trackWords != $trackWords) {
$this->filterChanged = TRUE;
}
$this->trackWords = $trackWords;
}

Is converting mysql to mysqli extremely necessary?

Here's my deal:
I found a simple ACL, and have absolutely fallen in love with it. The problem? It's all in mysql, not mysqli. The rest of my site is written in mysqli, so this bothers me a ton.
My problem is that the ACL can easily connect without global variables because I already connected to the database, and mysql isn't object oriented.
1) Is it needed to convert to mysqli?
2) How can I easily convert it all?
Code:
<?
class ACL
{
var $perms = array(); //Array : Stores the permissions for the user
var $userID = 0; //Integer : Stores the ID of the current user
var $userRoles = array(); //Array : Stores the roles of the current user
function __constructor($userID = '')
{
if ($userID != '')
{
$this->userID = floatval($userID);
} else {
$this->userID = floatval($_SESSION['userID']);
}
$this->userRoles = $this->getUserRoles('ids');
$this->buildACL();
}
function ACL($userID = '')
{
$this->__constructor($userID);
//crutch for PHP4 setups
}
function buildACL()
{
//first, get the rules for the user's role
if (count($this->userRoles) > 0)
{
$this->perms = array_merge($this->perms,$this->getRolePerms($this->userRoles));
}
//then, get the individual user permissions
$this->perms = array_merge($this->perms,$this->getUserPerms($this->userID));
}
function getPermKeyFromID($permID)
{
$strSQL = "SELECT `permKey` FROM `permissions` WHERE `ID` = " . floatval($permID) . " LIMIT 1";
$data = mysql_query($strSQL);
$row = mysql_fetch_array($data);
return $row[0];
}
function getPermNameFromID($permID)
{
$strSQL = "SELECT `permName` FROM `permissions` WHERE `ID` = " . floatval($permID) . " LIMIT 1";
$data = mysql_query($strSQL);
$row = mysql_fetch_array($data);
return $row[0];
}
function getRoleNameFromID($roleID)
{
$strSQL = "SELECT `roleName` FROM `roles` WHERE `ID` = " . floatval($roleID) . " LIMIT 1";
$data = mysql_query($strSQL);
$row = mysql_fetch_array($data);
return $row[0];
}
function getUserRoles()
{
$strSQL = "SELECT * FROM `user_roles` WHERE `userID` = " . floatval($this->userID) . " ORDER BY `addDate` ASC";
$data = mysql_query($strSQL);
$resp = array();
while($row = mysql_fetch_array($data))
{
$resp[] = $row['roleID'];
}
return $resp;
}
function getAllRoles($format='ids')
{
$format = strtolower($format);
$strSQL = "SELECT * FROM `roles` ORDER BY `roleName` ASC";
$data = mysql_query($strSQL);
$resp = array();
while($row = mysql_fetch_array($data))
{
if ($format == 'full')
{
$resp[] = array("ID" => $row['ID'],"Name" => $row['roleName']);
} else {
$resp[] = $row['ID'];
}
}
return $resp;
}
function getAllPerms($format='ids')
{
$format = strtolower($format);
$strSQL = "SELECT * FROM `permissions` ORDER BY `permName` ASC";
$data = mysql_query($strSQL);
$resp = array();
while($row = mysql_fetch_assoc($data))
{
if ($format == 'full')
{
$resp[$row['permKey']] = array('ID' => $row['ID'], 'Name' => $row['permName'], 'Key' => $row['permKey']);
} else {
$resp[] = $row['ID'];
}
}
return $resp;
}
function getRolePerms($role)
{
if (is_array($role))
{
$roleSQL = "SELECT * FROM `role_perms` WHERE `roleID` IN (" . implode(",",$role) . ") ORDER BY `ID` ASC";
} else {
$roleSQL = "SELECT * FROM `role_perms` WHERE `roleID` = " . floatval($role) . " ORDER BY `ID` ASC";
}
$data = mysql_query($roleSQL);
$perms = array();
while($row = mysql_fetch_assoc($data))
{
$pK = strtolower($this->getPermKeyFromID($row['permID']));
if ($pK == '') { continue; }
if ($row['value'] === '1') {
$hP = true;
} else {
$hP = false;
}
$perms[$pK] = array('perm' => $pK,'inheritted' => true,'value' => $hP,'Name' => $this->getPermNameFromID($row['permID']),'ID' => $row['permID']);
}
return $perms;
}
function getUserPerms($userID)
{
$strSQL = "SELECT * FROM `user_perms` WHERE `userID` = " . floatval($userID) . " ORDER BY `addDate` ASC";
$data = mysql_query($strSQL);
$perms = array();
while($row = mysql_fetch_assoc($data))
{
$pK = strtolower($this->getPermKeyFromID($row['permID']));
if ($pK == '') { continue; }
if ($row['value'] == '1') {
$hP = true;
} else {
$hP = false;
}
$perms[$pK] = array('perm' => $pK,'inheritted' => false,'value' => $hP,'Name' => $this->getPermNameFromID($row['permID']),'ID' => $row['permID']);
}
return $perms;
}
function userHasRole($roleID)
{
foreach($this->userRoles as $k => $v)
{
if (floatval($v) === floatval($roleID))
{
return true;
}
}
return false;
}
function hasPermission($permKey)
{
$permKey = strtolower($permKey);
if (array_key_exists($permKey,$this->perms))
{
if ($this->perms[$permKey]['value'] === '1' || $this->perms[$permKey]['value'] === true)
{
return true;
} else {
return false;
}
} else {
return false;
}
}
function getUsername($userID)
{
$strSQL = "SELECT `username` FROM `users` WHERE `ID` = " . floatval($userID) . " LIMIT 1";
$data = mysql_query($strSQL);
$row = mysql_fetch_array($data);
return $row[0];
}
}
?>
Just add a $mysqli property to this class and have the MySQLi object passed to it in constructor.
class ACL {
private $mysqli;
public function __construct(MySQLi $mysqli) {
$this->mysqli = $mysqli;
/* rest of your code */
}
}
The rest is pretty much search and replace.
The code is written to support PHP4. That tells me two things: firstly, the author couldn't use mysqli even if he wanted to, because PHP4 didn't have it, and secondly, the code is probably pretty old, and was written before the PHP devs started really trying to push developers to use mysqli instead of mysql.
If it's well written, then converting it to use mysqli instead should be a piece of cake. The API differences between mysql and mysqli at a basic level are actually pretty minimal. The main difference is the requirement to pass the connection object to the query functions. This was optional in mysql and frequently left out, as it seems to have been in this code.
So your main challenge is getting that connection object variable to be available wherever you make a mysqli function call. The easy way to do that is just to make it a property of the class, so it's available everywhere in the class.
I also recommend you drop the other php4 support bits; they're not needed, and they get in the way.

Categories