Michas
Michas

Reputation: 9428

PHP, isset and how to get rid of repetitive chains of variables?

I have strict error reporting. I have to use isset and it make me to write long, repetitive chains of variables in PHP. I have sometimes to write code like this:

if (isset($my_object->an_array[$a_variable])):
        $other_variable = $my_object->an_array[$a_variable];
else:
        $other_variable = false;
endif;

or

if (isset($my_object->an_array[$a_variable])):
        return $my_object->an_array[$a_variable];
endif;

Sometimes it is longer and more complicated. It isn't readable and take too much time to type. I'd like to get rid of it.

The question
Is there a way to write $my_object->an_array[$a_variable] only once?

Upvotes: 3

Views: 1066

Answers (7)

biziclop
biziclop

Reputation: 14596

I use these little helper functions to access properties of (multidimensional) arrays/objects without writing repetitive isset() statements. They might not be the fastest running solution, but they are very comfortable:

// AI(data,1,default) === data[1] or default
function AI( $a, $i, $d=null ){
  if( is_array ($a)){ if( array_key_exists( $i, $a ))  return $a[ $i ];   return $d;  }
  if( is_object($a)){ if( property_exists(  $a, $i ))  return $a -> $i;   return $d;  }
  return $d;
}


// AII(data,1,2,3) === data[1][2][3] or null
function AII( $o ){
  $a  = func_get_args();
  $al = func_num_args();
  for( $i=1; $i < $al; $i++ ){
    $k = $a[$i];
         if( is_array ($o) && array_key_exists($k,$o))  $o =& $o[ $k ];
    else if( is_object($o) && property_exists ($o,$k))  $o =& $o -> $k;
    else return null; // nothing to access
  }
  return $o;
}


// AIID(data,1,2,3,default) == data[1][2][3] or default
function AIID( $o ){
  $a  = func_get_args();
  $default = end( $a );
  $al = count( $a ) - 1;
  for( $i=1; $i < $al; $i++ ){
    $k = $a[$i];
         if( is_array ($o) && array_key_exists($k,$o))  $o =& $o[ $k ];
    else if( is_object($o) && property_exists ($o,$k))  $o =& $o -> $k;
    else return $default;
  }
  return $o;
}


// AAID(data,[1,2,3],default) == data[1][2][3] or default
function AAID( $o, $a, $default = null ){
  foreach( $a as $k ){
         if( is_array ($o) && array_key_exists($k,$o))  $o =& $o[ $k ];
    else if( is_object($o) && property_exists ($o,$k))  $o =& $o -> $k;
    else return $default;
  }
  return $o;
}

Upvotes: 0

Michas
Michas

Reputation: 9428

In the end I have found two solutions.

I. There is operator @ in PHP. It is very dangerous, tough.
http://www.php.net/manual/en/language.operators.errorcontrol.php

However, it is acceptable in my situation.

  1. This is not a fatal error.
  2. The value of undefined variable is defined as null. I'm fine with testing for this or using implicit conversions.
  3. I can use $php_errormsg in extreme situations.

The code example:

$tmp = $false_object->property->property; #Throw notice
$tmp = $false_array['a_field']['a_field']; #Throw notice
$tmp = @$false_object->property->property; #Quiet
$tmp = @$false_array['a_field']['a_field']; #Quiet
echo $php_errormsg; #I can print that notice

The downside is I don't receive information about lack of quotes in brackets.

$a = array('e'=>false);
$tmp = $a[e]; #Throw notice
$tmp = @$a[e]; #Quiet
echo $php_errormsg; #This variable still works

II. It is possible to use operator &.

  1. The value of undefined variable will be NULL too.
  2. The $php_errormsg variable doesn't work for undefined variables.
  3. I get notice for lack of quotes in brackets, though.

The code example:

$tmp = $false_object->property->property; #Throw notice
$tmp = $false_array['a_field']['a_field']; #Throw notice
$tmp = &$false_object->property->property; #Quiet
$tmp = &$false_array['a_field']['a_field']; #Quiet
var_dump($tmp); #NULL;

The lack of quotes problem:

$array = array('a_field'=>true);
$tmp = $array[a_field]; #Throw notice
$tmp = @$array[a_field]; #Quiet
$tmp = &$array[a_field]; #Throw notice

Upvotes: 2

flyingchen
flyingchen

Reputation: 11

now i get the same problem. i must check it and then get it ,it's so ugrly. so i write the function like this

function get_val($arr,$key,$default_val=false){
   if(!is_array($arr)) return $default_val;
   $idx = explode('>>',$key);
   $tmp = $arr;
   $catched = true;
   foreach($idx as $index) { 
     if(!isset($tmp[$index])){
        $catched = false;
        break;
     }else{
        $tmp = $tmp[$index];
     }
   }
   if($catched) $default_val = $tmp;
   return $default_val;
}
//for example
$arr = array('k1'=>array('k2'=>array(1,'k22'=>22,'k23'=>array('k3'=>1))));
get_val($arr,'k1>>k2>>k23>>k3');

Upvotes: 1

Hammerite
Hammerite

Reputation: 22340

I doubt you will get any suggestions that you will consider satisfactory. The best I can suggest is this, and I would add that I consider it quite ugly:

function ifset ($var) {
    return is_null($var) ? false : $var;
}

Having defined this function, you can call it like this:

$other_variable = ifset(@$my_object->an_array[$a_variable]);

Note that you need the error suppression operator here, because otherwise you'll get an undefined variable notice if the variable indeed doesn't exist. (The reason why you don't need it for isset() is that isset() is really a special parser token rather than an ordinary function.)

Upvotes: 1

Repox
Repox

Reputation: 15476

A method to extract those variables would probably be better in your case, then:

class MyObject
{
    private $an_array;

    public function __construct()
    {
        $this->an_array = array();
    }

    public function get( $key )
    {
        if(isset($this->an_array[$key]))
            return $this->an_array[$key];

        return false; //or empty string
    }

    public function set( $key, $value )
    {
        $this->an_array[$key] = $value; 
    }

}

That way, you can do it like this:

$my_object->get($a_variable]);

Upvotes: 0

&#193;lvaro Gonz&#225;lez
&#193;lvaro Gonz&#225;lez

Reputation: 146450

You can write functions to encapsulate repetitive code:

function get_variable(array $array, $variable_name, $default_value=FALSE){
    if( isset($array[$variable_name]) ){
        return $array[$variable_name];
    }else{
        return $default_value;
    }
}

Tweak to your needs.

Upvotes: 3

check123
check123

Reputation: 2009

function check($var)
{
   if(isset[$var])
       return $var;
   else 
       return "";
}

Then each time you need to do checking call like:

$other_b = check($b);

Upvotes: 1

Related Questions