arthur-eudeline
12/5/2018 - 8:06 AM

PHP get_the_value

Function that provides a secure way to check if a value is available in an array of data. It's ideal for metaboxes in WordPress for exemple.

<?php

/**
* Try to get a value in an array of data, if it doesn't exist, simply returns an empty string. Ideal for display values on input field.
*
* @method get_the_value
*
* @param  array         $data  The array where to look for the data to extract
* @param  string|int    $index The path of the data (eg: "index", "index[subindex]", "index[subindex][subindex]")
*
* @return string        The data to display or an empty string if no data is found
*/
function get_the_value(array $data, $index ){

  // Si on a trouvé $index sous la forme de "index[subindex1][subindex2][...]"
  if ( preg_match_all("(\[(.*?)\])", $index, $match) > 0 ){
    $index = substr( $index, 0, strpos( $index, "[" ) );
    $subindexes = $match[1];
  }

  // Si $index est bien présent dans le tableau $data
  if ( isset($data[$index]) ) {

    // Si l'élément existe, on vérifie qu'il nest pas vide
    if ( !empty($data[$index]) ) {

      // S'il contient un tableau :
      if ( is_array($data[$index]) ) {
        // Unserializing
        foreach ($data[$index] as $key => $value) {
          $unserialized_value = @unserialize( $value );
          if ( $unserialized_value !== false ) {
            $data[$index] = $unserialized_value;
          }
        }

        // On créer une phrase de recherche pour le paramètre $index de get_the_value();
        $first_subindex = $subindexes[0];
        unset($subindexes[0]);
        $searching_index = $first_subindex;
        if( is_array($subindexes) && !empty($subindexes) ){
          $searching_index .= "[" . implode("][", $subindexes) . "]";
        }

        // Si on a bien un $searching de défini, on appelle la fonction de façon récursive pour parcourir tout le tableau
        if ( isset($searching_index) ){
          return get_the_value($data[$index],  $searching_index);
        }

        else {
          // WP SINGLE : Si l'élément est bien un tablea, qu'il n'a qu'un élément, qu'il n'est pas vide et qu'il est bien accessible
          if ( is_array($data[$index]) && count($data[$index]) === 1 && !empty($data[$index]) && isset($data[$index][0]) ){
            return $data[$index][0];
          }

          return "";
        }
      }

      // Unserialize
      $unserialized_value = @unserialize( $value );
      if ( $unserialized_value !== false ) {
        $data[$index] = $unserialized_value;
      }

      // Si ce n'est pas un tableau, on retourne simplement le contenu de la case
      return $data[$index];
    }
  }

  // Sinon on retourne une chaîne vide
  return "";
}

function the_value(array $data, $index ){
  return get_the_value($data, $index);
}

?>
<?php

function get_the_value(array $data, $index ){

  // Si on a trouvé $index sous la forme de "index[subindex1][subindex2][...]"
  if ( preg_match_all("(\[(.*?)\])", $index, $match) > 0 ){
    $index = substr( $index, 0, strpos( $index, "[" ) );
    $subindexes = $match[1];
  }

  // Si $index est bien présent dans le tableau $data
  if ( isset($data[$index]) ) {

    // Si l'élément existe, on vérifie qu'il nest pas vide
    if ( !empty($data[$index]) ) {

      // S'il contient un tableau :
      if ( is_array($data[$index]) ) {
        // Unserializing
        foreach ($data[$index] as $key => $value) {
          $unserialized_value = @unserialize( $value );
          if ( $unserialized_value !== false ) {
            $data[$index] = $unserialized_value;
          }
        }

        // On créer une phrase de recherche pour le paramètre $index de get_the_value();
        $first_subindex = $subindexes[0];
        unset($subindexes[0]);
        $searching_index = $first_subindex;
        if( is_array($subindexes) && !empty($subindexes) ){
          $searching_index .= "[" . implode("][", $subindexes) . "]";
        }

        // Si on a bien un $searching de défini, on appelle la fonction de façon récursive pour parcourir tout le tableau
        if ( isset($searching_index) ){
          return get_the_value($data[$index],  $searching_index);
        }

        else {
          // WP SINGLE : Si l'élément est bien un tablea, qu'il n'a qu'un élément, qu'il n'est pas vide et qu'il est bien accessible
          if ( is_array($data[$index]) && count($data[$index]) === 1 && !empty($data[$index]) && isset($data[$index][0]) ){
            return $data[$index][0];
          }

          return "";
        }
      }

      // Unserialize
      $unserialized_value = @unserialize( $value );
      if ( $unserialized_value !== false ) {
        $data[$index] = $unserialized_value;
      }

      // Si ce n'est pas un tableau, on retourne simplement le contenu de la case
      return $data[$index];
    }
  }

  // Sinon on retourne une chaîne vide
  return "";
}

