Merging PHP IF statements to a single statement or function - php

So I have some code that it seems that I have to repeat over and over again for $round == P,1,2 and A. Is there any I can achieve this without producing redundant code?
I'm thinking of writing a function that simply swaps through through all 3 possible $round variables that can be available and echoing the relevant information. Any idea on how to achieve this?
The other information will remain the same - its only $round that will change,
// determine previous round
if($round == "P") echo "";
// if we are in round 1, look up round P bookings
if($round == "1")
{
$sql = "SELECT
*
FROM ts_request
INNER JOIN ts_day
ON ts_request.day_id = ts_day.id
INNER JOIN ts_period
ON ts_request.period_id = ts_period.id
INNER JOIN ts_allocation
ON ts_request.id = ts_allocation.request_id
WHERE ts_request.round=:round
AND ts_request.dept_id=:dept
ORDER BY ts_request.module_id ASC";
$stm = $pdo->prepare( $sql );
$stm->execute( array( ':round' => 'P', ':dept' => $loggedin_id ) );
$rows = $stm->fetchAll();
foreach ($rows as $row)
{
echo '<tr align="center">';
echo '<td>'.$row['module_id'].'</td>';
echo '<td>'.$row['day'].'</td>';
echo '<td>'.$row['period'].'</td>';
echo '<td>';
$sql = "SELECT * FROM ts_roompref
WHERE request_id=:id";
$stm = $pdo->prepare( $sql );
$stm->execute( array( ':id' => $row['request_id']) );
$rows2 = $stm->fetchAll();
foreach ($rows2 as $row2)
{
if ($row2['room_id']=="0")
{
echo "Any<br>";
}
else
{
echo $row2['room_id'].'<br>';
}
}
echo '</td>';
echo '<td>'.$row['status'].'</td>';
echo '</tr>';
}
}
// if we are in round 2, look up round 1 bookings
if($round == "2")
{
$sql .= "";
}
foreach ($rows as $row)
{
// echo results here
};
// if we are in round A, look up round 2 bookings
if($round == "A")
{
$sql .= "";
}
foreach ($rows as $row)
{
// echo results here
};

This may help.
$roundsInOrder = array('P', '1', '2', 'A');
$roundKey = array_search($incomingRoundLetter, $roundsInOrder);
if ($roundKey !== false || $roundKey != 0) {
$roundToQuery = $roundsInOrder[$roundKey - 1];
// your other code snipped
$stm->execute( array( ':round' => $roundToQuery, ':dept' => $loggedin_id ) );
//more code here
}
What this code does:
It sets up the rounds in order. Then, it searches the rounds for the incoming round. We really want the key. Then, the if statement checks to a) make sure we have actually found the round and b) the round is not the first one (0 = P) because we don't want to do any query then. Finally, the $roundToQuery gets the value out of the rounds that is directly before the current key.

I think what you are searching for is the switch() function in php.
Here is a nice and simple tutorial on how to use it:
http://www.tizag.com/phpT/switch.php
Hope this helps.

"Swapping" already exists, it's called "switch statement". In your case it should look like this:
switch($round) {
case "P":
//code
break;
case "1":
//code
break;
case "2":
//code
break;
case "A":
//code
break;
default:
//code, when value of $round doesn't match any case
break;
}

Related

How can I maintain multiple open queries?

