Problem adding operator condition to the string - php

I need to add AND or OR in-between my Query string. My conditions are as follows:
first case:
$array = [
"month" => "October",
"year" => 2020,
"information => "October 2020"
];
In this case, i need
"(MONTH(b.day) = 'October' AND YEAR(b.day) = '2020') OR b.information LIKE '%October 2020%'"
second case:
$array = [
"month" => "October",
"information => "October 2020"
];
In this case, i need
"(MONTH(b.day) = 'October') OR b.information LIKE '%October 2020%'"
I have tried following lines of code but I couldn't fix the AND OR in correctly.
$whereStr = '';
$alias = "b.";
$orCounter = 0;
$andCounter = 0;
$dateMonth = false;
if (array_key_exists('year', $array) && array_key_exists('month', $array)) {
$dateMonth = true;
}
foreach ($array as $key => $value) {
if (0 !== $orCounter) {
$whereStr .= ' OR ';
} elseif ($andCounter > 0 && true === $dateMonth) {
$whereStr .= ' AND ';
}
if ('month' === $key || 'year' === $key) {
++$andCounter;
echo $andCounter;
$whereStr .= strtoupper($key) . '(' . $alias . 'day' . ')';
$whereStr .= "= '$value'";
if ($andCounter === 2) {
++$orCounter;
}
continue;
}
if ('type' === $key) {
$whereStr .= "$alias$key IN ($value)";
continue;
}
$whereStr .= "$alias$key LIKE '%$value%'";
++$orCounter;
}
Can anybody please help me fix this?

just use simple if else conditions why using loop
$where ='';
if(isset($array['month']) && isset($array['year']) && isset($array['information'])){
$where = '(MONTH(b.day) = '".$array['month']."' and YEAR(b.day) = '".$array['year']."' ) or b.information like "%'.$array['information'].'%" ';
}else if(isset($array['month']) && !isset($array['year']) && isset($array['information']))
{
$where = '(MONTH(b.day) = '".$array['month']."' ) or b.information like "%'.$array['information'].'%" ';
}

It's cleaner with arrays:
$AND[] = "`fieldA` = 'Bar'";
$AND[] = "`fieldB` = 'Foo'";
$andString = implode(' AND ',$AND);
$andString is
`fieldA` = 'Bar' AND `fieldB` = 'Foo'
So your code can be
$qq = "SELECT * from foobar WHERE $andString";

Related

How to loop through a foreach until X is found, if not found, look for Y

