I downloaded some files from github (from this page, if matters ).
This is for php login stuff, and everything works, but I cannot understand how it is possible.
Here is the typical top part of my pages
require('inc/config.php'); // db credentials and connect
require('inc/password.php'); // class password, hashing etc
require('inc/user.php'); // class user
one of the first function in user.php is the following:
...
private function get_user_hash($username){
$_SESSION["uname"] = $username; // echo of this variable works
...
So, the question is - where the value of $username is coming from?
Because there is no such a variable in the preceding files (config.php and password.php).
This is its first occurrence in entire script workflow and how it is possible that it has some value?
find from where get_user_hash() is called and their will be some argument in it. It is not necessary that it should be named $username.
for ex-
$user="some user name";
get_user_hash($user);
$username is an argument of the get_user_hash function, which isn't executed until some code elsewhere in your script. Although it appears first, it isn't run first, and the code that calls this function will pass it a value for $username.
Related
/* I cant change this part (plugin core files) */
function test123(){
$secret = "hoho"; //i want to get this variable
do_action('custom'); //developer didnt pass any variable here
}
/* I cant change this part (plugin core files) */
add_action('custom',function() use ( $secret ) {
echo $secret; //didn't work
});
test123();
How to get $secret value? because the developer didnt pass any variable when using do_action
You can use like this:
function test123() {
$secret = 'hoho';
do_action( 'custom', $secret );
}
add_action('custom',function( $secret ) {
echo $secret;
});
test123();
Hope this works!
Your variable is out of scope
function test123(){
$secret = "hoho"; //i want to get this variable
do_action('custom'); //developer didnt pass any variable here
} //end of function scoope
add_action('custom',function() use ( $secret ) { //<-- $secret is undefined
echo $secret; //didn't work
});
There are several ways to fix this, but I cant really say how with so little context.
You could move add_action into the function
You could make $secret global etc.
modify the do action call to send it
make it a constant
make it global (keyword)
make it a property of class that maintains it's state (static etc.)
And so on, it depends how dynamic that value needs to be. Maybe that value is a static string, maybe it only exists in your function etc.
How many times you call that function may affect defining it inside, (add/remove action).
You can test this easly:
ini_set('display_errors', 1);
error_reporting(E_ALL);
add_action('custom',function() use ( $secret ) {
echo gettype($secret); //didn't work
});
Expected output
<br />
<b>Notice</b>: Undefined variable: secret in <b>...</b> on line <b>...</b><br />
NULL
UPDATE
I can't change test123()
I sort of figured that, which is why I only gave general solutions. In any case if it's just a plain old local variable within that function, there is no way to "get" its value outside of it short of editing the function in some way. This is a PHP thing (a language thing), not a WordPress thing. It has to do with how scope is handled within the function.
It may be possible to get that data some other way, that depends what it is. For example is it stored in the DB? You may be able to access that way etc... I can't say how to do that without knowing more about what it is.
It's not impossible to edit the original right. Obviously this is not ideal, but it's possible. Some tips are never edit the original. If it's part of a theme try to do it though a child theme. If it's plugin, or child theme doesn't work for it then you can duplicate it and change it's name.
I should mention depending how it's licensed this may be against that license.
You never want to edit the original because if you update the "plugin/theme" you may completely lose your changes. If it's in a copy you can comment around you changes like this:
/* START CUSTOM CODE */
And when you update the original "plugin/theme" you can easily find where your changes where (by searching for that comment text) and work them into the new version of the "plugin/theme". Which may be as simple as coping all the files but the one you changed (if nothing changed in it) etc.
As I said this isn't ideal, but it will work. It just depends how badly you want to implement it and how willing you are to maintain it.
Please see also
https://www.php.net/manual/en/language.variables.scope.php
within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope
I have perhaps the most perplexing issue I've ever had with PHP. Please see the following code:
public $profile;
public $account;
function __construct(){
if(isset($_SESSION['uid'])){
$this->$profile = $_SESSION['user_profile'];
$this->$account = $_SESSION['user_account'];
echo "<script> alert('".$this->$profile->forename."'); </script>"; //Shows nothing
}else{
unset($_SESSION['user_profile']);
unset($_SESSION['user_account']);
}
}
For some reason, it seems that either $this->$profile will be written or $this->$account will be written, but only if it is the last one. In the situation above, if I moved the profile line to be after the account line, it would be written. However, in this case it is not.
Both $_SESSION variables are objects retrieved from an SQL statement, and their assignments are valid as accessing either of the variables directly (eg. $_SESSION['user_profile']->forename) works fine.
Any ideas? Thank you.
You are using variable variables, but your code looks like you are trying to access a member variable.
Replace this:
$this->$profile
$this->$account
With this
$this->profile
$this->account
I'm creating a website and somewhere in the code I need to query for a user attribute (ex:account state) and in the same row I have the reason, case is account state is "suspended".
I'm trying to minimize the requests to the database, so I created a function to verify account state.
function getAccountState($userid,$reason){}
What I am trying to do is if account state is "suspended" I would change the $reason to "the database reason".
I've already done that but if I change the $reason inside the function, outside the function it will not change.
I searched for "php pointers" on google but I think there is not such thing.
Is there a way to do this? Other way I'll just make another database request...
You could of course pass the variable by reference but as you don't seem to need it, I would just return it from the function:
function getAccountState($userid){
// your code
return $reason;
}
and call it like:
$reason = getAccountState($userid);
If you want to stay your code as it is now, you could pass the variable by reference:
function getAccountState($userid,&$reason){}
^ like so
You could consider passing it in by reference. Or perhaps just changing the function to return the correct information.
In the definition of functions you can tell that $reason argument is passed by reference, not value. To do so, use & in front of variable:
function getAccountState($userid,& $reason){}
You are looking for references, in PHP terminology, not pointers.
They work this way :
function getAccountState($userid, &$reason){ // Notice the &
$reason = "database locked"; // Use it as a regular variable
}
getAccountState(12345, $reason); // Here, it is written as a regular variable, but it is a ref.
echo $reason; // echoes "database locked"
I've read quite a few posts that are very similar to the question I'm about to ask, but I just wanted to be sure that there wasn't a more sophisticated way to do this. Any feedback is greatly appreciated.
I want to create a mechanism to check whether or not a logged-in user has access to the php script that is currently being called. If so, the script will continue on; if not, the script just fails out using something like die('you have no access').
I came up with two ways of accomplishing this:
(please assume my session stuff is coded/working fine - i.e. I call session_start(), set up the session vars properly and etc)
Define a global variable first, then check the global variable in a required header file. For example:
Content of current_executing_script.php:
// the role the logged in user must have to continue on
$roleNeedToAccessThisFile = 'r';
require 'checkRole.php''
Content of checkRole.php:
if ($_SESSION['user_role'] != $roleNeedToAccessThisFile) die('no access for you');
Define a function within the header file and call the function immediately after including/requiring it:
Content of checkRole.php:
function checkRole($roleTheUserNeedsToAccessTheFile) {
return ($_SESSION['user_role'] == $roleTheUserNeedsToAccessTheFile);
}
Content of current_executing_script.php:
require 'checkRole.php';
checkRole('r') or die('no access for you');
I'm wondering if there is a way to basically just pass a parameter to checkRole.php as part of the include or require construct?
Thanks in advance.
There isn't a way to pass parameters to include or require.
However the code that is included joins the program flow at the point where you include it, so it will inherit any variables that are in scope. So for example if you set $myflag=true immediately before the include, your included code will be able to check what $myflag is set to.
That said, I wouldn't suggest using that technique. Far better for your include file to contain functions (or a class) rather than code that gets run straight off. If you've included a file containing functions then you can call your functions with whatever parameters you want at any point in your program. It's much more flexible, and generally a better programming technique.
Hope that helps.
This could be a useful workaround.
Register a function in say functions.php:
function get_template_partial($relative_include_path, $scoped_parameters)
{
$base_partial_directory = get_template_directory() . '/partials/';
return include $base_partial_directory . $relative_include_path;
}
Use the $scoped_parameters in the partial /partials/role-check.php:
$args = [
'id' => $scoped_parameters['user_id']
];
// A few moments later...
return [
'role_required' => 'admin'
];
Altogether now...
$partial_return_data = get_template_partial('role-check.php', [
'user_id' => 328
]);
echo $partial_return_data['role_required']; // admin
The only thing I can remember with this is if you're using an IDE it might complain that $scoped_parameters is undefined but it's not a third world issue I suppose.
You could have the required file return an anonymous function, and then call it immediately after.
//required.php
$test = function($param)
{
//do stuff
}
return $test
//main.php
$testing = require 'required.php';
$testing($arg);
In the past, many people have disagreed with this approach. But I think it is a matter of opinion.
You can't pass _GET or _POST param via a require() or include() , but you can you first set a _SESSION key/value and pull it on the other side.
I have a class called User with static function loginRequired(), which returns false if the user is logged in and true if the user is logged out. It also appends an error to an error class that I created that tells the person using the site that they must be logged in to view the content.
The idea is that for the top of each function that would require the user to be logged in, we write this code:
if(User::loginRequired()) return;
Which will output the error and immediately return from the function. I would rather do this, however:
User::loginRequired();
And return from the calling function inside of the loginRequired function... but because loginRequired() is in a separate class in a separate file, this won't work. Is it possible to return from the function that calls loginRequired(), within loginRequired()?
Thanks.
I'm not sure you can do exactly what you want, however, you might want to look at using exceptions. This would allow you to throw an exception in the User::loginRequired function and catch it at some higher level. You could also look at using the exit() PHP function.
The way I've seen a number of open source apps handle this is by having a require_login() function which performs a redirect should the user not be logged in.
Is the content WITHIN the actual page dynamic? What I mean is, do I need to authenticate just to see anything other than the login page, or do I see some things when I'm logged in and other things when I'm not, etc? Because if the entire directory/section of the server is behind a log-in screen you could just add something to the .htaccess file of the directory that redirects anyone not logged in, etc.
On the other hand, you could have that file holding the login status included into whatever page/script that the user is viewing, with the included file returning just the login status instead of its entire contents. This is covered under includes under Example 5, "include() and the return() statement". If you did this, you could use a ternary condition like:
$logged_in = (include('userlogin.php') == TRUE) ? TRUE : FALSE;
And then in each protected function have something like:
global $logged_in;
You are still stuck with an IF clause wrapping the entire function, but at least you have the login status. If you wanted to get rid of the IF inside of the function, you could always make calling the function conditional. Like:
$content = ($logged_in == TRUE) ? some_function() : redirect_User();
Then again, I just started learning this stuff 2 months ago and still don't understand classes and objects, so I could be way off base.
OT: I would consider changing the method's name to isLoggedIn() if your described purpose is the only one. A method called loginRequired() would be better off protecting confidential content.