Static Variable in Recursive Function

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
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Static Variable in Recursive Function

Post by Ollie Saunders »

I have function that creates instances of a simple class from arrays.
It uses a recursive loop so that complex arrays can be used as the argument.
Here is how I am currently calling it:

Code: Select all

$foo = osisSafeVar::fromArray(array(1,2,3));
$bar = osisSafeVar::fromArray(array(4,5,6));
print_r($bar);

Code: Select all

Array
(
    [0] => osisSafeVar Object
        (
            [data] => 1
        )

    [1] => osisSafeVar Object
        (
            [data] => 5
        )

    [2] => osisSafeVar Object
        (
            [data] => 6
        )

    [3] => osisSafeVar Object
        (
            [data] => 4
        )

)
As you can see bar is getting confused with foo.
This code has to run work on PHP 4.06. But I am testing it on my server running PHP 5.0 atm.
Here's the class:

Code: Select all

/**
* Keeps variables secure by preventing unfiltered accesss to them
*/
class osisSafeVar {	
	function osisSafeVar($data) {
		$this->data = $data;
	}
	/**
	* Get the data exactly as it was set. Never use the return value
	* of this in output. Use only for strlen, conditions etc.
	*/
	function getRaw() {
		return $this->data;
	}
	/**
	* Get variable back as HTML as defined in tfb with 
	* strim functionality
	*/
	function getHTML($limitLength = null) {
		global $tfb;
		if(!$limitLength) {
			if(!isset($this->HTML)) $this->HTML = $tfb->htmlClean($this->data);
			return $this->HTML;
		}
		if(!(isset($this->HTML) && $this->limitLength == $limitLength)) {
			$this->limitLength = $limitLength;
			$this->HTML = $tfb->strimAndClean($this->data,$limitLength);
		}
		return $this->HTML;
	}
	/**
	* Get variable back escaped ready to be added to queries
	*/
	function getMySQL() {
		global $db;
		if(!isset($this->MySQL)) $this->MySQL = mysql_real_escape_string($this->data,$db);
		return $this->MySQL;
	}
	/**
	* Filter the data to a specific type
	*/
	function cast($type) {
		$this->data = eval('return ('.$type.')'.'$this->data;');
		$this->reset();											// cached strings are out of date
	}
	/**
	* Set the data to something else. You could use overloading
	* instead, at the sacrifice of portability
	*/                   
	function set($data) {
		$this->data = $data;
		$this->reset();											// cached strings are out of date
	}
	/**
	* Destroy cached processed strings to force their regeneration
	* @access private
	*/
	function reset() {
		unset($this->HTML,$this->MySQL);
	} 
	/**
	* @access public static
	*/
	function fromArray($arr,$key = null) {
		if(isset($this)) return false;
		static $safe = array();
		if(is_array($arr)) {
			foreach($arr as $key => $value) self::fromArray($value,$key);
		} else {
			if($key == null) $safe[] = new osisSafeVar($arr);
			else $safe[$key] = new osisSafeVar($arr);
		}
		return $safe;
	}
}
I've tried using the fromArray function outside of the class and I get the same results.
One obvious solution is to use a global variable rather than a static one and a separate function call to clear it but can anyone think of a better solution to this.

Many thanks.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Why not use the return you already have?
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Why not use the return you already have?
I already am:

Code: Select all

$foo = osisSafeVar::fromArray(array(1,2,3));
$bar = osisSafeVar::fromArray(array(4,5,6));
print_r($bar);
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

I see you using $this->data but i see nowhere where you've defined that member variable.. And i thought that was not allowed in php... what does error_reporting tell you?

(If i'm not mistaken, there was (or is) a bug in php4 that doesn't handle statis members well. But if you use the static member as an array, it does work).
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

ole wrote:
Why not use the return you already have?
I already am:

Code: Select all

$foo = osisSafeVar::fromArray(array(1,2,3));
$bar = osisSafeVar::fromArray(array(4,5,6));
print_r($bar);
You're actually not because you are using a static.

Code: Select all

function fromArray($arr) {
                if(isset($this)) return false;
                if(is_array($arr)) {
                        $safe = array();
                        foreach($arr as $key => $value) {
                                $safe[$key] = self::fromArray($value);
                        }
                } else {
                        $safe = new osisSafeVar($arr);
                }
                return $safe;
        }
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

You're actually not because you are using a static.
Ahh so it turns out that statics in recursive functions suck ass. thanks feyd.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

timvw wrote:I see you using $this->data but i see nowhere where you've defined that member variable.. And i thought that was not allowed in php... what does error_reporting tell you?
I did that to avoid using var keyword which generates an error in PHP 5.
(If i'm not mistaken, there was (or is) a bug in php4 that doesn't handle statis members well. But if you use the static member as an array, it does work).
the static was already an array and as i said i'm testing in php 5.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

ole wrote: Ahh so it turns out that statics in recursive functions suck ass. thanks feyd.
Actually not. You just misused it. Static is a static, it preserves it's value across calls to the function that contains it, exactly what you've observed (and wanted it in the first place :) )
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

wow, did the smurf, smurf up a bit :-D
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
Post Reply