tags:

views:

93

answers:

5

I have like a hundred or so form elements in a multiple-page form and I have to check if certain session vars were defined or not.

The main thing is I have sub-namespaces within my sessions by way of a CONSTANT and then a fields key.

Is there some shortcut to doing say,

<input value="<?php echo isset($_SESSION[CONSTANT]['fields']['first_name']) ? $_SESSION[CONSTANT]['fields']['first_name'] : ''; ?>">

I doubt I could loop this because my structure isnt made of sibling input elements but very, very customised markup which cant be controlled within a loop structure.

Perhaps I could use Zend Session or something similar, last resort would be typing a variable to be replaced by my text editor, eg $s['first_name'] and replace all $s instances.

+6  A: 

Write a shortcut yourself.

function s($key) {
    return isset($_SESSION[CONSTANT]['fields'][$key]) ? $_SESSION[CONSTANT]['fields'][$key] : '';
}
$foo = s('first_name');
Matchu
This is definitely a shorter version than mine, both in implementation and access, however mine is designed to gracefully handle two scenarios: (1) one of the earlier elements (CONSTANT, 'fields') does not exist, and (2) data needs to be accessed from the session in a place other than `[CONSTANT]['fields']` as well, without having to write additional handling functions. In short my function cares a lot less about where things are, and that does require a bit more effort on the final end. Your suggestion, for the exact case posted in the example, is much more elegant, though =)
Dereleased
A: 

I would chuck those "sub-namespaces" then. I mean, in a proper html form, you'd give every input element a name anyway (and nowadays, an id too) , why not use - that? I mean, why care how these things are stored in the session? As long as you can unambigously set and get, I don't see why you'd have to make it more complicated by adding another level.

Roland Bouman
big systems, different modules, and session shared variables coexistense. thats why.
useless
sure. but why not use the namespace as a prefix for the session var names?
Roland Bouman
+3  A: 

Try this:

function sessionOrBlank() {
    $args = func_get_args();
    if (count($args) < 0) {
        return '';
    }
    $argCtr = 0;
    $argPtr =& $_SESSION;
    do {
        if (!isset($argPtr[$args[$argCtr]])) {
            return '';
        }
        $argPtr =& $argPtr[$args[$argCtr++]];
    } while($argCtr < count($args));
    return $argPtr;
}

Then use like:

<input value="<?php echo sessionOrBlank(CONSTANT,'fields','first_name'); ?>">

General Usage:

Pass arguments to this function in the order you wish to search the array. For exmaple, if you wish to search for $_SESSION['foo']['bar'], use sessionOrBlank('foo','bar');.

Edit: You Mentioned Setting

Not entirely sure what you meant, but this function behave similar to the previous one, except it will treat the last argument passed to it as the value to be set to. It will also return the value it sets, so that the result of using this function is the same as the result of an assignment expression (usually). It should not allow the overwriting of the entire session variable, however it will overwrite any keys that are not currently arrays if they do exist, or will supplement existing arrays if they do not. Enjoy.

function setSession() {
    $args = func_get_args();
    if (count($args) < 1) {
        return false; // don't overwrite whole session
    }
    $argCtr = 0;
    $argPtr =& $_SESSION;
    do {
        if (!isset($argPtr[$args[$argCtr]]) || !is_array($argPtr[$args[$argCtr]])) {
            $argPtr[$args[$argCtr]] = array();
        }
        $argPtr =& $argPtr[$args[$argCtr++]];
    } while($argCtr < count($args) - 1);
    $argPtr = $args[$argCtr];
    return $argPtr;
}
Dereleased
This doesn't seem much shorter to me. OP's main problem was typing out all those CONSTANT's and fields's, and though this may give it a slightly better syntax, it still doesn't take care of the real issue of redundancy in templates.
Matchu
I was assuming it was the tedium of writing out the statement twice, as in first with isset and then for a literal dump. The benefit of this function is that it is entirely agnostic to the depth which must be searched, so if it's one element deep or 20 elements deep it doesn't care, and it will also handle the case of one of the earlier elements not existing in a graceful manner. Of course, if we are assuming they always exist, one could simply change the initial reference `$argPtr =` to `$argPtr =` to achieve the same benefits but shorter.
Dereleased
The value of the setter is somewhat debatable, as PHP will automatically CREATE arrays of arbitrary depth, but will not change a scalar to an array, which this function WILL do.
Dereleased
What's funny is I was actually in the middle of writing up this exact solution before crushing it and submitting the other. Really. It was the same exact strategy, with func_get_args(), etc. Kinda funny, really xD
Matchu
+1  A: 