Sorry if this is a duplicate, I can't figure out what to search for to find the answer.
I have a foreach loop, and in that loop, I'm attempting to test if (A == B). Then once found I break the loop. If (A != B) in an iteration, I test if (X == Y).
My problem is that if (X == Y) is found to be true first, the loop breaks before if (A == B) can be tested.
Is there a better way to accomplish this task?
$variable[1] = ['A' => 'n', 'X' => 'n'];
$variable[2] = ['A' => 'n', 'X' => 'Y'];
$variable[3] = ['A' => 'B', 'X' => 'n'];
$test = 'B';
foreach ($variable as $value) {
if($value['A'] == $test || $value['X'] == "Y") {
echo 'The results: ' . $value['A'];
break;
}
}
// The results for $variable[2] are returned. I need the results for $variable[3] to be returned.
I did have an else statement which worked fine, but I was having to duplicate the output.
Thanks in advance!
The code above is a simplified version of what I'm working on. Here's the code I'm working actually working on.
foreach ($product_xml->products->product_styles as $style => $attribute) {
if(isset($_GET['color']) && $attribute['color'] == $color_selected || $attribute['is_default'] == "1") {
foreach ($attribute as $value){
$imgURL = (string)$value['imgurl'];
$thumburl = (string)$value['thumburl'];
$thumburl_array[(string)$value['side']] = (string)$value['thumburl'];
if (in_array($imgURL, $values)){continue;}
else{
array_push($values, $imgURL);
$imgURL = str_replace("REPLACE_DOMAIN_WITH",IDEQ_INKSOFTAPI_URL_SECURE,$imgURL );
$thumburl = str_replace("REPLACE_DOMAIN_WITH",IDEQ_INKSOFTAPI_URL_SECURE,$thumburl );
$thumburl = str_replace("150.png","500.png",$thumburl );
echo '<img src="'.$imgURL.'" class="pic'.$counter.'" title="'.$value['name'].'">';
$counter++;
}
}
break;
}
}
Use a temporary variable and move the echo to after the foreach.
$variable[1] = ['A' => 'n', 'X' => 'n'];
$variable[2] = ['A' => 'n', 'X' => 'Y'];
$variable[3] = ['A' => 'B', 'X' => 'n'];
$test = 'B';
$output = null;
foreach ($variable as $value) {
if($value['A'] == $test) {
$output = $value['A'];
break;
} else if ($output == null && $value['X'] == "Y") {
$output = $value['X'];
}
}
echo 'The results: ' . $output;
Here is my approximation with a function:
function search($variable, $test){
$alternative = null;
foreach($variable as $value){
if($value['A'] == $test){
return $value['A'];
}
if($value['X'] == 'Y' && $alternative === null){
$alternative = $value['A'];
}
}
return $alternative;
}
It will return first coincidence on A and if not found, first coincidence on X.
This way you only loop through foreach once.
Instead of looping you can use array_column to isolate one column of the array A or X.
Then use in_array to see if you find the $test in the array.
$test = 'B';
$test2 = 'Y';
If(in_array($test, array_column($variable, "A"))){
Echo $test . " Found in A";
}Else if(in_array($test2, array_column($variable, "X"))){
Echo $test2 . " Found in B";
}else{
Echo "none found";
}
https://3v4l.org/dv7Yp
Based off of the response from James Lalor I've come to this solution. If anyone sees a better/more optimal way of handling this, I'd love to hear!
$counter = 1;
$values = array();
$thumburl_array = array();
$found = false;
$find_default = false;
$style_count = count($product_xml->products->product_styles);
for ($i=0; $i < $style_count; $i++) {
if (isset($_GET['color']) && $product_xml->products->product_styles[$i]['color'] == $color_selected) {
$found = true;
} elseif (!$found && !$find_default && $i == $style_count - 1) {
$find_default = true;
$i = 0;
}
if ($find_default && $product_xml->products->product_styles[$i]['is_default'] == '1') {
$found = true;
}
if ($found) {
foreach ($product_xml->products->product_styles[$i] as $value){
$imgURL = (string)$value['imgurl'];
$thumburl = (string)$value['thumburl'];
$thumburl_array[(string)$value['side']] = (string)$value['thumburl'];
if (in_array($imgURL, $values)){continue;}
else{
array_push($values, $imgURL);
$imgURL = str_replace("REPLACE_DOMAIN_WITH",IDEQ_INKSOFTAPI_URL_SECURE,$imgURL );
$thumburl = str_replace("REPLACE_DOMAIN_WITH",IDEQ_INKSOFTAPI_URL_SECURE,$thumburl );
$thumburl = str_replace("150.png","500.png",$thumburl );
echo '<img src="'.$imgURL.'" class="pic'.$counter.'" title="'.$value['name'].'">';
$counter++;
}
}
break;
}
}
Simplified version
$variable[] = ['A' => 'n', 'X' => 'n', 'result' => 'do'];
$variable[] = ['A' => 'n', 'X' => 'Y', 'result' => 're'];
$variable[] = ['A' => 'B', 'X' => 'n', 'result' => 'mi'];
$found = false;
$find_default = false;
$count = count($variable);
$test = 'B';
for ($i=0; $i < $count; $i++) {
if ($variable[$i]['A'] == $test) {
$found = true;
} elseif (!$found && !$find_default && $i == $count - 1) {
$find_default = true;
$i = 0;
continue;
}
if ($find_default && $variable[$i]['X'] == 'Y') {
$found = true;
}
if ($found) {
echo "Resulsts: " . $variable[$i]['result'];
break;
}
}
Thank you all for your feedback, much appreciated. Cheers.

How to get all values between two array values in php?

