Variable scope

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

larrygingras
Forum Newbie
Posts: 8
Joined: Wed May 19, 2010 12:52 pm

Variable scope

Post by larrygingras »

How can I make a function that will share (or at least have access to) calling function's scope? I dig a lot of manuals and examples still I see nothing on this.
I think that should be possible. At least there is built-in function "extract" that is able to access and modify calling function's scope...
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Variable scope

Post by Eran »

you can't share scope between functions. The closest you can get is sharing data through the $this scope for functions belonging to the same object. Perhaps if you explained why you need this we could offer alternative ways to go about it
larrygingras
Forum Newbie
Posts: 8
Joined: Wed May 19, 2010 12:52 pm

Re: Variable scope

Post by larrygingras »

1. So how it is possible for built-in functions like "extract" to access calling function's scope? Are built-in functions have wider possibilities?

2. I think about design of good and easy query escaping function. Now I can just put variables in query string (double-quoted) and they are expanded. This is very handy but not secure. What I want is to put variable names (it could be array members as well) to some sort of tags and I want function to parse such string and escape everything that is inside those tags. So this function's code should act as if it would be executed inside calling function.
In C, for example, I can write macro for such purpose...
larrygingras
Forum Newbie
Posts: 8
Joined: Wed May 19, 2010 12:52 pm

Re: Variable scope

Post by larrygingras »

I think I've not made myself very clear.
I mean in my way variables (inside tags) will NOT be expanded by means of PHP, but when function will parse these tags it will expand everything inside and after escape it.So this function should have access to same variables as in scope of calling function.
larrygingras
Forum Newbie
Posts: 8
Joined: Wed May 19, 2010 12:52 pm

Re: Variable scope

Post by larrygingras »

I think I could make like this:

Code: Select all

eval(safe_query("update table set var='%val%'"));
Function safe_query will return PHP code that will be executed in calling function's scope.
This way is closest approach to C macro way. But it looks not so good...
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Variable scope

Post by AbraCadaver »

If you would show some code it would be easier to help you. What you are describing sounds a lot like prepared statements: http://php.net/manual/en/pdo.prepared-statements.php

But to answer your question, extract() needs an array to extract. And for one function to access vars from another function they would either need to be passed in to the called function or they would need to be global. Consider this:

Code: Select all

function one() {
   $a = 1;
   $b = 2;
   $GLOBALS['vars'] = get_defined_vars();
   two();
}
function two() {
   extract($GLOBALS['vars']);
   echo $a;
   echo $b;
}
However I would investigate using a class for this type of functionality.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
larrygingras
Forum Newbie
Posts: 8
Joined: Wed May 19, 2010 12:52 pm

Re: Variable scope

Post by larrygingras »

AbraCadaver wrote:But to answer your question, extract() needs an array to extract
Yes, but it is extracting this array into the calling function's scope. But it looks it isn't possible within PHP language itself, right?

As for other things.
I cannot show code as right now it is just design concept.
Prepared statements is not what I want as I want to execute queries with just one call, simple and clear. I prefer code to be as laconic as possible.
I think, get_defined_vars (again - this function CAN read calling scope) is good idea, but I don't want to execute it every time I call query function.

Code: Select all

function safe_query($q,$vars=get_defined_vars())
{
...
}
Will something like this work?
Again, I could use eval but it will make code not so clean...
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Variable scope

Post by Eran »

What is the problem with passing the variables in an array?
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Variable scope

Post by AbraCadaver »

No, I was just illustrating how it works. You really need to do this by either using a class or by passing the vars in. This is just quick of the top of my head:

Code: Select all

function safe_query() {
	$args = func_get_args();
	$query = array_shift($args);

	foreach($args as $key => $val) {
		//whatever here
		$query = str_replace("%$key%", mysql_real_escape_string($val), $query);
	}
	return mysql_query($query);
}
$var = $_POST['var'];
safe_query("update table set var='%0%'", $var);
Or you could write your function to take an array:

Code: Select all

$var = $_POST['var'];
safe_query("update table set var='%val%'", array('val'=>$var));
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
larrygingras
Forum Newbie
Posts: 8
Joined: Wed May 19, 2010 12:52 pm

Re: Variable scope

Post by larrygingras »

Well, imagine I make an insert with about 20 fields or more. That is big and complicated query. So I will put all variable names in my query string (inside my special tags), but I do not want to repeat these variables again in array or something.
This why I not want to use printf-like approach - I not want to count what argument stay in what position. I want it as simple as I write now:

Code: Select all

mysql_query("update `table` set `var`='$_GET[val]' where `id`='$_GET[id]'");
But I want it be secure as well...
Or you could write your function to take an array:

Code: Select all

$var = $_POST['var'];
safe_query("update table set var='%val%'", array('val'=>$var));
Well, this approach I like better than before as at least I don't need to count argument's position. But still this syntax is more complicated and you can imagine how more complicated will become queries with >20 arguments...
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Variable scope

Post by Eran »

How about the following mock syntax:

Code: Select all

update('table',array('var1' => $var1));
insert('table',array('var1' => $var1));
larrygingras
Forum Newbie
Posts: 8
Joined: Wed May 19, 2010 12:52 pm

Re: Variable scope

Post by larrygingras »

Well, good idea. Not think about that before.
Not complete solution, for example complicated "select" with a lot of external arguments is still not covered, but for most common cases this can be good approach...
However, IDEALLY I want what I state before. And still, what about:

Code: Select all

function safe_query($q,$vars=get_defined_vars())
{
...
}
Will this work as I want - make $vars contain scope of calling function?
Well, I think I should just test this myself :)
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Variable scope

Post by AbraCadaver »

Regardless of how you do it, you're going to have to pass the vars into the function. To simplify you might build an array from the start instead of using single vars. If vars come from get or post then you already have an array. If not, then something like:

Code: Select all

$vars['var'] = 1;
$vars['var2'] = 2;
Or:

Code: Select all

$var = 1;
$var2 = 2;
$vars = compact("var", "var2");
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
larrygingras
Forum Newbie
Posts: 8
Joined: Wed May 19, 2010 12:52 pm

Re: Variable scope

Post by larrygingras »

Unfortunately, no. It seems that it is not permitted to use function for default argument value: PHP Parse error: syntax error, unexpected '(', expecting ')' in /cd/home/admin/test.php on line 2
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Variable scope

Post by AbraCadaver »

larrygingras wrote:Unfortunately, no. It seems that it is not permitted to use function for default argument value: PHP Parse error: syntax error, unexpected '(', expecting ')' in /cd/home/admin/test.php on line 2
You can do this, however I would recommend one of the other solutions:

Code: Select all

safe_query('query', get_defined_vars());
If the variables are global, then you can just use the $GLOBALS array in the safe_query() function.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
Post Reply