Using the $_COOKIE var to keep important data - php

I'm creating a wordpress plugin. All the functions I'm writing are 'hooked' into certain wordpress events. This means I have a hard time creating variables that I need to use in several functions.
For example:
There's two functions that are hooked in somewhere:
Display_if_facebook_connected() {
if (Check_facebook_connected()) { return 'Yes, connected!' }
return '';
}
Display_if_facebook_connected() {
if (!Check_facebook_connected()) { return 'No, not connected!' }
return '';
}
And they both run a very heavy function:
Check_facebook_connected() { // some heavy facebook connect stuff, return bool }
I'm basically trying to avoid having the heavy function run twice, since it will have the same result.
In this case, would it be safe to do $_COOKIE['check_facebook_connected'] = true; and then read that variable in the Display_if_facebook_connected()?
By safe I mean that the user can't see or change the value. Since the cookie is never actually set, I think/hope it just disappears at the end of the php code.
I wouldn't be surprised if there is some better way, or better var, to do this with, but with my limited understanding of php I can't think of any.
UPDATE:
About sessions: I don't need the values to persist over multiple pages, just one page load. Since Wordpress doesn't use sessions I see no reason to change it.
I experimented a bit and the problem persists:
All of the following code is in the main file of my wordpress plugin. The way I understand it, the plugin file is 'included' at every request, so all code is run everytime I refresh my testpost.
Firstly I create the variable:
$myplugin_connected = false;
Then I hook my function in the right place:
add_shortcode( 'myplugin_notconnected', 'myplugin_notconnected_func' );
This basically hooks the myplugin_notconnected_func() function into the [myplugin_notconnected] shortcode. (A shortcode is text in a wordpress post, some id between [ ]-brackets. Wordpress loads the code associated with the shortcode whenever it appears.)
Here's the myplugin_notconnected_func():
function myplugin_notconnected_func( $atts, $content = null ) {
echo '<p>connected: ' . var_export($myplugin_connected, true) . '</p>';
return '$contents';
}
And here's the result:
connected: NULL
This is why I was trying to use $_COOKIE variables because at least they persist over the whole php instance. I apologize for lack of coherence, I'm learning as I go and I definitely appreciate the help!

Display_if_facebook_connected() {
$result = Check_facebook_connected();
if (!$result) { return 'No, unconnected!' } else { return 'Yes, connected!' }
}
$connected = Display_if_facebook_connected();

Scope
Referring to the updated part of your question:
Defining
$myplugin_connected = false;
and getting NULL as result on a subsequent
var_export($myplugin_connected, true)
could mean, that you either defined $myplugin_connected outside global scope (e.g. in a function instead of main), or you have defined in global scope, but have some unset($myplugin_connected) somewhere before the var_export. In both cases the return value of var_export would be NULL.
In your case I believe the former is more probably. You could use:
$GLOBALS['myplugin_connected'] = false;
and
var_export($GLOBALS['myplugin_connected'], true)
to have the connection state (which already has been determined once by your "heavy" function before) available in your shortcode handler.
Cookie
To answer your origin question:
In this case, would it be safe to do
$_COOKIE['check_facebook_connected'] = true; and then read that
variable in the Display_if_facebook_connected()?
Well, $_COOKIE is a server-side superglobal, so yes, as long as you never actually send/set that cookie on response, the user wouldn't see, nor could change it.
Personally, using $_COOKIE to save a state which is only valid for a single page load, feels just plain wrong to me.
I'd recommend to use at least $GLOBALS over $_COOKIE - or maybe even better use a static variable instead of a superglobal in this case - e.g. something like this:
function isConnected() {
static $bConnected = null;
if ($bConnected === null)
$bConnected = Check_facebook_connected();
return $bConnected;
}
But that's always in the eye of the beholder^^

session_start();
Check_facebook_connected()
{
if(isset($_SESSION["is_facebook_connected"])) return ($_SESSION["is_facebook_connected"] === true);
// if we get here we haven't checked the facebook connection status, so do it
...
}

Related

Is there a way to automatically unset a variable after accessing in php?

I am trying to display success or failure messages using session variables. I want them to be unset once the session variable once it is accessed. Is there some kind of PHP configuration where I can do it automatically with out writing any extra code?
I want something like this:
$_SESSION['message'] = 'print success';
echo $_SESSION['message'];
unset($_SESSION['message'])// I want this to be done automatically.
Could somebody help me with this?
You can write your own session handler and have a custom method for that. I strongly suggest Illuminate/Session, though, and use it's flash feature which keeps items in flash bag for the duration of one request only.
class Session {
public function read($str){
return isset($_SESSION[$str]) ? $this->deleteAndRet($str) : null;
}
protected function deleteAndRet($str){
$ret = $_SESSION[$str];
unset($_SESSION[$str]);
return $ret;
}
}

$_GLOBAL variables set in config file are not being read correctly

this might be a stupid question but I'm stuck here at this silly problem for the part 2 hours.
I have this function which checks if a particular config file's variable are not empty.
Here's the function :-
include 'inc.config.php';
function not_valid_settings()
{
if((empty($_GLOBAL['id'])) || (empty($_GLOBAL['username'])) || empty($_GLOBAL['password']))
{
return true;
}
else
{
return false;
}
}
Here's the config inc.config.php file:
$_GLOBAL=array();
$_GLOBAL['id'] = "asas";
$_GLOBAL['username'] = "asas";
$_GLOBAL['password'] = 'as';
Function Calling
include 'inc/inc.functions.php';
if(not_valid_settings())
{
echo "Please enter correct entries in inc/inc.config.php";
exit();
}
For some reason, I always get the Please enter correct details. Even if my $_GLOBAL['username']='';.
What wrong am I doing here?
The problem is that $_GLOBAL appears to be a PHP superglobal, but it is not -- there is no such superglobal in PHP. As a result, this variable is not immediately accessible everywhere. If you add global $_GLOBAL; as the first line if your function, your code should work:
function not_valid_settings()
{
global $_GLOBAL;
Perhaps you meant to use $GLOBALS instead, though I would strongly advise against it. Use a name like $SETTINGS instead, and don't forget to use global $SETTINGS; in functions where you need to access the settings object.
In general, you should avoid choosing variable names that start with $_ unless they are PHP superglobals; this prefix implies a superglobal, while your variable is not. This will create unnecessary confusion.
$GLOBALS is what you mean to use, though this is not a good practice.
http://php.net/manual/en/reserved.variables.globals.php

PHP - Run function after while loop ends

This may not be the best solution to my problem, but I'm interested to know anyway.
Is it possible to defer a function or piece of code till after a while loop ends? I assumed this happened anyway if it was placed below, but that doesn't seem to be the case.
What I'm trying to accomplish is inside the while loop some session data is being saved (if it does not exist, which is the condition). When the loop finally ends, since the session data is set, the code below which relies on the session data can be executed.
This is in a CodeIgniter 3.0 system, so it is using the session driver:
// Uses a helper function session_isset (see below) to check if the session data is set, and if at least one of the supplied data variables is null then try to set it
while(!session_isset(array('instance_id','instance_prefix'))) {
$this->session->set_userdata('instance_id', $instance->instance_id);
$this->session->set_userdata('instance_prefix', $instance->instance_prefix);
}
// The get_managers() function, which ultimately calls a model function, relies on the set session data to get a table prefix which is prepended to all relevant database queries
// This should ideally only be allowed to run once the session data has been confirmed as set
if($manager = $this->manager->get_managers(array($manager_id))[0]) {
$manager->instance_id = $instance->instance_id;
$manager->instance_prefix = $instance->instance_prefix;
echo json_encode($manager);
}
function session_isset($data) {
$ci =& get_instance();
foreach ($data as $value) {
if(is_null($ci->session->userdata($value))) return FALSE;
}
return TRUE;
}
So just to reiterate, is there a way to defer code until a while loop has ended, similar to a callback?
Also, is there perhaps a better way to ensure session data is set before running functions that depend on it?

How to "globalize" PHP variables?

I have a page named ChangeApprovalInfo.php - It has a function called Row_Rendered as follows;
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$RecordOwner = $this->RequestUser->CurrentValue;
echo $RecordOwner;
}
Echoing $RecordOwner gets me the data I will need for a sql query on another page....
I have another page called ChangeApprovalEdit.php - This page has
<?php include_once "ChangeApprovalinfo.php" ?>
at the top of the file.
ChangeApprovalEdit.php has a function where I need the $RecordOwner variable as defined in ChangedApprovalInfo.php
If I add "echo $RecordOwner" on the ChangeApprovalEdit.php page, I get an error saying it's an unknown variable. My understanding is that I need to "make it global" or some such business. I know very little about PHP and the pages I am editing are long and complex. (to me, at least)
What do I need to do? I know that the information I have provided might not be enough to answer the question. I don't know enough to even know exactly what I need to ask. If more information is needed, I will edit and follow up.
pastebin of the files
ChangeApprovalInfo.php = http://pastebin.com/bSRM1wwN
ChangeApprovalEdit.php = http://pastebin.com/AStG9pqb
EDIT:
Changing Row_Rendered to this seems to be more effective. I'm having trouble seeing WHERE I can later echo this variable... but I'm getting somewhere with this...
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
Don't echo variables from functions, which just outputs them to the standard output. return them from the function so you can use the value elsewhere as well.
function Row_Rendered() {
$RecordOwner = $this->RequestUser->CurrentValue;
return $RecordOwner;
}
Then instead of
$obj->Row_Rendered();
use
echo $obj->Row_Rendered();
and if you want to use the value elsewhere, use
$value = $obj->Row_Rendered();
You can do a couple of things:
First, you can return $RecordOwner from the function, and store its value in a variable. This method is usually preferred.
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$RecordOwner = $this->RequestUser->CurrentValue;
echo $RecordOwner;
return $RecordOwner;
}
// Store it in a variable when calling the function.
$RecordOwner = Row_Rendered();
Or, you can make it global inside the function:
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
echo $GLOBALS['RecordOwner'];
}
You can use the $GLOBALS superglobals array, like this:
function Row_Rendered() {
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
However, you should not do that. Instead, refactor your application so that the view in ChangeApprovalinfo.php just contains a function, which is then called with the appropriate parameters.
EDIT: Chaning Row_Rendered to this seems to be more effective. I'm having trouble seeing WHERE I can later echo this variable... but I'm getting somewhere with this...
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
I feel compelled to write another answer to this update. Let me demonstrate the use of globals as seen from outside that function:
$obj->Row_Rendered();
$obj->foobar();
echo $GLOBALS['RecordOwner'];
Quick, what will be echoed and where does that value come from? Well, it depends on what $obj-foobar() does. Maybe it changes the global variable. Maybe it doesn't. Who knows if the variable has been set at all? How would you trace back what happened exactly without adding a debug line after every single function call?
And that's just three lines of code. Imagine that in an application of any complexity.
Now, the same thing if I return the value from Row_Rendered:
$owner = $obj->Row_Rendered();
$obj->foobar();
echo $owner;
If the Row_Rendered method is behaving as it should (returning the owner), this code is very predictable. If you do not follow this pattern, you'll have a hell of a time getting anything done when the application grows to any halfway complex size.
Set the variable as global from within the function
$my_global_var = "old value";
function doing_stuff(){
global $my_global_var; //this will use the global variable instead of creating a local one
$my_global_var = "new value";
}
echo $my_global_var;//returns "new value"

Is it possible to pass an unset variable to a function or otherwise validate forms without isset()?

I've got a project that passes JSON between the frontend and the backend. So, the frontend PHP would generate the statement { "command" : "getuser", "parameters" : { "userid" : 1 } } and send it to the backend. The backend then executes
if ($command == 'getuser') {
validate($parameters['userid']);
if ($this->valid) { <<get the user>> }
}
Validate checks the variable and sets $this->valid. It creates an error message if necessary. I want to create an error message in case the front end passes in { "command" : "getuser", "parameters" : "" }. In this case, $parameters['userid'] is never set, and validate() will complain that it was passed an unset variable.
I've come up with two solutions. The first solution is to set $parameters['userid'] = "unset" before loading in the JSON, and then check for it in the validator. The other solution is to use
if (isset($parameters['userid'])) {
validate($parameters['userid']);
}
else {
echo("Error"); }
It'd be nice if validate() could figure out on its own whether or not the variable is there. Is there a more elegant way I should be doing things?
In short, no. The error happens as, rather than after, validate() is called so there is no way for it to intercept that.
It sounds like a better solution would be to have a validateUser() function that is passed in the whole $parameters variable then does the check you're looking for against the 'user_id'. This allows you to to further separate your concerns (validation, versus response).
If you want this style of code, you could pass arg to function by reference
If not, try to use this validate($parameters, 'userid');
You would have to pass $parameters into validate and let it check if userid was there and if not create the error message.

Categories