I have JSON Response Request and want make one variable $Where from them, this the JSON pattern :
"filter":
{"filters":[
{"logic":"and","filters":[
{"field":"NAMA","operator":"eq","value":"Rahmat"},
{"field":"NAMA","operator":"eq","value":"Rosadi"}
]},{"logic":"or","filters":[
{"field":"NIPK","operator":"eq","value":"1919191919"},
{"field":"NIPK","operator":"eq","value":"818181818181"}
]},{"logic":"and","filters":[
{"field":"JK","operator":"eq","value":"P"},
{"field":"JK","operator":"eq","value":"L"}
]}
],
"logic":"and"}
Can anyone tell me how make thats patter to singgle row PHP variable like this :
$Where = "(NAMA = 'Rahmat' or NAMA = 'Rosadi') and (NIPK = '1919191919' or NIPK != '818181818181') and (JK='P' AND JK='L')"
Sorry for my bad english.
You can enumerate the filters list into PHP arrays, building each of them as a list of SQL OR values, then join them with implode(' OR ', ...); and further implode the arrays in a list of ' AND ' clauses.
This approach loses much of the flexibility allowed from your JSON setup, though; it can be extended to an AND-list of either OR-clauses or single clauses, and maybe coalesce OR clauses for the same field using the IN syntax, but not much more.
You can look to algorithm that convert from RPN notation to algebraic to look for a more powerful (albeit more complex) approach.
The simple version is
$ops = array(
'eq' => '=',
'ne' => '!=',
'gt' => '>',
'lt' => '<',
'ge' => '>=',
'le' => '<=',
// CHECK THIS OUT, FIX & COMPLETE
);
$arr_Filters = array();
foreach($filters as $filter)
{
/* $filter is a set of subfilters:
{"logic":"and","filters":[
{"field":"NAMA","operator":"eq","value":"Rahmat"},
{"field":"NAMA","operator":"eq","value":"Rosadi"}
]},
which we see as:
*/
$logic = $filter['logic'];
$arr_Filter = array();
foreach($filter['filters'] as $fov)
{
$op_f = $fov['operator'];
$op = $ops[$op_f];
$value = /* FUNCTION TO SQL ESCAPE A VALUE */ $fov['value'];
$value = is_numeric($value) ? $value : "'".$value."'";
$arr_Filter[] = "$fov[field] $op $value";
}
$arr_Filters[] = '('.implode(' ' . $filter['logic'] . ' ', $arr_Filter).')';
}
$sql_filter = 'WHERE ' . implode(' AND ', $arr_Filters);
Using json_decode() an object can be retrieved that can be manipulated thus:
// ($ops omitted, same as above)
$arr_Filters = array();
foreach($filters->filter->filters as $filter)
{
/* $filter is a set of subfilters:
{"logic":"and","filters":[
{"field":"NAMA","operator":"eq","value":"Rahmat"},
{"field":"NAMA","operator":"eq","value":"Rosadi"}
]},
which we see as:
*/
$logic = $filter->logic;
$arr_Filter = array();
foreach($filter->filters as $fov)
{
$op_f = $fov->operator;
$op = $ops[$op_f];
$value = /* FUNCTION TO SQL ESCAPE A VALUE */ $fov->value;
$value = is_numeric($value) ? $value : "'".$value."'";
$arr_Filter[] = "{$fov->field} $op $value";
}
$arr_Filters[] = '('.implode(' ' . $filter->logic . ' ', $arr_Filter).')';
}
$sql_filter = 'WHERE ' . implode(' ' . $filters->filter->logic . ' ', $arr_Filters);
Related
I'm working with an API to retrieve records based on user input.
There are filters and filter groups that will be concatenated, however, I do not want the last AND or OR in the nested for each loop to be concatenated to the string.
I would like to have an if statement that looks for the last item in the nested foreach loop and concatenates a different string to the end, like this:
if($i == $lastItem) {
$conditions .= 'WHERE ' . $type . ' = '. "'". $tag . "'";
}
else {
$conditions .= 'WHERE ' . $type . ' = '. "'". $tag . "'" . ' ' . $condition . " ";
}
What is the best practice for finding the last item of a nested for each loop using PHP?
Here is the reference code:
$conditions = "";
$filters = "";
foreach($request->filters as $key=>$filter) {
foreach($filter as $item) {
if($item['tag']) {
$type = $item['code'];
$tag = $item['tag'];
$condition = $item['condition'];
$conditions .= 'WHERE ' . $type . ' = '. "'". $tag . "'" . ' ' . $condition . " ";
}
}
$groupCondition = $request->conditions[$key]['condition'];
$filters .= '('.$conditions.') ' . $groupCondition . " ";
}
Here is an example of a request, the two objects are combined in the foreach loop:
filter: {
0 {
0 {
code: 'gl_code',
condition: 'OR',
tag: '10-140-4700-0401'
}
1 {
0 {
code: 'ty_letter_no',
condition: 'AND',
tag: 'AM123'
},
1 {
code: 'gl_code',
condition: 'OR',
tag: '10-140-4700-0401'
}
}
groupConditions: {
0 {
condition: 'OR'
}
1 {
condition: 'AND'
}
}
Here an example of the current output:
"(WHERE ty_letter_no = 'AM123' AND )
OR
(WHERE ty_letter_no = 'AM123' AND WHERE solicit_code = '19-10NL' AND WHERE ty_letter_no = 'AU' AND )
AND
(WHERE ty_letter_no = 'AM123' AND WHERE solicit_code = '19-10NL' AND WHERE ty_letter_no = 'AU' AND WHERE solicit_code = '19-04HRGOLF' AND )
AND "
I would like it to output:
"(WHERE ty_letter_no = 'AM123')
OR
(WHERE ty_letter_no = 'AM123' AND WHERE solicit_code = '19-10NL' AND WHERE ty_letter_no = 'AU')
AND
(WHERE ty_letter_no = 'AM123' AND WHERE solicit_code = '19-10NL' AND WHERE ty_letter_no = 'AU' AND WHERE solicit_code = '19-04HRGOLF')"
I shall work under these assumptions:
the request comes from a "LEGO model" builder, so that the condition entry is always present, but sometimes not significant (specifically, when it is the last of its group).
the resulting code has to be a valid SQL condition.
the string values do not need escaping and have been proofed against SQL injection.
If this is so, then you can use a limited state machine to achieve your result:
$completeCondition = '';
$groupjoin = '';
foreach ($request->filter as $index => $conditions) {
$conditionjoin = '';
$partialCondition = '';
foreach ($conditions as $triplet) {
$partialCondition .= "{$conditionjoin}{$triplet->code} = '{$triplet->tag}'";
$conditionjoin = " {$triplet->condition} ";
}
$completeCondition .= "{$groupjoin}({$partialCondition})";
$groupjoin = " {$request->groupConditions[$index]->condition} ";
}
if (!empty($completeCondition)) {
$completeCondition = " WHERE {$completeCondition}";
}
Using this version of your request,
$request = json_decode('{
"filter": [
[
{ "code": "gl_code", "condition": "OR", "tag": "10-140-4700-0401" }
],
[
{ "code": "ty_letter_no", "condition": "AND", "tag": "AM123" },
{ "code": "gl_code", "condition": "OR", "tag": "10-140-4700-0401" }
]
],
"groupConditions": [ { "condition": "OR" }, { "condition": "AND" } ]
}');
the result is the following, valid SQL:
WHERE (gl_code = '10-140-4700-0401')
OR (ty_letter_no = 'AM123' AND gl_code = '10-140-4700-0401')
(if the destination language is not SQL then the code can be changed slightly, of course).
a more refined result (PDO support)
Normally you do not want to include the request strings in your SQL code as is, because this allows the user to arbitrarily alter the SQL code you will execute. For example if I were to send along a tag of
'||SLEEP(60)||'
the code above would happily encode it as, say, gl_code = ''||SLEEP(60)||'', which is a valid SQL request and will be executed, halting your thread for sixty seconds. If I know you're using MySQL, I can perform some tricks with the LOCK() function and try to exhaust the internal metadata memory. If you're really unlucky and composite queries have not been disabled (they usually are!), then I very much fear I can own your SQL server. Even if they are, there are several dirty tricks that can be done with LEFT JOINs, UNIONs and SELECT 'code' INTO DUMPFILE '/var/www/nasty.php', and not all installations are hardened against all of them.
To avoid this we use PDO and SQL parameterization. This requires sending the query in two parts, a prepared query like
`...AND gl_code = :value1`
and a binding list containing ...':value1' => 'AL-1234-56'....
$completeCondition = '';
$groupjoin = '';
$bindingList = array();
foreach ($request->filter as $index => $conditions) {
$conditionjoin = '';
$partialCondition = '';
foreach ($conditions as $triplet) {
$bind = ':b' . count($bindingList);
$partialCondition .= "{$conditionjoin}{$triplet->code} = {$bind}";
$conditionjoin = " {$triplet->condition} ";
$bindingList[$bind] = $triplet->tag;
}
$completeCondition .= "{$groupjoin}({$partialCondition})";
$groupjoin = " {$request->groupConditions[$index]->condition} ";
}
if (!empty($completeCondition)) {
$completeCondition = " WHERE {$completeCondition}";
}
// Now we could safely do (supposing $pdo is my PDO DB object)
$stmt = $pdo->prepare($completeCondition);
$stmt->execute($bindingList);
while ($row = $stmt->fetch()) {
// Do something with the row.
}
Just an idea: you can always understand if the current iteration is the first (by using a flag).
In this way, you can:
skip the first iteration
save at each iteration the current item, to be used at the next iteration
Update the query at the Nth iteration appending information related to the (N-1)th iteration
Outside the loop append the information related to the last iteration applying the modifications you need
Something like
$conditions = "";
$filters = "";
$isFirst = true;
foreach($request->filters as $key=>$filter) {
foreach($filter as $item) {
if($isFirst)
{
$isFirst = false;
}
else
{ if($previousItem['tag']) {
$type = $previousItem['code'];
$tag = $previousItem['tag'];
$condition = $previousItem['condition'];
$conditions .= 'WHERE ' . $type . ' = '. "'". $tag . "'" . ' ' . $condition . " ";
}
}
$previousItem = $item;
}
$groupCondition = $request->conditions[$key]['condition'];
$filters .= '('.$conditions.') ' . $groupCondition . " ";
}
if(isset($previousItem))
{
$type = $previousItem['code'];
$tag = $previousItem['tag'];
$conditions .= 'WHERE ' . $type . ' = '. "'". $tag . "'"
}
You could try adapting this solution to your needs.
To strictly answer your question, can you see if you're working on the last iteration by checking the current iteration (in your case, the key) against the length (count()) of the array. You can avoid doing something on that iteration by making sure that if( $iteration < $length - 1 ), then you're not in the last iteration. If you want to check that you are in the last, if( $iteration == $length - 1 ).
To address the larger scope of the question:
When programmatically building queries, I've often found it easier to make use of the WHERE 1=1 to start, since it allows you to implode() an array using AND as a glue (and some DBMS will not even parse the 1=1).
$filters = "";
$length = count($request->filters);
foreach($request->filters as $key => $filter) {
$conditions = array( "WHERE 1=1" );
foreach($filter as $item){
$tag = $item['tag'];
$type = $item['code'];
$condition = $item['condition'];
$conditions[] = "{$type} = '{$tag}'";
}
// Build the conditions
$filters .= sprintf( '(%s)', implode(' AND ', $conditions ) );
// If this isn't the last item, add the group conditions
$filters .= ( $key < $length-1 ) ? " {$request->conditions[$key]['condition']} " : '';
}
The last line checks to make sure it's not the last item (by making sure the current index is less than the $length-1 before appending that last condition. Using the above, you'd end up with a filter like:
(WHERE 1=1 AND gl_code = '10-140-4700-0401') OR (WHERE 1=1 AND ty_letter_no = 'AM123' AND gl_code = '10-140-4700-0401')
If the service you're sending that to doesn't like the 1=1 (it shouldn't have any effect at all, but if it does) you can do $filters = str_replace( '1=1 AND ', '', $filters ); at the end.
(WHERE gl_code = '10-140-4700-0401') OR (WHERE ty_letter_no = 'AM123' AND gl_code = '10-140-4700-0401')
Also note that this doesn't output strictly valid SQL, just the format you requested (I'm assuming the service wants the filters in this format for their own reasons)
Here's a quick example
I have an HTML-table, where various selections can be made. The selected variables that contain the respective values, build the array $data[]. Now, with this array I would like to make an SQL request where all selected criteria should be met. This means, that I need the following request:
SELECT * FROM fruitgroups
WHERE $selection[1] = $value[1]
AND $selection[2] = $value[2]
AND $selection[3] = $value[3]
etc ...
Can anybody please help me with the loop that generates exactly the string:
...
$selection[1] = $value[1]
AND $selection[2] = $value[2]
AND $selection[3] = $value[3]
... etc ...
...that I need for the request?
Thank you in advance!
You can make a SQL request like this:
$selection = array("one", "two", "three");
$value = array("Tone", "Ttwo", "Tthree");
$concat = array();
foreach($selection as $key => $var){
$new = $selection[$key] . " = " . $value[$key];
array_push($concat, $new);
}
$concat = implode(" AND ", $concat);
$request = 'SELECT * FROM fruitgroups WHERE ' . $concat . ';';
echo $request;
Run example
Similar to the answer above, but keep it simple and don't forget the single quotes around the values:
$clauses = [];
foreach ($values as $i => $value) {
$conditions[] = "{$selection[$i]} = '$value'";
}
$query = "SELECT * FROM fruitgroups WHERE " . implode(' AND ', $conditions);
Even better, use an ORM like Eloquent:
$conditions = [];
foreach ($values as $i => $value) {
$conditions[$i] = $value;
}
$result = App\FruitGroups::where($conditions)->get();
I'm assuming you are sanitizing your inputs first, of course.
Here is my function.
I want to simplify this function.
Any one help me please?
public function showData($table,$fields,$values)
{
$first = true;
$whereClause=null;
foreach($fields as $key => $value)
{
if($first)
{
$whereClause .= " WHERE $value = '$values[$key]'";
$first = false;
}
else
{
$whereClause .= " AND $value = '$values[$key]'";
}
}
$sql = "SELECT * FROM $table $whereClause";
$q = $this->conn->prepare($sql) or die("failed!");
$q->execute();
while ($r = $q->fetch(PDO::FETCH_ASSOC))
{
$data[] = $r;
}
return $data;
}
foreach($ob->showData($tablenm,$field,$val) as $roleval)
{
//Do Something
}
Any other way to simplify this function.
Help me please.
public function query($sql, $params = NULL)
{
$stmt = $this->conn->prepare($sql);
$stmt->execute($params)
return $stmt;
}
$data = $ob->query("SELECT * FROM table WHERE foo = ? AND bar = ?", [$foo, $bar]);
foreach($data as $roleval)
{
//Do Something
}
This function is way more simpler, way more powerful and way more flexible than yours. Put aside that yours is essentially and irrecoverably prone to SQL injection, just mocking a prepared statement but not using it really.
You have to understand that keywords in SQL serve for the great purpose of readability, makes whole statement readable and unambiguous, comprehensible by the every programmer in the world. And so you can tell that your initial idea to save yourself typing of SELECT or WHERE turns to be not that brilliant.
Besides, PDO supports dozens of different return formats, while you are limiting yourself with only one.
You may read further in my article Your first database wrapper's childhood diseases
function showData($table, $fields, $values) {
if(!(is_array($fields) && is_array($values) ) || count($fields) !== count($values))
throw new Exception('Arguments error: "fields" and "values" must be arrays with equal number of elements.');
foreach ($fields as $key => &$field)
$field = '`' . str_replace('`', '``', $field) . '` = ' . $this->conn->quote($values[$key]);
return 'SELECT * FROM `' . str_replace('`', '``', $table) . (empty($fields) ? '`' : '` WHERE ' . implode(' AND ', $fields)) . ';';
}
test case:
echo showData('table`name', ['col`1', 'col\`2', 'col\\`3'], ["Tom's cat 1", "Tom's cat 2", "Tom's cat 3"]);
#output: SELECT * FROM `table``name` WHERE `col``1` = 'Tom\'s cat 1' AND `col\``2` = 'Tom\'s cat 2' AND `col\``3` = 'Tom\'s cat 3';
Of course you will execute the SQL instead of returning it as test output.
Is there any way to make the below-given code reusable for different tables, e.g. using foreach? So, how to send and use arrays of column names and values? Any example is highly appreciated.
<?php
include_once 'include/DatabaseConnector.php';
if(isset($_POST['flightNum'])) {
$flightNum=$_POST['flightNum'];
$from=$_POST['from'];
$STADate=$_POST['STADate'];
$query = 'UPDATE flightschedule
SET frm="'.$from.'",STADate="'.$STADate.'"
WHERE flightNum="'.$flightNum.'"';
DatabaseConnector::ExecuteQuery($query);
echo '1';
} else {
echo '0';
}
?>
UPDATE: What if I don't know column names apriori? How to create flexible UPDATE statement?
you can convert your code into a reusable function. for example.
function updateDB($tableName, $flightNum, $from, $STADate) {
include_once 'include/DatabaseConnector.php';
$query = 'UPDATE ' . $tableName
SET frm="'.$from.'",STADate="'.$STADate.'"
WHERE flightNum="'.$flightNum.'"';
$execute = DatabaseConnector::ExecuteQuery($query);
return $execute;
}
and to use it
if(isset($_POST['flightNum']) {
$update = updateDB('flightschedule', $_POST['flightNum'], $_POST['from'], $_POST['STADate']);
echo $update;
}
Update:
I want to send an array of column names to the function 'updateDB'.
Let's say these are column names for SET and WHERE parts of UPDATE
statement. And then I could use FOREACH, but I need some example for
this.
this is how you can do it.
function updateDB($tableName, $columns, $where) {
//do some validation here to check if proper data is being passed like
if(!isarray($columns)) {
throw new Exception('argument two $columns should be an associative array');
}
include_once 'include/DatabaseConnector.php';
$query = 'UPDATE ' . $tableName;
foreach($columns as $column => $data) {
$query .= ' SET ' . $column . ' = ' . $data . ', ';
}
//remove last comma from the update query string
$query = substr($query, 0, -1);
$query .= ' WHERE ' . $where['column'] . ' = ' . $where['value'];
$execute = DatabaseConnector::ExecuteQuery($query);
return $execute;
}
and to use it.
if(isset($_POST['flightNum']) {
$columns = array(
'frm' => $_POST['frm'],
'STADate' => $_POST['STADate']
);
$where = array(
'column'=> 'flightNum',
'value' => $_POST['flightNum']
);
$update = updateDB('flightschedule', $columns, $where);
echo $update;
}
Something like this should work:
function generateUpdateQuery($table, $fields, $where) {
$updateFields = array();
foreach ($fields as $k => $v) {
$updateFields[] = $k.' = \''.$v.'\'';
}
$sqlQuery = 'UPDATE '.$table.
' SET '.implode(', ', $updateFields).
' WHERE '.implode(' AND ', $where);
return $sqlQuery;
}
echo generateUpdateQuery('table_name',
array(
'field_a' => '10',
'field_b' => 'hello',
'field_c' => 'world'),
array(
'id=12',
'datetime > NOW()')
);
Keep in mind that this is a simple example without any security check. Something like PDO would be recommended.
Moreover, if you're looking for something more robust and flexible you should give a look to a ORM system, like Doctrine
So I'm trying to create a function that generates a SQL query string based on a multi dimensional array.
Example:
function createQueryString($arrayToSelect, $table, $conditionalArray) {
$queryStr = "SELECT ".implode(", ", $arrayToSelect)." FROM ".$table." WHERE ";
$queryStr = $queryStr.implode(" AND ",$conditionalArray); /*NEED HELP HERE*/
return $queryStr;
}
$columnsToSelect = array('ID','username');
$table = 'table';
$conditions = array('lastname'=>'doe','zipcode'=>'12345');
echo createQueryString($columnsToSelect, $table, $conditions); /*will result in incorrect SQL syntax*/
as you can see I need help with the 3rd line as it's currently printing
SELECT ID, username FROM table WHERE
lastname AND zipcode
but it should be printing
SELECT ID, username FROM table WHERE
lastname = 'doe' AND zipcode = '12345'
You're not actually imploding a multidimensional array. $conditions is an associative array.
Just use a foreach loop inside your function createQueryString(). Something like this should work, note it's untested.:
$terms = count($conditionalArray);
foreach ($conditionalArray as $field => $value)
{
$terms--;
$queryStr .= $field . ' = ' . $value;
if ($terms)
{
$queryStr .= ' AND ';
}
}
Note: To prevent SQL injection, the values should be escaped and/or quoted as appropriate/necessary for the DB employed. Don't just copy and paste; think!
function implodeItem(&$item, $key) // Note the &$item
{
$item = $key . "=" . $item;
}
[...]
$conditionals = array(
"foo" => "bar"
);
array_walk($conditionals, "implodeItem");
implode(' AND ', $conditionals);
Untested, but something like this should work. This way you can also check if $item is an array and use IN for those cases.
You will have to write another function to process the $conditionalArray, i.e. processing the $key => $value and handling the types, e.g. applying quotes if they're string.
Are you just dealing with = condition? What about LIKE, <, >?
Forgive me if its not too sexy !
$data = array('name'=>'xzy',
'zip'=>'3432',
'city'=>'NYK',
'state'=>'Alaska');
$x=preg_replace('/^(.*)$/e', ' "$1=\'". $data["$1"]."\'" ',array_flip($data));
$x=implode(' AND ' , $x);
So the output will be sth like :
name='xzy' AND zip='3432' AND city='NYK' AND state='Alaska'
I'd advise against automated conditionals creation.
Your case is too local, while there can be many other operators - LIKE, IN, BETWEEN, <, > etc.
Some logic including several ANDs and ORs.
The best way is manual way.
I am always doing such things this way
if (!empty($_GET['rooms'])) $w[]="rooms='".mesc($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mesc($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";
Though if you still want it with this simple array, just iterate it using
foreach ($conditions as $fieldname => $value)...
and then combine these variables in the way you need. you have 2 options: make another array of this with field='value' pairs and then implode it, or just concatenate, and substr trailing AND at the end.
I use a variation of this:
function implode_assoc($glue,$sep,$arr)
{
if (empty($glue)) {$glue='; ';}
if (empty($sep)) {$sep=' = ';}
if (is_array($arr))
{
foreach ($arr as $k=>$v)
{
$str .= $k.$sep.$v.$glue;
}
return $str;
} else {
return false;
}
};
It's rough but works.
Here is a working version:
//use: implode_assoc($v,"="," / ")
//changed: argument order, when passing to function, and in function
//output: $_FILES array ... name=order_btn.jpg / type=image/jpeg / tmp_name=G:\wamp\tmp\phpBDC9.tmp / error=0 / size=0 /
function implode_assoc($arr,$glue,$sep){
$str = '';
if (empty($glue)) {$glue='; ';}
if (empty($sep)) {$sep=' = ';}
if (is_array($arr))
{
foreach ($arr as $key=>$value)
{
$str .= $key.$glue.$value.$sep;
}
return $str;
} else {
return false;
}
}
I know this is for the case of a pdo mysql type.. but what i do is build pdo wrapper methods, and in this case i do this function that helps to build the string, since we work with keys, there is no possible way to mysql inject, since i know the keys i define / accept manually.
imagine this data:
$data=array(
"name"=>$_GET["name"],
"email"=>$_GET["email"]
);
you defined utils methods...
public static function serialize_type($obj,$mode){
$d2="";
if($mode=="insert"){
$d2.=" (".implode(",",array_keys($obj)).") ";
$d2.=" VALUES(";
foreach ($obj as $key=>$item){$d2.=":".$key.",";}
$d2=rtrim($d2,",").")";}
if($mode=="update"){
foreach ($obj as $key=>$item){$d2.=$key."=:".$key.",";}
}
return rtrim($d2,",");
}
then the query bind array builder ( i could use direct array reference but lets simplify):
public static function bind_build($array){
$query_array=$array;
foreach ($query_array as $key => $value) { $query_array[":".$key] = $query_array[$key]; unset($query_array[$key]); } //auto prepair array for PDO
return $query_array; }
then you execute...
$query ="insert into table_x ".self::serialize_type( $data, "insert" );
$me->statement = #$me->dbh->prepare( $query );
$me->result=$me->statement->execute( self::bind_build($data) );
You could also go for an update easy with...
$query ="update table_x set ".self::serialize_type( $data, "update" )." where id=:id";
$me->statement = #$me->dbh->prepare( $query );
$data["id"]="123"; //add the id
$me->result=$me->statement->execute( self::bind_build($data) );
But the most important part here is the serialize_type function
Try this
function GeraSQL($funcao, $tabela, $chave, $valor, $campos) {
$SQL = '';
if ($funcao == 'UPDATE') :
//Formata SQL UPDATE
$SQL = "UPDATE $tabela SET ";
foreach ($campos as $campo => $valor) :
$SQL .= "$campo = '$valor', ";
endforeach;
$SQL = substr($SQL, 0, -2);
$SQL .= " WHERE $chave = '$valor' ";
elseif ($funcao == 'INSERT') :
//Formata SQL INSERT
$SQL = "INSERT INTO $tabela ";
$SQL .= "(" . implode(", ", array_keys($campos) ) . ")";
$SQL .= " VALUES ('" . implode("', '", $campos) . "')";
endif;
return $SQL;
}
//Use
$data = array('NAME' => 'JOHN', 'EMAIL' => 'J#GMAIL.COM');
GeraSQL('INSERT', 'Customers', 'CustID', 1000, $data);