I'm creating a web application that relies heavily upon getting data from MySQL using PHP. In ~50 functions I have very similar code requesting single data values from MySQL:
function get_profile_picture($whatmember) {
global $connection;
$whatmember = mysql_prep($whatmember);
$query = "SELECT picture_location FROM members WHERE member_id={$whatmember} LIMIT 1";
$returnval = mysqli_query($connection,$query);
if(!$returnval) {
return "Query failed: " . mysqli_error($connection);
}
if(mysqli_num_rows($returnval) > 0 ) {
$row = mysqli_fetch_assoc($returnval);
return $row["picture_location"];
}
return false;
}
So my question is this: is there a generic AND safe way to make the function so that I can just input "SELECT what-value FROM what-database.what-table WHERE what-criteria=what-value" that allows for arrays of results as well as single values? I made an attempt with the following, but it obviously is a hack and slash method that only gets single values:
function get_single_value($database_name,$column_name,$table_name,$criteria,$criteria_value) {
$database_name = mysql_prep($database_name);
$column_name = mysql_prep($column_name);
$table_name = mysql_prep($table_name);
$criteria = mysql_prep($criteria);
$criteria_value = mysql_prep($criteria_value);
if(!empty($column_name) && !empty($table_name) && !empty($criteria) && !empty($database_name)) {
global $connection;
global $gamesconnection;
global $locationconnection;
if($database_name=="connection") {
$database_connection = $connection;
} else if ($database_name=="games") {
$database_connection = $gamesconnection;
} else if ($database_name=="locations") {
$database_connection = $locationconnection;
} else {
die("Database connection doesn't exist for {$database_name}.");
}
$query = "SELECT {$column_name} FROM {$table_name} WHERE {$criteria}='{$criteria_value}' LIMIT 1";
$result = mysqli_query($database_connection,$query);
if(!$result) {
die("Unable to get {$column_name} from {$table_name}. Error: " . mysqli_error($database_connection) . " Query: " . $query);
}
if(mysqli_num_rows($result)>0) {
$row = mysqli_fetch_assoc($result);
return $row[$column_name];
}
}
return false;
}
And my get_profile_picture() function would then look more like this:
function get_profile_picture($whatmember) {
return get_single_value("connection","picture_location","members","member_id",$whatmember);
}
I'm still pretty new to PHP and MySQL so any pointers to improve my code would be great as well. Thanks in advance!
Alright I wrote my own. It might not have all the security of PDO, but I don't have the learn another framework in order to use it.
function get_from_database($database_variable) {
//PASS IN $database_variable WHICH IS AN OBJECT CONTAINING THE FOLLOWING POSSIBLE VALUES
$database_name = $database_variable["database_name"]; //DATABASE NAME
$column_name = $database_variable["column_name"]; //COLUMN(S) BEING REQUESTED
$table_name = $database_variable["table_name"]; //TABLE BEING SEARCHED
$criteria = $database_variable["criteria"]; // 'WHERE X'
$limit = $database_variable["limit"]; //ANY LIMITS, IF REQUIRED
$group_by = $database_variable["group_by"]; //ANY GROUPING, IF REQUIRED
$order_by = $database_variable["order_by"]; //ANY SORT ORDERING, IF REQUIRED
if(!empty($column_name) && !empty($table_name)&& !empty($database_name)) {
global $connection;
global $gamesconnection;
global $locationconnection;
global $olddataconnection;
if($database_name=="connection") {
$database_connection = $connection;
} else if ($database_name=="games") {
$database_connection = $gamesconnection;
} else if ($database_name=="locations") {
$database_connection = $locationconnection;
} else if ($database_name=="olddata") {
$database_connection = $olddataconnection;
} else {
error_log("\nDatabase connection doesn't exist for {$database_name}." . get_backtrace_info());
return false;
}
if(is_null($limit)) {
//IF LIMIT NOT SUPPLIED, MAKE LIMIT 0, IE NO LIMIT
$limit = 0;
}
if(is_int($limit)==false) {
//NOT AN INTEGER
error_log("\nError in limit provided: " . $limit . get_backtrace_info());
return false;
}
$query = " SELECT {$column_name}
FROM {$table_name} " . (!empty($criteria) /*CHECK IF CRITERIA WAS REQUIRED*/ ? "
WHERE {$criteria} " : "") . (!empty($group_by) /*CHECK IF GROUP BY WAS REQUIRED*/ ? "
GROUP BY {$group_by} " : "") . (!empty($order_by) /*CHECK IF ORDER BY WAS REQUIRED*/ ? "
ORDER BY {$order_by} " : "") . ($limit!==0 /*CHECK IF LIMIT WAS REQUIRED*/ ? "
LIMIT {$limit} " : "");
$result = mysqli_query($database_connection,$query);
if(!$result) {
error_log("\nUnable to process query, got error: " . mysqli_error($database_connection) . "\nQuery: " . $query . get_backtrace_info());
return false;
}
if(mysqli_num_rows($result)>0) {
//RESULT SUPPLIED
$row_array = array();
while($row = mysqli_fetch_assoc($result)) {
$row_array[] = $row;
}
mysqli_free_result($result);
return $row_array;
}
}
return false;
}
Function to trace function call back to source:
function get_backtrace_info(){
//GET INFORMATION ON WHICH FUNCTION CAUSED ERROR
$backtrace = debug_backtrace();
$backtrace_string = "";
for($i=0;$i<count($backtrace);$i++) {
$backtrace_string .= '\n';
if($i==0) {
$backtrace_string .= 'Called by ';
} else {
$backtrace_string .= 'Which was called by ';
}
$backtrace_string .= "{$backtrace[$i]['function']} on line {$backtrace[$i]['line']}";
}
return backtrace_string;
}
Now I can request data from MySQL as follows:
Single value requested:
function get_profile_picture($whatmember) {
$linked_member_code = get_linked_member_code($whatmember);
return get_from_database([ "database_name" => "connection",
"column_name" => "picture_location",
"table_name" => "members",
"criteria" => "linked_member_code='{$linked_member_code}' AND team_id=0",
"limit" => 1
])[0]["picture_location"];
}
2 values requested:
function get_city_and_region_by_id($whatid) {
$row = get_from_database([ "database_name" => "locations",
"column_name" => "city, region",
"table_name" => "cities",
"criteria" => "row_id={$whatid}",
"limit" => 1
]);
return $row[0]["city"] . ", " . $row[0]["region"];
}
Unknown number of rows:
function get_linked_teams($linkedmembercode) {
return get_from_database([ "database_name" => "connection",
"column_name" => "team_id",
"table_name" => "members",
"criteria" => "linked_member_code='{$linkedmembercode}' AND team_id!=0"
]);
}
Related
Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1
given in C:\xampp\htdocs\swift\core\functions\general.php on line 49
Notice: Undefined variable: conn in
C:\xampp\htdocs\swift\core\functions\users.php on line 85
Warning: mysqli_query() expects parameter 1 to be mysqli, null given
in C:\xampp\htdocs\swift\core\functions\users.php on line 85
Fatal error: Uncaught Error: Call to undefined function
mysqli_result() in C:\xampp\htdocs\swift\core\functions\users.php:86
Stack trace: #0 C:\xampp\htdocs\swift\loginact.php(14): f_exists('')
#1 {main} thrown in C:\xampp\htdocs\swift\core\functions\users.php on line 86
I keep on getting those errors but i cant find a way, i already tried everything.. Hopefully someone can help me as I am new to php.
Ive been doing this for almost like a day now and i cannot figure out the answer.
This is the General.php.
<?php
$connect_error = 'Sorry, there was some connectivity issue!';
$conn = mysqli_connect('localhost','root','');
$db = mysqli_select_db($conn, 'swift');
function activation($to, $subject, $body) {
mail($to, $subject, $body, 'From: swift#srikanthnatarajan.com');
}
function recovery_user_pass($to, $subject, $body) {
mail($to, $subject, $body, 'From: swift#srikanthnatarajan.com');
}
function f_protect_page() {
if(f_logged_in() === false) {
header('Location: flogin.php');
exit();
}
}
function user_protect_page() {
if(f_logged_in() === false) {
header('Location: fprotect.php');
exit();
}
}
function use_protect_page() {
if(f_logged_in() === true) {
header('Location: fprotect.php');
exit();
}
}
function f_logged_in_redirect() {
if(f_logged_in() === true) {
header('Location: index.php');
exit();
}
}
function array_sanitize($item) {
$item = htmlentities(strip_tags(mysqli_real_escape_string($item)));
}
function sanitize($data) {
return htmlentities(strip_tags(mysqli_real_escape_string($data)));
}
function output_errors($errors) {
return '<ul><li>' . implode('</li><li>', $errors) . '</li></ul>';
}
?>
this is the USERS.PHP can someone please check this.
<?php
$connect_error = 'Sorry, there was some connectivity issue!';
$conn = mysqli_connect('localhost','root','');
$db = mysqli_select_db($conn, 'swift');
function f_recover($mode, $f_mailid) {
$mode = sanitize($mode);
$f_mailid = sanitize($f_mailid);
$f_data = f_data(f_id_from_email($f_mailid),'f_id','f_fname','f_uname');
if ($mode == 'f_uname') {
recovery_user_pass($f_mailid, 'Recovery: Your username', "Hello " . $f_data['f_fname'] . ",\n\nYour username is: " . $f_data['f_uname'] . "\n\n-Swift Airlines");
}
else if($mode == 'f_password') {
$generated_password = substr(md5(rand(999, 999999)), 0, 8);
f_change_password($f_data['f_id'], $generated_password);
update_f($f_data['f_id'], array('f_passrec' => '1'));
recovery_user_pass($f_mailid, 'Recovery: Your password', "Hello " . $f_data['f_fname'] . ",\n\nYour new password is: " . $generated_password . "\n\n-TOFSIS");
}
}
function f_activate($f_mailid, $f_mailcode) {
$f_mailid = mysqli_real_escape_string($_POST['f_mailid']);
$f_mailcode = mysqli_real_escape_string($_POST['f_mailcode']);
if(mysqli_result(mysqli_query("SELECT COUNT(`f_id`) FROM `flight_users` WHERE `f_mailid` = '$f_mailid' AND `f_mailcode` = '$f_mailcode' AND `f_active` = 0"), 0) == 1) {
mysqli_query("UPDATE `flight_users` SET `f_active` = 1 WHERE `f_mailid` = '$f_mailid' ");
return true;
}
else {
return false;
}
}
function update_f($f_id, $update_data) {
$update = array();
array_walk($update_data, 'array_sanitize');
foreach ($update_data as $field => $data) {
$update[] = '`' . $field . '` = \'' . $data . '\'';
}
mysqli_query("UPDATE `flight_users` SET " . implode(', ',$update) . "WHERE `f_id` = $f_id") or die(mysqli_error($conn));
}
function f_change_password($f_id, $f_password) {
$f_id = (int)$f_id;
$f_password = md5($f_password);
mysqli_query("UPDATE `flight_users` SET `f_password` = '$f_password', `f_passrec` = 0 WHERE `f_id` = $f_id");
}
function register_f($register_data) {
array_walk($register_data, 'array_sanitize');
$register_data['f_fname'] = ucwords(strtolower($register_data['f_fname']));
$register_data['f_lname'] = ucwords(strtolower($register_data['f_lname']));
$register_data['f_password'] = md5($register_data['f_password']);
$register_data['f_uname'] = strtolower($register_data['f_uname']);
$fields = '`' . implode('`, `', array_keys($register_data)) . '`';
$data = '\'' . implode('\', \'', $register_data) . '\'';
mysqli_query("INSERT INTO `flight_users` ($fields, `f_regdate`) VALUES ($data, NOW())");
activation($register_data['f_mailid'], 'Swift Airlines: Activate your account', "Hello " . $register_data['f_fname'] . ", \n\nYou need to activate your account in order to use the features of Swift Airlines. Please click the link below: \n\nhttp://srikanthnatarajan.com/swift/activate.php?f_mailid=" . $register_data['f_mailid'] . "&f_mailcode=" . $register_data['f_mailcode'] . " \n\n-Swift Airlines");
}
function f_data($f_id){
$data = array();
$f_id = (int)$f_id;
$func_num_args = func_num_args();
$func_get_args = func_get_args();
if($func_num_args > 1) {
unset($func_get_args[0]);
$fields = '`'. implode('`, `', $func_get_args) . '`';
$data = mysqli_fetch_assoc(mysqli_query("SELECT $fields FROM `flight_users` WHERE `f_id` = $f_id"));
return $data;
}
}
function f_logged_in() {
return (isset($_SESSION['f_id'])) ? true : false;
}
function f_exists($f_uname) {
$f_uname = sanitize($f_uname);
$query = mysqli_query($conn, "SELECT COUNT(`f_id`) FROM `flight_users` WHERE `f_uname`= '$f_uname'");
return (mysqli_result($conn, $query, 0) == 1) ? true : false;
}
function f_email_exists($f_mailid) {
$f_mailid = sanitize($f_mailid);
$query = mysqli_query($conn, "SELECT COUNT(`f_id`) FROM `flight_users` WHERE `f_mailid`= '$f_mailid'");
return (mysqli_result($conn, $query, 0) == 1) ? true : false;
}
function f_regid_exists($f_regid) {
$f_regid = sanitize($f_regid);
$query = mysqli_query($conn, "SELECT COUNT(`f_id`) FROM `flight_users` WHERE `f_regid`= '$f_regid'");
return (mysqli_result($conn, $query, 0) == 1) ? true : false;
}
function f_active($f_uname) {
$f_uname = sanitize($f_uname);
$query = mysqli_query($conn, "SELECT COUNT(`f_id`) FROM `flight_users` WHERE `f_uname`= '$f_uname' AND `f_active` = 1");
return (mysqli_result($conn, $query, 0) == 1) ? true : false;
}
function f_id_from_username($f_uname) {
$f_uname = sanitize($f_uname);
$query = mysqli_query($conn, "SELECT `f_id` FROM `flight_users` WHERE `f_uname` = '$f_uname'");
return mysqli_result($conn, $query, 0, 'f_id');
}
function f_id_from_email($f_mailid) {
$f_mailid = sanitize($f_mailid);
$query = mysqli_query($conn, "SELECT `f_id` FROM `flight_users` WHERE `f_mailid` = '$f_mailid'");
return mysqli_result($conn, $query, 0, 'f_id');
}
function f_login($f_uname, $f_password) {
$f_id = f_id_from_username($f_uname);
$f_uname = sanitize($f_uname);
$f_password = md5($f_password);
$query = mysqli_query($conn, "SELECT COUNT(`f_id`) FROM `flight_users` WHERE `f_uname`= '$f_uname' AND `f_password` = '$f_password'");
return (mysqli_result($conn, $query, 0) == 1) ? $f_id : false;
}
?>
and this is the Loginact.php------------------
<?php
$title = 'Swift Airlines | Login Error';
include $_SERVER["DOCUMENT_ROOT"].'/swift/core/init.php';
if(empty($_POST) === false) {
$f_uname = $_POST['f_uname'];
$f_password = $_POST['f_password'];
if(empty($f_uname) === true || empty($f_password) === true){
$errors[] = 'You need to enter both, the username and the password!';
}
else if (f_exists($f_uname)===false) {
$errors[] = 'No such user exists! Please register!';
}
else if(f_active($f_uname)===false) {
$errors[] = 'Please activate your account!';
}
else {
if(strlen($f_password)>32) {
$errors[] = 'Password too long!';
}
$f_login = f_login($f_uname, $f_password);
if($f_login===false) {
$errors[] = 'Username and Password do not match!';
}
else {
$_SESSION['f_id'] = $f_login;
header('Location: http://localhost/swift/index.php');
exit();
}
}
}
else {
$errors[] = 'No Log In credentials received!';
}
include $_SERVER["DOCUMENT_ROOT"].'/swift/includes/overall/header.php';
if(empty($errors) === false) {
?>
<br/><h4>We tried to log you in, but : </h4><br/>
<?php
echo output_errors($errors);
}
include $_SERVER["DOCUMENT_ROOT"].'/swift/includes/overall/footer.php';
?>
I keep on getting those errors but i cant find a way, i already tried everything.. Hopefully someone can help me as I am new to php.
Ive been doing this for almost like a day now and i cannot figure out the answer.
i know php is kind of hard yea and ive been looking for the answer for almost a day now. Im just new to programming and im doing my best to study hard about these kind of things hopefully someone can help me.
And i hope i can learn more about php and other programming language here.. ill keep looking for the answer even if im asking right now.. big thanks though.
I doubt you tried everything!
It looks as if you are trying to migrate from mysql_ functions to mysqli_.
From the manual for mysqli_fetch_array:
$query = "SELECT Name, CountryCode FROM City ORDER by ID LIMIT 3";
$result = mysqli_query($link, $query);
/* numeric array */
$row = mysqli_fetch_array($result, MYSQLI_NUM);
printf ("%s (%s)\n", $row[0], $row[1]);
$link is your mysqli connection. In your code it is $conn.
Within your functions you have a scope issue. $conn is in the global scope, so is not set within the function's scope.
Break it down, start with something like your f_id_from_email function, and follow and try to translate the manual's examples.
The error messages are actually quite helpful if read. But you are likely overwhelmed, as you are faced with many.
Call to undefined function mysqli_result()
That's because there is no mysqli_result function.
1- general.php line 49: look at mysqli_real_escape_string, in procedural code, you must specify 2 arguments, the link (or connection) and the string.
function array_sanitize($conn,$item) {
$item = htmlentities(strip_tags(mysqli_real_escape_string($conn,$item)));
}
function sanitize($conn,$data) {
return htmlentities(strip_tags(mysqli_real_escape_string($conn,$data)));
}
2- users.php, both on line 85, the $conn does not exist in the scope of the function. Pass $conn as an argument to the function and call it with ($conn,$f_uname).
function f_exists($conn,$f_uname) {
$f_uname = sanitize($f_uname);
$query = mysqli_query($conn, "SELECT COUNT(`f_id`) FROM `flight_users` WHERE `f_uname`= '$f_uname'");
return (mysqli_result($conn, $query, 0) == 1) ? true : false;
}
3- your question at line 86, it is the same as my #2 point.
I am working on an Item Inventory Web App. I want users should be able to add and assign item to a user. Each user is entitled to one item at a time. If, say, user a already has an item assigned and you want to add more item, the system should lodge an error that will tell you
to withdraw the item be issuing a new one but the errors are not getting lodged in the error[] array even though it shows that the array is not empty. It only echo out the serial number a = 1 and a++ but the text is not there.
class.inc.php
class Summary {
public $result;
public $conn;
public $SQ;
public $q;
public $updateDB;
public $checkDB;
public $returned_result;
public $a;
public $data;
public $col;
public function __construct(){
$this->conn = new PDO('mysql:host=localhost; dbname=dB', 'root', '');
$this->conn->setAttribute(PDO:: ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public function updateDB($coloumn, $data, $id){
$SQ = "UPDATE mytable SET $coloumn = ? WHERE staffID = ?";
$q = $this->conn->prepare($SQ) or die("ERROR: " . implode(":", $this->conn->errorInfo()));
$q->bindParam(1, $data);
$q->bindParam(2, $id);
if ($q->execute()){
$success = 'Record updated successfully';
};
return $success;
}
public function checkDB($col, $data){
$status = 'Active';
$SQ = "SELECT surname FROM mytable WHERE $col = ? AND status = ?";
$q = $this->conn->prepare($SQ) or die("ERROR: " . implode(":", $this->conn->errorInfo()));
$q->bindParam(1, $data);
$q->bindParam(2, $status);
$q->execute();
if($result = $q->fetch(PDO::FETCH_BOTH)){
$a = $result[0];
if ($a == ''){
$this->returned_result = 'N';
}
else {
$this->returned_result = "This item (". $data . ") is in use by ". $a . ". Please widthraw the item";
}
}
return $this->returned_result;
}
}
index.php:
include('class.inc.php');
$summary = new Summary;
$error = array();
if(isset($_POST['saveRecord']) ) {
$system_name = strtoupper ( $_POST['system_name'] );
$result =$summary->checkDB('systemName', $system_name); //check if the item is in use
if ( $result == 'N' ){
$summary->updateDB('systemName', $system_name, $id);
$update = $summary->updateDB;
}
else $error[] = $result;
$system_serial_number = strtoupper ( $_POST['system_serial_number'] );
$result =$summary->checkDB('CPUSerial', $system_serial_number); //check if the item is in use
if ( $result == 'N' ){
$summary->updateDB('CPUSerial', $system_serial_number, $id);
$update = $summary->updateDB;
}
else $error[] = $result;
}
if(isset($_POST['saveRecord']) && !empty( $error ) ) {
echo "<div class = 'text-error'>";
$a = 1;
foreach ($error as $err){
echo '<p>' . $a . '. ' .$err . '</p>';
$a++;
}
echo "</div>";
}
Any help will be greatly appreciated. And what am I doing wrong with regards to OOP way of programming?
I am working on an assignment using PHP & MYSQL.
one of the tasks is to search on any combination of the fields. That includes Dropdown boxes populated from the Database. and Text fields.
t2ath contains
ID
SPORT
COUNTRY
GENDER
FIRSTNAME
LASTNAME
Image
I've been working on this code for a week to be able to search on any combination with no errors.
I am wondering if there is another more efficient way to do it.
$selectedSport = $_POST['sport']; $gender =$_POST['gender']; $fName =$_POST['fname']; $lName =$_POST['lname']; $country =$_POST['country'];
$sql_fName=""; $sql_lName=""; $sql_gender=""; $sql_sport=""; $sql_country="";
$checkFiled=False;
$where="";
$and="";
//
if ( $selectedSport=="showAll")
{
!isset($selectedSport);
}
else
{
if (isset($selectedSport))
{
if ($checkFiled==True)
{
$sql_sport = " AND t2ath.sport = '$selectedSport'" ;
}
else
{
$sql_sport = " t2ath.sport = '$selectedSport' " ;
$checkFiled=True;
}
}
else {
$sql_sport = "";
}
}
//
if ( $country =="showAll")
{
!isset($country);
}
else
{
if (isset($country))
{
if ($checkFiled ==True)
{
$sql_country = " AND t2ath.country = '$country'" ;
}
else
{
$sql_country = " t2ath.country = '$country' " ;
$checkFiled=True;
}
}
else {
$sql_country = "";
}
}
//
if ( $gender=="Gender")
{
!isset($gender);
}
else
{
if (isset($gender))
{
if ($checkFiled ==True)
{
$sql_gender = " AND t2ath.gender = '$gender'" ;
}
else
{
$sql_gender = " t2ath.gender = '$gender' " ;
$checkFiled=True;
}
}
else {
$sql_gender = "";
}
}
//
if ($fName =="")
{
!isset($fName);
}
else
{
if (isset($fName))
{
if ($checkFiled==True)
{
$sql_fName = " AND t2ath.firstName = '$fName'" ;
}
else
{
$sql_fName = " t2ath.firstName = '$fName' " ;
$checkFiled=True;
}
}
else {
$sql_fName = "";
}
}
//
if ($lName =="")
{
!isset($lName);
}
else
{
if (isset($lName))
{
if ($checkFiled==True)
{
$sql_lName = " AND t2ath.lastName = '$lName' " ;
}
else
{
$sql_lName = " t2ath.lastName = '$lName' " ;
$checkFiled=True;
}
}
else
{
$sql_lName = "";
}
}
if ($checkFiled == True)
$where=" where ";
$selectString = "SELECT t2ath.lastName,t2ath.firstName,t2ath.image,t2ath.sport,t2ath.gender,t2ath.country,t2country.flag FROM t2ath LEFT JOIN t2country
ON t2ath.country = t2country.name $where $sql_sport $sql_country $sql_gender $sql_fName $sql_lName ";
$result = mysql_query($selectString);
Instead of all those conditionals about whether to add AND when concatenating to the query, use an array and implode.
$fields = array('sport' => 'sport',
'gender' => 'gender',
'fname' => 'firstName',
'lname' => 'lastName',
'country' => 'country');
$wheres = array();
foreach ($fields as $postfield => $dbfield) {
if ($_POST[$postfield] != 'showAll') {
$wheres[] = "$dbfield = '" . mysql_real_escape_string($_POST[$postfield]) . "'";
}
}
$selectString = "SELECT t2ath.lastName, t2ath.firstName, t2ath.image, t2ath.sport, t2ath.gender, t2ath.country, t2country.flag
FROM t2ath LEFT JOIN t2country
ON t2ath.country = t2country.name";
if (count($wheres) > 0) {
$selectString .= " WHERE " . implode(" AND ", $wheres);
}
$result = mysql_query($selectString);
To see how to do it similarly using PDO prepared statements, see my answer here: What code approach would let users apply three optional variables in PHP/MySQL?
I've done something similar in the past where I checked the value from different fields and then added them to a series of arrays. I created an array for select, from, where, order. You can do similar for other sets like group or limit. Then I ran 'array_unique', imploded them and put them into the SQL string.
$array_select = array('users.Id'); // SET SOME DEFAULTS SO THE QUERY WILL ALWAYS RUN
$array_from = array('users');
$array_where = array();
$array_order = array();
if (isset($first_name)) {
$array_select[] = 'First_Name';
$array_from[] = 'users';
}
if (isset($city)) {
$array_select[] = 'City';
$array_from[] = 'user_contact';
$array_where[] = 'users.Id = user_contact.City';
}
if ($array_select) {
$array_select = array_unique($array_select);
$string_select = implode(', ', $array_select);
}
if ($array_where) {
$array_where = array_unique($array_where);
$string_where = 'WHERE '.implode(' AND ', $array_where);
}
// REPEAT FOR OTHERS ...
// BUILD THE QUERY OUT
$sql = 'SELECT '.$string_select.' FROM '.$string_from.' '.$string_where.' ...
Why not evaluate your string with each column (this is a guide only, I'm not building your PHP code there:
SELECT
*
FROM
table
WHERE
(ID = $id OR $id = 'showAll')
AND (SPORT = $sport OR $sport = 'showAll')
AND (COUNTRY = $country OR $country = 'showAll')
AND (GENDER = $gender OR $gender = 'showAll')
AND (FIRSTNAME = $firstname OR $firstname = 'showAll')
Just need to make sure you NVL the variables to an appropriate value (whether it be int or string)
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.
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.