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!
Related
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.
Please help me with my problem.. can i call once Mysql Select Query from different function from two different function too... Sorry i don't know how to explain.. but below my sample what i want to archive..
I want use single query for 2 function.. so maybe i have to write code like below?
function sqlSelect ($db, $id, $id2) {
$sql = mysqli_query($db, "SELECT * FROM xxx WHERE id='$id' AND id2='$id2'");
$row = mysqli_num_rows($sql);
$field = mysqli_fetch_object($sql);
return $row;
}
but how to use $field inside 2 diff function?
function aaa ($a,$b,$c) {
if($row >= 1){
//Do something with $a $b and $c
//$reget field with $field['column'];
$field['column']; //???
}
return $result;
}
function bbb ($a,$b,$c) {
if($row >= 1){
//Do something with $a $b and $c
//get field with $field['column'];
$field['column']; //???
}
}
what i do right now is
function aaa ($db,$id,$id2,$a,$b,$c) {
$sql = mysqli_query($db, "SELECT * FROM xxx WHERE id='$id' AND id2='$id2'");
$row = mysqli_num_rows($sql);
$field = mysqli_fetch_object($sql);
if($row >= 1){
//Do something with $a $b and $c
//get field with $field['column'];
}
}
function bbb ($db,$id,$id2,$a,$b,$c) {
$sql = mysqli_query($db, "SELECT * FROM xxx WHERE id='$id' AND id2='$id2'");
$row = mysqli_num_rows($sql);
$field = mysqli_fetch_object($sql);
if($row >= 1){
//Do something with $a $b and $c
//get field with $field['column'];
}
}
But if i use what i write and code right now i think it's have to call same query twice. I cannot use query outside function so i have to write query on each function but i want to just write query once and can use in two different function..
Sorry for stupid explanation..
Thank you for help
One implementation can be as follow by passing an array as argument,
<?php
$arg['db']="database";
$arg['tabe']="table";
$arg['search']['id1']="id1";
$arg['search']['id2']="id2";
$arg['do_something']['a']="a";
$arg['do_something']['b']="b";
$arg['do_something']['c']="c";
function searchAndDoSomethingAndReturnResult($arg)
{
$return = NULL;
$query="SELECT * FROM ".$arg['table'];
$flag=false;
foreach($arg['search'] as $key=>$value)
{
if($flag)
$query.=" AND ";
else
$flag=true;
$query.= $key." = '".$value."' ";
}
$row = mysqli_num_rows($query);
$field = mysqli_fetch_object($query);
if($row >= 1)
{
foreach($arg['do_something'] as $job=>$value)
{
// $return[] = "some result"
// do something
}
}
return $return;
}
?>
let me know if this solve your problem
You can either pass in the $field variable as a function argument
<?
$field = ...;
function sql1($field,...,...){
// Use $field here
}
function sql2($field,...,...){
// Use $field here
}
?>
Alternatively, you can use the global keyword to access variables from outside of the function
<?
$field = ...;
function sql1(){
global $field;
// Use $field here
}
function sql2(){
global $field;
// Use $field here
}
?>
is it possible to simplify this code? I am trying to put all cases in a switch but always d break in the first case and i need all echo's in the html. What is possible? Thank you!
$resultservices = mysqli_query($connecDB,"SELECT * FROM clients WHERE id_client = $id_client");
while($rowservice = mysqli_fetch_array($resultservices)){
$php = (int)$rowservice['php'];
$java = (int)$rowservice['java'];
$ruby = (int)$rowservice['ruby'];
$node = (int)$rowservice['node'];
}
// Values can be "1" or "0". Example: php:1, java:1, ruby:0, node:1
switch ($php) {
case 0: break;
case 1: echo "<li>php</li>"; break;
}
switch ($java) {
case 0: break;
case 1: echo "<li>java</li>"; break;
}
switch ($ruby) {
case 0: break;
case 1: echo "<li>ruby</li>"; break;
}
switch ($node) {
case 0: break;
case 1: echo "<li>node</li>"; break;
}
While I'm not sure what you're trying to do, how about:
$resultservices = mysqli_query($connecDB,"SELECT * FROM clients WHERE id_client = $id_client");
while($rowservice = mysqli_fetch_array($resultservices)){
$service[1] = (int)$rowservice['1'];
$service[2] = (int)$rowservice['1'];
$service[3] = (int)$rowservice['0'];
$service[4] = (int)$rowservice['1'];
}
foreach ($service as $k=>$v) {
if ($v) {
echo "<li>service".$k."</li>";
}
}
[edit] I see we've got some new variables.
while($rowservice = mysqli_fetch_array($resultservices)){
$service['php'] = (int)$rowservice['php'];
$service['java'] = (int)$rowservice['java'];
$service['ruby'] = (int)$rowservice['ruby'];
$service['node'] = (int)$rowservice['node'];
}
foreach ($service as $k=>$v) {
if ($v) {
echo "<li>".$k."</li>";
}
}
Although really, all you're doing is outputting the last row of your MySQL, so you could also do
$resultservices = mysqli_query($connecDB,"SELECT * FROM clients WHERE id_client = '".mysqli_real_escape_string($connecDB, $id_client)."' ORDER BY id DESC LIMIT 1");
while($rowservice = mysqli_fetch_array($resultservices)){
if ($rowservice['php']) {
echo "<li>php</li>"
}
if ($rowservice['java']) {
echo "<li>java</li>"
}
if ($rowservice['ruby']) {
echo "<li>ruby</li>"
}
if ($rowservice['node']) {
echo "<li>node</li>"
}
}
Given that 3 of your four service values are going to have the SAME value, you could eliminate 2 of the switches and end up with the same results:
$service01 = (int)$rowservice['1'];
$service02 = (int)$rowservice['1']; // identical to service01
$service03 = (int)$rowservice['0'];
$service04 = (int)$rowservice['1']; // identical to service01
meaning you could have:
switch($service01) {
case 0: break;
case 1: echo "<li>service01, 02, and 04</li>"; break;
}
And then, assuming these values will never be anything but true/false 0/1 values, you could eliminate the switches entirely and go with a conventional if:
if ($service01) {
echo "service 01, 02 and 04";
}
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;
}
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.