user5175034
user5175034

Reputation:

Convert CSV Containing Some Boolean Values to Array

I've been using a little function for years to convert comma-separated values to arrays but have come across an instance where the values contain Booleans which seem to be passed as strings so are true even when they are not supposed to be.

Seeing that this is normal, I found a little snippet of code that I tried and it works well on values that are already in an array but not on those that are from CSV. What can I do to keep the TRUE/FALSE values as Boolean rather than strings?

// Makes array from character-separated values; default comma
function csv2Array($string, $separator = ',') {
  //Explode on comma
  $vals = explode($separator, $string);

  //Trim whitespace
  foreach($vals as $key => $val) :
    $vals[$key] = trim($val);
  endforeach;
  //Return empty array if no items found
  return array_diff($vals, array(""));
}

function boolify($var) {
    $ret = array();
    if( is_array( $var ) ) foreach( $var as $ek=>$ev ) $ret[$ek] = boolify( $ev );
    else if( $var === strtolower('false')) $ret = FALSE;
    else if( $var === strtolower('true')) $ret = TRUE;         
    else $ret = $var;
    return $ret;
}

$Buttons = "Save New,
    Save Changes,
    FALSE,
    Delete Entry,
    Are you sure?,
    FALSE, 
    Save Copy, 
    FALSE, 
    Reset Typing, 
    FALSE, 
    Submit Clear";

$AsArray = csv2Array($Buttons,",");

var_dump(boolify($AsArray));

array(11) { 
[0]=> string(12) "Save New" 
[1]=> string(19) " Save Changes" 
[2]=> string(12) " FALSE" 
[3]=> string(19) " Delete Entry" 
[4]=> string(20) " Are you sure?" 
[5]=> string(12) " FALSE" 
[6]=> string(17) " Save Copy" 
[7]=> string(13) " FALSE" 
[8]=> string(20) " Reset Typing" 
[9]=> string(13) " FALSE" 
[10]=> string(20) " Submit Clear" } 

expected Booleans to be bool(FALSE)

NOTE: Fully functional boolify() is:

function boolify($var) {
    $ret = array();
    if (is_array($var)) foreach($var as $ek=>$ev) $ret[$ek] = boolify($ev);
    elseif (strtolower($var) === 'false') $ret = FALSE;
    elseif (strtolower($var) === 'true') $ret = TRUE;
    else $ret = $var;
    return $ret;
}

UPDATED: I had to add $ret = array(); to the boolify() function to eliminate occasional errors. If running PHP 7.X, it can have $ret = [];

Upvotes: 1

Views: 283

Answers (1)

sam
sam

Reputation: 2984

As it has been mentioned in the comments csv values are type-less. That means you will not see it as boolean true or false.

PHP does not require (or support) explicit type definition in variable declaration; a variable's type is determined by the context in which the variable is used. That is to say, if a string value is assigned to variable $var, $var becomes a string. If an integer value is then assigned to $var, it becomes an integer.

One thing you can do to make convert their types is to cast it. PHP allows you to change types (when valid). To learn more about this you can read their documentation here.

For example:

$stringBoolean = 'true';

echo type($stringBoolean); // string

echo type((bool) $stringBoolean); // bool

In practice you could do something like this:

function csv2Array($string, $separator = ',') {
  //Explode on comma
  $vals = explode($separator, $string);

  //Trim whitespace
  foreach($vals as $key => $val) :

    if( $val == 'FALSE' || $val == 'TRUE' ) {
      $val = (bool) $val;
    }

    $vals[$key] = trim($val);
  endforeach;

  //Return empty array if no items found
  return array_diff($vals, array(""));
}

Or if you want to keep your boolify() function you can do this:

/**
 * Cast type to bool
 *
 * @param   string $value
 * @return  mixed
 */
function boolify( string $value )
{

  if( strtolower($value) === 'false' || strtolower($value) === 'true' )
    return (boolean) $value;


  return $value;

}

As a side note, I would recommend not passing an array to then reloop back to its own function... Do that outside of the function, keep it as a simple as you can. When adding unnecessary noise you make your code more complex it ought be.

Upvotes: 1

Related Questions