Can I set variables inside if-construct? In general, where is it allowed to set variables?
function set_login_session ( $passhash )
{
$_SESSION['login']['logged_in'] = 1;
if ( ERROR ) return false;
}
// Does it set the Session variable?
if ( set_login_session ( $passhash ) === false)
return false;
Short answer
Yes
Long answer
If this script has called start_session() earlier (or the session.auto_start configuration flag is set) then session variable can be set anywhere by using superglobal $_SESSION array.
Yes you can and it's allowed. But the thing is that what if the IF does not run and you incorrectly handle that situation.
So usually I initialize my big vars in the widest scope of the function and temporary vars is ok to be set inside somethings.
You should be aware though in your case. That you are initializing a global variable.
You haven't specified what the ERROR variable is. If it being true indicates an error, set_login_session can be essentially reduced to
$_SESSION['login']['logged_in'] = 1;
return !ERROR;
and the outer code to
return set_login_session( $passhash );
There's no need to do such explicit bool value comparisons.
And yes, it's perfectly valid to set variables in functions, but make sure the variable is set always, no matter of the code path taken, so there are no uninitialized/unexistant variables used in your code. Otherwise you're asking for trouble or, at least, big fat warnings in script output.
The $_SESSION superglobal should be present if there's a session started. If there was no ['login']['logged_in'] in it, that's fine.
Related
I have a script running permanently from command line on a web server.
There is a loop checking new stuff in DB.
To save some load I need to add a condition not to check the DB if there is no reason.
When the change occurs I need immediate reaction, however it might happen that there is no change for a few hours.
And yes, it is not possible to do it in the webpage_script.php :)
The idea is to use some kind or a SUPERGLOBAL variable and in webpage_script.php save TRUE to that variable and then check it in that condition in permanently_running_script_on_the_same_server.php.
However I didn't find any variable that can be used for that reason... when I try to use session_id('whateverisinhereblahblab') - to share the session, the webpage_script.php will not get loaded as the session is probably continually occupied...
webpage_script.php
$the_shared_variable['whatever'] === FALSE;
if ($something_happens){
$the_shared_variable['whatever'] === TRUE;
}
permanently_running_script_on_the_same_server.php
while (true) {
if($the_shared_variable['whatever'] === TRUE){
}
}
I am trying to encapsulate isset() and empty() in a function.
It worked fine on my home development sever (apache 2.4.3, PHP 5.2.17 under WinXP). When I ported it to my university Linux machine running Fedora, I got a notice about undefined index.
I checked my php.ini on my home computer, and error reporting is set to all. I put error_reporting(E_ALL); in my PHP script to try duplicate the error. It didn't happen.
Question 1: Why am I not getting the notice on my home development computer?
Here is my function:
<?php
function there($s) {
if (! isset($s)) {
return false;
}
if (empty($s)) {
return false;
}
return true;
}
?>
Here I test if a session variable exists:
if (! there($_SESSION['u'])) {
$_SESSION['u'] = new User();
}
I switched my function so that I test empty() before I test isset() thinking this will avoid getting the notice. I haven't had a chance yet to test this at school.
Question 2: Does empty() in general avoid giving a notice if the variable is undefined, or not set?
Question 3: Can I use my there() function to do this, or will I get the notice just by passing the undefined or unset parameter?
isset and empty are not functions, they are language constructs. As such, they can get away with such things as reading the literal variable name instead of trying to access the value. Any function you define can't do that.
With that in mind, there is no need to test for both. empty is a superset of isset, so you only really need to check for empty.
Your function is almost equivalent to !empty:
if (empty($_SESSION['u'])) {
$_SESSION['u'] = new User();
}
The only difference is: your wrapper function will complain if it's passed a variable that doesn't exist - whereas, as a language construct empty will not (and neither will isset).
Your sub-questions
Why am I not getting the notice on my home development computer?
Probably because you've got error reporting turned off.
Does empty() in general avoid giving a notice if the variable is undefined, or not set?
Yes.
Can I use my there() function to do this, or will I get the notice just by passing the undefined or unset parameter?
You will get notices about undefined variables.
As a way of proving #Kolink 's fine reply really, something which I had not realised ...
echo '<form action="" method=POST>
<input type=text value="" name="string" />
<input type=text value=0 name="int" />
<input type=submit />
</form>';
if( empty($_POST['string'] ) ){
var_dump( $_POST['string']) ;
}
if( empty($_POST['int'] ) ){
var_dump( $_POST['int']) ;
}
if( empty($_POST['something'] ) ){
echo 'something was not set, but you cannot var_dump it without a warning';
}
I realize this is an old thread, and it already has an accepted answer. So, I will not answer the questions again here. But for completeness sake and in the hope that it may help others I am sharing something I use.
Take a look at the following code:
<?php
echo var_dump($_SESSION['something']);
This will give you:
PHP Notice: Undefined variable: _SESSION in - on line 2
NULL
But if you do this:
<?php
echo var_dump(mycheck($_SESSION['something']));
function mycheck( &$var ){ // Note the & so we are passing by reference
return $var;
}
You will get:
NULL
This is because internally the $var variable will get created the instant the function is called. But since the $_SESSION['something'] does not exist, the $var is getting set to null which is then returned. Voila, notice gone. But be aware that the variable $_SESSION['something'] has now been created internally, even though isset($_SESSION['something']) will still return false because isset determines 'if a variable is set and is not NULL'.
PHP manual for isset: http://php.net/manual/en/function.isset.php
I'm writing a small extenstion for PHP. Is there way to know at runtime, the name of the script file (e.g.: test.php) that is running? Maybe some global or environment variables?
You can fetch $_SERVER['PHP_SELF'] (or any other $_SERVER variable if you need to), like this:
// This code makes sure $_SERVER has been initialized
if (!zend_hash_exists(&EG(symbol_table), "_SERVER", 8)) {
zend_auto_global* auto_global;
if (zend_hash_find(CG(auto_globals), "_SERVER", 8, (void **)&auto_global) != FAILURE) {
auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
}
}
// This fetches $_SERVER['PHP_SELF']
zval** arr;
char* script_name;
if (zend_hash_find(&EG(symbol_table), "_SERVER", 8, (void**)&arr) != FAILURE) {
HashTable* ht = Z_ARRVAL_P(*arr);
zval** val;
if (zend_hash_find(ht, "PHP_SELF", 9, (void**)&val) != FAILURE) {
script_name = Z_STRVAL_PP(val);
}
}
The script_name variable will contain the name of the script.
In case you're wondering, the first block, that initializes $_SERVER, is necessary because some SAPIs (e.g.: the Apache handler) will initialize $_SERVER only when the user script accesses it (just-in-time). Without that block of code, if you try to read $_SERVER['PHP_SELF'] before the script tried accessing $_SERVER, you'd end up with an empty value.
Obviously, you should add error handling in the above code in case anything fails, so that you don't invoke undefined behavior when trying to access script_name.
Try the variable $argv. The first item in that array contains the name of the script.
EDIT
For C the function
int main takes two paramters argc and argv (see here). The same still holds as above. i.e. argv[0] is the command name.
I tried this script, but it didn't work for me. The first statement:
if (!zend_hash_exists(&EG(symbol_table), "_SERVER", 8)
fails. I'm running PHP from the CLI. However, I did set variables through my PHP script and when I use print_r($_SERVER) through the same script I get a full array of values.
I think the negation in before the zend_hash_exists() is not necessary in this context.
Does anyone know how isset and empty is interpreted by the translator, or how the translator treats undefined variables?
To expand on my question, I have the below code in my include file:
define('USER_AUTH', !empty($_SESSION['username']) && !empty($_SESSION['status'])); //user is verified
define('ACC_IS_PENDING', $_SESSION['status'] == '0');//checks to see if user status is pending which has a status of 0
USER_AUTH is used as a quick hand to check if user is authenticated. ACC_IS_PENDING is used as a quick hand for when the account status is pending. However, PHP gives me a notice to advise me that $_SESSION['status'] in my second line of code is undefined. I know that it is undefined, but I haven't used it yet! How dare you tell me what I already know. LoL
However, when I trick the code with the below:
define('USER_AUTH', !isempty($_SESSION['username']) && !isempty($_SESSION['status']));
define('ACC_IS_PENDING', $_SESSION['status'] == '0');
Where isempty() is a custom made function that will always return FALSE. Then no notice!
Alternatively, if I use the below code:
define('USER_AUTH', notempty($_SESSION['username']) && notempty($_SESSION['status']));
define('ACC_IS_PENDING', $_SESSION['status'] == '0');
Where notempty() always return TRUE, then again no notice.
Am I right in saying that the translator checks that the variable has been tested once, and that if the test resulted in true, then the translator sees this as the variable has been defined?
If this was the case, then what about isset and empty? They both seem to give me notices no matter if the evaluation is true or false.
define('USER_AUTH', isset($_SESSION['username']) && isset($_SESSION['status']));
define('ACC_IS_PENDING', $_SESSION['status'] == '0');
and
define('USER_AUTH', empty($_SESSION['username']) && empty($_SESSION['status']));
define('ACC_IS_PENDING', $_SESSION['status'] == '0');
Apologies for the long winded question. This seems trivial, but it would be nice to have a quick defined constant without having to get notices! Any help in explanation or a better solution for such trivial task would be appreciated, thanks!
PHP complains because the index 'status' is not defined in the array. You would need to write
!isset($_SESSION['status']) || empty($_SESSION['status']
When you "trick" the code as described, PHP will never try to access the non-existing array index, which is why you don't get any notice.
In the fourth code example (with isset), you are still accessing the non-existing array index in the second line of code, so I suspect that's why there's still a notice.
a) If you wants to use $_SESSION['status'], you have to check first that the variable is not empty ( see http://www.php.net/manual/fr/function.isset.php for more details) :
if (isset($_SESSION['status'])) {
// here the value exists and can be used
Do something...
} else {
// here the value does not exist and cannot be used
}
b) I believe that
empty($_SESSION['username']) && !empty($_SESSION['status'])
is not constant : it varies from one run to the other. You may want to use
$user_is_logged = empty($_SESSION['username']) && !empty($_SESSION['status']);
and use the variable $user_is_logged instead of a constant. See this section http://www.php.net/manual/fr/language.constants.php for a speek about constants.
Is there a way to prevent a code-block or a function within a code from running more than once even if I re-execute (or reload) the PHP file?
I mean, can I restrict someone from executing a php script more than once? I can't seem to find the way to do this.
Yes, you can use a $_SESSION variable to determine if the code has been executed. The session variable will be set until the user closes their browser. If you want to extend it further than that, you can set a cookie. Please see the following links for more details.
Session Variables
Cookies
If you are using sessions, then you can set a flag in the user's session array after the code has executed:
function doSomething(){
if (empty($_SESSION['completed'])){
//Do stuff here if it has not been executed.
}
$_SESSION['completed'] = TRUE;
}
You should also check the sesison variable to see if the task has been executed previously. This assumes that the user can accept a session cookie.
I have an app that does that.
What we did was create a table in the db called version, and stored a version number in there. When the script is ran, it compared the version number in the database with that in the php script. And perform whatever it needs to "upgrade" it to the new version, and then updates the version number in the database.
Of couse, if the version table does not exist, the code will create it and mark it as storing version zero.
Just put a counter in the function. If the counter is greater that 0, then don't do anything. The counter variable should be static so it "remembered" across multiple calls.
function sample() {
static $call_counter = 0;
if ( $call_counter>0 ) {
return;
}
...
$call_counter++;
}
As for making sure a file is only executed once, just use "include_once()" instead of "include()".