I have some php file which needs to use SQL. In that SQL I get multiple results and I use here a while($stmt->fetch()){} loop inside which I need to use another SQL. Can this be accomplished or do I need to store result of the first SQL query and after closing it I can open new SQL query.
Here's code:
function compute_production($local_id, $GameID) {
global $mysqli, $M, $Q;
$sql = "SELECT `x`, `y`, `building`, `tier` FROM `GOD_battlefields` WHERE `owner`=? AND `game_id`=?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ii", $local_id, $GameID);
$stmt->execute();
$stmt->bind_result($x, $y, $BUILDING, $TIER);
while($stmt->fetch()) {
$AB_triggered = array();
fOReaCh(tech_get_value($BUILDING, "abilities") as $ability_name => $required_tier) {
if ($TIER >= $required_tier) {
switch($ability_name) {
case "auto_production":
$AB_triggered[$ability_name] = "true";
break;
case "toggle_production":
case "double_production":
// check if the order is clicked
$sql = "SELECT `post_value` FROM `GOD_cache` WHERE `post_name`=? AND `post_value` LIKE ? AND `game_id`=? AND `round`=?";
$AB_triggered[$ability_name] = "false";
$post_name = 'AbilityOrder_'.$x.'_'.$y;
$stmt2 = $mysqli->prepare($sql);
$stmt2->bind_param("ssii", $post_name, $ability_name, $GameID, $Q->game_round);
$stmt2->execute();
$stmt2->bind_result($AbilityOrder);
if ($stmt2->fetch()) {
$stmt2->close();
$AB_triggered[$ability_name] = "true";
} else {
// Keep calm and do nothing
// Everything is fine
// No action needed
// Really
}
break;
}
}
}
foreach(tech_get_value($BUILDING, "production") as $r => $value) {
if ($r == "s" || $r == "io" || $r == "w") {
// check if cell contains those resources
$multiplier = ($Q->resources_in_cell($x, $y)[$r] > $value ? 1 : 0.15);
$value *= $multiplier; // Multiply gained resources --> if mines/forests/quarries are empty, gained resources are decreased
}
$value *= tech_get_value($BUILDING, "productionm", $r) ** ($TIER - 1);
if ($AB_triggered["toggle_production"] == "true" || $AB_triggered["auto_production"] == "true") {
$RES_PER_TURN[$r] += $value;
}
}
// information about production costs
$HTML_battlefield .= "for the cost of: <br />";
foreach(resources_for_production_gen($x, $y, array($BUILDING, $TIER)) as $resource => $cost) {
if ($AB_triggered["toggle_production"] == "true" || $AB_triggered["auto_production"] == "true") {
$RES_PER_TURN[array_search($resource, $dictionary_resource)] -= $cost;
}
}
}
return $RES_PER_TURN;
}
Keeps throwing errors on the $stmt2->bind_param();
The answer is: there is no way, how to maintain multiple open queries.
Solution may be using some INNER JOIN, or other JOIN or storing the information from first SQL, close the SQL and then open the next SQL and use stored information.

php variable scope inside a loop in a function

I am wondering is there any way to get the value of a variable, that was defined in a loop inside a function?
Do variables declared in a loop / if-then-else, etc have a limited scope (only inside these blocks)?
here is an example of a function:
<?php
function getComments($tabName) {
$sql = "select
a.owner,
a.table_name,
a.column_name,
a.data_type,
a.data_length,
a.data_precision,
b.comments
from
all_tab_columns a,
user_col_comments b
where
a.TABLE_NAME = b.table_name
and a.COLUMN_NAME = b.column_name
and a.owner = 'CORE'
and a.table_name ='" . $tabName . "'
order by
a.column_id";
$stid = oci_parse(getConnect(), $sql);
// runs the query above
oci_execute($stid);
while ($row = oci_fetch_array($stid, OCI_ASSOC + OCI_RETURN_NULLS)) {
foreach ($row as $column => $entry) {
// Column name
if ($column == 'COLUMN_NAME') {
$output = "this is a column";
}
}
}
return $output;
}
And here I get the "Undefined variable: output" error.
if I put echo instead the $output variable, I get the result.
Is it because the $output scope? How can I get the $output value in my return?
try to satisfy this condition
if ($column == 'COLUMN_NAME') {
$output = "this is a column";
}
and also u can try to return immediately after ur condition
if ($column == 'COLUMN_NAME') {
return "this is a column";
}

PHP BETWEEN Clause usage

