I want to toggle this option. When the option is true, I want to update it to false.
update_option('maintenance', true);
I've tried the following:
if(get_option('maintenance') == true) {
update_option('maintenance', false);
}
if(get_option('maintenance') == false) {
update_option('maintenance', true);
}
But for some reason this does not work, and is overcomplicated. I'm sure there's a better way to do this.
Does anyone got suggestions?
You are toggling it twice each time. If it was true, you are updating it to false, then reading it again, finding it to be false, then setting it to true.
Just do it once in a one liner as such (replace all your code):
update_option('maintenance', !get_option('maintenance'));
This says: Update it to the inverse of what it is right now.
What #zed writes is exactly what I'd propose too. But you can use a variable, or even 'normal' ifs, if you think it's a bit too complex to do it in one line.
With a variable inbetween. This allows you to more easily inspect the variable (for debugging), or to combine multiple values if you would need to.
$newvalue = !get_option('maintenance');
update_option('maintenance', $newvalue);
Or, if you want to have an if, use `else to prevent the second piece to be executed right away:
if(get_option('maintenance') == true) {
update_option('maintenance', false);
} else {
update_option('maintenance', true);
}
Needless to say that in this particular and simple case, zed's suggestion is the most straightforward.
Related
I'd like to know from a design POV whether changing the value of a constant per HTTP request is discouraged or perfectly ok.
I have a few constants that are defined at the start of a PHP script and they're used to figure out a particular context (what is the user trying to do at the time). The constants are never changed throughout the lifecycle of the script so they conform with the rules of constants and they work well. However, the values of these constants depends on what the user's doing. I'm wondering whether this is discouraged or perfectly acceptable in PHP.
<?php
// This function is only run once per HTTP request at the start
function new_paper() {
define('NEW_PAPER', 1);
define('NEW_VERSION', 0);
}
// This function is also only run once per HTTP request at the start
function new_paper_version() {
define('NEW_PAPER', 0);
define('NEW_VERSION', 1);
}
// This function is subsequently called by both functions above
function a_handler_of_sorts() {
if (NEW_PAPER) {
// Do something if it's a new paper
}
elseif (NEW_VERSION) {
// Do something if it's a new version
}
else {
}
}
In no circumstances are both new_paper() and new_paper_version() run in the same HTTP request.
A typical use case would be something like:
define('DEBUG', !empty($_GET['debug']));
if (DEBUG) echo 'some debugging statement';
Obviously don't do this only based on a query parameter, especially not in production, but you get the idea.
So, yes, setting constant values based on the request is fine. Whether this is the best thing to do in your particular case is questionable and I don't know. I'd really reserve it for "meta" values like debug flags, not for values which are essentially function parameters, inputs for your business logic. Do this sparingly.
"Constant values" which influence how every script works independently of the request would be something like config files or environment variables, e.g. containing database access credentials and such.
Constants should not change during the request but as you said yours don't so I think you're OK there.
They represent fixed things such as how many DB connections are allowed, the name of the application etc. If you're trying to use them to store the state of your application then you could consider doing something like:
<?php
define('STATE_PAPER', 0);
define('STATE_VERSION', 1);
define('STATE_INVALID', 2);
$applicationState = null;
if (someCheckForPaper() === true) {
$applicationState = NEW_PAPER;
} else if (someCheckForVersion() === true) {
$applicationState = NEW_VERSION;
} else {
$applicationState = STATE_INVALID;
}
// Save $applicationState somewhere... maybe session?
// Somewhere else
if ($applicationState === STATE_PAPER) {
...
}
I have couple of mysql queries in PHP and at the end of each query I did this
mysql_query(STRING) or die(mysql_error());
This is fine as far as I am in DEV environment but I dont want production users to see these errors. Any good Idea to remove this messages by just setting ON OFF.
Apart from the fact that you shouldn't use mysql_ as they're deprecated, you can simply make another function:
define('DEV', true);
function mysql_query_custom() {
$result = call_user_func_array('mysql_query', func_get_args());
if ($result === false) {
if (DEV) {
die(mysql_error());
}
}
return $result;
}
mysql_query_custom(STRING);
Lots of ways to do it. The most terse and most like you're doing now:
// do this once
$PRODUCTION = true;
// now use
mysql_query() or ($PRODUCTION ?: die(mysql_error()));
I caution though this is not a maintainable way to debug in the long term. There's a lot of good alternatives in this thread.
Whatever you do, develop a comprehensive error detection, logging, and response mechanism in your code. If you're using a framework, leverage its facilities.
Even easier you could just replace all die( with error_handle( or something else, and include this function:
function error_handle($err) {
die($err); // Comment this line out if you don't want the error to be displayed.
}
This is also great because you could extend the code to log errors etc in production. You could in addition define a $debug-variable somewhere in your global code if you are using Git or other version-control-systems.
Edit: I suggest replace all die( and not just die to avoid replaces where you don't want it, if you e.g use die in a sentence or something.
Then set a configuration variable called $DEBUG and just wrap your logic in a conditional if/else?
$DEBUG = true;
if ($DEBUG) {
mysql_query(STRING) or die(mysql_error());
}
else {
mysql_query(STRING);
}
const DEBUG = true;
function fail($message) { die (DEBUG ? $message : ''); }
...
use_mysql_query_even_though_it_sucks() or fail(mysql_error());
// seriously. Use mysqli.
Better still, use something like this:
if($_SERVER['SERVER_NAME'] != "dev.mydomain.com"){
ini_set("display_errors",0);
ini_set("log_errors", 1);
}
It saves you having to remember to disable the errors when you upload it to the production server.
The file_exists function returns TRUE on success but I think it would be more useful if instead of just TRUE, it returned the value of the passed $filename. Am I wrong to think that?
If the function was designed like that, we would be able to use:
$file = file_exists("dir/file.ext");
if($file)
{
// do something
}
... instead of the more complicated:
$file = "dir/file.ext";
$success = file_exists("dir/file.ext");
if($success)
{
// do something
}
I don't see why that would be an improvement. Consider that:
In practice you will put the file_exists call inside the condition, thus there will be no extra $success variable
The name file_exists predisposes the reader of the code that the function will return a yes/no answer (boolean value)
So in conclusion, I think that it would be a bad idea to change nothing but the type of the return value.
file_exists? is basically a yes or no question, so it gives a yes or no (boolean) answer.
Does the file exist? "Yes", it exists.
So it's aptly named for what it does
That would just make no sense. It could also return the file permissions, the file size, the last modified date, and still it would make as much sense as the filename. It is nothing but a check that gives a Boolean value, and you can make decisions based on it.
By the way, I don't get your examples, what could be easier than:
$file = "dir/file.ext";
if(file_exists($file))
{
// do something with $file
}
Or if you really need the return value later, you could do:
$file = "dir/file.ext";
if($success=file_exists($file))
{
// do something with $file
}
Well, nothing really prevents you from writing this function:
function get_filename_if_exists($fname) {
return (file_exists($fname) ? $fname : FALSE );
}
It is IMHO problematic as it has multiple return types, and doesn't give you any more information than you'd get from file_exists() - and therefore worse than pointless; but it is possible to shoot yourself in the foot like this, if you really want.
(this behavior is unlikely to get retrofitted into file_exists(), for the reasons stated here and in the other answers)
Then what would be the use of fopen?
$res = fopen("my/path.txt");
if ($res===FALSE) {
// File does not exists or an error while opening
}
If you specifically want to know whether a file exists then the file_exists function does what it is supposed to do.
if (FALSE===file_exists("my/path.txt")) {
// Stop here,
}
I'm probably overlooking something really obvious here.
Comments are in to help explain any library specific code.
public function areCookiesEnabled() {
$random = 'cx67ds';
// set cookie
cookie::set('test_cookie', $random);
// try and get cookie, if not set to false
$testCookie = cookie::get('test_cookie', false);
$cookiesAppend = '?cookies=false';
// were we able to get the cookie equal ?
$cookiesEnabled = ($testCookie === $random);
// if $_GET['cookies'] === false , etc try and remove $_GET portion
if ($this->input->get('cookies', false) === 'false' AND $cookiesEnabled) {
url::redirect(str_replace($cookiesAppend, '', url::current())); // redirect
return false;
}
// all else fails, add a $_GET[]
if ( ! $cookiesEnabled) {
url::redirect(url::current().$cookiesAppend);
}
return $cookiesEnabled;
}
Firstly, I wanted an easy way to check if cookies were enabled. I achieved this, but in the event of no cookies, there was an ugly ?cookies=false in the URL.
That was OK, but then if you reloaded the page and did have cookies enabled again, I wanted to redirect the user so it stripped off ?cookies=false in the URL (allowing the method to recheck and learn that cookies now are enabled.).
After $cookiesEnabled = ($testCookie === $random);, there are 4 cases:
$cookiesEnabled is true and $_GET['cookies'] === 'false' is true
$cookiesEnabled is true and $_GET['cookies'] === 'false' is false
$cookiesEnabled is false and $_GET['cookies'] === 'false' is true
$cookiesEnabled is false and $_GET['cookies'] === 'false' is false
Case 1 is handled by the first if block. The return statement is intended to handle cases 2 and 3; the second if block is intended to handle only case 4, but it catches both case 3 and 4. In case 3, the URL already has ?cookies=false, but since $cookiesEnabled is false, we redirect to add ?cookies=false, and cycle back into case 3.
You must be leaving something out since there is no loop in that code. If you meant that the browser is looping (e.g. getting continuous redirects), then I recommend installing the Live HTTP Headers extension to Firefox and watch what the browser and server are actually saying to each other. Putting in some logging code in the snippet above might also be instructive.
Update for comment:
Then I really recommend putting in print statements inside the ifs so you can see which ones you're going through and what the various values are. Clearly something is not getting set the way you thought it would be, so now you need to find out what it actually is.
One thing I have encountered several times is that the code itself is OK, but there is a .htaccess file that is working against you, so go double check any .htaccess files in any of the directories, starting from DOCUMENT_ROOT.
I need to do a PHP while loop, but only if a variable is true. And I can't really put the while loop in an "if" statement, which seems like the obvious thing to do, since the code block is huge and it would be ugly and confusing. Do I need to break out the code in the loop into a function, or is there an easier way to deal with this?
Here's the basic idea:
if(condition){
while(another_condition){
//huge block of code loops many times
}
} else {
// huge block of code runs once
}
I want the huge block of code to execute regardless of the state of the condition variable-- but only to execute once if condition is false, and execute for as long as another_condition is true if condition is true.
The following code doesn't work, but gives an idea of what I want to accomplish:
if(condition){ while(another_condition){ }
// huge block of code
if (condition){ } } // closes the while loop-- obviously throws an error though!
thanks in advance.
If I understood your problem correctly, you could use the do ... while() structure:
do
{
// your code
} while(condition);
This will execute // your code once regardless of any factor, and then only for the second iteration and those after will it check for the condition.
For readability if your huge block of code can be separated in several specialized functions, do it. It will surely pay out if you need to debug later.
I would put the huge block of code in a function so it can be used again without having duplicate code.
function hugeBlockOfCode() {
// Huge block of code.
}
while (condition && another_condition) {
hugeBlockOfCode();
}
if (!condition) {
// Run code once.
hugeBlockOfCode();
}
or
do {
hugeBlockOfCode();
} while (another_condition);
Is this kind of what you are looking for?
while (condition && another_condition) {
// large block of code
}
if (!condition) {
// do something else
}