ive this class, it can handle namespaces:

class Core_Session extends Singleton{

  /**
   * Core_Session::getVar($varname,$context='global',...mas contextos)
   *
   * @param mixed $varname nombre de la variable
   * @param mixed $context contexto en el que se llama
   * @return valor de la variable (null si no existe o si estan mal los parametros)
   */
    public static function listContextVars($context='global'){
        $contexts = func_get_args();
        if(count($contexts)==1&&is_array($contexts[0]))
            $contexts = $contexts[0];
        $values = &$_SESSION;
        foreach($contexts as $context){
            if(!isset($values[$context]))
                return(null);
            $values = &$values[$context];
        }
        return(array_keys($values));
    }
    public static function listContextValues($modo='array', $context='global'){
        $contexts = func_get_args();
        $contexts = array_slice($contexts, 1);
        if(count($contexts)==1&&is_array($contexts[0]))
            $contexts = $contexts[0];
        $values = &$_SESSION;
        foreach($contexts as $context){
            if(!isset($values[$context])){
                return(null);
            }
            $values = &$values[$context];
        }
        switch($modo){
            case 'array':{
                $ret = array();
                foreach($values as $varname=>$value){
                    $ret[] = array(
                        'varname'=>$varname,
                        'value'=>self::getVarMulticontext($varname, $contexts)
                    );
                }
                break;
            }
            case 'Core_Object':{
                $ret = array();
                foreach($values as $varname=>$value){
                    $oret = new Core_Object();
                    $oret->setVarname($varname);
                    $oret->setValue(self::getVarMulticontext($varname, $contexts));
                    //$oret->setData($varname, self::getVarMulticontext($varname, $contexts));
                    $ret[] = $oret;
                }
            }
        }
        return($ret);
    }
    public static function getVar($varname, $context='global'){
        if(isset($context)&&is_string($context)){
            $args = func_get_args();
            $contexts = array_slice($args, 1);
            return(self::getVarMulticontext($varname, $contexts));
        }
        return(null);
    }
    public static function getVarMulticontext($varname, $contexts=array()){
        if(!is_array($contexts)||!count($contexts))
            return(null);
        if($varname!=null)
            $contexts = array_merge($contexts, array($varname));
        $values = &$_SESSION;
        foreach($contexts as $context){
            if(!isset($values[$context]))
                return(null);
            $values = &$values[$context];
        }
        if($values===null)
            return($values);
        return(unserialize($values));
    }
  /**
   * Core_Session::setVar()
   *
   * @param mixed $varname nombre de la variable
   * @param mixed $value valor a setear
   * @param string $context contexto en el que se llama
   * @return true si esta bien, false si no
   */
    public static function setVar($varname, $value, $context='global'){
        if(isset($context)&&is_string($context)){
            /*if(is_object($value))*/
            $args = func_get_args();
            $contexts = array_slice($args, 2);
            return(self::setVarMulticontext($varname, $value, $contexts));
        }
        return(false);
    }
    public static function setVarMulticontext($varname, $value, $contexts=array()){
        if(!is_array($contexts)||!count($contexts))
            return(null);
        if($varname!=null)
            $contexts = array_merge($contexts, array($varname));
        $parent_context = null;
        $values = &$_SESSION;
        //var_dump($contexts);
        foreach($contexts as $context){
            $parent_context = &$values;
            $values = &$values[$context];
        }
        if($value==null){
            //$values = null;
            $find = array_search($context, array_keys($parent_context));
            if($find!==null && $find!==false){
                array_splice($parent_context, $find, 1 );
            }
        }
        else
            $values = serialize($value);
        return(true);
    }

    public function getInstance(){
        return(self::getInstanceOf(__CLASS__));
    }
}
useless
A: 
$var = & $_SESSION[CONSTANT]['fields'];
echo $var['first_name'];
chris