A hint of globalizing

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

User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

A hint of globalizing

Post by phice »

I'm currently building a templating system and would like to know how to check if a variable is set in the php document, inside a function.

I currently have:

Code: Select all

function replace_var( $var )
	{
		if ( @$GLOBALS[ $var[1] ] )
		{
			return $GLOBALS[ $var[1] ];
		}
		else
		{
			return $var[0];
		}
	}
	
	$contents = preg_replace_callback ( "#{\\$([A-Za-z0-9]+)}#i", "replace_var", $contents );
If you notice, if the variable $var[1] (what's found inside the parenthesis) is previously created then it returns it's contents; otherwise it returns back to what it was. I would like to replace the if ( @$GLOBALS[ $var[1] ] ) (or modify it) so that I can use replace_var('thisvar') or replace_var("that['array'][1][346]"). I don't want to have to globalize anything because I want to be able to use any variable (aside from get, post, session and cookie because those are already in a custom variable).

Your help is greatly appreciated.
Image Image
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

I would also like to be able to give a list of variables that are restricted from access (eg, config variables) if you would be so inclined to help.
Image Image
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

probably should use a preg_split to break apart the array bits, then reconstruct it in an isset-type loop. :?:
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

Could you show me what you're talking about? I've never used preg_split before.
Image Image
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Code: Select all

<?php

$test = 'testї\'some\']ї&quote;more&quote;]ї4]їplay]';

$parts = preg_split('#\ї(ї&quote;\']?)(.*?)\\1\]#', $test, -1, PREG_SPLIT_DELIM_CAPTURE );

var_export($parts);

?>

Code: Select all

array (
  0 => 'test',
  1 => '\'',
  2 => 'some',
  3 => '',
  4 => '&quote;',
  5 => 'more',
  6 => '',
  7 => '',
  8 => '4',
  9 => '',
  10 => '',
  11 => 'play',
  12 => '',
)
:)
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

Now that was just confusing. :P

Could you show me how to build a $GLOBALS[] variable out of that? Many thanks.
Image Image
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Code: Select all

<?php

function getGlobal( $str )
{
	$parts = preg_split('#\ї(ї&quote;\']?)(.*?)\\1\]#', $str, -1, PREG_SPLIT_DELIM_CAPTURE );
	
	$var =& $GLOBALS;
	
	foreach( $parts as $v )
	{
		if( $v != '\'' && $v != '' && $v != '&quote;' )
		{
			if( isset( $varї$v] ) )
			{
				$var =& $varї$v];
			}
			else
			{
				unset($var);
				break;
			}
		}
	}
	
	return isset($var) ? $var : null;
}

$str  = 'testї\'some\']ї&quote;more&quote;]ї4]їplay]';
$str2 = 'thisїdoes]їnot]їexist]';

$testї'some']ї'more']ї4]ї'play'] = 'hi I\'m a global variable!';

var_export(getGlobal( $str ));

echo &quote;\n\n&quote;;

var_export(getGlobal( $str2 ));

?>

Code: Select all

'hi I\'m a global variable!'

NULL
could potentially use a reference as the return, and the return just gives you a flag of success fail. (could return an array too, I guess)
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post by vigge89 »

I've done this recently, it required a lot of work to get it to properly work :/
You have too split the variable name and the array-bits, and the do an eval ("return $var;");.

Here's a function I made for the purpose of converting variable- and array-names to global names:

Code: Select all

function parser_var2globals ($string) {
	$string = preg_replace ('#\$([a-zA-Z0-9_\-]+)#', '$GLOBALS[\\1]', $string);
	return $string;
}
If you want to return the value of the variable immidiately, swap the return-line with this:

Code: Select all

return eval ('return '.$string.';');
What it does is that it looks after patterns matching "${varname}" and replaces them with "$GLOBALS[{varname}]". This works for arrays too, since it stops after the name of the variable, for example: "${varname}[array][1]" is replaced with "$GLOBALS[{varname}][array][1]". The [array][1] stays, it's just the {varname} which gets replaced.