PHP
I have having problem with my case, statements. I am trying to search books between 2 years but i am having trouble i can search one year using this code perfectly but trying for two is not working. I do understand i am more than likely going about this the wrong way to get desired result but any help would be greatly appreciated.
Also i am getting ERROR Notice: Undefined variable: Year1 for the else part of the last case. Thanks.
If Year and Year1 have a value it should look bettwen the two years if Year just has a value just find books in that year.
<?php
include 'header.php';
include 'searchscript.php';
$sql = "SELECT DISTINCT bk.title AS Title, bk.bookid AS BookID, bk.year AS Year, bk.publisher AS Publisher, aut.authorname AS Author
FROM book bk
JOIN book_category bk_cat
ON bk_cat.book_id = bk.bookid
JOIN categories cat
ON cat.id = bk_cat.category_id
JOIN books_authors bk_aut
ON bk_aut.book_id = bk.bookid
JOIN authors aut
ON aut.id = bk_aut.author_id";
if(isset($_GET['searchInput'])){
$input = $_GET['searchInput'];
$input = preg_replace('/[^A-Za-z0-9]/', '', $input);
}
if (isset($input)){
$getters = array();
$queries = array();
foreach ($_GET as $key => $value) {
$temp = is_array($value) ? $value : trim($value);
if (!empty($temp)){
if (!in_array($key, $getters)){
$getters[$key] = $value;
}
}
}
if (!empty($getters)) {
foreach($getters as $key => $value){
${$key} = $value;
switch ($key) {
case 'searchInput':
array_push($queries,"(bk.title LIKE '%$searchInput%'
|| bk.description LIKE '%$searchInput%' || bk.isbn LIKE '%$searchInput%'
|| bk.keywords LIKE '%$searchInput%' || aut.authorname LIKE '%$searchInput%')");
break;
case 'srch_publisher':
array_push($queries, "(bk.publisher = '$srch_publisher')");
break;
case 'srch_author':
array_push($queries, "(bk_aut.author_id = '$srch_author')");
break;
case 'srch_category':
array_push($queries, "(bk_cat.category_id = '$srch_category')");
break;
**case 'Year' && 'Year1':
if("$Year1" ==""){
array_push($queries, "(bk.year = '$Year')");
} else {
array_push($queries, "(bk.year BETWEEN '$Year' AND '$Year1')");
}
break;**
}
}
}
if(!empty($queries)){
$sql .= " WHERE ";
$i = 1;
foreach ($queries as $query) {
if($i < count($queries)){
$sql .= $query." AND ";
} else {
$sql .= $query;
}
$i++;
}
}
$sql .= " GROUP BY bk.title ORDER BY bk.title ASC";
}else{
$sql .= " GROUP BY bk.title ORDER BY bk.title ASC";
}
$rs = mysql_query($sql) or die(mysql_error());
$rows = mysql_fetch_assoc($rs);
$tot_rows = mysql_num_rows($rs);
?>
Your code:
foreach($getters as $key => $value)
switch ($key) {
case 'Year' && 'Year1':
if("$Year1" ==""){
array_push($queries, "(bk.year = '$Year')");
} else {
array_push($queries, "(bk.year BETWEEN '$Year' AND '$Year1')");
}
break;
}
}
shows two issues:
case statements don't work this way. You can't use boolean operators the same way here like when using an if() statement. (see manual)
You cannot expect the iterator variable $key in foreach($getters as $key=>$value) hold both values at the same time, which you imply by saying 'Year' && 'Year1'!
To solve those issues, you could do something like:
foreach($getters as $key => $value)
switch ($key) {
case 'Year':
if($getters["Year1"] ==""){
array_push($queries, "(bk.year = '{$value}')");
} else {
array_push($queries, "(bk.year BETWEEN '{$value}' AND '{$getters['Year1']}')");
}
break;
}
}
In this case the block is executed when the foreach($getters) hits the key 'Year'. The if statement now handles 'Year1' correctly by accessing the value in the array directly instead of looking at the iterator variables.
Adding as a seperate answer
Your code shows severe security flaws which should be fixed!
Excerpt:
// 1. happily copies all GET variables into an array
foreach ($_GET as $key => $value) {
$getters[$key] = $value;
}
if (!empty($getters)) {
foreach($getters as $key => $value) {
// 2. happily assings any PHP variable in the current scope to almost
// unfiltered input from a malicious user
${$key} = $value;
}
}
// any variable read after this point can not be trusted because
// the value might be manipulated by a malicious user!
Also, SQL injection all over the place! i won't repeat that SQL injection story again. See related questions!

using a $_GET id to filter a mysql_fetch_array in PHP

