Static variable in function returning incorrect value...

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

Post Reply
Bennettman
Forum Contributor
Posts: 130
Joined: Sat Jun 15, 2002 3:58 pm

Static variable in function returning incorrect value...

Post by Bennettman »

Okay, this is a bit of a complicated one, so bear with me. Probably be best to explain how it works first.


The script works by having the designer use tags like <=path[forum]> for calling variables and whatnot, and the script going through the code at the end, recognising the custom tags through regexp and getting the right value.

This also includes functions - the code is <#func(args)> where func is the function name and args is the arguments. It does work - I've been able to call predefined and user-created functions with it and they work as they should.

Now, I've got a function that uses a static variable $vinc to go back and forth between 1 and 2 every time the function is called (to do alternating row colours in tables and whatnot). When it's used (the code is <#varinc()>) it goes through the regexp function and the function-calling function, but it returns the same value all the time. For example, if $vinc is set to 1 in the first run, it is always returned 1, despite the fact that $vinc is being set to 2 correctly inside the function. If it's set to, say, 63 in the first run, it's always 63.

Anyway, I've tested it by printing the value of $vinc every time it's called, and I get a regular 1-2-1-2-1 result, but when it's returned a line later, it's 1-1-1-1-1. Tried switching to global, same result. However, when I call the function in PHP, it works.


Here's the applicable code. I hope someone here can help because I'm tearing my hair out figuratively here :roll:

Code: Select all

<?php

// scan_page(STRING html) - scans html for email addresses, large images, and var/array/function references, and returns fixed code
function scan_page($html) {
// only showing function part - the rest are practically the same anyway ;p
	preg_match_all("/<#([_a-z0-9]+)\((.*)\)>/i", $html, $temp_func);
	for ($i = 0; $temp_func[1][$i]; $i++) {
		$find_func[$i] = $temp_func[0][$i];
		$replace_func[$i] = get_func($temp_func[1][$i], $temp_func[2][$i]);
	}
	$html = str_replace($find_func, $replace_func, $html);

	return $html;
}

// get_func(STRING function, STRING values) - returns the value of the function specified by function
function get_func($func, $values) {
	$values = explode(',', $values);
	return call_user_func_array($func, $values);
}

// varinc(NULL) - returns an alternating number between 1 and 2
function varinc() {
	static $vinc;
	if ($vinc != 1) $vinc = 1;
	else $vinc = 2;
	print $vinc .':'; // my happy-happy test ¬_¬
	return $vinc;
}

// $index_content has all the HTML and tags at this point
$index_content = scan_page($index_content);

// output
print $index_content;

?>
Update: Tried using modular division, same result. Also tried putting the static variable earlier in the system and passing it through to varinc() but same result again.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

basically your problem boils down to this simple test:

Code: Select all

$txt = <<<EOF
  a()
  sdf
  a()
  b()

EOF;

$search = array(
        'a()',
        'a()',
        'b()',
        );
$replace = array(
        'first a''s return value',
        'second a''s return value',
        'b''s return value',
        );
echo str_replace($search, $replace, $txt);
Bennettman
Forum Contributor
Posts: 130
Joined: Sat Jun 15, 2002 3:58 pm

Post by Bennettman »

How so? I don't really understand what you're getting at.

Is it something to do with the repeating "a()"s in your example corresponding to the repeating calls to the function?

Edit: Wait, oh! I get it. You mean all the calls to the same function are being replaced with the replacement for the first call, since they're identical, yeah? I couldn't actually do the test since I'm at college, so it took a while to figure it out >_>
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

Bennettman wrote: Edit: Wait, oh! I get it. You mean all the calls to the same function are being replaced with the replacement for the first call, since they're identical, yeah?
Exactly. I would suggest to implement a replacement for str_replace :) which will replace matches one by one, something like this:

Code: Select all

function my_str_replace($search, $replace, $txt) {
    $ret = $txt;
    foreach(array_keys($search) as $i)
        $ret = preg_replace('/' . preg_quote($search[$i],'/') . '/', $replace[$i], $ret, 1);
    return $ret;
}
It will affect the perfomance, but will work according to your expectations :D
Bennettman
Forum Contributor
Posts: 130
Joined: Sat Jun 15, 2002 3:58 pm

Post by Bennettman »

Heh, I'd just gotten it working when you posted that ;p

I ended up replacing the str_rep with the str_replace_count function in php.net's notes for str_rep (omg theif!!11!), and switching the organisation around a bit. It uses strpos and substr so it's likely more efficient than preg_rep anyway.

Anyway, thanks for helping me out there! ^_^

Ian
Post Reply