EDIT: feyd's method seems to be a little better, as you recieve an reference to the variable. That's what I myself tried to do from the start, put I couldn't manage to find a way to do it. Anyway, my method is at least less code ;)
Last edited by vigge89 on Tue Apr 19, 2005 10:51 am, edited 1 time in total.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

vigge89:
you actually can use the evaluate modifier in the regular expression, and lose the eval :) ... the problem is, yours is intended for single level variables, not arrays.
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

Indeed, I was about to say that.
Image Image
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post by vigge89 »

feyd wrote:vigge89:
you actually can use the evaluate modifier in the regular expression, and lose the eval :) ... the problem is, yours is intended for single level variables, not arrays.
As I said, it works for arrays, the reason is that it just replaces the varname, and leaves the array-bit, try it out for yourself ;)

Edit: btw, just a tiny question for you feyd; If I'd use the evaluate-modifier, how should the call look like? Like this?

Code: Select all

function parser_var2globals ($string) {
    $string = preg_replace ('#\$([a-zA-Z0-9_\-]+)#e', 'return $GLOBALS[\\1];', $string);
    return $string;
}
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

Both return Array as the variable contents. feyd's way makes every variable replaced into the whole contents of $GLOBALS, and I slightly modified vigge's code to do exactly the same as what my previous code does.

I now have:

Code: Select all

$name = &quote;Don&quote;;
	$that = &quote;huh?&quote;;
	//$jksdf = &quote;dsjfjkref&quote;;
	$array = array ( );
	$arrayї'key'] = &quote;value, hehehehehehehehehehehehe&quote;;
	
	
	function replace_var( $var )
	{
		/*if ( @$GLOBALSї $varї1] ] )
		{
			return $GLOBALSї $varї1] ];
		}
		else
		{
			return $varї0];
		}*/
		
		$string = preg_replace ('#\$(їa-zA-Z0-9_\-]+)#', '$GLOBALSї\\1]', $var);
		
		$string = eval ( &quote;return &quote; . str_replace ( array ( &quote;{&quote;, &quote;}&quote; ), &quote;&quote;, $stringї0] . &quote;;&quote; ) );
		
		if ( $string )
		{
			return $string;
		}
		else
		{
			return $varї0];
		}
	}
	
	$contents = &quote;<p>Hello, {$name}. Welcome to my site. {$jksdf} {$that} {$name}</p><p>what about {$arrayї'key']} ?</p>{template=\&quote;another.tpl\&quote;}&quote;;
	$contents = preg_replace_callback ( &quote;#{\\$(їA-Za-z0-9]+)}#i&quote;, &quote;replace_var&quote;, $contents );

Code: Select all

Hello, Don. Welcome to my site. {$jksdf} huh? Don

what about {$arrayї'key']} ?
As you can see, array's still aren't working.
Image Image
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

vigge89 wrote:Edit: btw, just a tiny question for you feyd; If I'd use the evaluate-modifier, how should the call look like? Like this?

Code: Select all

function parser_var2globals ($string) {
    $string = preg_replace ('#\$(їa-zA-Z0-9_\-]+)#e', 'return $GLOBALSї\\1];', $string);
    return $string;
}

Code: Select all

$string = preg_replace ('#\$(їa-zA-Z_]їa-zA-Z0-9_]+)(ї^\s]*?)(?=\s)#se', '$GLOBALSї&quote;\\1&quote;]\\2', $string);
is more accurate, I believe.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

as for your current problem Phice, you have your test string in double quotes.. (PHP is parsing all the variables first) :) Although fixing it, is another story.
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

Finally I got it to work...

Code: Select all

function replace_var( $var )
	{
		$string = preg_replace ('#\$([a-zA-Z_][a-zA-Z0-9_]+)([^\s]*?)#se', '$GLOBALS["\\1"]\\2', $var);
		
		if ( str_replace ( array ( "{", "}" ), "", $string[0] ) != "" )
		{
			return eval ( 'return $GLOBALS[\'' . $string[1] . '\']' . $string[2] . ';' );
		}
		else
		{
			return $var[0];
		}
	}
Image Image
Post Reply