Using an html FORM let's convert $core in 100 and $mhz in 1000
emag and koyos are table rows
So if $core is set $parameters['emag'] = "$core"; is emag=100else it is null
AND and WHERE are dinamically setted to appear, so the problem is that I collect all data of variables in $parameters[] and foreach() them.
With my code I am get exactly what $core is. This is the code:
if (!empty($core)) {
$parameters['emag'] = "$core";
}
if (!empty($mhz)) {
$parameters['koyos'] = $mhz;
}
$sql = "SELECT * FROM $tbl_name WHERE 1=1 ";
if (!empty($parameters)) {
foreach ($parameters as $k => $v) {
$sql .= " AND " . $k . "='" . $v . "'";
}
}
$sql .= " ORDER BY emag, performanta_cpu_core DESC, performanta_cpu DESC LIMIT $start, $limit";
And it is results just rows with emag=100, but I have need all numbers equals or little than 100 not just 100
Your query conditions, based on the data you've provided, are:
WHERE 1=1 AND emag = '100' AND koyos = '1000'
And so obviously will only show rows where emag = 100. If you want to show all those up to 100 then change = to <= when the table name is emag:
foreach ($parameters as $k => $v) {
if ($k == 'emag')
{
$sql .= " AND " . $k . "<='" . $v . "'";
}
else
{
$sql .= " AND " . $k . "='" . $v . "'";
}
}
Try this:
foreach ($parameters as $k => $v) {
if ($k == 'emag') {
$sql .= " AND " . $k . "<='" . $v . "'";
continue;
}
$sql .= " AND " . $k . "='" . $v . "'";
}
Related
I began to write a generic class for SELECT queries that looks like this:
class DbQuery
{
private $database;
public function __construct()
{
$db_config = array(
"type" => "mysql",
"host" => "localhost",
"port" => "3306",
"charset" => "utf8",
"db" => "dbname",
"user" => "user",
"password" => "topsecret"
);
$this->database = DatabaseFactory::getFactory()->getConnection($db_config);
}
public function Select($keys = array("*"), $table, $whereClauseArray = null, $orderValues = null, $orderDirection = null, $limitIndex = null, $limitLength = null)
{
$statement = "SELECT " . implode(',', $keys) . " FROM " . $table;
if (!empty($whereClauseArray)) {
$whereClauseString = " WHERE ";
$i = 0;
foreach ($whereClauseArray as $whereClause) {
if ($i > 0) {
$whereClauseString .= " " . $whereClause['link'] . " ";
}
$whereClauseString .= $whereClause['key'] . " " . $whereClause['operand'] . " :" . $whereClause['key'] . "_" . $i;
$i++;
}
$statement .= $whereClauseString;
}
if (!empty($orderValues)) {
$orderClause = " ORDER BY ";
foreach ($orderValues as $order) {
$orderClause .= $order . ", ";
}
$orderClause = substr($orderClause, 0, -2);
$statement .= $orderClause . " " . $orderDirection;
}
if ($limitIndex != null && $limitLength != null) {
$statement .= " LIMIT " . $limitIndex . "," . $limitLength;
}
$query = $this->database->prepare($statement . ";");
$file = $_SERVER["DOCUMENT_ROOT"] . '/../db.log';
$current = file_get_contents($file);
$current .= date("Y-m-d H:i:s", time()) . " => ";
$current .= "Statement: " . $statement . "\n";
file_put_contents($file, $current);
$j = 0;
foreach ($whereClauseArray as $whereClause) {
$keystring = ":" . $whereClause['key'] . "_" . $j;
$bindValue = trim(strip_tags($whereClause['value']));
$query->bindValue($keystring, $bindValue);
$file = $_SERVER["DOCUMENT_ROOT"] . '/../db.log';
$current = file_get_contents($file);
$current .= date("Y-m-d H:i:s", time()) . " => ";
$current .= "BindValue: " . $keystring . " -> " . trim(strip_tags($whereClause['value'])) . "\n";
file_put_contents($file, $current);
$j++;
}
// $query->execute();
if ($keys === "count(*)") {
return $query->fetchColumn(0);
} else {
return $query->fetchAll();
}
}
}
I call the function like that:
$obj_artikel_startseite = new DbQuery();
$obj_artikel_startseite->Select(array("*"), "psartikel", array(array("link" => "AND", "key" => "status", "value" => "freigeschaltet", "operand" => "="), array("link" => "OR", "key" => "status", "value" => "reserviert", "operand" => "=")), array("id"), "DESC", 0, 3)) {
As long as I leave the execution commented, I get a proper output in my db.log file:
2022-10-23 19:35:51 => Statement: SELECT * FROM psartikel WHERE status = :status_0 OR status = :status_1 ORDER BY id DESC
2022-10-23 19:35:51 => BindValue: :status_0 -> freigeschaltet
2022-10-23 19:35:51 => BindValue: :status_1 -> reserviert
But when I try to execute the prepared statement with binded values, it leads to an endless loop. I donĀ“t understand why.
Regards
Edit: Endless loop means the execution limit exceeds and the output in my log is about thousands, indentical entries...
I am trying to write some PHP that fits in to a larger method so that I can dynamically create a MySQL query.
I haven't included the code to the larger method that contains this code because I think the logic of this bit is self-contained.
So, I have a multi-dimensional array:
$where=array(array('username', 'pid', 'name'), array('=','<=', '='), array('alex',2,'james'));
which when I print_r() shows this structure:
Array
(
[0] => Array
(
[0] => username
[1] => pid
[2] => name
)
[1] => Array
(
[0] => =
[1] => <=
[2] => =
)
[2] => Array
(
[0] => alex
[1] => 2
[2] => james
)
)
What I would like to do if use the first value in each second level array to build up the start of the query such as
SELECT * FROM table WHERE username = alex
and then use the other values to build up the query such as (depending upon the number of items in the arrays)
SELECT * FROM table WHERE username = alex AND pid <= 2 AND name = james
Below is the code I have written
if (is_array($where[0])){
$i=0;
$field = $where[0][$i];
$operator = $where[1][$i];
$value= $where[2][$i];
$sql= "SELECT * FROM table WHERE {$field} {$operator} {$value}";
while($i=0 ) {
print $sql;
$i++;
}
while($i>0 AND $i< sizeof($where[0]))
$field = $where[0][$i];
$operator = $where[1][$i];
$value= $where[2][$i];
print $sql .= " AND {$field} {$operator} {$value}";
$i++;
}
However this prints out just one query
SELECT * FROM table WHERE username = alex AND username = alex
I am using PDO so in reality {$value} is replaced by ? and bound elsewhere in the method. I've just shown it here in full.
$sql = 'SELECT * FROM table WHERE';
for($i = 0; $i < count($where[0]); $i++){
$sql .= " {$where[0][$i]} {$where[1][$i]} {$where[2][$i]} AND";
}
$sql = substr($sql, 0, strlen($sql) - 4);
I personally would however save your statements like this:
$array = array('username = alex', 'pid <= 2');
If you needed the different parts of the statements, you could just do
explode(' ', $array[num]);
$companyFilter = "";
$auth = getFormulaAuth();
$companyFilter = "AND company_id = {$auth['company_id']} ";
$arguments = func_get_args();
if ($WhereFilterName_xxx) {
} else {
$db = new Database();
$this_get_table_form = getFormulaFormDetails($FormName);
$tbfields_data = Formula::getTBFields($this_get_table_form["id"], $db);
$q_string = "SELECT * FROM `" . $this_get_table_form["form_table_name"] . "`";
$valid_param_check = count($arguments) - 2;
$cache_key = "*";
if ($valid_param_check >= 1 && $valid_param_check % 3 == 0) {
$found_indexes = array();
$q_string_where = " WHERE ";
$search = " (NOT EXISTS(SELECT * FROM tbtrash_bin WHERE record_id = " . $this_get_table_form["form_table_name"] . ".id
AND form_id = " . $this_get_table_form["id"] . "
AND table_name='" . $this_get_table_form["form_table_name"] . "')) AND ";
$q_string_where .= $search;
for ($i = 2; $i < count($arguments); $i+=3) {
$field_key = $arguments[$i];
$operator = $arguments[$i + 1];
$value = $arguments[$i + 2];
if ($i > 2) {
$q_string_where .= " AND ";
}
$q_string_where .= " `" . $field_key . "` " . $operator;
if (($tbfields_data["" . $field_key]["field_input_type"] == "Number" || $tbfields_data["" . $field_key]["field_input_type"] == "Currency") || strtoupper($operator) == "IN") {
$q_string_where .= " " . $value . " ";
} else {
$q_string_where .= " '" . $value . "' ";
}
$q_string_orderby .= $q_string_where;
$sort_by = isset($_GET['s']) ? $_GET['s'] : false;
switch ($sort_by) {
case $tbfields_data;
break;
default:
$sort_by = 'DateCreated';
}
$q_string_orderby .= ' ORDER BY '.$sort_by.' ';
$direction = isset($_GET['d']) ? $_GET['d'] : false;
if ($direction != 'ASC' && $direction != 'DESC')
$direction = 'DESC';
$q_string_orderby .= $direction;
$res = $db->query($q_string_orderby);
$results = array();
if ($res) {
while ($r = mysql_fetch_assoc($res)) {
$results[] = $r;
}
}
$cache_key.="::" . $field_key . "::" . $operator . "::" . $value . "::" . $q_string_orderby;
}
$q_string .= $q_string_orderby;
}
$this_record = Formula::getLookupValue("formula_lookup_where_array", $this_get_table_form, $q_string, $cache_key);
array_push($GLOBALS['formula_executed_data_collector']['collected_form_id'], array(
"form_id" => $this_get_table_form['id'],
"where" => $q_string_where,
"function_name" => "Total",
"whole_query" => $q_string
));
$rslt = array_values(array_map(function($a) use($ReturnField) {
if (gettype($ReturnField) == "array") {
$array_collector = array();
foreach ($ReturnField as $key => $value) {
$array_collector[$value] = $a[$value];
}
return $array_collector;
} else if ($ReturnField == "*") {
return $a;
} else {
return $a[$ReturnField];
}
}, $this_record));
return $rslt;
}
}
In the loop below I want $value[0] to increment on each pass of the loop. So, if $count = 2 the loop will run twice and output $key . " " . $value[0] and $key . " " . $value[1].
Right now, my loop is outputting $key . " " . $value[0] twice. What did I do wrong?
$count = count($updates['positionTitle']);
for($i = 1; $i<=$count; $i++){
foreach($updates as $key => $value){
if(!is_array($value))
echo $key . " " . $value . "<br/>";
else
echo $key . " " . $value[0]++ . "<br/>";
}
}
You need to store what the current index is. I'm not actually sure what loop you were talking about though. I'm assuming it was the outer for loop. I still think this is broken but based on your comment this is what you want.
$count = count($updates['positionTitle']);
$idx = 0;
for($i = 1; $i<=$count; $i++){
foreach($updates as $key => $value){
if(!is_array($value))
echo $key . " " . $value . "<br/>";
else
echo $key . " " . $value[$idx] . "<br/>";
}
$idx++;
}
Change:
foreach($updates as $key => $value){
To:
foreach($updates as $key => &$value){
Trying to loop through a querystring in php but only getting last value. What should I be doing to get all values?
example:
querystring = ?style=ranch&style=barn&style=colonial
php:
$sqlStyle = "SELECT DISTINCT COUNT(*) as count FROM houses_single ";
$i = 1;
foreach ($_GET as $key => $value) {
if ($i == 1){
$sqlStyle .= "where ";
}else{
$sqlStyle .= " and ";
}
$sqlStyle .= $key . " like '%" . $value ."%'";
$i++;
}
echo $sqlStyle;
Result:
SELECT DISTINCT COUNT(*) as count FROM houses_single Where Houses like '%colonial%'
The query parameter "style" is an array in this case and must be identified by square brackets - if not, the last key=value pair will overwrite the others.
?style[]=ranch&style[]=barn&style[]=colonial
$_GET['style'] is an array then you can loop over by using foreach:
foreach ($_GET['style'] as $value) {
// ...
}
if 'style' is not the only parameter you want to add, you can use a is_array() check in the foreach loop:
foreach ($_GET as $key => $value) {
if ($i == 1){
$sqlStyle .= "where ";
}else{
$sqlStyle .= " and ";
}
if(is_array($value)) {
$sec = array();
foreach($value as $second_level) {
$sec[] = $key . " LIKE '%" . $second_level."%'";
}
$sqlStyle .= implode(' AND ', $sec);
}
else {
$sqlStyle .= $key . " LIKE '%" . $value ."%'";
}
$i++;
}
echo $sqlStyle;
alternative without foreach:
<?php
$statement = "SELECT DISTINCT COUNT(*) as count FROM `houses_single`";
if(is_array($_GET)) {
$statement .= ' WHERE';
// create copy to keep the $_GET array
$add_where = $_GET;
array_walk(function($elem,$key){
is_array($elem) {
return implode(' AND ', array_map(function($sec) using ($key) {
return "$key LIKE '%$sec%'";
}, $elem);
}
else {
return "$key LIKE '%$elem%'";
}
},$add_where);
$statement .= implode(' AND ', $add_where);
}
(codes are untested)
Sidenode about safety: I hope you won't use this code snippet you provided in productive environment without any escaping of the parameters.
I have a export script that export items to a csv file. I want to export the additional images for each item on each product row in the csv file.
That part looks like this:
$img_query=tep_db_query("SELECT additional_images_id, products_id, popup_images
FROM " . TABLE_ADDITIONAL_IMAGES . "
WHERE products_id=" . $products['products_id'] ."");
if (!tep_db_num_rows($img_query)) {
$imageextra2 = " ";
} else {
$img_rows=tep_db_num_rows($img_query);
while ($img = tep_db_fetch_array($img_query)) {
$img2 = $img['popup_images'];
$pid = $img['products_id'];
$a = array($img2);
foreach($a as &$img){
}
foreach($a as $imageextra) {
$imageextra = "http://www.URL.com/images/". $img2.";";
$imageextra2 .= $imageextra;
}
} }
But when I export more than one product that have additional images the images from the line abowe follows to the next line in the csv file.
Heres an exampe of the result. Each item has one additional image:
Item-A;AdditionalImage-A.jpg;AdditionalImage-A2.jpg
Item-B;AdditionalImage-A.jpg;AdditionalImage-A2.jpg;AdditionalImage-B.jpg;AdditionalImage-B2.jpg
Item-C;AdditionalImage-A.jpg;AdditionalImage-A2.jpg;AdditionalImage-B.jpg;AdditionalImage-B2.jpg;AdditionalImage-C.jpg;AdditionalImage-C2.jpg
What can I do to get this working?
Cheers,
Fredrik
Edit
Below is the complete section of php that grab the info and generate the export file:
<?php
require('includes/application_top.php');
if (isset($_POST['create'])) {
if (isset($_POST['product']) && is_array($_POST['product'])) {
foreach ($_POST['product'] as $product_id) {
$products_query_raw = "select p.products_id, p.products_image, p.products_model, products_image_pop, p.products_price, p.products_quantity, p.products_tax_class_id, pd.products_name, pd.products_description from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_id = $product_id and pd.products_id = p.products_id and pd.language_id = $languages_id";
$products_query = tep_db_query($products_query_raw);
if ($products = tep_db_fetch_array($products_query)) {
//++++ QT Pro: End Changed Code
$products_attributes_query = tep_db_query("select count(*) as total from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_ATTRIBUTES . " patrib where patrib.products_id='" . $products['products_id'] . "' and patrib.options_id = popt.products_options_id and popt.language_id = '" . (int)$languages_id . "'");
$products_attributes = tep_db_fetch_array($products_attributes_query);
if ($products_attributes['total'] > 0) {
//++++ QT Pro: Begin Changed code
$products_id = $products['products_id'];
require_once(DIR_WS_CLASSES . 'pad_single_radioset_print.php');
$class = 'pad_single_radioset';
$pad = new $class($products_id);
$attribs .= $pad->draw();
//++++ QT Pro: End Changed Code
}
$product_desc = (isset($_POST['strip_tags']) && ($_POST['strip_tags'] == '1'))
? strip_tags($products['products_description'],'<br>, <li>, </li>, <ul>, </ul>') //ORG
: $products['products_description'];
$tax_rate = 0;
$taxes_query_raw = "select tax_rate from " . TABLE_TAX_RATES . " where tax_class_id = " . $products['products_tax_class_id'];
$taxes_query = tep_db_query($taxes_query_raw);
while ($taxes = tep_db_fetch_array($taxes_query)) {
$tax_rate += $taxes['tax_rate'];
}
$tax = ($products['products_price'] * $tax_rate) / 100;
$stock = $products['products_quantity'];
$product_desc=preg_replace("/([[:space:]]{2,})/",' ',$product_desc);
// Categories - just show the sub-category
$categories_list = Array();
$categories_query_raw = "select cd.categories_name, cd.categories_id from " . TABLE_PRODUCTS_TO_CATEGORIES . " ptc, " . TABLE_CATEGORIES_DESCRIPTION . " cd where ptc.products_id = " . $products['products_id'] . " and cd.categories_id = ptc.categories_id and cd.language_id = $languages_id";
$categories_query = tep_db_query($categories_query_raw);
while ($categories = tep_db_fetch_array($categories_query)) {
$categories_list[] = $categories['categories_name'];
$categories_id = $categories['categories_id'];
}
$category_name = implode(' / ', $categories_list);
// Additional images
$img_query=tep_db_query("SELECT additional_images_id, products_id, popup_images
FROM " . TABLE_ADDITIONAL_IMAGES . "
WHERE products_id=" . $products['products_id'] ."");
if (!tep_db_num_rows($img_query)) {
$imageextra2 = "; ; ";
} else {
$img_rows=tep_db_num_rows($img_query);
while ($img = tep_db_fetch_array($img_query)) {
$img2 = $img['popup_images'];
$pid = $img['products_id'];
$a = array($img2);
$imageextra2 = " "; # This avoid letting the additional images from lines abowe follow.
foreach($a as $imageextra) {
$imageextra = "http://www.URL.com/images/". $img2.";";
$imageextra2 .= $imageextra;
}
}
}
$export .=
$products['products_model'].';'.
$products['products_name'].';'.
$product_price.';'.
$products['products_quantity'].';'.
$product_desc.';'.
$categories_id.';'.
$shipping_cost.';'.
'http://www.URL.com/images/'.basename($products['products_image_pop']).';'.
$imageextra2.
"\n";
}
}
if ($fp = #fopen($_SERVER['DOCUMENT_ROOT'] . '/feed/t-butik.csv', 'w')) {
$utf = iconv("windows-1252","ISO-8859-1",$export);
$out = 'variable_name='.$utf;
fwrite($fp, $utf);
fclose($fp);
$messageStack->add("Feed generates successfully!!!", 'success');
} else {
$messageStack->add("ERROR: Permissions error trying to write feed to disk.", 'error');
}
}
}
?>
There doesn't seem to be enough of the code to give you an absolute answer but my guess would be that the variable $imageextra2 is not being reset on each iteration.
When you change a product you should reset the variable thats holding the images, which I assume is $imageextra2
Change This
if (!tep_db_num_rows($img_query)) {
$imageextra2 = "; ; ";
} else {
$img_rows=tep_db_num_rows($img_query);
while ($img = tep_db_fetch_array($img_query)) {
$img2 = $img['popup_images'];
$pid = $img['products_id'];
$a = array($img2);
$imageextra2 = " "; # This avoid letting the additional images from lines abowe follow.
foreach($a as $imageextra) {
$imageextra = "http://www.URL.com/images/". $img2.";";
$imageextra2 .= $imageextra;
}
}
}
To This
$imageextra2 = " "; # resets images
if (tep_db_num_rows($img_query)) {
$img_rows=tep_db_num_rows($img_query);
while ($img = tep_db_fetch_array($img_query)) {
$img2 = $img['popup_images'];
$pid = $img['products_id'];
$a = array($img2);
foreach($a as $imageextra) {
$imageextra = "http://www.URL.com/images/". $img2.";";
$imageextra2 .= $imageextra;
}
}
}
Best Regards,
Jason