How can I find all values between two array items (including start and end value)?
Example:
array('3X' => '3X','EX'=> 'EX','VG'=>'VG','G'=>'G','F'=>'F','P'=>'P')
Input: $arr, 'EX', 'F'
Output: 'EX', 'VG', 'G', 'F'
Thanks in advance..
$array = array('3X' => '3X','EX'=> 'EX','VG'=>'VG','G'=>'G','F'=>'F','P'=>'P');
$start = "3X";
$end ="F";
$new_array = [];
$i=0;$go=false;
foreach ($array as $element) {
if($go){
$new_array[$i] = $element;
$i++;
}
if($element==$start){
$go = true;
}
if($element==$end){
$go = false;
}
}
$total_elems_new = count($new_array);
unset($new_array[$total_elems_new-1]);
print_r($new_array);
Testeed on PHP 5.6
Try:
$arr = array('3X' => '3X','EX'=> 'EX','VG'=>'VG','G'=>'G','F'=>'F','P'=>'P');
function findValuesBetweenTwoItems($arr, $start, $end) {
$result = [];
$has_started = false;
foreach ( $arr as $item->$value ) {
if( ( $item != $end && $has_started ) || $item == $start) {
array_push($result, $value);
$has_started = true;
}
if( $item == $end ) {
array_push($result, $value);
return $result;
}
}
$my_values = findValuesBetweenTwoItems($arr, 'EX', 'F');
var_dump($my_values);
Try this:
$array = array('3X' => '3X','EX'=> 'EX','VG'=>'VG','G'=>'G','F'=>'F','P'=>'P');
$arrayKeys = array_keys($array);
$input1 = '3X';
$input2 = 'F';
if(in_array($input1,$array) && in_array($input2,$array)) {
if (array_search($input1, array_keys($array)) >= 0) {
if (array_search($input2, array_keys($array)) >= 0) {
if (array_search($input1, array_keys($array)) < array_search($input2, array_keys($array))) {
echo "Keys in between: ";
for ($i = array_search($input1, array_keys($array)); $i <= array_search($input2, array_keys($array)); $i++) {
echo $array[$arrayKeys[$i]] . ", ";
}
} else {
echo "Keys in between: ";
for ($i = array_search($input2, array_keys($array)); $i <= array_search($input1, array_keys($array)); $i++) {
echo $array[$arrayKeys[$i]] . ", ";
}
}
} else {
echo "Value not found!";
}
} else {
echo "Value not found!";
}
} else{
echo "Value not found!";
}
$from = 'EX';
$to = 'F';
$result = null;
$state = 0;
foreach ($a as $k => $v) {
if (($state == 0 && $from === $v) || ($state == 1 && $to === $v))
$state++;
if ($state && $state < 3)
$result[$k] = $v;
elseif ($state >= 2)
break;
}
if ($state != 2)
$result = null;
The loop searches for the first occurrence of $from, if $state is 0 (initial value), or the first occurrence of $to, if $state is 1. For other values of $state, the loop stops processing.
When either $from, or $to is found, $state is incremented. The values are stored into $result while $state is either 1 ($from is found), or 2 ($to is found).
Thus, $state == 2 means that both values are found, and $result contains the values from the $a array between $from and $to. Otherwise, $result is assigned to null.

How to merge two arrays and concat the values with PHP

I'm looking for an easy solution to create a little function to merge two arrays with value concat (I'm using it to create html tag attribute):
$default["class"] = "red";
$new["class"] = "green";
$new["style"] = "display:block"
The result:
$res["class"] = "red green";
$res["style"] = "display: block";
and one more option:
if the $new is not an array, just concat with the $default["class"] (if this exist), and the other side: if the $default is a simple string, convert to array: $default["class"] = $default;
I created a function but would like to use an easier, shorter way for that:
function attrMerge( $default, $new="" ){
$res = array();
if(!is_array($default)) {
$res["class"] = $default;
}
else {
$res = $default;
}
if( $new !== "" ){
if(!is_array($new)) {
if(isset($res["class"])){
$res["class"].= " ".$new;
}
}
else {
foreach($new as $key=>$value) {
if( isset($res[$key]) ) {
$res[$key].= " ".$value;
}
else {
$res[$key] = $value;
}
}
}
}
return $res;
}
$a = attrMerge("red", array("class"=>"green", "style"=>"display: block;"));
I think this is the function that you need. I have initialised the css classes and styles as empty and in depends what you pass into the function then you get the relevant array
/**
* This function returns an array of classes and styles
*
* #param $default
* #param $new
* #return array
*/
function attrMerge($default=null, $new=nul)
{
$result = array();
$result['class'] = "";
$result['style'] = "";
// add default class if exists
if (!empty($default) && is_string($default)) {
// $default is string
$result['class'] = $default;
}
if (!empty($default)
&& is_array($default)
) {
if (array_key_exists('class', $default)
&& !empty($default['class'])
) {
// $default['class'] exists and it's not empty
$result['class'] = $default['class'];
}
if (array_key_exists('style', $default)
&& !empty($default['style'])
) {
// $default['style'] exists and it's not empty
$result['style'] = $default['style'];
}
}
// add additional classes OR styles
if (!empty($new)) {
if(!is_array($new)) {
$result['class'] = empty($result['class'])
? $new
: $result['class'] . " " . $new;
} else {
foreach ($new as $key => $value) {
if (isset($result[$key])) {
$result[$key] = empty($result[$key])
? $value
: $result[$key] . " " . $value;
} else {
$result[$key] = $value;
}
}
}
}
return $result;
}
A way I believe suits your need, hopefully it's as adaptable and effecient as you were expecting.
$array1 = array(
'class' => 'class1',
'style' => 'display: none;'
);
$array2 = array(
'class' => 'class2'
);
$arrayFinal = arrayMerge($array1, $array2);
var_dump($arrayFinal);
function arrayMerge($arr1, $arr2 = ''){
// Array of attributes to be concatenated //
$attrs = array('class');
if(is_array($arr2)){
foreach($attrs as $attr){
if(isset($arr1[$attr]) && isset($arr2[$attr])){
// Not using .= to allow for smart trim (meaning empty check etc isn't needed //
$arr1[$attr] = trim($arr1[$attr] . ' ' . $arr2[$attr]);
}
}
}else{
$arr1['class'] = trim($arr1['class'] . ' ' . $arr2);
}
return $arr1;
}
$def = ['class' => 'red'];
$new = ['class' => 'green', 'style' => 'style'];
function to_array($in) {
return is_array($in) ? $in : ['class' => $in];
}
$def = to_array($def);
$new = to_array($new);
$res = $def;
array_walk($new, function ($val, $key) use (&$res) {
$res[$key] = trim(#$res[$key] . ' ' . $val);
});
var_dump($res);

changing a value in array

I have an array
N America | S America | Europe | Asia | (blank)
I am trying to make a query of it. But I want to change some values. I have a code like this:
if (!empty($md)) {
$mds = '';
if(count($md) > 0 ){
$mds .= 'AND ( FALSE';
foreach($md as $key => $value){
if ($key == '(blank)') {
$value ='';
$mds .= " OR data.m = '$value'";
} else {
$mds .= " OR data.m = '$value'";
}
}
$mds .= ') ';
}
}
And actually it finds the '(blank)' value and change it to ''. But it at the end all I get is:
AND (FALSE
OR data.m = ''
OR data.m = 'S America'
OR data.m = 'Europe'
OR data.m = 'Asia'
OR data.m = '(blank)')
It seems like it change the first value to my '' and unfortunately there is still '(blank)' at the end.
My question is how to change a value in an array in a correct way?
You need to check if $value is '(blank)' not the key, so:
if ($value == '(blank)') { ... }
For a simple array like $x = array('First','Second'); When you look over the array in a foreach, $key will be the index, so $x[0] would be the value 'First'.
Change 7 line to:
if ($value == '(blank)') {
My scripts works with first value:
$md = Array('N America','S America','Europe','Asia','(blank)');
if (!empty($md)) {
$mds = '';
if(count($md) > 0 ){
$mds .= 'AND ( FALSE';
foreach($md as $key => $value){
if ($value == '(blank)') {
$value ='';
$mds .= " OR data.m = '$value'";
} else {
$mds .= " OR data.m = '$value'";
}
}
$mds .= ') ';
}
}
AND ( FALSE OR data.m = 'N America' OR data.m = 'S America' OR data.m = 'Europe' OR data.m = 'Asia' OR data.m = '')

Calculate all possible combinations from sets/groups

I need to create a list of urls for all possible combinations from a set of filters/parameters.
Input
$data = array(
array(
'vehicle=car',
'vehicle=bike',
'vehicle=plane',
),
array(
'fruit=apple',
'fruit=banana',
'fruit=strawberry'
),
array(
'music=pop',
'music=rock',
'music=jazz'
)
);
The generated items must have the parameters in alphabetical order.
For example:
INCORRECT: ?vehicle=bike&fruit=apple&music=rock
CORRECT: ?fruit=apple&music=rock&vehicle=bike
Output
?vehicle=car
?vehicle=bike
?vehicle=plane
?fruit=apple&vehicle=car
?fruit=banana&vehicle=car
?fruit=strawberry&vehicle=car
?fruit=apple&vehicle=bike
?fruit=banana&vehicle=bike
?fruit=strawberry&vehicle=bike
?fruit=apple&vehicle=plane
?fruit=banana&vehicle=plane
?fruit=strawberry&vehicle=plane
?fruit=apple&music=pop&vehicle=car
?fruit=apple&music=rock&vehicle=car
?fruit=apple&music=jazz&vehicle=car
?fruit=banana&music=pop&vehicle=car
?fruit=banana&music=rock&vehicle=car
?fruit=banana&music=jazz&vehicle=car
?fruit=strawberry&music=pop&vehicle=car
?fruit=strawberry&music=rock&vehicle=car
?fruit=strawberry&music=jazz&vehicle=car
?fruit=apple&music=pop&vehicle=bike
?fruit=apple&music=rock&vehicle=bike
?fruit=apple&music=jazz&vehicle=bike
?fruit=banana&music=pop&vehicle=bike
?fruit=banana&music=rock&vehicle=bike
?fruit=banana&music=jazz&vehicle=bike
?fruit=strawberry&music=pop&vehicle=bike
?fruit=strawberry&music=rock&vehicle=bike
?fruit=strawberry&music=jazz&vehicle=bike
?fruit=apple&music=pop&vehicle=plane
?fruit=apple&music=rock&vehicle=plane
?fruit=apple&music=jazz&vehicle=plane
?fruit=banana&music=pop&vehicle=plane
?fruit=banana&music=rock&vehicle=plane
?fruit=banana&music=jazz&vehicle=plane
?fruit=strawberry&music=pop&vehicle=plane
?fruit=strawberry&music=rock&vehicle=plane
?fruit=strawberry&music=jazz&vehicle=plane
?music=pop&vehicle=car
?music=rock&vehicle=car
?music=jazz&vehicle=car
?music=pop&vehicle=bike
?music=rock&vehicle=bike
?music=jazz&vehicle=bike
?music=pop&vehicle=plane
?music=rock&vehicle=plane
?music=jazz&vehicle=plane
?fruit=apple
?fruit=banana
?fruit=strawberry
?fruit=apple&music=pop
?fruit=apple&music=rock
?fruit=apple&music=jazz
?fruit=banana&music=pop
?fruit=banana&music=rock
?fruit=banana&music=jazz
?fruit=strawberry&music=pop
?fruit=strawberry&music=rock
?fruit=strawberry&music=jazz
?music=pop
?music=rock
?music=jazz
Is there anyone that could help me out with this. I've been struggling with it for two days now but I can't seem so find a correct solution. There are a lot of (almost) similar issues on Stackoverflow but none of them seems to solve/fit my problem.
[SOLVED]
Here is the final working version based on Dusan Plavak's answer:
function createFilterCombinations($data, &$urls = array(), $index = 0, $query = false){
$keys = array_keys($data);
$_query = $query;
if ($index == count($data)) {
return;
}
for($i=0; $i < count($data[$keys[$index]]); $i++){
$query = $_query;
if($index == 0){
$query = "?" . $data[$keys[$index]][$i];
}else{
if($query != "?"){
$query .= "&" . $data[$keys[$index]][$i];
}else{
$query .= $data[$keys[$index]][$i];
}
}
$urls[] = $query;
createFilterCombinations($data, $urls, $index+1, $query);
}
if($index == 0){
$query = "?";
} else {
$query = $_query;
}
createFilterCombinations($data, $urls, $index+1, $query);
}
function prepareArray($array){
$newArray = array();
foreach ($array as $subArray) {
sort($subArray);
$newArray[substr($subArray[0], 0, strpos($subArray[0], '='))] = $subArray;
}
ksort($newArray);
return $newArray;
}
createFilterCombinations(prepareArray($data), $result);
var_dump($result);
So look at this http://codepad.org/TZWf7Vxd
and code for a time when link will be dead :D
<?php
$data = array(
"vehicle" => array(
'vehicle=car',
'vehicle=bike',
'vehicle=plane',
),
"fruit" => array(
'fruit=apple',
'fruit=banana',
'fruit=strawberry'
),
"music" => array(
'music=pop',
'music=rock',
'music=jazz'
)
);
function hop($index, $query, $data){
$keys = array_keys($data);
if($index == count($data)){
return;
}
$queryBackup = $query;
for($i=0;$i<count($data[$keys[$index]]);$i++){
$query = $queryBackup;
if($index == 0){
$query = "?".$data[$keys[$index]][$i];
}else{
if($query != "?"){
$query .= "&".$data[$keys[$index]][$i];
}else{
$query .= $data[$keys[$index]][$i];
}
}
echo $query."\n";
hop($index+1, $query, $data);
}
if($index == 0){
$query = "?";
}else{
$query = $queryBackup;
}
hop($index+1, $query, $data);
}
ksort($data);
hop(0,"", $data);
?>
This is not a ready-made solution but you can use a function that returns an array combinations. I hope this could help You.
<?
$collect = false;
function combinations($arr, $temp_string, &$collect) {
if ($temp_string != "")
$collect[] = $temp_string;
for ($i = 0; $i < sizeof($arr); $i++) {
$arrcopy = $arr;
$elem = array_splice($arrcopy, $i, 1);
if (sizeof($arrcopy) > 0) {
combinations($arrcopy, $temp_string . " " . $elem[0], $collect);
} else {
$collect[] = $temp_string . " " . $elem[0];
}
}
return $collect;
}
var_dump(combinations(array('abc', 'cde', 'fgi'),'',$collect));
?>
see WORKING CODE

Categories