Reputation: 3981
Lets say you have an program like this:
$info = array(
'username'=>'jeff',
'password'=>'kay'
);
function authenticate($user, $pass) {
if($user == $info['username'] && $pass == $info['password']) {
return true;
}
return false;
}
This code won't work because the $info
array isn't in authenticate()
's scope. You would have to pass $info
as a parameter of authenticate()
like so:
function authenticate($info, $user, $pass) { // ... }
This feels wrong to me.
I could certainly add global $info;
inside of authenticate
but that feels even more wrong. What is best practice for structuring a PHP program to avoid scope issues like this? You don't see functions requiring you to pass in the 'global' object in modern code it seems like. How do I avoid unnecessary function arguments?
Upvotes: 0
Views: 163
Reputation: 28269
Most people do not notice, but this is actually a very good question.
Many other languages (especially functional ones) have lexical scope. With PHP 5.3 lambdas you get that capability, but only within lambdas. Let me show you what I mean:
$info = array(
'username'=>'jeff',
'password'=>'kay'
);
$authenticate = function ($user, $pass) use ($info) {
if ($user == $info['username'] && $pass == $info['password']) {
return true;
}
return false;
}
if ($authenticate($_POST['username'], $_POST['password'])) {
// use authenticated
}
With the use
you can import variables from the outer scope, but it only works for anonymous functions. It really depends on what kind of style and framework you're coding in/with.
If you don't want to define these inline (since you must assign them to variables, which is not so nice), I'd suggest you go with your instincts, so pass $info
into authenticate
or make $info
an instance variable of the class that authenticate
belongs to.
Upvotes: 2
Reputation: 5869
Edit in reply to comment:
Assuming the 'global' object is an actual object (as in an instantiation of a class) then you need only provide it with a static function that returns the necessary data. Said function will be accessible from anywhere including inside your authentication function.
Upvotes: 0
Reputation: 6548
Usually login information isn't hardcoded into a script like that, so this is a rather difficult example to expand on.
If you store your information in a DB or a file, then you would just reference that data store in your function and wouldn't have a need for a global variable like that.
If you are dead set on this way, this is something you could do:
function authenticate($user, $pass) {
if(checkUser($user, $pass)) {
// I am assuming you'll do more here than just return true
return true;
}
else {
return false;
}
}
function checkUser($user, $pass) {
$info = array(
'username'=>'jeff',
'password'=>'kay'
);
if($user == $info['username'] && $pass == $info['password']){
return true;
}
else {
return false;
}
}
This way if you ever decide to change your data store or check user code, as long as it returns the proper boolean to authenticate, you'll be fine. Hurray abstraction!
Upvotes: 0
Reputation: 88697
It really depends on exactly where your data is coming from.
Given the above example:
include()
that file within the function, and $info
will be in the scope of the function.global
, $GLOBALS
et al).I would say that the real question you should be asking (of yourself) is:
"How can I optimise the way in which I store and retrieve my data to avoid scoping problems?"
Upvotes: 0
Reputation: 14091
So out of two possible ways of injecting a variable into scope, both feel wrong to you? That makes no sense.
What's the best way of structuring stuff? The simplest one - if you know number of parameters you need and what type of parameters you need - send those parameters to the function.
Your example code was ok, there's nothing wrong with it (save of course, $info not being passed).
Don't reinvent hot water.
Upvotes: 0
Reputation: 324800
In this situation, just not using a function would be better. For instance, where you would have:
if( authenticate($user, $pass, $info))
Try:
if( Array("username"=>$user,"password"=>$pass) == $info)
However, as a more general thing, I prefer to pass function parameters where needed. I also like using associative arrays, like you have $info
there, as much as possible to have lots of data in few parameters.
Upvotes: 0