In PHP, is there a fastest/proper way of ordering if/else if statements? For some reason, in my head, I like to think that the first if statement should be the anticipated "most popular" met condition, followed by the 2nd, etc. But, does it really matter? Is there is a speed or processing time affected if the 2nd condition is the most popular choice (meaning the system must always read the first condition)
Ex:
if ("This is the most chosen condition" == $conditions)
{
}
else if ("This is the second most chosen condition" == $conditions)
{
}
else if ("This is the third most chosen condition" == $conditions)
{
}
Speedwise, it won't make a difference... Not a noticeable one... The order does count (it's sensibly faster putting the most used condition first), however it doesn't count for much. Choose the order which provides the best readability to those modifying and maintaining your code. They'll thank you later.
EDIT:
Also, consider this:
My function will return with a 25% chance.
I prefer writing:
if ( $chance25 )
return;
else if ( $chance40 )
doSomething();
else if ( $chance30 )
doSomethingElse();
else if ( $chance5 )
doSomethingElse2();
rather than:
if ( $chance40 )
doSomething();
else if ( $chance30 )
doSomethingElse();
else if ( $chance25 )
return;
else if ( $chance5 )
doSomethingElse2();
It's just nicer ordering by functionality...
EDIT2:
One size does not fit all. If your conditions are methods returning booleans, order them by how fast the method runs combined with the chance. I guess there's not really one good answer, you need to adapt. For example, if my $chance25 was replaced by a method reallySlowMethodDoNotUseUnlessYouReallyHaveTo(), I would surely check it last. :D
I agree with what #Luchian. Your primary focus should be readability of the code
You should profile your application before you optimize your code. How you order your condition is highly dependent on how much time is spent in "each if condition".
Let's take an example:
Execution time - %ge called
Case 1 - 50 seconds (80% of time)
Case 2 - 10 seconds (15% of time)
Case 3 - 1 second (5% of time)
100 runs:
Order A (In the order of "how often a condition is executed")
Case 1, Case 2, Case 3 = (80 * 50) + (15 * 60) + (5 * 61) = 5205 seconds
Order B (In the order of "execution times")
Case 3, Case 2, Case 1 = (5 * 1) + (15 * 11) + (80 * 61) = 5050 seconds
Your application is probably a web application (since this is most popular usage of PHP), so most of the time it waits for external resources like database, file access or webservices. Unless you're doing it in a loop that's executed thousands of times, or in a recursive method, it won't really matter which condition goes first. Strive for code that's easy to read.
depends on your preference of operation
you might want condition two to activate rather than condition one and vice versa
$value=25;
if ($value > 20)
{
$value=200;
}
else if ($value < 50)
{
$value=5;
}
If you are simply checking the value of $conditions against multiple possible text values, instead of doing if/else, use switch.
switch ($conditions) {
case "This is the most chosen condition":
// do stuff
break;
case "This is the second most chosen condition":
// do stuff
break;
case "This is the third most chosen condition":
// do stuff
break;
default:
// do stuff
}
If the most common condition is first, it will not have to evaluate any other cases and will therefore be faster, but the difference is going to be so extremely small that it really isn't going to matter one way or another. Usually you should go for readability over speed.
Related
I can't figure out how to efficiently get SQL data for a Room/Rates/Dates=Amount...
First I load all the "RateData" for a date range with a PDO select. There are many rows, for many rooms, each with many rates... maybe, or maybe it is all empty except a couple of Amounts. It needs to display $0 for missing dates, so next...
I load the Rooms with PDO and loop through them, and for each room I load the Rates with PDO and loop through them (not a ton of rates per room, and not a ton of rooms, but possibly a very long date-range).
So then I loop through the date range and add $0 to the giant UI grid of Amounts by Rate/Date, nested under each Room. I have to do this anyway, as I also have a ton of logic on what to display in the parent Room row that averages the Rates and such.
So what I need to do is instead of using $0, I need to see if the Room/Rate/Date exists in RateData...
$RateAmount = 0;
$RateDataRow = $RateData.filter('Room=1 && Rate=1 && Date=2022-10-01');
If ($RateDataRow exists) {$RateAmount = $RateDataRow['Amount']}
How to I write the above sudocode in PHP?
The only alternative I can think of would be to do 1000's of SQL calls to populate the grid... which seems bad. Maybe it is not that bad though if PDO caches and doesn't actually query the DB for each grid cell. Please advise. Thanks.
I tried this:
$currcost = 0;
//if $ratedata exists for currdate + currrate + currroom
function ratematch($row)
{if (($row['RoomType_Code']=$currrate)
&& ($row['RatePlan_Code']=$currroom)
&& ($row[ 'Rate_Date']=$currdate->format("Y-m-d")))
{return 1;}
else {return 0;}
}
$match = array_filter($ratedata, 'ratematch');
if (!empty($match)) {$currcost = $match['Rate_Amount'];}
But got an error about redeclaring a function. I have to redeclare it because it is in a loop of currdate under a loop of currrate under a loop of currroom (about 1000 cells).
I made it work, I just have to manually loop through the RateData...
//Get Amount from DB
$currcost = 0;
foreach($ratedata as $datarow)
{if (($datarow['RoomType_Code']==$currroom)
&& ($datarow['RatePlan_Code']==$currrate)
&& ($datarow[ 'Rate_Date']==$currdate->format("Y-m-d")))
{$currcost = $datarow['Rate_Amount'];
break;
}
}
If anyone knows a more efficient way to "query" a previous query without a trip to the SQL server, please post about it. Looping through the fetchAll 1000's times seems bad, but not as bad as doing 1000's of WHERE queries on the SQL Server.
I suppose I could make a 3-dimentional array of $0, then just loop through the RateData once to update that array, and finally loop through the 3-dimentional array to do my other calculations (average rate per room per week sat-sun). Sounds hard though.
im currently stuck with an issue. Ive built a basic "team-work platform" in which you can set tasks in a to-do list. I've implemented the functionality that can mark a task as complete by setting the value of done to 1
I need to be able to check if all of the tasks in the list are set to done, and if so echo something. My code checks for the value 1, but it settles with a single entry being set to 1. But i need it to check if all tasks have the value 1 and if they do it should echo something.
$res3 = mysql_query("SELECT * FROM tasks WHERE tasks.planet_id=1 AND team_id=$teamid AND done=1")
or die(mysql_error());
if ($res3 && mysql_num_rows($res3) > 0)
{
echo 'Complete!';
}
else
{
echo 'Not done yet!';
}
I'll try to give you an example of how i want it to work: Lets say i have 10 tasks in the table. I want the code to recognise when all 10 of these tasks are marked as done with the value 1 set. And then echo "all your tasks are complete". So it needs to somehow loop through all the entries in the table and check if they are all set to 1, and when they are all set to 1 it echoes something.
Please help! :)
Assuming that done is an integer can can be either 0 or 1, you could do something like:
SELECT COUNT(*) total, SUM(done) totalDone FROM tasks WHERE tasks.planet_id=1 AND team_id=$teamid;
And then test in your PHP code that total == totalDone.
Alternatively, if you really want to only get a row out of the database when total == totalDone (as your comments seem to suggest), you could write something like this:
SELECT * FROM (SELECT COUNT(*) total, SUM(done) totalDone FROM tasks WHERE tasks.planet_id=1 AND team_id=$teamid) _X WHERE _X.total = _X.totalDone;
But that just adds a lot of extra complexity for no real gain, and I wouldn't recommend doing it that way.
Note that you should not use mysql_* functions in new code, and should instead use either mysqli or PDO. mysql_* is not recommended for new code.
Also, you should be careful with using variables directly in query strings. That can easily lead to sql injection vulnerabilities. Instead, use parameterized queries with mysqli or PDO.
The answer to 'all tasks done' is best done with the question of how many tasks where done <> 1.
I.e.
SELECT count(*) as 'incomplete'
FROM tasks
WHERE tasks.planet_id=1
AND team_id=$teamid and done <> 1;
Therefore you're able to use the code:
if($res3) {
$incompleteQueryResult = mysql_fetch_assoc($res3);
if ($incompleteQueryResult['incomplete'] > 0) {
echo "Not done yet";
} else {
echo "Complete!";
}
} else {
echo "Could not retrieve completed tasks";
}
If you still need to retrieve both the number of completed tasks as well as the number of incomplete, you could modify the query similar to the following.
SELECT
IF(done = 1, 'complete', 'incomplete') as status,
COUNT(*) AS 'number_in_status'
FROM tasks
WHERE tasks.planet_id=1
AND team_id=$teamid
GROUP BY done
And you'll need to modify how you retrieve it in the PHP as well if so.
If you need to know all of the above, then either execute two queries (one as an aggregate/summary and one as the full data set) or keep track of it in a variable. e.g.
$numIncompleteTasks = 0;
while($row = mysql_fetch_assoc($res3)) {
$numIncompleteTasks += ! (bool) $row['done'];
}
// you now know how many tasks are incomplete.
You could modify this code to track both complete and incomplete.
Deprecation notice.
I'd recommend reviewing your use of mysql_* functions - PHP deprecated and removed these functions in recent versions of PHP.
The answer from jbafford will not work in certains conditions.
Let's imagine we have only three possible values: 0,1 and 2. In the case of 0+1+2, the algorithm will say that COUNT = SUM, when in reality, we have a {0,1,2} and not {1,1,1}.
Why do I ask? Because I'm looking for a way in MYSQL to check if it is all ones, and I ruled out COUNT=SUM or in my case, taking the average, as I have this exception in my data.
A way to handle this exception is to add a COUNT DISTINCT. If COUNT DISTINCT=1 and COUNT=SUM, then the dataset is only 1s.
I have to do some php work for a student group I am part at in school. Clients make use of our provided services, and every ten requests (which are made online) they make of our service, they are required to do a check-in.
When we receive the request, we get all the info (id, special requests, notes, etc) from our database. I've added the form that indicates if a check-in is required no problem...no issues with the front end. It's just a matter of the backend that I'm unsure of due to my lack of experience in php and mysql.
Here is an example:
echo "<td>Half Size</td>";
echo "<td>". ($value["halfsize"] == 1 ? "Yes" : "No") . "<br/>";
echo "</td>";
echo "</tr><tr>";
If clients want half size for the request, they fill it out...when we receive it, we see whether that want a full size of half size.
Here is what I want to do with pseudocode, but since I'm lacking in SQL knowledge, I'm not sure what to do.
echo "<td>Check-in Required</td>";
**//Check count of rows (any table)
//If divisible by 10 (%10), return "Yes", else "No"**
echo "</td>";
echo "</tr><tr>";
What I need to figure out is how to check the number of rows, if that can be divisible by 10 then a check-in is required.
Hopefully that was clear enough and you understand what I'm asking, because reading it back it still sounds a bit hard to follow. I'll be happy to clarify if you have any questions. Thank you!
I'm not sure I completely get what you're doing, but I think what you need is the modulo operator (%).
if(count($rows) % 10 == 0){ // divisible by 10
}
else{ //not divisible by 10
}
PHP supports modulo which gets the remainder.
$divisor = 10;
$rowCount = 4; // put your method here that returns the number of rows
$result = $rowCount % $divisor == 0 ? "Yes" : "No";
PHP Modulo
You can alter the database table for clients, add one more column to store the count value.
Add: a column, say, counter --> integer to clients table.
Change your code to do:
Every time client makes a request, query select * from clients where id =
take out counter value and check if (counter%10 == 0).
if(counter%10 == 0)
{
request to check in;
}
accept request;
then update clients counter column (increment by 1)
Updating table will remember requests from previous sessions too. But if you want to check number of requests in only current session, then you just have to add a counter variable in your PHP code and check for %10 before every request.
This was just a pseudo-code. If its tenth request, you request check in, and then accept request and increment clients counter.
else you just accept request and increment counter.
(Sorry for writing just pseudo code, instead of actual code. But that is one way to do it. I may have misunderstood the question, but if this solves your problem, I'm happy.)
I just see this artice
i need to know what's is best berformance in this cases
if statment in query
SELECT *,if( status = 1 , "active" ,"unactive") as status_val FROM comments
VS
<?php
$x = mysql_query("SELECT * FROM comments");
while( $res = mysql_fetch_assoc( $x ) ){
if( $x['status'] == 1 ){
$status_val = 'active';
}else{
$status_val = 'unactive';
}
}
?>
Cut 10 from string
SELECT * , SUBSTR(comment, 0, 10) as min_comment FROM comments
VS
<?php
$x = mysql_query("SELECT * FROM comments");
while( $res = mysql_fetch_assoc( $x ) ){
$min_comment = substr( $x['comment'],0,10 ) ;
}
?>
etc ????? and When i use MYSQL functions or PHP functions ?
It depends.
From a network point of view, in the first VS, PHP wins and in the second VS, MYSQL wins. That's because you send less data via socket. And thus the script becomes faster.
Here is a nice description of your question:
Doing calculations in MySQL vs PHP
In case of the second example the speed issue can be significant.
First of all you do not know how big are your comments, so in case of
$x = mysql_query("SELECT * FROM comments");
while( $res = mysql_fetch_assoc( $x ) ){
$min_comment = substr( $x['comment'],0,10 ) ;
}
you ask your server to return you everything (here I mean the whole length of the comment) and this can be significant. Multiplying by the number of rows in the table it can be quite big size of data, which you have to transfer between php and sql. In the second case this SELECT * , SUBSTR(comment, 0, 10) as min_comment FROM comments
this will be already done on the server and will not require additional memory.
In case of the first example, I think it is also better to do it on sql side, because you will still need to do additional loop afterwards. Apart from this, people who will be reading your code might be confused why exactly do you need that code.
In that case, using MySQL functions keeps you from looping in PHP and saves you a lot of code.
In other cases they have no alternative : for instance, when you use them in the WHERE part.
In terms of performance, the difference is trivial in most cases : use the simplest solution.
Only answer: Measure it! You have two working solutions and want to achieve the best execution time.
I'd say it all depends on the systems on either end and current load. Typically DB servers are more stout than desktop machines and it would be faster to do the whole thing on the DB side rather than split it and use PHP partly.
I have a script that updates the information of various livestream channels while they are active. I want to check if $max_viewers is greater than $current_viewers.
In this case I do not need to take action, however if $current_viewers is larger I want to update the max_viewers field in the database.
I have tried several ways and methods from research, but my PHP is limited and self taught and I think I am misunderstanding the outcome of my statements.
I have tried:
$current_viewers > $max_viewers
$current_viewers >= $max_viewers
But these seem to always update the max_viewer count, or never if reversed. Hence I think I am misunderstanding how these work and what they return.
You should have something like:
$max_viewers = 4;
$current_viewers = 2;
if ($current_viewers > $max_viewers) {
// Current viewers has exceeded the maximum
echo 'exceeded';
} else {
// Current viewers is either less than or equal to the maximum
echo 'not exceeded';
}
In the above example, not exceeded would be shown. For your example, you probably want to replace echo 'exceeded'; with your call to update the database record.