$data = array(
  "main"  => array(
    "term_id" => 217,
    "name"    => "Agence Originis",
    "slug"    => "lieu-de-test"
  ),
  "meta"  => array(
    "adresse" => ["5 Square De La Résistance, 58000 Nevers, France"],
    "complement-adresse"  => [""],
    "coords-clean"  => array(
      "lat" => "46.99212000000003",
      "lng" => "3.1605839999999716"
    ),
    "coords"    => array('a:2:{s:3:"lat";s:17:"46.99212000000003";s:3:"lng";s:18:"3.1605839999999716";}')
  ),

  "test"    => "test1",
  "index"   => array(
    "sub1"    => array(
      "sub1val"   => "sub1val",
      "sub2"      => array(
        "sub2val"   => "sub2val",
        "sub3"      => array(
          "sub3val"   => "sub3val",
          "sub4"      => "sub4value"
        )
      )
    ),
  ),
);

$tests = array(
  array(
    "index"   => "meta[adresse]",
    "expected"=> "5 Square De La Résistance, 58000 Nevers, France"
  ),
  
  array(
    "index"   => "meta[complement-adresse]",
    "expected"=> ""
  ),

  array(
    "index"   => "meta[coords][lat]",
    "expected"=> "46.99212000000003"
  ),
  array(
    "index"   => "meta[coords-clean][lat]",
    "expected"=> "46.99212000000003"
  ),

  array(
    "index"   => "test",
    "expected"=> "test1"
  ),
  array(
    "index"   => "index[sub1][sub1val]",
    "expected"=> "sub1val"
  ),
  array(
    "index"   => "index[sub1][sub2][sub2val]",
    "expected"=> "sub2val"
  ),
  array(
    "index"   => "index[sub1][sub2][sub3][sub4]",
    "expected"=> "sub4value"
  ),
  array(
    "index"   => "index[sub1]",
    "expected"=> null,
  ),

);
?>

<!DOCTYPE html>
<html lang="fr" dir="ltr">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title></title>
  <meta name="description" content=""/>

  <link rel="stylesheet" type="text/css" href="#" />

  <style>
    * { font-family: sans-serif; }
    code, pre { font-family: monospace; color: rgb(14, 148, 233); font-weight: bold;}
    td, th {
      border: solid 1px #888;
      padding: 5px;
    }

    table{
      border-collapse: collapse;
    }
  </style>
</head>

<body>

  <h2>Données :</h2>
  <div>
    <!-- <pre>
      array(
        "test"    => "test1",
        "index"   => array(
          "sub1"    => array(
            "sub1val"   => "sub1val",
            "sub2"      => array(
              "sub2val"   => "sub2val",
              "sub3"      => array(
                "sub3val"   => "sub3val",
                "sub4"      => "sub4value"
              )
            )
          ),
        ),
      );
    </pre> -->

    <pre><?php var_dump($data); ?></pre>
  </div>

  <h2>Tests</h2>
 <table style="width:100%">

   <thead style="text-align:left">
     <tr>
       <th>
         valeur <code>$index</code>
       </th>

       <th>
         résultat
       </th>

       <th>
         résultat attendu
       </th>

       <th>
         correct ?
       </th>
     </tr>
   </thead>

   <tbody>
     <?php foreach($tests as $test){ ?>
      <tr>
        <td><pre><?php echo $test["index"]; ?></pre></td>
        <td><pre><?php var_dump(get_the_value($data, $test["index"] )) ?></pre></td>
        <td><code><?php var_dump($test["expected"]); ?></code></td>
        <td><?php echo (get_the_value($data, $test["index"]) == $test["expected"]) ? '<span style="color:green;font-weight:bold">OUI</span>' : '<span style="color:red;font-weight:bold">NON</span>' ?></td>
      </tr>
    <?php } ?>
   </tbody>

 </table>


</body>
</html>