So I have a query that I am returning all of the items into a mysql_fetch_array. Now, I know I could write another query and just select the items I need into a seperate query but, is there a way to just filter from the larger query what I want dependent on $_GET?
So, in english the user comes from a hyperlink that has ?id=1 and I peform a while that gets the all the values but, only display the $_GET['id'] items in a list
<?php //give ma all values but only echo out list of the $_GET['id'] in the url
while ($row = mysql_fetch_array($result) {
$id = $rowvideo["id"];
$title = $rowvideo["title"];
$length = $rowvideo["length"];
}
echo("<li><a href='#'>". $title." " .$length. "</a></li>");
?>
Hope this makes sense. Thank you all.
If you do not want a second query to get just what you need, a simple-if-statement in your loop should work:
<?php
$getId = isset($_GET['id']) ? $_GET['id'] : false;
//give ma all values but only echo out list of the $_GET['id'] in the url
while ($row = mysql_fetch_array($result)) {
$id = $row["id"];
$title = $row["title"];
$length = $row["length"];
if ($id == $getId) {
echo("<li><a href='#'>". $title." " .$length. "</a></li>");
}
}
?>
Note that I declared $getId outside of the loop to prevent having to use isset() during every iteration. If you don't verify if it's set and attempt to use it it will throw an undefined index warning - assuming you have error_reporting turned on (with that level enabled).
Alternatively, you could use PHP's array_filter() on the data after you've parsed it all:
$results = array();
while ($row = mysql_fetch_array($result)) $results[] = $row;
if (isset($_GET['id'])) {
$filtered = array_filter($results, function($element) use ($_GET['id']) { return ($element['id'] == $_GET['id']); });
$results = $filtered;
}
foreach ($results as $result) {
echo("<li><a href='#'>". $result['title']." " .$result['length']. "</a></li>");
}
My personal opinion would be to be more efficient and write the second query though, assuming of course you don't actually need all of the results when an id is specified. It would be as simple as:
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
$query = 'SELECT id, title, length FROM table WHERE id=' . (int)$_GET['id'];
} else {
$query = 'SELECT id, title, length FROM table';
}
// your existing code as-is
A little more clarity here:
This will allow the filter by id in the url by specifying id=xxx, IF xxx is an integer that is positive. So id of 'bob' or -1 will not filter the results still giving all results
$filter=false;
if(isset($_GET['id']))
{
$filter_id=intval($_GET['id']);
if($id>0) $filter=true;
}
while($row = mysql_fetch_array($result))
{
if( (!$filter) || ( ($filter) && ($filter_id==$row['id']) ) )
{
$id = $row["id"];
$title = $row["title"];
$length = $row["length"];
// do other stuff here
}
}
I also changed $rowvideo to $row as this is the array you used to fetch the results.
<?php //give ma all values but only echo out list of the $_GET['id'] in the url
while ($row = mysql_fetch_array($result)) {
$id = $rowvideo["id"];
$title = $rowvideo["title"];
$length = $rowvideo["length"];
if ($id == $_GET['id']) { // or even ===
echo("<li><a href='#'>". $title." " .$length. "</a></li>");
}
}
?>

PHP if / else statements don't seem to work

I've created some if / else statements to get name from url like http://website.com/page.php?name=Love It seems to look good and trows no errors, but for some reason I am not getting data from the database. Basically it gets 'name' from url and checks of it is one of allowed categories, if yes it selects article from database that has st_category = to what user selected.
But than again for some reason it doesn't work.
Here is a snippet of code that I think causes the problem.
<?php
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if ($category = "Love") {
$st_category = "Love";
}
else if ($category = "Work") {
$st_category = "Work";
}
else if ($category = "Money") {
$st_category = "Money";
}
else if ($category = "Kids") {
$st_category = "Kids";
}
else if ($category = "Health") {
$st_category = "Health";
}
else if ($category = "Friends") {
$st_category = "Friends";
}
else if ($category = "Education") {
$st_category = "Education";
}
else if ($category = "Other") {
$st_category = "Other";
}
else {
header("Location: http://www.inelmo.com/");
exit;
}
$sql = mysql_query("SELECT * FROM stories WHERE showing = 1 AND st_category = '$st_category' ORDER BY st_date DESC LIMIT 10") or die (mysql_error("There was an error in connection"));
//And another stuff here to display article
?>
= is not the same as ==. In your if statements you are doing assignments not comparison.
if ($category = "Love") should be changed to if ($category == "Love") (or to if ($category === "Love") and so on...
That could be tidied up to much less code, much more maintainable, using in_array().
$categories = array(
'Love',
'Work',
'Money',
'Kids',
'Health',
'Friends',
'Education',
'Other'
);
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if (!in_array($category, $categories)) {
header("Location: http://www.inelmo.com/");
exit;
}
$sql = mysql_query("SELECT * FROM stories WHERE showing = 1 AND st_category = '$category' ORDER BY st_date DESC LIMIT 10") or die (mysql_error("There was an error in connection"));
And this also fixes the problem that #matino rightly pointed out, which is that you were assigning and not comparing.
You have used a single "=" in every if.
The correct syntax is with "==" or "===", like:
<?php
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if ($category == "Love") {
$st_category = "Love";
}
else if ($category == "Work") {
$st_category = "Work";
}
...
?>
Please use double equal sign like
if($foo=="foo1")
In your if-statements you used the = while you had to used the == sign. With the = you assign a value to a variable on the left, like $sum = 1 + 2; you wanted is $sum==3.

Categories