To start off I'm sorry for the noob question. Learning as I go but I'm having issues with this and couldn't fine the right search.
What I'm trying to accomplish:
I'm currently trying to combine strings of text and numbers for a ban list.
For example a person is banned for 40 minutes, In the SQL database it is stored as the value 40.That is fine when displayed in a table however issues arise when a person is banned for 10080 minutes (1 week)
What I have:
$sql = "SELECT name, authid, name, length FROM sb_ctbans";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
if ($row["length"] < '60'){
$row["length"] . "Minutes" == $ban['length'];
echo $ban['length'];
} else {
$row["length"] . "Undefined length" == $ban['length'];
}
echo "<tr>"."<td>" . $row["name"] ."</td>" . "<td>" . $row["authid"] ."</td>" . "<td>" . $ban['length'] . "</td>" ."</tr>";
}
Expected output: 2 Minutes
Actual output:
Cheers for any help.
Edit:
After changing from:
$row["length"] . "Minutes" == $ban['length'];
To:
` $ban['length'] = $row.['length'] . 'Minutes';`
I am now reviving the output ArrayArray Minutes
You have a couple of problems here. You fixed the first wrong line, but it's again wrong at $row["length"] . "Undefined length" == $ban['length'];. Also, you're checking if the $row['length'] is less than the STRING '60', not the number 60, which could be causing errors. Finally, as others have said, storing the number of minutes to ban is sure to cause problems eventually. Instead, when the ban is first established, calculate the time it will be when the ban expires and store that instead. When you check it, calculate how long til the time you stored. Otherwise as time passes, you must update every ban record every minute or they become inaccurate.
Related
Trying my first simplexml loop
I have got to this:
foreach ($xml->GetCapabilityResponse->Srvs->Srv as $rows)
{
echo $xml->GetCapabilityResponse->Srvs->Srv->GlobalProductCode . " ";
echo $xml->GetCapabilityResponse->Srvs->Srv->MrkSrv->LocalProductCode . " " ;
echo $xml->GetCapabilityResponse->Srvs->Srv->MrkSrv->ProductShortName . "<br>";
}
It returns the correct amount of rows '6' but all 6 are the same data from the first row, how do I adjust to show the 6 different rows own data, it's not limited to 6, could be 12 or more etc
thanks
Mazz
so if $rows is an array, you should rely on the item you are processing
$row->GlobalProductCode . " ";
On a website I am creating, I have the store 'open hours' in three locations on one page. One in the header, one in the body and one in the footer. I am trying to pull these in with PHP for simplicity when updating. I wrote an array:
<?php
$UniqID = uniqid(day);
$day1 = 'Mon-Fri: 9:00a-5:00p';
$day2 = 'Saturday: 9:00a-1:00p';
$day3 = 'Sunday: CLOSED';
$days = array(
"1" => "<span id=" . $UniqID . " class='editable-text'>" . $day1 . "</span>",
"2" => "<span id=" . $UniqID . " class='editable-text'>" . $day2 . "</span>",
"3" => "<span id=" . $UniqID . " class='editable-text'>" . $day3 . "</span>",<
);
?>
and then am calling it on the page as such:
<span>Address | Phone <br/> Our Hours: <?php echo $days[1] ?>, <?php echo $days[2] ?>, <?php echo $days[3] ?></span>
The problem I have is that I need a unique ID EVERY time these are called to the page, and obviously this gives a unique ID for 1, 2 and 3 - but if I call that same thing on the page 2 or 3 times... well, then all three of the first instances have the same ID and so on.
So to sum it all up, I want to create an array that stores the hours like above - and be able to call them to the page however many times necessary but always get a unique ID wherever they show up.
Any help is appreciated, I can't process this anymore!
What you can do is declare the unique ID at the very top, like you have with $uniqueID=X
Then, every time you insert $uniqueID into the DOM, increment it as well. So:
<?php echo "<span id='".$uniqueID++."'>STUFF IN SPAN</span>"; ?>
If $uniqueID is an int, the "++" will increment it, thus maintaining a unique one for each time it's inserted.
Instead of declaring one unique ID at the top, declare it once for every <span>. It is also possible to declare it in a loop with a variable variable, like this:
$day1 = 'Mon-Fri: 9:00a-5:00p';
$day2 = 'Saturday: 9:00a-1:00p';
$day3 = 'Sunday: CLOSED';
for ($i = 1; $i <= 3; $i++) {
$days[$i] = "<span id='uid" . uniqid() . "' class='editable-text'>" . ${'day'.$i} . "</span>";
}
This will produce something like:
Array
(
[1] => <span id='uid53350c2f730eb' class='editable-text'>Mon-Fri: 9:00a-5:00p</span>
[2] => <span id='uid53350c2f73156' class='editable-text'>Saturday: 9:00a-1:00p</span>
[3] => <span id='uid53350c2f731d0' class='editable-text'>Sunday: CLOSED</span>
)
Note that the id attribute cannot start with a number (or else it's not valid HTML), so you should probably put some letters before the uniqid() like I did (with uid). Also, you were missing quotes around the id value.
I do not believe this to be a duplicate, I've looked for it, but really had no clue what to call it exactly.
I want to know why a loop that is ten times larger than another loop doesn't take ten times longer to run.
I was doing some testing to try and figure out how to make my website faster and more reactive, so I was using microtime() before and after functions. On my website, I'm not sure how to pull lists of table rows with certain attributes out without going through the entire table, and I wanted to know if this was what was slowing me down.
So using the following loop:
echo microtime(), "<br>";
echo microtime(), "<br>";
session_start();
$connection = mysqli_connect("localhost", "root", "", "") or die(mysqli_connection_error());;
echo microtime(), "<br>";
echo microtime(), "<br>";
$x=1000;
$messagequery = mysqli_query($connection, "SELECT * FROM users WHERE ID='$x'");
while(!$messagequery or mysqli_num_rows($messagequery) == 0) {
echo('a');
$x--;
$messagequery = mysqli_query($connection, "SELECT * FROM users WHERE ID='$x'");
}
echo "<br>";
echo microtime(), "<br>";
echo microtime(), "<br>";
I got the following output and similar outputs:
0.14463300 1376367329
0.14464400 1376367329
0.15548900 1376367330
0.15550000 1376367330 < these two
[a's omitted, for readability]
0.33229800 1376367330 < these two
0.33230700 1376367330
~18-20 microseconds, not that bad, nobody will notice that. So I wondered what would happen as my website grew. What would happen if I had 10 times as many (10,000) table rows to search through?
0.11086600 1376367692
0.11087600 1376367692
0.11582100 1376367693
0.11583600 1376367693
[lots of a's]
0.96294500 1376367694
0.96295500 1376367694
~83-88 microseconds. Why isn't it 180-200 microseconds? Does it take time to start and stop a loop or something?
UPDATE: To see if it was the mySQL adding variables, I tested it without the mySQL:
echo microtime(), "<br>";
echo microtime(), "<br>";
session_start();
$connection = mysqli_connect("localhost", "root", "W2072a", "triiline1") or die(mysqli_connection_error());;
echo microtime(), "<br>";
echo microtime(), "<br>";
$x=1000000;
while($x > 10) {
echo('a');
$x--;
}
echo "<br>";
echo microtime(), "<br>";
echo microtime(), "<br>";
Now it appears that at one million, it takes ~100 milliseconds(right?) and at ten million it takes ~480 milliseconds. So, my question still stands. Why do larger loops move more quickly? It's not important, I'm not planning my entire website design based off of this, but I am interested.
Normally, loops will scale linearly.
Possible bug: If you haven't already done so, consider what might happen if there was no record with id 900.
I would strongly recommend using MySQL to do your filtration work for you via WHERE clauses rather than sorting thru information this way. It's not really scalable.
Frankly, the line
while(!$messagequery or mysqli_num_rows($messagequery) == 0) {
doesn't make sense to me. $messagequery will be false if a failure occurs, and you want the loop to run as long as mysqli_num_rows($messagequery) is NOT equal to zero, I think. However, that's not what the above code does.
If mysqli_num_rows($messagequery) is equal to zero, the loop will continue.
If mysqli_num_rows($messagequery) is NOT equal to zero, the loop will stop.
See operator precedence: http://php.net/manual/en/language.operators.precedence.php
Does that help answer your question?
If you are really interested in this, you might take a look at the op codes that PHP creates. The Vulcan Logic Disassembler (VLD) might help you with this.
However, this shouldn't be your problem if you are only interested in your site speed. You won't have speed benefits/drawbacks just because of the loops themselves, but on the things they actually loop on (MySQL queries, arrays, ...).
Compare this small test script:
<pre>
<?php
$small_loop = 3000;
$big_loop = $small_loop*$small_loop;
$start = microtime(true);
// Big loop
for ($i = 0; $i < $big_loop; $i++) {
; // do nothing
}
echo "Big loop took " . (microtime(true) - $start) . " seconds\n";
$start = microtime(true);
// Small loops
for ($i = 0; $i < $small_loop; $i++) {
for ($j = 0; $j < $small_loop; $j++) {
;
}
}
echo"Small loops took " . (microtime(true) - $start) . " seconds\n";
?>
</pre>
The output for me was:
Big loop took 0.59838700294495 seconds
Small loops took 0.592453956604 seconds
As you can see the difference in 1 loop vs. 3000 loops isn't really significant.
I am outputting a table of rates. Each rate period has a Daily Rate and a Weekly rate, but the rate PERIODS remain the same.
So I am attempting to change the background color after ever TWO sets. So basically, the table will show:
Date 1 - Weekly Rate
Date 1 - Daily Rate
<change bg color>
Date 2 - Weekly Rate
Date 2 - Daily Rate
<change bg color back to original>
At the moment, I have two styles set up for background colors in my stylesheet. And the code i am using is giving me ALTERNATING rows. I just cannot see why it's changing every one, instead of every OTHER one!
To do this, I MUST compare one Date1 to Date2. ( I cannot make it change every two iterations, for reasons I do not want to go into.)
Here is my code so far inside the while loop. Help! And thank you.
if ($previous !== $row[datefrom])
{
$thecolor = "bg1";
}
else
{
$thecolor = "bg2";
}
echo "<tr class=\"".$thecolor."\"> \n";
echo "<td>" . $row[datefrom] . " - " . $row[dateto]. "</td> \n";
echo "<td>" . str_replace(" 3-5","",$row[Ratetype]) . "</td> \n";
echo "<td>$" . $row[Rate] . "</td> \n";
echo "</tr> \n";
$previous = $row[datefrom];
You also have to remember last used background color, without it background will change only for first entry in group. Example:
$use_original_bg = TRUE;
for(/*...*/){
if ($previous !== $row[datefrom]) {
$use_original_bg = !$use_original_bg;
}
$thecolor = $use_original_bg?"bg1":"bg2";
}
We can see the reason for this very easy if we set up the states of current date and prev for each iteration:
1. date1, prev = nothing => bg1
2. date1, prev = date1 => bg2
3. date2, prev = date1 => bg1
4. date2, prev = date2 => bg2
One easy way to solve this problem is to also take into account the state of the background. I'll leave that up to you to give it some thinking.
On a website I have a number of small PHP scripts to automate changes to the text of the site, depending on a figure that's calculated from a MySQL database. The site is for a fundraising group, and the text in question on the home page gives the total amount raised.
The amount raised is pulled from the database and rounded to the nearest thousand. This is the PHP I use to round the figure and find the last three digits of the total:
$query4 = mysql_query("SELECT SUM(amountraised) AS full_total FROM fundraisingtotal;");
$result4 = mysql_fetch_array($query4);
$fulltotal = $result4["full_total"];
$num = $fulltotal + 30000;
$ftotalr = round($num,-3);
$roundnum = round($num);
$string = $roundnum;
$length = strlen($string);
$characters = 3;
$start = $length - $characters;
$string = substr($string , $start ,$characters);
$figure = $string;
(£30,000 is the amount that had been raised by the previous fundraising team from when the project first started, which is why I've added 30000 to $fulltotal for the $num variable)
Currently the text reads:
the bookstall and other fundraising events have raised more than £<? echo number_format($ftotalr); ?>
I've just realised though that because the PHP is rounding to the nearest thousand, if the total's for example £39,200 and it's rounded to £40,000, to say it's more than £40,000 is incorrect, and in that case I'd need it to say 'almost £40,000' or something similar. I obviously need to replace the 'more than' with a variable.
Obviously I need to test whether the last three digits of the total are nearer to 0 or 1000, so that if the total was for example £39,2000, the text would read 'just over', if it was between £39,250 and £39,400 something like 'over', between £39,400 and £39,700 something like 'well over', and between £39,700 and £39,999, 'almost.'
I've managed to get the last three digits of the total as a variable, and I think I need some sort of an if/else/elseif code block (not sure if that would be the right approach, or whether to use case/break), and obviously I'm going to have to check whether the figure meets each of the criteria, but I can't figure out how to do that. Could anyone suggest what would be the best way to do this please?
Instead of nested if else blocks, you could have a function that takes in the dollar amount and inside the function throw the variable in a switch case statement and at a particular case return the correct echo'd text.
Switch cases provide readability over several if else statements. If you need coIde examples, let me know.
Update:
Performing comparisons on integers only, switch case is the best bet. When comparing conditions that result in a boolean value, using if else is what you need.
I had took your code and switched the case to be if else and here is what it looks like with an example output:
function qualifier($figure) {
if ($figure < 249) return "just over";
elseif ($figure < 399) return "over";
elseif ($figure < 699) return "well over";
elseif ($figure < 999) return "almost";
else return "No number entered";
}
echo "We are " . qualifier(250) . " our goal!";
// outputs: "We are over our goal!"
The simplest and most elegant solution imho would be, like Lizard pointed out, to floor the value and always say "over". You could even make exception for the first-1000 problem and floor anything below that to the next 100 or so, something like...
<?
function getFlooredText($amount) {
if($amount < 1000) {
return floor($amount/100)*100;
} else {
return floor($amount/1000)*1000;
}
}
echo "We've raised over £" . getFlooredText(455) . "\n"; // 400
echo "We've raised over £" . getFlooredText(1455) . "\n"; // 1000
echo "We've raised over £" . getFlooredText(38800) . "\n"; // 38000
?>
If you absolutely don't want that you could always do a four or five layer if-sandwich, it would be the easiest approach towards the idea you described but maybe not the prettiest. Something like this, if I understood where you were going with it...
<?
function getRoundedText($amount) {
$n = substr($amount, -3);
if($n < 250) {
return "just over £" . round($amount, -3);
} elseif($n < 500) {
return "well over £" . round($amount, -3);
} elseif($n < 750) {
return "close to £" . round($amount, -3);
} elseif($n < 1000) {
return "almost £" . round($amount, -3);
}
}
echo "We've raised " . getRoundedText(38200) . "\n";
echo "We've raised " . getRoundedText(38400) . "\n";
echo "We've raised " . getRoundedText(38700) . "\n";
echo "We've raised " . getRoundedText(38900) . "\n";
?>
Hope that helps.
You might not need to change the text... take a look at the floor function http://php.net/manual/en/function.floor.php
It will always round down, so you can still say 'more than'.
I would use "approximately" to cover all cases!