debug(); // a counter if(!$args->is_set("clic_counter")) $args->set("clic_counter", "-1"); // very fun counter else $args->set("clic_counter", $args->get("clic_counter") +1); ... */ class PageArgs { var $args; // encrypt non scalar values. can help with security hole in urls. // scalar are strings, booleans and numbers. var $crypt_non_scalar = true; var $crypt_key_tag = "xx-encoded-xx"; // end with xx var $prefix; // variable prefix. function PageArgs($prefix = ""){ if($prefix == "") $prefix = "args_"; elseif(strstr($prefix, "_")) $this->prefix = $prefix; else $this->prefix = $prefix."_"; // we can get args from PHP _REQUEST var if(isset($_REQUEST)) { // args is a reference to page REQUEST arguments $this->args = &$_REQUEST; $uncrypted_args = array(); // analyse each variable : scalar, array, compressed, crypted ... foreach ($this->args as $key=>$val) { if($key == "PHPSESSID") continue; // only variables with my prefix is in interest if(!strstr($key, $this->prefix) && $this->prefix != "") continue; //this is a clear serealized array (or object) like a:3:{i:0;i:-1;i:1;i:2;i:2;s:5:\"string\";} if(preg_match("/a:\d+:/", $val)){ $this->un_set($key); $uncrypted_args[$key] = unserialize(stripslashes(urldecode($val))); continue; } else { // this is an encoded object. // try to see if we can match $this->crypt_key_tag in the beginning of the key value. // else this is not our crypted value. $crypt_key = substr( $this->crypt($this->crypt_key_tag), 0, strlen($this->crypt_key_tag)); if(preg_match("/$crypt_key(.+)/", $val, $values)){ // extract crypted_key from the begining. last part is the serealized value. $data = $this->decrypt($val); $tag = $this->crypt_key_tag; preg_match("/$tag(.+)/", $data, $values); // get last part in $values[1] $this->un_set($key); $obj = unserialize(stripslashes(urldecode($values[1]))); // can not insert directly to args, because foreach loop enter in this new value. // so make un intermediate array. $uncrypted_args[$key] = $obj; } else { # this is a scalar value not crypted : no this to do with it. # printf("PageArgs($key, $val) %s / %s : received unkown data from arguments page.\n", __FILE__, __LINE__); } } } if(count(new_args > 0)) { foreach ($uncrypted_args as $key=>$value){ $this->set_no_prefix($key, $value); } } } else // an empty array $this->args = array(); // print_r($this); } function get($name) { return($this->args[$this->prefix."$name"]); } // $ref = &$args->ref("value"); $ref++; // $ref = &$args->ref("my_array[counter]"); $ref++; // construct not allowed by php : &$args->ref("my_array[counter]")++; // return a reference to an objet, an array or a value by name. function &ref($name) { // printf("PageArg->ref($name)\n"); // match name[index] if(preg_match("/(.+?)\[(.+?)\]/", $name, $values)){ printf ("match '$name' -> array type1 : %s - %s\n", $values[1], $values[2]); $idx1 = $values[1]; $idx2 = $values[2]; $ref = &$this->args[$this->prefix."$idx1"]["$idx2"]; printf ("ref = $ref\n"); return($ref); } else // single name # $ref = &$this->args["$name"]; return($ref = &$this->args[$this->prefix."$name"]); return($ref); } function set($name, $value) { $this->set_no_prefix("{$this->prefix}{$name}", $value); } function set_no_prefix($name, $value) { $this->args["$name"] = $value; } // alias to set function add($name, $value) { $this->set($name, $value); } // remove a variable from arg list. function un_set($name) { unset($this->args[$this->prefix."$name"]); } // alias to unset function delete($name) { $this->un_set($name); } function is_set($name) { return(isset($this->args[$this->prefix."$name"])); } // an alias to set function add($name, $value) { $this->set($name, $value); } // return full url, with all arguments ; pair ($key, $value) are local and trancient and are not pushed to real args. // values a crypted by default, when not of scalar type. // function url($key="", $val="") { // copy arg list localy -args passed to this member function must not be put in global arguments values. // they are only local values. // this is needed if $this->url() is called more than once. $local_args = $this->args; if($key!=""){ // match val[index] if(preg_match("/(.+?)\[(.+?)\]/", $key, $values)){ $idx1 = $values[1]; $idx2 = $values[2]; $local_args["{$this->prefix}{$idx1}"]["$idx2"] = $val; } else // add local arg to args. $local_args["{$this->prefix}{$key}"] = $val; } if(count($local_args) == 0) return($this->self_url()); else { $url = ""; $count=0; foreach($local_args as $key=>$val) { $count++; // don't need to mamage this variable, it is done internaly by php. if($key != "PHPSESSID") { if(is_scalar($val)){ $url.= sprintf("&%s=%s", urlencode($key), urlencode($val)); } elseif(is_array($val)){ if($this->crypt_non_scalar){ $url.= sprintf("&%s=%s", urlencode($key), urlencode($this->crypt($this->crypt_key_tag . serialize($val)))); } else { $url.= sprintf("&%s=%s", urlencode($key), urlencode(serialize($val))); } } else { // this may be an object, a class or any thing else. if($this->crypt_non_scalar){ $url.= sprintf("&%s=%s", urlencode($key), urlencode($this->crypt($this->crypt_key_tag . serialize($val)))); } else { $url.= sprintf("&%s=%s", urlencode($key), urlencode(serialize($val))); } } } } // first arg has a &, : we don't want this char. Should use 'join()' + but don't kown how to $url = preg_replace("/^\&/", "", $url); return(sprintf("%s?%s", $this->self_url(), $url)); } } function debug() { print("args = "); print_r($this->args); } function self_url() { return($_SERVER["PHP_SELF"]); } function crypt($string) { // not really a crypt systeme. could use this : http://www.php.net/manual/en/function.mdecrypt-generic.php return(base64_encode($string)); } function decrypt($string) { return(base64_decode($string)); } }